Подходит ли сообщение «Ошибка сегментации» под STDERR?

17

Я запустил исполняемый файл в bash

./code > log

Он показывает случайные сообщения об ошибках на терминале, тогда как все операторы printf попадают в файл журнала. Я перезапускаю это как ниже

./code >& log

Теперь случайные сообщения об ошибках также попадают в журнал. Но если есть ошибка сегментации, она все равно отображается на терминале. Почему? Как сделать так, чтобы сообщение Segmentation fault (core dumped)попадало в файл журнала?


пользователь $ bash --version

GNU bash, версия 4.2.24 (1) -релиз (i686-pc-linux-gnu)

user13107
источник

Ответы:

14

Ошибка сегментации является сигналом, если вы не поймаете это, то ваша программа будет прервана, и ваша оболочка выведет это на свой stderr (а не на stderr вашей программы).

Когда это происходит, ваша программа или оболочка могут предпринимать определенные действия, либо программа перехватывает сигнал, либо ваша оболочка перехватывает сигнал SIGCHILD и затем проверяет состояние выхода вашего ребенка.

cjh
источник
1
@ user13107help trap
Карлос Кампдеррос
2
Ага. понял. если кому-то интересно, вот что я сделал pastebin.com/QyeJYYHC
user13107
1
Команда оболочки trapперехватывает сигналы, отправленные в оболочку . Так что поймать того, кого отправляют в вашу программу, не получится.
Дероберт
1
@ warl0ck можно поймать segfault так же, как вы ловите любой сигнал, однако это может привести к неопределенному поведению, но если вы знаете, что делаете, вы можете хотя бы умереть разумным способом. ОП хотел напечатать на stderr, в этом случае перехватить ошибку и печать безопасна.
cjh
1
@ warl0ck: вы можете, это просто очень плохая идея делать что-либо в обработчике, кроме входа и выхода. Есть несколько специализированных случаев использования.
Linuxios
19

Сообщение «ошибка сегментации» выводится в stderr, но это стандартная ошибка оболочки, а не стандартная ошибка программы. Оболочка печатает это сообщение, когда обнаруживает, что программа завершилась из-за сигнала.

Вы можете заставить сообщение замолчать, перенаправив stderr вокруг части скрипта оболочки, которая запускает программу:

{ ./code; } >&log
Жиль "ТАК - прекрати быть злым"
источник