【转】gdb 调试段错误

转自:blog.csdn.net/yangzhu1982/article/details/6318600

开发嵌入式Linux的时候经常会遇到segmentation fault,也就是段异常错误,一般是使用错误的指针访问内存导致。这种错误可以通过打开内核的异常信息输出,再用gdb对发生段异常的地址进行定位。

1.打开内核的异常信息输出:

mips的内核代码关闭了arch/mips/mm/fault.c的do_page_fault():133中的这段代码:

#if 0
printk("do_page_fault() #2: sending SIGSEGV to %s for "
"invalid %s/n%0*lx (epc == %0*lx, ra == %0*lx)/n",
tsk->comm,
write ? "write access to" : "read access from",
field, address,
field, (unsigned long) regs->cp0_epc,
field, (unsigned long) regs->regs[31]); #endif 

在发生段异常的时候会打印当前是哪个进程出错,出错的epc和返回地址ra是多少。打开这段代码,这样可以得到发生段异常时的指令地址。还可以增加打印内核栈和寄存器的函数,例如:

#if 1
printk("do_page_fault() #2: sending SIGSEGV to %s for "
"invalid %s/n%0*lx (epc == %0*lx, ra == %0*lx)/n",
tsk->comm,
write ? "write access to" : "read access from",
field, address,
field, (unsigned long) regs->cp0_epc,
field, (unsigned long) regs->regs[31]); show_registers(regs);
dump_stack();
#endif 

2.定位发生段异常的代码

打印的出错信息:

do_page_fault() #2: sending SIGSEGV to myprog for invalid read access from
00000004 (epc == 00479628, ra == 00482228)
....... Lo : 00000001
epc : 00479628 0x479628 Not tainted
ra : 00482228 0x482228
Status: 0000f413 USER EXL IE
Cause : 00800008
BadVA : 00000004
PrId : 00019374
Modules linked in: pppoe ppp_async ppp_deflate ppp_mppe pppox ppp_generic slhc
Process myprog (pid: 7487, threadinfo=81096000, task=811135b8)
Stack : 2ab4f360 00000001 100055a0 004d0000 1000b320 004d0000 100055a0 00482228
10036248 004d0000 2ab4f360 00000001 1000b320 004d0000 004cac44 004825f0
00000000 004ba948 004bebe0 004ccce8 004cac44 000000a8 100055a4 0043886c
1000b320 0040d8d0 00000000 0040d8d0 00000000 10003494 0040ddfc 0040dd18
004b2250 004b2278 004b2284 0040d83c 1000b320 00000000 1000b320 7fcdff80
...
Call Trace: Code: 00000000 1090000a 00000000 <8c820004> 8c830000 8f998078 ac430000 0320f809 ac620004
Call Trace:
[<8006dc04>] do_page_fault+0x214/0x430
[<8006dbfc>] do_page_fault+0x20c/0x430
[<800a881c>] handle_IRQ_event+0x70/0xfc
[<800a89e4>] __do_IRQ+0x13c/0x158
[<8006e328>] tlb_do_page_fault_0+0xf8/0x100
[<8006130c>] ar7100_interrupt_receive+0xec/0x100 Segmentation fault 

可以看到,发生异常的程序地址(epc寄存器)是0x00479628,程序返回地址(ra寄存器)是0x00482228。使用gdb来定位,注意编译myprog程序时要带编译参数-g -ggdb,否则myprog中没有调试信息。

#mipseb-linux-uclibc-gdb myprog

(gdb) l *(0x00479628)

0x479628 is in DropAll (../../../include/util.h:107).

102      *

103      * This is only for internal list manipulation where we know

104      * the prev/next entries already!

105      */

106     static inline void __list_del(struct list_head *prev, struct list_head *next)

107     {

108         next->prev = prev;

109          prev->next = next;

110     }

111

(gdb) l *(0x00482228)

0x482228 is in FW_CleanEnv (firewall.c:325).

320         {

321             g _apstFwHashTable[i] = NULL;

322         }

323

324         /* ?3? ¢ */

325         DropAll(&g_lLanDev);

326          DropAll(&g_lWanDev);

327     }

328

329  

