【问题标题】:What are the pros and cons of collecting libc backtrace always?总是收集 libc 回溯的优缺点是什么?
【发布时间】:2012-12-21 20:35:02
【问题描述】:

正如问题所述,总是在所有错误函数和信号处理程序中收集基于软件的回溯(如使用 libc 回溯 http://www.gnu.org/software/libc/manual/html_node/Backtraces.html)是否有用?

它对调试各种各样的错误(如内存、并发错误等)不是很有帮助吗?我猜它不会损害正常性能,并且只会在错误路径中触发。

【问题讨论】:

    标签: gdb glibc backtrace


    【解决方案1】:

    正如问题所述,始终收集基于软件的回溯是否有用

    是的,在以下情况下拥有崩溃堆栈跟踪通常非常有用:

    • 您的代码在您自己的环境中运行,您不必担心堆栈跟踪会泄露任何秘密。
    • 当崩溃处理程序没有进一步损坏 coredump、没有挂起等时。

    喜欢使用 libc 回溯

    glibc backtrace 在特定条件下调用calloc,在崩溃处理程序中是不安全的。它可能导致挂起和上述进一步的损坏。编写一个能够以异步信号安全的方式可靠地打印堆栈跟踪的崩溃处理程序并非易事。

    为什么“标准”应用程序中的错误函数不调用回溯?

    考虑cat /no/such/file。目前它产生:

    cat: /no/such/file: No such file or directory
    

    这是您真正需要知道的全部。让这个印刷品做其他任何事情都是没有用的。如果你有很多这样的文件,并且 cat 为每个文件打印一个完整的堆栈跟踪,你会得到很多页的错误输出,这只会让找到真正的问题变得更加困难。

    对于致命的信号处理程序(例如SIGSEGV),答案是大多数“标准”应用程序实际上并不处理此类信号,而只是使用默认操作,这会产生核心转储。

    但如果他们确实捕捉到了信号,从信号处理程序中调用backtracebacktrace_symbolsbacktrace_symbols_fd 将同样不安全,并且可能死锁,这比简单地转储核心要糟糕得多。考虑一下如果您有一个包含 1000 个命令的长时间运行的脚本会发生什么。您启动它,一周后发现它没有任何进展,因为第二个命令在尝试打印崩溃堆栈跟踪时崩溃并死锁。

    【讨论】:

    • 感谢您的信息!我想知道为什么 Coreutils 等标准应用程序中的错误函数默认不调用回溯?
    • @user655617 “为什么要执行错误函数……不调用回溯?”您是指错误函数(例如“cat unreadable-file”),还是指崩溃函数?如果是前者,堆栈跟踪可能只会增加噪音。如果是后者,我认为您没有理解答案的“可能导致挂起”部分——在没有堆栈跟踪的情况下崩溃肯定要好得多,然后(有时)无限期挂起。
    • Hmm.. 对于错误函数:为什么堆栈跟踪只会增加噪音?对于崩溃函数:我理解您担心在信号处理程序中调用 backtrace() 和 backtrace_symbols() 不安全,但我们不能使用 backtrace_symbols_fd() 来克服这个问题吗?
    • @user655617 我已经更新了答案。 backtrace_symbols_fdbacktrace 更安全。是什么让你不这么认为?
    • 好吧,我读到backtrace_symbols_fd 不会调用malloc,因此可以在后一个函数可能失败link 的情况下使用,这在link 中也提到过。那么,为什么它也 not 安全?另外,我猜ioctl 调用使用printk 的设备对于信号处理程序也是不安全的?
    猜你喜欢
    • 2014-01-24
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多