如何在main之前调试崩溃?

问题描述 投票:8回答:7

我的程序在访问gdb中的main之前静态链接到许多库和崩溃。我如何诊断问题是什么?

c gdb
7个回答
4
投票

开始逐一取出库,直到它停止崩溃。然后检查罪魁祸首。


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提供的。


4
投票

这篇文章有答案,你必须在crt0启动代码中的main之前设置一个断点:Using GDB without debugging symbols on x86?


3
投票

我没有在C中遇到过这个问题,但如果你链接到c ++库,静态初始化就会崩溃。您可以通过在静态范围变量的构造函数中使用断言来轻松创建它。


3
投票

它可能会崩溃,因为一些组件抛出一个异常,没有人抓住它,因为还没有输入main()。在抛出异常时设置断点:

catch throw
run

(如果catch throw第一次启动它时不起作用,运行一次让它加载动态库,然后再执行catch throw并再次运行)。


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?


2
投票

如果可以,请动态链接您的程序而不是静态链接,并关注@denniston.t answer。也许从动态链接器调试跟踪将有助于解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.