【问题标题】:reverse engineer OSX User Diagnostic Report stack trace逆向工程 OSX 用户诊断报告堆栈跟踪
【发布时间】:2015-05-29 00:22:31
【问题描述】:

我想找出用 C/C++ 编写的应用程序到底在哪里失败了。我无法直接调试应用程序,既不使用 gdb / lldb 也不使用 IDE,因为该应用程序是由程序启动的(它是 webots 机器人模拟软件的机器人控制器)。在 OSX 控制台中,我可以找到一个“用户诊断报告”,它甚至会在崩溃时显示轨迹跟踪。 我只需要找出崩溃发生在我的源代码中的确切位置,但我不理解以下堆栈跟踪语法:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       EXC_I386_GPFLT

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib               0x00007fff92d6b859 strtol_l + 77
1   controller_2                    0x0000000100006b57 main + 4839
2   controller_2                    0x00000001000010b4 start + 52

显然,在我的 int main() {} 函数中的某个地方 (+4839) 最终调用了 strtol_l(必须是间接的,因为在控制器代码中没有出现此函数调用)导致崩溃。

+ 4839 代表什么?它是内存块偏移量吗?它不能是源代码行号,因为控制器的源代码只有约 1200 行,并且控制器没有使用调试信息编译。

【问题讨论】:

  • 我会说+ 4839 是说它在进入main 后的第4839 条处理器指令中调用了strtol_l。如果你反汇编你运行的二进制文件,你应该能够找到它是什么指令,并且可能找到对周围程序集中熟悉的代码行的引用。
  • 这是一个字节数,距离main开头的偏移量。
  • 如果你重新编译控制器代码,使用'-ggdb'(这将使可执行文件显着变大)然后让它运行直到它出现段错误,然后堆栈跟踪将包括行号等
  • 当控制器软件段发生故障时,它会输出一个“核心”文件。使用该核心文件作为 gdb 的输入。 (让所有源代码对 gdb 可见,并使用(至少 '-g' 最好是 '-ggdb'名称,行号等。注意:由于您可能没有从源代码编译库,因此库函数中的细节仍然相当少,但是,问题的根源,在您的主函数中,将非常明显
  • 您可能对这个问题的答案感兴趣:stackoverflow.com/questions/16227845/…

标签: c++ c macos crash-reports webots


【解决方案1】:

您可以在 gdb 中调试您的机器人控制器进程,方法是使用 gdb attach 命令和您要调试的机器人控制器进程的 PID。这将允许 gdb 动态附加进程并对其进行调试,就好像它最初是从 gdb 启动的一样。这在此处的 Webots 文档中得到了很好的解释:http://www.cyberbotics.com/dvd/common/doc/webots/guide/section5.5.html

【讨论】:

  • 好吧,是的,你确实可以,但在我看来,这很难/不切实际。我正在运行 150 * 10 次模拟,并且崩溃发生在随机时间(不确定)。我必须编写一个脚本来查找所有 2 * 14 控制器的 PID,并将所有这些 PID 附加到所有 1500 个模拟中的每一个的 GDB。每次模拟后,我假设退出 GDB。我认为这不是找出问题所在的最简单方法:/
  • 那么,也许你可以尝试将gdb设置为你的机器人的控制器程序,并在controllerArg字段中设置你要调试的实际控制器的名称,加上-x选项和“运行" 命令,以便 gdb 立即开始运行控制器。但是,我不确定当您的一个控制器崩溃时会发生这种情况。我想,您应该从控制台启动 webbots 以查看 gdb 的输出。让我们知道这是否是一个可行的解决方案。
  • 嗯,我认为(之前不确定)段错误完全使 MacPro 崩溃。它早些时候崩溃了(我使用 TeamViewer 远程监控 MacPro 运行模拟,在某些时候屏幕变黑并且连接丢失。然后我必须物理重启 MacPro。)因为这刚刚发生,我希望有人可以重启MacPro 明天或下班后我会知道这是否可行。我确实添加了 -ggdb 作为编译标志,所以我很好奇我现在是否可以在用户诊断报告中看到更详细的堆栈跟踪信息。了解更多后会更新!
  • 将 gbd 设置为控制器程序不起作用。有一个 /controllers/gdb/gdb 文件夹结构,其中 gdb 是 /usr/local/bin/gdb 的符号链接不起作用。我对lldb尝试了同样的方法,但没有奏效。不过,这将是最好的选择。我读到 gdb 和 lldb 都支持调试多个线程/进程,所以它应该是可能的。我正在考虑编写一个新的控制器,它对 gdb 进行系统调用来运行真正的控制器。这行得通吗?
  • 我不认为它不起作用。这显然值得一试...随时通知我们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2019-06-16
  • 2012-01-29
  • 2011-07-27
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多