用Make and GCC编译C 程序后,我在运行时经历了分段故障。该程序只是在没有任何错误消息的情况下退出。
即使我没有在调试模式下编译程序,但通过使用GDB运行它,我实际上收到了一个错误消息,以查看Segfault发生的位置。
我想知道的是:
- 为什么GDB显示了导致错误的线路,但常规bash没有?
- 当程序未在调试模式下编译时,GDB如何显示该行?
- 过去,我总是以调试模式重新编译(要符合二进制文件的符号表),并使用DDD调查了核心转储的返回。这是修复分割故障的正确方法,还是这样做的常见方法是什么?
为什么GDB显示该线路导致错误,但常规bash没有?
?
因为GDB是为此而构建的。将segfault捕获并向您报告它是其工作的一部分,可以帮助您调试。例如,您可以获取回溯,检查各种堆栈框架等,以确定误差的性质以及可能的原因。Bash不是为此而建造的,也没有免费提供此类行为。
当程序未在调试模式下编译时,GDB如何显示该行?
显然,即使您不要求它,默认情况下将某种调试信息默认插入了二进制信息。至少足以提供代码的行号。如果您使用的是GCC,则可能对应于-g1
,而-g
等于-g2
。如果您很好奇,可以使用-g0
编译以查看是否消除了行号信息。
过去,我总是以调试模式重新编译(要符合二进制文件的符号表),并使用DDD调查了核心转储的回溯。这是修复分割故障的正确方法,还是这样做的常见方法是什么?
除了"任何有效的工作"之外,这里都没有"适当的"。
我确实发现,通过禁用优化的审核程序更容易调试程序,当然,调试信息最有用 - 所有这些都可以使用这样的二进制来重现错误。每当我正在从事segfaults的程序时,我也倾向于参与Valgrind。当有调试信息可用时,这也是更有信息的,如果存在内存问题(几乎总是指示该问题),那么即使程序的调试版本没有崩溃,Valgrind也可能会识别它。至于DDD,这只是几个UI选择之一,包括受支持的工具的本地选择。在这方面使用对您有用的东西。
哦,在编程的数十年中,我从来没有不得不求助于分析核心转储。当然,我的时间最终可能到了,但是我很满足于推迟。