Как говорится в вопросе, полезно ли всегда собирать программную трассировку?
Да, обычно очень полезно иметь трассировку стека сбоев, когда:
- ваш код работает в вашей собственной среде, и вы не беспокоитесь о том, что трассировка стека раскроет какие-либо секреты.
- когда обработчик сбоя не портит дамп ядра, не зависает и т. д.
как использование обратной трассировки libc
glibc backtrace
вызывает calloc
при определенных условиях и небезопасен в обработчике сбоев. Это может вызвать как зависание, так и дальнейшее повреждение, упомянутое выше. Написание обработчика сбоя, который будет надежно печатать трассировку стека безопасным для асинхронных сигналов способом, довольно нетривиально.
почему тогда функции ошибок в «стандартных» приложениях не вызывают обратную трассировку?
Рассмотрим cat /no/such/file
. В настоящее время производит:
cat: /no/such/file: No such file or directory
и это все, что вам действительно нужно знать. Делать этот отпечаток чем-либо еще бесполезно. Если бы у вас было много таких файлов, и cat выводил полную трассировку стека для каждого, вы бы получили много страниц вывода ошибок, и это только затруднило бы поиск реальной проблемы.
Для обработчиков фатальных сигналов (например, SIGSEGV
) ответ заключается в том, что большинство «стандартных» приложений на самом деле не обрабатывают такие сигналы, а просто используют действие по умолчанию, которое создает дамп памяти.
Но если бы они поймали сигнал, вызов backtrace
, backtrace_symbols
или backtrace_symbols_fd
из обработчика сигнала был бы в равной степени небезопасен и мог бы привести к взаимоблокировке, что намного хуже, чем просто сброс ядра. Подумайте, что произойдет, если у вас есть долго работающий скрипт с 1000 командами. Вы запускаете ее, а через неделю обнаруживаете, что она не продвинулась ни на йоту, потому что вторая команда потерпела крах и зашла в тупик, пытаясь распечатать трассировку стека сбоя.
person
Employed Russian
schedule
08.01.2013