调试Mac上的分段错误?

时间:2011-12-03 19:47:11

标签: c macos debugging gcc segmentation-fault

我在使用Mac上运行导致分段错误的程序时出现问题。我正在为IOCCC整理一个条目,这意味着我的程序有以下几点:

  • 这是一个名为prog.c
  • 的单个文件中的一个非常小的C程序
  • 我不会在这里发布,因为它不会帮助(并且可能会使比赛条目无效)
  • 使用“cc -o prog prog.c -Wall”
  • 在gcc下完全编译
  • 尽管(或者更确切地说,因为它)包含了许多奇怪的C用途,但它的构造非常谨慎。我不知道它的任何一部分是粗心的记忆(这并不是说不可能存在错误,只是如果它们不可能是显而易见的那些)
  • 我主要是Windows用户,但几年前我成功编译并在几台Windows机器,几台Mac机和一个Linux机器上运行它,没有任何问题。从那时起,代码没有改变,但我无法访问这些机器。

我没有重新测试的Linux机器,但作为最后的测试,我尝试在MacBook Pro上编译和运行它 - Mac OSX 10.6.7,Xcode 4.2(即GCC 4.2.1)。同样,它从命令行干净地编译。似乎在Mac上键入“prog”不会使编译的程序运行,但“open prog”似乎。大约10秒钟没有任何事情发生(我的程序成功运行大约需要一分钟),但它只是说“分段错误”,并结束。

以下是我尝试使用this useful StackOverflow thread收集的答案来追踪问题:

  • 在Windows上,用_ASSERTE(_CrtCheckMemory())填充代码; - 代码运行速度慢,但运行成功。没有任何断言被触发(当我故意添加可怕的代码以确保_CrtCheckMemory和_ASSERTE按预期工作时,它们会这样做,但不会这样做)
  • 在Mac上,我尝试了Mudflap。我尝试使用“g ++ -fmudflap -fstack-protector-all -lmudflap -Wall -o prog prog.c”的变体构建代码,这只会产生错误“cc1plus:error:mf-runtime.h:没有这样的文件或目录“。谷歌搜索这个问题没有提出任何结论,但似乎有一种感觉,Mudflap在Mac上不起作用。
  • 同样在Mac上,我尝试了Valgrind。我安装并构建了它,并使用“cc -o prog -g -O0 prog.c”构建了我的代码。使用命令“valgrind --leak-check = yes prog”运行Valgrind会产生错误“valgrind:prog:command not found”。记住你让你在Mac上“打开”一个exectable我尝试了“valgrind --leak-check = yes open prog”,这似乎运行程序,并运行Valgrind,它没有发现任何问题。但是,即使我使用专门设计用于触发错误消息的程序运行它,Valgrind也未能为我找到问题。我在Mac上打破了吗?
  • 我尝试在Xcode中运行程序,在Product-> Edit Scheme ...菜单中勾选了所有Diagnostics复选框,并在malloc_error_break中设置了符号断点。断点没有被击中,代码在包含一个东西(“dlopen”)的callstack中停止,并且在输出窗口中显示的唯一注意事项如下:
  

警告:无法恢复以前选择的框架。   现在没有可用于编程的内存:调用malloc不安全

我没有想法。我试图让Cygwin设置(虽然需要花费数小时),看看是否有任何工具可以正常工作,但如果失败那么我就会感到茫然。当然必须有一些能够跟踪Mac上分段错误原因的工具吗?

3 个答案:

答案 0 :(得分:7)

您是否使用-g编译并在gdb内运行?应用程序崩溃后,您可以获得bt的回溯,该回溯应显示崩溃发生的位置

答案 1 :(得分:1)

更现代的lldb风味

$ lldb --file /path/to/program
...
(lldb) r
Process 89510 launched
...
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x726f00)
  * frame #0: 0x00007fff73856e52 libsystem_platform.dylib`_platform_strlen + 18
...

答案 2 :(得分:0)

在许多情况下,macOS 将最近的程序崩溃日志存储在 ~/Library/Logs/DiagnosticReports/ 文件夹下。

通常我会在 macOS 上进行故障排除时尝试以下步骤:

  1. 清除 ~/Library/Logs/DiagnosticReports/ 下的现有崩溃日志
  2. 再次运行程序以重现问题
  3. 等待几秒钟,崩溃日志将出现在文件夹下。崩溃日志的名称类似于 {your_program}_{crashing_date}_{id}_{your_host}.crash
  4. 使用文本编辑器打开崩溃日志,搜索关键字 Crashed 以找到导致崩溃的线程。它会显示崩溃期间的堆栈跟踪,并且在许多情况下,还会记录导致崩溃的确切源代码行。

一些链接:

[1] https://mac-optimization.bestreviews.net/analyze-mac-crash-reports/