在linux系统中我们写C语言应用程序经常会遇到让编译器不能找出来的错误,它一般在编译后显示为段错误,而段错误不像其它语法错误,编译器会自动提示你错误在哪一行,在这里就不详提出现段错误的原因有哪些,主要是讲讲一些查找段错误的方法,不过提醒下大部分还是因为内存的不合理使用造成的,而C语言在使用内存时一般都是用指针,所以说在写C程序时用指针时一定要小心。下面我就介绍几种比较常用的方法来查找段错误:

方法1:printf的使用

使用printf函数,就是在出现段错误后在你认为会有错误的地方用printf函数随便打印一句话,如果编译后能够看到你写的那句话,那就说明出现段错误的地方在那句printf函数后面,然后接着在后面使用printf函数,直到你要printf打印的那句话在编译后没有打印出来,说明那个出现段错误的地方在printf函数上面。以此方法可以很方便的找出出现段错误的那行代码。这种方法只适合代码少的程序,如果代码很多的话,这种方法就显得非常慢了。


方法2:gdb之动态符号-rdynamic

通过GDB调试工具查找,可以快速方便的查找出现段错误的地方。在此我编写了一个由于指针没有分配内在就使用而导致的段错误的示例test.c:

#include<stdio.h>
int main()
{
int a;
int *p=&a;
int *q;
*p=5;
printf("p=%d\n",*p);
*q=7;
printf("q=%d\n",*q);
}

然后利用gcc编译:[root@localhost test]# gcc test.c -o test -g -rdynamic

然后用gdb调试:[root@localhost test]# gdb test

GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/test/test...done.
(gdb) 

输入命令:r 

运行后出现(gdb) r
Starting program: /home/test/test 
p=5
Program received signal SIGSEGV, Segmentation fault.
0x0804853c in main () at 1.c:9
9           *q=7;
(gdb)

我们可以发现出现段错误的地方是第9行代码。分析代码可知指针q出现错误而p没有错误是出于q没有分配内存。 注意:在编译test.c时参数-g 和 -rdynamic 不能少,其中-g 是用来gdb调试的,-rdynamic是用来通知链接器将所有符号添加到动态符号表中。

方法3:gdb之core文件

           用命令:ulimit -c unlimit,产生core文件,就是程序运行发行段错误时的文件。我们就继续拿上面的示例代码来说吧,首先输入以下命令: ulimit -c unlimit

接下来的看以下操作:

[root@localhost test]#gcc test.c -o test -g

[root@localhost test]# ls
test.c  core.18161  test

在这里我们发现已经生成了core文件,接下来利用它们调试:
[root@localhost test]# gdb test core.18161 
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/test/test...done.
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
#0  0x080483bc in main () at 1.c:9
9           *q=7;
(gdb) 

我们发现在输入:gdb test core.18161命令后直接跳到了*q=7的这一行,而这一行也正是出现段错误的代码行。

        GDB工具是一个不错的调试工具,利用好了它在以后的调试工作上可以事半功倍。








Logo

更多推荐