【问题标题】:Can one use libSegFault.so to get backtraces for SIGABRT?可以使用 libSegFault.so 获取 SIGABRT 的回溯吗?
【发布时间】:2013-09-13 10:18:57
【问题描述】:

魔法咒语

LD_PRELOAD=/lib/libSegFault.so someapp

使用 libSegFault.so 运行 someapp,提供有关 SIGSEGV 的回溯信息,如 many different places 中所述。

除了使用类似于signal(7) 的方法使SIGABRT 调用SIGSEGV 处理程序之外,还有其他方法可以让libSegFault 为assert(3) 故障提供回溯信息吗?

【问题讨论】:

    标签: stack-trace glibc sigabrt segmentation-fault backtrace


    【解决方案1】:
    env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/libSegFault.so someapp
    

    请注意,预加载库的实际路径可能不同。在我的机器上,我会使用

    env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so some-64bit-app
    

    env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so some-32bit-app
    

    取决于我运行的应用程序是 64 位还是 32 位编译的。 (可以使用file查看。)


    source 告诉我们三个环境变量定义了libSegFault.so 的行为方式:

    • SEGFAULT_SIGNALS:导致堆栈跟踪的信号列表。 默认值为SIGSEGV。已定义但为空的 SEGFAULT_SIGNALS 表示没有信号导致堆栈跟踪。 支持的值为segvillabrtfpebus(在具有 SIGBUS 信号的系统上)、stkflt(在具有 SIGSTKFLT 信号的系统上)和all(针对所有这些) .

    • SEGFAULT_USE_ALTSTACK:如果在环境中定义,libSegFault.so 使用替代堆栈作为堆栈跟踪信号。 如果您正在调试堆栈损坏,这可能会派上用场。

    • SEGFAULT_OUTPUT_NAME:如果在环境中定义,堆栈跟踪将写入此文件而不是标准错误。

    说实话,我最初是通过使用 strings /lib/libSegFault.so | sed -e '/[^0-9A-Z_]/ d' 检查库来发现这些的。所有标准库(libSegFault.so 已成为 GNU C 库的一部分)都可以通过环境变量进行调整,因此使用类似该命令的命令来转储任何看起来像环境变量名称的字符串是查找要搜索的内容的快速方法。在"SEGFAULT_SIGNALS" "SEGFAULT_OUTPUT_NAME" 上进行网络搜索会产生许多有用的链接;看到它现在是 GNU C 库的一部分,我去了source git 档案,找到了该库的实际源文件,并发布了我的答案。

    【讨论】:

    • 谢谢。 SEGFAULT_SIGNALS 的行为记录在哪里?我花了一些时间挖掘有关 libSegFault.so 的详细信息,结果一直空白。
    • @RhysUlerich:在源头上,sourceware.org/git/?p=glibc.git;a=blob;f=debug/…——我将从源头中收集到的描述添加到我的答案中,以防以后对某人有所帮助。
    • 另外,很抱歉没有早点授予赏金。不知道为什么我认为一旦我接受答案就会发生。再次感谢您为此花费的时间。
    • 你不需要完全限定的路径名​​,LD_PRELOAD=libSegFault.so 如果库在 dl 路径中就可以了。
    • @FernandoSilveira:我建议不要向初学者提及这一点,因为他们通常最终会在不同的库方向安装多个版本的库,当他们似乎无所事事时会感到悲伤和哀号有效果。当然,修复方法是验证在任何标准库目录中是否只有一个库副本,但位置因发行版而异(甚至取决于您是否安装了 multilib)。不,先生;引导他们使用完整的路径名肯定更好。
    【解决方案2】:

    与此类似,glibc 异常处理程序在堆损坏错误时将堆栈转储写入/dev/console

    如果您在非 tty(即 systemd 进程或其他分离的进程)中运行可执行文件,则崩溃输出会转到 /dev/null,这不是很有用。

    有一个未记录的功能将输出重定向到/dev/stderr。设置如下环境变量:

    export LIBC_FATAL_STDERR_=1
    

    这可以与 libSegFault.so 结合使用,以实现最大程度的取证。

    还值得一提的是,如果您还为 SIGABRT 启用回溯,这可能会给您两个堆栈跟踪,因为 glibc 首先进行堆栈跟踪,然后发出信号 SIGABRT ...然后 libSegFault 提供第二个堆栈跟踪。

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 2013-08-13
      • 2021-06-23
      • 2015-10-10
      • 2012-10-24
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多