我的程序在访问gdb中的main之前静态链接到许多库和崩溃。我如何诊断出问题所在?
答案 0 :(得分:10)
LD_DEBUG
可以帮助你,这是一个不错的选择。试试这个:LD_DEBUG=all ./a.out
。这将允许您轻松识别程序崩溃时正在加载的库。
(编辑:如果不清楚,a.out
意味着引用通用二进制文件 - 在这种情况下,将其替换为可执行文件的名称。)
编辑2:
为了澄清,LD_DEBUG
是一个环境变量,当程序开始执行时由动态链接器检查。如果将LD_DEBUG
设置为某个值,则动态链接器将输出有关在程序执行,符号绑定等过程中加载的动态库的大量信息。
对于初学者,请在您的计算机上执行以下操作:
LD_DEBUG=help ls
您将在列出的系统上看到LD_DEBUG
的有效选项。最详细的设置是all
,它将显示所有可用信息。
现在,使用它就像ls
示例一样简单,只用您的程序名称替换ls
。为了使用LD_DEBUG,不需要gdb,因为它是由动态链接器提供的功能,而不是由gdb提供。
答案 1 :(得分:4)
开始逐个取出库,直到它停止崩溃。 然后检查罪魁祸首。
答案 2 :(得分:4)
这篇文章有答案,您必须在crt0启动代码中的main之前设置一个断点: Using GDB without debugging symbols on x86?
答案 3 :(得分:3)
我没有在C中遇到过这个问题,但是如果链接到c ++库,静态初始化就会崩溃。您可以通过在静态范围变量的构造函数中使用断言来轻松创建它。
答案 4 :(得分:3)
它可能会崩溃,因为某些组件会抛出异常而没有人捕获它,因为尚未输入main()
。设置抛出异常的断点:
catch throw
run
(如果catch throw
第一次启动时不起作用,请运行一次以使其加载动态库,然后执行catch throw
并再次运行。
答案 5 :(得分:3)
<强> starti
强>
starti
在执行的第一条指令处中断,另请参阅:Stopping at the first machine code instruction in GDB
如果你的GDB不够新,那么另一种选择:
break _start
如果您知道入口点方法的名称是_start
,或者:
info files
搜索Entry point
:
Entry point: 0x400440
并运行:
break *0x400440
TODO:了解如何使用调试符号编译crt*
个对象并进入它们:How to compile my own glibc C standard library from source and use it?
答案 6 :(得分:2)
如果可以,请动态链接您的程序,而不是静态链接,并关注@denniston.t answer。也许从动态链接器调试跟踪将有助于解决这个问题。