正如问题所述,在所有错误函数和信号处理程序中始终收集基于软件的回溯(如使用 libc 回溯http://www.gnu.org/software/libc/manual/html_node/Backtraces.html )是否有用?
对调试各种各样的错误(如内存、并发错误等)不是很有帮助吗?我想它不会损害正常性能,并且只会在错误路径中触发。
正如问题所述,在所有错误函数和信号处理程序中始终收集基于软件的回溯(如使用 libc 回溯http://www.gnu.org/software/libc/manual/html_node/Backtraces.html )是否有用?
对调试各种各样的错误(如内存、并发错误等)不是很有帮助吗?我想它不会损害正常性能,并且只会在错误路径中触发。
正如问题所述,始终收集基于软件的回溯是否有用
是的,在以下情况下进行崩溃堆栈跟踪通常非常有用:
就像使用 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 个命令的长时间运行的脚本会发生什么。您启动它,一周后发现它没有取得任何进展,因为第二个命令在尝试打印崩溃堆栈跟踪时崩溃并陷入僵局。