Ogólnie rzecz biorąc, nie sądzę, że możesz niestety. (Niektóre systemy operacyjne mogą to zapewniać, ale nie znam tych, które znam.)
Dokument referencyjny dotyczący limitów zasobów: getrlimitz POSIX 2008.
Weźmy na przykład limit procesora RLIMIT_CPU.
- Jeśli proces przekroczy miękki limit, zostanie wysłany
SIGXCPU
- Jeśli proces przekroczy twardy limit, otrzyma zwykły
SIGKILL
Jeśli potrafisz wait()w swoim programie, możesz stwierdzić, czy został zabity SIGXCPU. Ale nie można było odróżnić SIGKILLwysłanego za złamanie twardego limitu od zwykłego starego zabójstwa z zewnątrz. Co więcej, jeśli program obsługuje XCPU, nie zobaczysz tego nawet z zewnątrz.
To samo dotyczy RLIMIT_FSIZE. Widać SIGXFSZod wait()stanu, jeśli program nie poradzić. Ale gdy limit rozmiaru pliku zostanie przekroczony, jedyną rzeczą, która się zdarza, jest to, że kolejne operacje we / wy, które spróbują ponownie przetestować ten limit, po prostu otrzymają EFBIG- zostanie to obsłużone (lub niestety) wewnętrznie przez program. Jeśli program działa SIGXFSZtak samo jak powyżej - nie będziesz o tym wiedział.
RLIMIT_NOFILE? Cóż, nawet nie dostajesz sygnału. openi przyjaciele właśnie wracają EMFILEdo programu. Nie przeszkadza to w inny sposób, więc zawiedzie (lub nie) w jakikolwiek sposób, aby zakodować go w takiej sytuacji.
RLIMIT_STACK? Dobry stary SIGSEGV, nie można go odróżnić od wyniku z innych powodów, aby go dostarczyć. (Będziesz wiedział, że to właśnie zabiło proces, ze waitstatusu).
RLIMIT_ASi RLIMIT_DATApo prostu zrobi, malloc()a kilka innych zacznie się nie powieść (lub otrzyma, SIGSEGVjeśli limit AS zostanie przekroczony podczas próby rozszerzenia stosu w systemie Linux). O ile program nie jest bardzo dobrze napisany, prawdopodobnie w tym momencie prawdopodobnie losowo się nie powiedzie.
W skrócie, ogólnie mówiąc, awarie albo nie różnią się wyraźnie od innych przyczyn śmierci procesowej, więc nie możesz być pewien, albo można je całkowicie obsłużyć z programu, w którym to przypadku decyduje, czy / kiedy / jak będzie przebiegać, nie ty z zewnątrz.
O ile mi wiadomo, możesz napisać trochę kodu, który rozwidla twój program, czeka na niego i:
- sprawdź status wyjścia w celu wykrycia
SIGXCPUi SIGXFSZ(AFAIK, sygnały te będą generowane przez system operacyjny tylko w przypadku problemów z ograniczeniem zasobów). W zależności od swoich potrzeb, można założyć, że SIGKILLi SIGSEGVbyły również związane z ograniczeniami zasobów, ale to jest trochę odcinku.
- spójrz na to, co możesz uzyskać ze
getrusage(RUSAGE_CHILDREN,...)swojej implementacji, aby uzyskać wskazówki na temat innych.
Mogą istnieć narzędzia specyficzne dla systemu operacyjnego, które mogą w tym pomóc (być może rzeczy takie jak ptraceLinux lub Solaris dtrace), lub ewentualnie techniki typu debuggera, ale będzie to jeszcze bardziej związane z konkretną implementacją.
(Mam nadzieję, że ktoś inny odpowie magiczną rzeczą, której jestem całkowicie nieświadomy.)
mallocale niestety nie rozwiązuje to ogólnie problemu z pamięcią, ponieważ ogólnie chodzi o wywołanie systemowebrk(mam rację?).