2012-01-12 14 views
9

Mam zarejestrowany program obsługi sygnału w moim programie. Po otrzymaniu niepożądanego sygnału (SIGABRT), wywołuję "exit (-1)" w procedurze obsługi sygnału, aby opuścić proces. Ale jak zauważyłem w kilku okazjach, wywołuje exit(), ale nie kończy procesu.Czy exit() nie może zakończyć procesu?

Emisja została losowo wygenerowana i mocno podejrzewam, że wykonano exit().

Czy mogą istnieć jakiekolwiek powody lub przypadki, w których exit() może nie zakończyć procesu.

Dzięki.

+1

Ja zdecydowanie radzę szukać innej przyczyny błędu niż funkcji typu 'exit'.Prawie zawsze, gdy myślisz, że jest błąd w kompilatorze lub standardowej bibliotece itp., To twój błąd powoduje błąd. – Shahbaz

+3

@Shahbaz: Mandar nie pyta o błąd w implementacji lub sugeruje, że taki istnieje. Pytanie brzmi, czy 'exit' jest określony, aby zawsze zakończyć program, a odpowiedź brzmi nie (a zwłaszcza nie, jeśli wywołana z obsługi sygnału). –

+0

Dlaczego po prostu ustawić program obsługi dla SIGABRT, aby zakończyć()? Cokolwiek robisz w obsłudze sygnału, wykonaj je w wywołaniu atexit(). –

Odpowiedz

13

Czy wywołujesz exit() z obsługi sygnału?

W man 7 signal, sekcja funkcji async-signal-safe można zobaczyć wszystkie funkcje, które są gwarantowane do pracy, gdy wywołany z obsługi sygnału:

funkcja obsługi sygnału musi być bardzo ostrożnym, gdyż przetwarzanie w innym miejscu może zostać przerwane w którymś z arbitralnych punktów w wykonaniu programu. POSIX ma pojęcie "bezpiecznej funkcji". Jeśli sygnał przerywa wykonywanie niebezpiecznej funkcji, a funkcja obsługi wywołuje funkcję niebezpieczną, wówczas zachowanie programu jest niezdefiniowane.

POSIX.1-2004 (znany również jako POSIX.1-2001 Technicznego Sprostowanie 2) wymaga wdrożenia do gwarancji, że następujące funkcje mogą być bezpiecznie nazwie wewnątrz obsługi sygnału:

Nie można zobacz funkcje _Exit(), _exit() i abort(), ale w szczególności nie exit(). Więc nie powinieneś wywoływać tego z obsługi sygnału.

Brzydką rzeczą jest to, że nawet jeśli wywołasz niebezpieczną funkcję z obsługi sygnału (printf()?), To będzie działać przez większość czasu ... ale nie zawsze.

+1

Wywołanie niebezpiecznej funkcji sygnału asynchronicznego z procedury obsługi sygnału jest * całkowicie legalne *, chyba że sygnał przerwał inną niebezpieczną funkcję asynchronicznego sygnału. Wyjaśnia to powód, dla którego działa "przez większość czasu", ale oznacza to również, że możesz używać niebezpiecznych sygnałów asynchronicznych w procedurach obsługi sygnału nawet w poprawnym, niezawodnym kodzie, jeśli dbasz o to, aby funkcja obsługi sygnału nie mogła przerwać niebezpiecznej (na przykład pozostawienie sygnału zamaskowanego przez większość czasu i odblokowanie go tylko podczas wykonywania czysto arytmetycznych lub bezpiecznych sygnałów asynchronicznych wywołań bibliotek, takich jak deskryptor plików IO i 'select'). –

+0

@R .. Masz rację, oczywiście. Ale w praktyce trudno jest to zapewnić, z wyjątkiem bardzo szczególnych przypadków. Osobiście uważam, że jest o wiele wygodniej, aby uniknąć niebezpiecznych funkcji. – rodrigo

+1

Zobacz też: http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html –

3

Tak, istnieją pewne okoliczności, takie jak:

Wyjście() funkcja musi najpierw wywołać wszystkie funkcje zarejestrowane przez atexit() w kolejności odwrotnej do ich rejestracji, chyba że funkcja nazywa po wszelkich wcześniej zarejestrowanych funkcjach, które zostały już wywołane w momencie rejestracji. Każda funkcja jest wywoływana tyle razy, ile została zarejestrowana. Jeśli podczas wywołania dowolnej funkcji wywołane zostanie wywołanie funkcji longjmp(), która zakończyłaby wywołanie zarejestrowanej funkcji, zachowanie jest niezdefiniowane.

Jeśli funkcja zarejestrowana przez wywołanie atexit() nie powróci, pozostałe zarejestrowane funkcje nie zostaną wywołane, a pozostałe operacje exit() nie zostaną zakończone. Jeśli exit() jest wywoływane więcej niż jeden raz, zachowanie jest niezdefiniowane.

Zobacz stronę POSIX pod numerem exit.

Aby uzyskać więcej informacji, dołącz debugera, gdy dojdziesz do sytuacji i spójrz na stos połączeń.

Powiązane problemy