Czy komunikat „Błąd segmentacji” znajduje się pod STDERR?


17

Uruchomiłem plik wykonywalny bash

./code > log

Pokazuje sporadyczne komunikaty o błędach na terminalu, podczas gdy wszystkie instrukcje printf przechodzą do pliku dziennika. Ponownie uruchamiam go jak poniżej

./code >& log

Teraz sporadyczne komunikaty o błędach przechodzą również do dziennika. Ale jeśli wystąpi błąd segmentacji, nadal jest wyświetlany na terminalu. Dlaczego? Jak sprawić, aby wiadomość Segmentation fault (core dumped)trafiła do pliku dziennika?


user $ bash --version

GNU bash, wersja 4.2.24 (1) -release (i686-pc-linux-gnu)

Odpowiedzi:


14

Błąd segmentacji jest sygnałem, jeśli tego nie złapiesz, wtedy twój program zostanie zakończony, a twoja powłoka wydrukuje to na swoim stderr (a nie na stderr twojego programu).

Możliwe jest, że Twój program lub powłoka podejmie określone działania, gdy to nastąpi, albo przez program przechwytujący sygnał, albo przez powłokę wychwytującą sygnał SIGCHILD, a następnie sprawdzającą status wyjścia dziecka.


1
@ user13107help trap
Carlos Campderrós

2
tak. Rozumiem. jeśli ktoś jest zainteresowany, oto co zrobiłem pastebin.com/QyeJYYHC
user13107

1
Komenda powłoki trapprzechwytuje sygnały wysyłane do powłoki . Więc nie zadziała złapanie tego wysyłanego do twojego programu.
derobert

1
@ warl0ck można złapać segfault w ten sam sposób, w jaki odbierasz dowolny sygnał, jednak może to prowadzić do nieokreślonego zachowania, ale jeśli wiesz, co robisz, możesz przynajmniej umrzeć w rozsądny sposób. OP chciał wydrukować na stderr, w tym przypadku złapanie segfault i drukowanie jest bezpieczne.
cjh

1
@ warl0ck: możesz, to bardzo zły pomysł, aby zrobić cokolwiek w module obsługi, ale zalogować się i wyjść. Istnieją jednak pewne wyspecjalizowane przypadki użycia.
Linuxios,

19

Komunikat „błąd segmentacji” jest drukowany na stderr, ale jest to standardowy błąd powłoki, a nie błąd standardowy programu. Powłoka drukuje ten komunikat, gdy wykryje, że program zakończył się z powodu sygnału.

Możesz wyciszyć wiadomość, przekierowując stderr wokół części skryptu powłoki, która uruchamia program:

{ ./code; } >&log
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.