【问题标题】:Handling POSIX signals: how to get stack trace without using backtrace_symbols?处理 POSIX 信号:如何在不使用 backtrace_symbols 的情况下获取堆栈跟踪?
【发布时间】:2014-01-22 12:11:31
【问题描述】:

我正在尝试将简单的崩溃日志记录添加到我的适用于 Mac OS 和 Linux 的 C++ 应用程序中。我对backtrace_symbols 的输出不满意。我想采用 backtrace() 返回的任何内容并手动构建堆栈跟踪(带有符号名称)。怎么做?我找不到一个例子,甚至找不到 backtrace() 返回的具体内容的解释。

更新:找到 this 代码 sn-p,但它无法在 OS X 上编译。

【问题讨论】:

  • @n.m.:我认为它甚至没有改进的能力。撇开玩笑不谈,对于初学者来说,我想获得一个损坏的函数名称列表,而无需解析字符串。
  • @n.m.:另外,我看不出是哪个线程实际导致了信号,但我猜这是backtrace 本身的问题。
  • “不想解析字符串”有点像“不想加数字”。解析字符串是程序员的工作,没有办法绕过它。
  • @n.m.:太棒了。让我们获取一些数据,编译成人类可读的字符串,然后忘记我们最初拥有该数据并解析字符串以获取我们的信息片段。听起来完全像程序员一直在做的事情。
  • 崩溃的线程(无效的操作码、总线错误、分段错误...)接收到信号。不是backtrace的问题。

标签: c++ gcc stack-trace backtrace signal-handling


【解决方案1】:

libunwind 具有 unw_get_proc_name 函数,它会为您提供堆栈帧的错位函数名称。该文档声称 unw_get_proc_name 在信号处理程序中是安全的。根据this,backtrace_symbols 使用malloc,因此在POSIX 信号处理程序中使用not safe

我不知道如何使用回溯返回来调用它,因此您可能还需要使用 libunwind。

【讨论】:

  • 谢谢,我在看 libunwind。我得到一个提示,它做了一些特定于架构的事情,并且不适用于 ARM,如果可以的话,我正在尝试首先编写符合 POSIX 的跨平台代码。
  • 我不知道该项目是否在 arm/osx 上得到官方支持,但在 apple.com 上托管了一份源代码副本,所以我假设它被人们使用并且他们提供补丁。我敢肯定手臂上的情况也差不多。
【解决方案2】:

查看man page for backtrace(),我看到backtrace 返回指向包含一堆地址的数组的指针。

backtrace_symbols() 将这些地址转换为符号,如果有调试符号,它会看到它。否则你会得到一个地址。

话虽如此,不使用backtrace_symbols() 是没有意义的。如果您不喜欢输出,请随意修改它,但您不会获得更多有用的回溯信息。

在您找到的示例中,他们以一种糟糕的方式模仿 backtrace_symbols()。另外,请注意第一条评论:

A hacky replacement for backtrace_symbols in glibc

【讨论】:

  • 修改输出意味着解析字符串(更不用说分配很多新字符串!),据我所知,没有明确的分隔符。但看起来我必须解析它,毕竟。
  • 我确实介意这条评论。不要在乎它是否可行。但是我的 OS X 10.9 上甚至不存在其中所需的一半。
  • @VioletGiraffe backtrace_symbols() 的输出是 c 字符串数组,但我的意思不是解析 c 字符串。创建 std::vector<std::string>> 并改为解析它。应该很容易做到。
猜你喜欢
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
相关资源
最近更新 更多