可以看到FW_CleanEnv()中的第325行调用的DropAll(&g_lLanDev)导致了段异常,具体是在DropAll()使用的util.h:107的宏

__list_del()产生的异常。

【转】gdb 调试段错误的更多相关文章

  1. gdb调试段错误及使用

    在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...

  2. 使用gdb调试段错误

    [https://blog.csdn.net/xj9120/article/details/91380074] 1.bt 2.frame number 3.一般是内存问题 4.kill

  3. Linux下调试段错误 (gdb,core,ulimit)

    Linux环境下经常遇到某个进程挂掉而找不到原因,我们可以通过生成core file文件加上gdb来定位. (1)首先 在makefile中要增加编译调试选项 -g,才可以利用下面的gdb来调试 gc ...

  4. linux ulimit的使用,如何产生core文件,调试段错误

    ---恢复内容开始--- 下面先简单介绍下ulimit命令: 1. limit -a 可以查看系统各种资源的限制,如: core文件大小,数据段的大小等. $ ulimit -a core file ...

  5. 使用单进程、strace、gdb调试PHP错误

    使用单进程.strace.gdb调试PHP错误 PHP一般是在FPM的呵护下运行的,但是某些情况下进程异常崩溃会导致502.下面是解决思想: 1. 单进程运行: php -d display_erro ...

  6. 在Linux中调试段错误(core dumped)

    在Linux中调试段错误(core dumped) 在作比赛的时候经常遇到段错误, 但是一般都采用的是printf打印信息这种笨方法,而且定位bug比较慢,今天尝试利用gdb工具调试段错误. 段错误( ...

  7. linux驱动调试--段错误之oops信息分析

    linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...

  8. GDB core命令的使用调试段错误

    #include <stdio.h> void func(){ int *p = NULL; printf("*p:%d\n", *p);//断错误 } int mai ...

  9. 利用linux信号机制调试段错误(Segment fault)

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

随机推荐

  1. T-sql创建表,插入数据

    SET NOCOUNT ON; USE hibernateSqlServer GO IF OBJECT_ID('Orders') IS NOT NULL DROP TABLE Orders; GO I ...

  2. [开源]基于STM32的录音播放装置

    这是帮一个同学做毕设做的,基本要求如下(有些指标看看就好,实际当然不需要,哈哈): (1)放大器1的增益为46dB,放大器2的增益为40dB,增益均可调:(2)带通滤波器:通带为300Hz-3.4kH ...

  3. centos7 yum安装mysql5.7并在root密码忘记的情况下重设密码

    CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源   1 $ wget http://repo.mysql ...

  4. k近邻算法的Java实现

    k近邻算法是机器学习算法中最简单的算法之一,工作原理是:存在一个样本数据集合,即训练样本集,并且样本集中的每个数据都存在标签,即我们知道样本集中每一数据和所属分类的对应关系.输入没有标签的新数据之后, ...

  5. VC6在win7环境下无法添加以及打开现有文件的解决办法

       在VC6.0中使用键盘快捷键或者是文件菜单打开现有文件以及添加文件出现编辑器停止响应,弹出内容为Microsoft(R) Developer Studio已停止工作 Windows正在检查解决该 ...

  6. 本地blast用法

    格式化数据库: makeblastdb -in db.fasta -dbtype prot -parse_seqids -out dbname 参数说明: -in:待格式化的序列文件 -dbtype: ...

  7. js_css_dl.dt实现列表展开、折叠效果

    第一种方式:不提倡 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w ...

  8. Linux入门:运行级别解析

    Linux入门:运行级别解析   一.查看当前运行级别 Ubuntu中,runlevel命令 可以查看当前运行级别: CentOS中,who -r 命令查看当前运行级别:   www.2cto.com ...

  9. Java关于md5+salt盐加密验证

    一.陈述一下工作流程: 1.根据已有的密码字符串去生成一个密码+盐字符串,可以将盐的加密字符串也存放在数据库(看需求), 2.验证时将提交的密码字符串进行同样的加密再从数据库中取得已有的盐进行组合密码 ...

  10. RuntimeWarning: invalid value encountered in divide

    import numpy as np olderr = np.seterr(all='ignore') 在程序的开头加上如上代码 https://docs.scipy.org/doc/numpy/re ...