C程序查找段错误的方法

          在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工具是一个不错的调试工具,利用好了它在以后的调试工作上可以事半功倍。








  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
段错误是一种常见的错误类型,通常是由于访问无效的内存地址引起的。在调试 Linux 驱动程序时遇到段错误,可以按照以下步骤进行排查和解决: 1. 确认段错误的位置:可以使用调试工具(如 gdb)来定位段错误发生的位置。通过在代码中插入调试语句或设置断点,可以逐步执行程序并观察在哪个特定的代码行发生段错误。 2. 检查指针和数组:段错误通常与指针或数组的访问有关。确保您的指针已正确初始化并分配了内存。检查数组的索引是否超出了范围,并避免访问已释放的内存。 3. 检查内存分配和释放:如果您使用动态内存分配函数(如 malloc 或 kmalloc),请确保在使用完内存后进行适当的释放(free 或 kfree)。内存泄漏可能导致内存耗尽或无效的内存访问。 4. 检查函数参数和返回值:确保函数参数的类型和数量与函数声明匹配,并正确处理函数的返回值。传递无效的参数或对未初始化的返回值进行操作可能导致段错误。 5. 检查系统调用和驱动接口:如果您的驱动程序使用系统调用或与其他模块或设备进行交互,请确保正确处理错误情况和无效的参数。使用适当的错误处理机制,如返回适当的错误代码或设置错误标志。 6. 使用调试工具:除了 gdb 之外,还可以使用其他调试工具,如 Valgrind(用于检测内存错误)或 Ftrace(用于跟踪函数调用和内核事件)。这些工具可以帮助您更详细地分析和定位段错误。 7. 重现和记录问题:尝试重现段错误,并记录相关的环境、输入或操作。这将有助于更深入地分析问题并找到解决方案。 请注意,以上步骤只是一些常见的排查方法,具体的解决方案可能因问题的具体情况而异。如果问题仍然存在,请尝试搜索相关的文档、论坛或寻求其他开发者的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值