用GDB调试

2022-03-02 22:08:49

我的第一个编程语言是C++,很长一段时间,我都在Windows中使用VisualStudio Express。当我不得不调试某个东西时,我会点击行号设置断点,然后按F5。也许我会给手表窗口添加一些变量,然后按几次F键。最近,我换了工作,现在主要是用C语言开发固件。自从7年前我改用Linux和Vim以来,我需要更新我的调试工作流程。事实上,我没有找到一个完整的教程,所以我想我可以自己写一个。

在过去的5年里,我主要使用Python,我真的很喜欢Python中的bug。您只需在代码中的某个地方放入一个breakpoint()函数调用,并将其复制到程序中。我想看看我在C语言中离这有多近。由于C语言不是一种解释语言,我的希望并没有那么高,但事实证明,在C语言中调试是相当舒服的。作为奖励,您可以使用GDBNOW只调试C和C++,但也可以使用RIST、Nim,以及可能尊重C-ABI的任何语言(我不知道这是事实)。

//节目。c#包括<;斯特迪奥。h>#包括<;stdlib。h>#包括<;时间h>;无效打印产品(int a,int b){int product=a*b;printf(";产品:%d\n";产品);}无效的print_参数(intargc,char**argv){for(inti=1;i<;argc;i++){printf(";%s";,argv[i])}printf(";\n";)}int main(int argc,char**argv){print_参数(argc,argv);srand(time(NULL));for(int i=0;i<;10;i++){print_乘积(rand(),rand());}返回0;}

要调试程序,必须包含调试符号。使用gcc编译时添加调试符号添加-g标志。让我们来编译这个程序:

这将使我们进入一个repl。要运行程序,直到它达到主功能,请键入start。现在有了典型的调试器操作,可以通过在repl中键入它们来执行。你可以通过输入n(当然你也必须按Returns)进入下一行,s进入当前函数调用,r运行直到到达一个断点,等等。设置断点,键入b<;生产线>;何处<;生产线>;是你要的电话号码。如果项目包含多个文件,则必须键入b<;文件名>;:&书信电报;生产线>;然而,<;文件名>;不需要是一个完整的路径,只需要名称就足够了。顺便说一句,gdb允许制表符完成。或者,您可以为这样的函数设置断点<;functionname>;。

要查看变量的上下文,如果在第6行断开,我们可以使用类似于p的p乘积。但我们也可以计算几乎任意的c表达式,例如pproduct*5。

但这仍然不好,现在我们必须在重新启动调试会话时反复输入所有断点。但还有一个问题:gdb脚本。如果使用-x选项调用gdb,可以向它传递一个包含gdb命令的文件,该命令应该执行。

现在我们的断点被存储了。但还有更多。通常我想检查一些变量,我对运行程序不太感兴趣。比如说,我们希望看到productvariable的值,对于所有循环,而不关心其余的:

现在,gdb将快速打印出所有迭代的产品价值,然后再次退出。断点后的commands语句将在命中断点后执行所有包含的命令。最后一个命令,c表示继续,并将继续程序流,直到下一个断点被击中。一旦上次击中断点,gdb将通过--batch参数结束执行。

另一个很酷的例子:不管出于什么原因,我们只在第三次调用print_product()时才对产品的价值感兴趣。(这当然很愚蠢,因为程序无论如何都会打印出来,但在现实调试中,可能会出现这样的情况)

set$n=0b 6如果$n==3 printf",则命令set$n=$n+1;产品是:%d\n";,产品名称:c endendrun

正如您所见,我们定义了一个变量$n,并使用它进行计数,并在第三轮打印出我们所需的信息。第三轮结束后,多亏了--batch,gdb自动退出。要更全面地了解gdb的脚本功能,我推荐adacore教程。com:第一部分和第二部分。

有一个脚本,如果存在,gdb将始终隐式加载:~/。GDBInit您可以将经常使用的函数或配置放在其中。我的看起来像这样:

将宽度和高度设置为0,将防止gdb分页长输出,第三行使gdb美化输出,最后一行防止它询问我们是否真的想退出。

这就是我所拥有的。总的来说,我对它的力量和灵活性很满意。这可能比在anIDE中放置一个断点要多一些工作,但你可以从中得到更多。此外,在IDE中,我总是发现用参数调用调试器是不合适的,因为您必须找到正确的选项对话框。在这里,您可以简单地将它们附加到debuggerinvocation:

此外,如果你需要一个更复杂的调试设置,例如,因为你必须启动其他程序,你可以把所有这些放在一个bash脚本中。

当然,关于gdb还有很多需要了解的,而这只是一个介绍。