UNIX系统开发-SDB调试技术

我们说程序调试的主要目的是观察变量的变化情况 。但如果程序就一直不停地运行直至它终止或出错时才停下来的话,将没有机会去观察任何变量 。因此,如何有效地控制程序中各语句的执行,使之在适当的时候暂停下来,待调试人员在显示或设置了某些存储单元的值之后再从停下的地方继续执行下去,是调试程序应具有的一项基本功能 。在这一节中我们就来具体介绍如何控制程序的运行 。

对程序执行控制的第一个问题是设置断点 。一个断点实际上就是程序中某行语句 。当程序执行到这条语句时控制会重复返回到sdb,由此提供给用户进行其他操作,如显示变量值的机会 。

1.断点的设置和删除

在sdb中设置断点的方法比较多 。但基本是b命令的变种 。例如,我们可以使用如下语句在main()函数的第一个可执行(非变量定义这类语句)设置一个断点:* main:b

也可以直接用行号来设置断点 。例如,在myprog.c中,第10行是main()函数中的第一个可执行语句,则使用如下命令也能达到同样的效果:* 10b

注意这是在myprog.c为当前文件的情况下进行的 。如果直接输入:* b 命令,则可将当前行设成是一个断点 。但是若当前行不是一个可执行语句,那么sdb将把当前行之后的第一个可执行语句处设置一个断点 。在设置完断点之后,为了解程序中设置有哪些断点,可以使用B命令:* B

0x80483f0 myprog.c:10 main 0x8
0x80483f7 myprog.c:11 main 0xf
0x8048407 myprog.c:12 main 0xlf
0x8048440 myprog.c:9 TestInput
0x8048447 myprog.c:10 TestInput0x7
0x804482 myprog.c:13 TestInput0x42

在设置完断点之后要将其删除,可以使用d命令 。如:* main:d

sdb将把在main()函数中设置的第一个可执行行上的断点删除 。如果直接使用d命令,sdb将逐个列出所有断点并询问用户是否删除之 。回答y断点将被删除 。使用D命令则可删除程序中设置的所有断点 。

2.sdb中启动程序的运行

在设置好所需的断点之后我们就可以重新启动程序的运行了 。这可以使用r命令 。如:* r 111 2

BREAKPOINT process 554 function main() in myprog.c
10: for(i=1;i *
sdb将在main()函数中设置第一个断点处停下来并显示该行的语句 。r后面给出的是传给可执行程序myprog的两个参数 。因此上述命令同在shell提示符下输入: $ myrprog 111 2 是相同的 。不同的只是在sdb中程序的执行会在断点处停下来 。
如果只输入 * r 命令,sdb使用最近一次执行调试程序时给它提供的参数来启动之 。如果想不带任何参数来重新启动程序的运行,可使用 * R 命令 。

3.控制程序的单步或者连续执行

在用r(R)命令启动程序的运行之后,sdb将在第一个断点处暂停程序的运行 。此时断点行成为当前行,但并未被执行 。此时我们可以在sdb的星号(*)提示符下输入前面已介绍过的或后面将要介绍的各种命令 。当然最重要的是显示那些关键变量的值,以了解程序的运行情况 。在这之后便可以继续程序的执行 。继续执行有两种方式 。一种是单步方式,即逐条语句执行 。这可以使用S命令完成:

* s
STEPPED process 584 function main() in myprog.c
14: printf("The %dth value "%s" tis BAD!n",i,argv[i]);
*
sdb在执行完当前语句之后,将当前行后移一行并显示出其代码 。对于用户自定义的函数调用,S命令并不将其当成是一条语句,此时它将指示sdb进入该函数(使之成为当前函数) 。如我们可以接着上面输入下列命令:

* s
STEPPED process 584 function main() in myprog.c
11: if(TestInput(argv[i])== TESTOK)
* s
BREAKPOINT process 594 function main() in myprog.c

推荐阅读