来看看在哪些情况下需要对程式进行调试。

第一种情况(这是大多数用户都会碰到的),程式在运行过程中突然跳了出来,屏幕上显示一个xxxx-core dumped消息,
然后Shell提示符就又显示出来了,其中xxxx表示出错原因。这种情况的出现一般是系统核心认为进程的执行出现了异常,
如进程试图去访问一块不允许他访问的存储区域(Memory Fault,Segmentation Fault);或扫描某个无终止符的字符串
(Bus Error);或浮点运算溢出或被0除(Arithmetic Exception),等等。此时操作系统会把进程当时的内存映象写到
当前目录下的一个名叫core的文档中。这种情况下我们能够使用sdb来检查此core文档,以决定出错的地点连同程式执行
的状态,如函数间的调用关系、变量的值,等等。

第二种情况,程式可能并没有什么异常行为,但就是怎么也得不到正确的输出结果。这时需要在该进程运行过程中对之进
行调试。这种情况下我们能够使用sdb逐条语句地跟踪程式的执行过程,并在执行过程中检查有关变量的值的变化情况。

上述两种情况并不是绝然分开的。实际上他们能够结合在一起使用。例如,当我们利用core文档对某个已终止的进程进行
调试时,能够在sdb中重新启动相应程式的运行,然后对语句的执行进行一些控制。这样我们就能够知道在出现异常之前哪
个程式到底是如何动作的。

为了使sdb能够很好地对程式进行调试,在编译程式时应指示编译程式和链接程式在目标代码中加入调试用的各种信息,如
程式中的变量名、函数名及其在源程式中的行号等。我们知道,使用-g选项能够完成这一点。如我们能够用如下命令编译
前一章给出的有毛病的程式代码:

$ cc -o myprog myprog.c myfunc.c

myprog.c:

myfunc.c:

$ ls -l myprog

-rwx-xr-x 1 yxz users 4224 Sep 1 10:17 myprog

$ cc -g -o myprog myprog.c myfunc.c

myprog.c

myfunc.c

$ ls -l myprog

total 26

-rwxr-xr-x 1 yxz users 5404 Sep 1 10:21 myprog

$

这时我们会发现,新生成的myprog比不带-g 选项生成的myprog要大的多。故在程式调试完成之后应将可执行程式中的调试
用信息去掉。最简单的方法当然是使用不带-g 选项的cc命令重新编译一遍。另外UNIX系统提供了另外一个名为strip的工具,
使用此命令也能够将程式中的调试信息去掉。

现在我们能够试着运行一下那个有问题的程式myprog。在shell提示符下输入:

$ myprog 1 111

Arithmetic Exception -core dumped

$

我们看到,程式由于异常而推出了,并且在当前目录下将生成一个名为core 的文档。这个文档有时很庞大。在文档系统
的维护中,有一条就是要定期找出各目录下的core 文档并将其删除掉。

发生此种情况时能够使用sdb来对之进行调试。输入:

$ sdb myprog

即可进入sdb调试程式。

sdb将接受三个参数:

待调试的可执行文档名;
待调试的core文档名,一般缺省是core;
由冒号分隔的一个目录表,sdb将在这些目录表中去查找有关的源文档。此目录表的缺省配置是当前目录
有时当前目录下的core文档可能并不是待调试的程式的core 文档,此时用这个core 文档进行调试就是不合适的了。为防止
这一点,可在命令行中指定第二个参数为减号(-),如下所示:

$ sdb myprog -

这里的"-"告诉sdb忽略当前目录下的core文档。

第三种情况,我们试用对活动过程(正在运行的进程)进行调试的情况。例如,假定某个程式正在后台运行,但我们注意到
该程式的某些部分执行起来很慢,这时我们能够在不杀死这个进程的情况下对之进行调试:

$ sdb /proc/1111

这里1111为待调试进程的进程号,用户能够用PS命令得到。系统在/proc目录下用文档的形式保存了每一个活动进程的信息,
而文档名正好就是相应的进程号。

指定的进程将在执行时碰到第一个系统调用或调用sdb后收到某个软中断信号时暂停其运行,我们就能够在sdb中检查变量的值、
配置断点、恢复执行,等等。在退出sdb时,控制又返回程式,执行进程又从其原停止的地方继续执行。

第四种情况,一般情况下当被调试的活动进程在收到某个软中断信号时sdb会停止该进程。为了防止这一点,能够使用-s 选项。
例如:

$ sdb -s 14 myprog

将告诉sdb不要因为软中断信号14(闹钟报警信号)而使进程的执行停止。此时该信号被传给相应进程。在程式接收并处理多个
软中断信号的情况下,能够使用多个-s选项。

在sdb命令行中更有其他一些选项,对此我们不再一一列举,读者能够参考命令帮助。

在使用上述方法之一进入sdb之后,便能够进行在前一节中提到的各种操作,如显示或配置变量值、函数调用关系、控制语句的
执行等。下一节我们将周详讨论完成这些操作的方法。



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选项才会有,他指的是将要被执行的那条语句。和当前行相应,有一个行号的概念。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!