当前位置: 首页 > 科技观察

GDB的七个单步调试命令

时间:2023-03-17 20:31:14 科技观察

调试器是一种运行您的代码并检查问题的软件。GNU调试器(GBD)是最流行的调试器之一,在这篇文章中,我查看了GDB的step命令和其他几种常见情况的相关命令。step是一个广泛使用的命令,但它有一些人们不太了解的方面,这会让他们很困惑。此外,还有一些方法可以在不使用step命令的情况下进入函数,例如使用鲜为人知的advance命令。1.没有调试符号考虑下面的简单示例程序:#includeintnum(){return2;}voidbar(inti){printf("i=%d\n",i);}intmain(){bar(num());return0;}如果你编译时没有调试sysbolsgoption),那么在bar上设置一个断点,然后尝试在这个函数中使用step单步执行语句。GDB将给出无行号信息gccexmp.c-oexmpgdb./exmp(gdb)bbarBreakpoint1at0x401135(gdb)rStartingprogram:/home/ahajkova/exmpBreakpoint1,0x0000000000401135inbar()(gdb)stepSinglesteppinguntilexitfromfunctionbar,它没有行号信息。i=20x0000000000401168inmain()2、stepi命令但是你仍然可以单步执行没有行号信息的函数内部的语句,但是使用stepi命令而不是step。stepi一次只执行一条指令。在使用GDB的stepi命令时,通常先执行display/i$pc会很有用,它会在每一步后显示程序计数器程序计数器的值和相应的机器指令:(gdb)bbarBreakpoint1at0x401135(gdb)rStartingprogram:/home/ahajkova/exmpBreakpoint1,0x0000000000401135inbar()(gdb)display/i$pc1:x/i$pc=>0x401135:sub$0x10,%rsp在上面的显示命令中,i代表机器指令,$pc代表程序计数器寄存器(即PC寄存器)。使用inforegisters命令打印寄存器的内容也很有用。(gdb)信息寄存器rax0x22rbx0x7fffffffdbc8140737488346056rcx0x403e184210200(gdb)打印$rax$1=2(gdb)stepi0x0000000m0004011ovdbc8inbar()1:x/i$pc1=4-ed>39bar+(%rcomplexfunction)calls在-g选项中加上调试符号,重新编译示例程序后,可以使用行号在mainpoint中对bar的调用设置一个break,然后单步执行bar函数的语句:gcc-gexmp.c-oexmpgdb./exmp(gdb)bexmp.c:14Breakpoint1at0x401157:fileexmp.c,line14.(gdb)rStartingprogram:/home/ahajkova/exmpBreakpoint1,main()atexmp.c:1414柱(数());接下来使用step单步执行bar()函数语句:(gdb)stepnum()atexmp.c:44return2;函数调用的参数需要在实际函数调用之前处理,bar()函数的参数是num()函数,所以num()会在bar()调用之前执行。但是,通过GDB调试,您如何才能随心所欲地进入bar()函数呢?您可以使用finish命令,然后再次使用step命令。(gdb)finishRuntillexitfrom#0num()atexmp.c:40x0000000000401161inmain()atexmp.c:1414bar(num());返回的值是$1=2(gdb)stepbar(i=2)在exmp.c:99printf("i=%d\n",i);4.tbreak命令tbreak命令会设置一个临时断点。如果您不想设置永久断点,此命令很有用。例如