【问题标题】:Debugging seg fault (can't modify source code or makefile)调试 seg 错误(无法修改源代码或 makefile)
【发布时间】:2016-04-28 15:56:28
【问题描述】:

我正在尝试在研究代码中调试 C 中的段错误。我无法修改源代码/makefile。由于我无法修改 makefile(即重新编译程序)并且未使用 -g 选项编译可执行文件,我假设这会将 gdb 调试抛出窗口?或者有没有办法在不使用-g编译可执行文件的情况下使用gdb?

我可以请求更改源代码,但我几乎可以肯定 seg 错误是由于我的一个输入文件造成的,所以它不应该是源代码问题。

有人建议我使用我不太熟悉的“strace”。这是我对程序进行 strace 时输出的结尾:

close(27)                               = 0
munmap(0x2abe4843d000, 65536)           = 0
write(2, "==== backtrace ====\n", 20==== backtrace ====
)   = 20
write(2, " 2 0x00000000000597bc mxm_handle"..., 113 2 0x00000000000597bc mxm_handle_error()  /var/tmp/OFED_topdir/BUILD/mxm-3.3.3055/src/mxm/util/debug/debug.c:641
) = 113
write(2, " 3 0x000000000005992c mxm_error_"..., 121 3 0x000000000005992c mxm_error_signal_handler()  /var/tmp/OFED_topdir/BUILD/mxm-3.3.3055/src/mxm/util/debug/debug.c:616
) = 121
write(2, " 4 0x00000037ccc326a0 killpg()  "..., 37 4 0x00000037ccc326a0 killpg()  ??:0
) = 37
write(2, " 5 0x00000000004ec6ef interpLema"..., 99 5 0x00000000004ec6ef interpLemansToMopar_linear()  /home/dzdang/w16/sources/mopar_bc_interp.c:559
) = 99
write(2, " 6 0x000000000040c4ee main()  /h"..., 68 6 0x000000000040c4ee main()  /home/dzdang/w16/sources/lemans.c:611
) = 68
write(2, " 7 0x00000037ccc1ed5d __libc_sta"..., 48 7 0x00000037ccc1ed5d __libc_start_main()  ??:0
) = 48
write(2, " 8 0x0000000000403c99 _start()  "..., 37 8 0x0000000000403c99 _start()  ??:0
) = 37
write(2, "===================\n", 20===================
)   = 20
brk(0x2958000)                          = 0x2958000
tgkill(15432, 15432, SIGSEGV)           = 0
rt_sigreturn(0x3c48)                    = 46993935941696
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault

任何想法这意味着什么?或者关于如何调试的任何建议?

【问题讨论】:

  • 错误的输入数据不应产生段错误。就是这样,真的。一条错误消息,比如“第 XX 行输入数据错误”,没问题。
  • 如何将命令直接编译到您的终端,而不使用 makefile 来获取带有调试信息的可执行文件?
  • 此代码涉及读取输入文件并将它们存储在动态分配的数组中。我在想也许输入文件是错误的,它导致不正确的读取(或根本没有读取),因此在尝试访问该数组时,它可能超出范围?这个程序没有太多的错误检查代码。
  • @MikeCAT 嗯。这对于很多源代码是否实用?我有超过 500 多个用 C&Fortran 编写的文件链接在一起。
  • 不过,总的来说,您可以通过非常仔细地检查输入文件以检查其有效性,甚至编写程序来验证它们,从而更有效地利用您的时间。

标签: c segmentation-fault gdb strace


【解决方案1】:

"...但我几乎可以肯定 seg 错误是由于我的输入文件之一"

那么你的调试应该集中在你的输入文件上。有输入规范吗?

如果您有许多输入文件并且手动检查文件是不可行的,您可以用 C 编写一个验证器,检查所有输入文件的格式是否正确并报告错误。有了这些经过验证的文件,相关程序就不会再崩溃了(希望如此)。

(编辑)

至于输入的调试,请尝试最小输入并将其扩展,直到您获得完整的输入。某个地方会发生崩溃,这可能会给您一个指示。

【讨论】:

    【解决方案2】:

    我认为这会将 gdb 调试抛到窗外?
    我几乎可以肯定 seg 错误是由于我的一个输入文件造成的,所以它不应该是源代码问题。

    你做了很多很多无根据的假设。

    1. SIGSEGV总是是源代码问题:无效输入应该产生错误,而不是崩溃。
    2. 您显示的strace 的输出包含文件和行信息,通常意味着程序实际上是使用-g 编译的。
    3. GDB 完全能够调试没有-g 编译的程序,但它需要熟练的操作员。
    4. 程序似乎会自行报告某种错误。不幸的是,您已经删除了该错误的所有相关部分,并且只显示了堆栈跟踪(如果没有早期的输出,这没有任何意义)。

    应该做什么:

    1. 停止做出无根据的假设和猜测。
    2. 编辑您的问题(或开始一个新问题),显示程序实际报告的错误。
    3. 在GDB下运行程序,观察到其实可以看到文件/行信息,可能参数和局部变量值。
    4. 阅读源代码,了解崩溃的方式和原因,检查崩溃点的变量,了解原因(即实际调试问题)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 2015-02-18
      • 2015-08-24
      • 2021-04-05
      • 2013-01-03
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多