sdb命令的使用
同我们前面介绍过的mail,ftp一类工具类似,sdb也是一个命令解释程序。也就是说,用户在sdb提示符(一个星号*)下输入sdb能够识别的命令,sdb将根据被调试的程序的具体情况给出响应。
例如,在运行myprog出错,生成core文件之后进入sdb时,sdb将给出如下的响应:
$ sdb myprog
12: return ((100/atoi(ValueInput))? TESTOK:! TESTOK);
*
sdb给出来的实际上是程序出错所在的函数,在源程序文件中的行号以及出错那一行的语句。
在sdb的使用中要注意三个“当前”概念:
(1)当前文件 即当前将要被执行的语句所在的那个源程序文件
(2)当前函数 即当前将要被执行的语句所在的那个函数
(3)当前行 这个概念只有在编译时加入-g选项才会有,它指的是将要被执行的那条语句。与当前行相应,有一个行号的概念。它指的是每条语句在程序中位于第几行。注意行号是从文件头开始计算的,第一行的行号为1,空白行和注释也包括在内。
在用core文件进行调试时,当前行和当前函数分别被设成是程序出错时所执行的那条语句所在地行和函数(如同上面显示出来的那样)。但如果在编译时未加-g选项,显示出来的将只有函数名和函数的地址了。
在对活动进程进行排错时,sdb将把当前函数和当前行分别设成是main()函数和main()函数的第一个可执行的语句行。
不论是哪种情况,sdb都将显示出*提示符。在此提示符之下我们可以输入各种sdb命令,以控制程序的执行或观察变量的变化情况,等等。在下面的几个小节中我们将分别详细讨论这些问题。
源程序的显示和搜索
程序出错一般来说不只是出错的那条语句本身造成的。事实上出现错误经常是前面或相关的代码执行了不正确的操作或少了某些必要的处理。因此调试过程中经常要观察一下源程序中的语句,或者在程序中搜索某个符号出现在什么地方。其中字符串的搜索功能同vi基本上是相同的,而文件的显示则同另外一个我们没有具体讨论的编辑器ed类似。下面我们将具体介绍这些命令。
1.源程序的显示
在用core进入sdb之后,在*提示符后输入w命令,该命令指示sdb显示源程序中的当前行为中心的前后10行的内容并保持当前行不变:
* w
7:int
8: TestInput(char * ValueInput)
9: {while ( * ValueInput)
10: if (! isdigit( * ValueInput)) return (! TESTOK);
11: else ValueInput++;
12: return ((100/atoi(ValueInput))? TESTOK:! TESTOK);
13: }
*
我们看到,在进入sdb时,当前行是第12行,以该行为中心的10行内容正好就是上面所显示出来的。其他可以显示源程序语句的sdb命令如下:
P 显示当前行
l 显示对应于当前指令的那条语句
Z 显示当前行开始的下面10条语句
Ctrl+D 显示当前行之后(不包括当前行)的第10条语句
n 显示第n条语句,这里n是一个数
注意这些命令显示出的是源程序语句还是汇编语句(后面我们将要介绍)取决于最近一次显示出的是什么。
2.改变当前行
在用户显示语句时,当前行也会相应地发生变化。例如,Z命令将使当前行向程序尾移动9行,而Ctrl+D则使当前行向后移动10行。
在使用数字来显示某行语句时将使该行语句成为当前行。而在*提示符之后按一下回车,当前行将下移一行。例如,接着上面的例子,输入:
* 8p
8: TEstInput(char * ValueInput)
* 回车
9: { while ( * ValueInput)}
*
这里8p实际上是两条命令的组合。它使当前行移至源文件的第八行,然后再显示出新的当前行。按回车键将使当前行后移一行。