【转】gdb 调试段错误
【转】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 调试段错误的更多相关文章
- gdb调试段错误及使用
在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...
- 使用gdb调试段错误
[https://blog.csdn.net/xj9120/article/details/91380074] 1.bt 2.frame number 3.一般是内存问题 4.kill
- Linux下调试段错误 (gdb,core,ulimit)
Linux环境下经常遇到某个进程挂掉而找不到原因,我们可以通过生成core file文件加上gdb来定位. (1)首先 在makefile中要增加编译调试选项 -g,才可以利用下面的gdb来调试 gc ...
- linux ulimit的使用,如何产生core文件,调试段错误
---恢复内容开始--- 下面先简单介绍下ulimit命令: 1. limit -a 可以查看系统各种资源的限制,如: core文件大小,数据段的大小等. $ ulimit -a core file ...
- 使用单进程、strace、gdb调试PHP错误
使用单进程.strace.gdb调试PHP错误 PHP一般是在FPM的呵护下运行的,但是某些情况下进程异常崩溃会导致502.下面是解决思想: 1. 单进程运行: php -d display_erro ...
- 在Linux中调试段错误(core dumped)
在Linux中调试段错误(core dumped) 在作比赛的时候经常遇到段错误, 但是一般都采用的是printf打印信息这种笨方法,而且定位bug比较慢,今天尝试利用gdb工具调试段错误. 段错误( ...
- linux驱动调试--段错误之oops信息分析
linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...
- GDB core命令的使用调试段错误
#include <stdio.h> void func(){ int *p = NULL; printf("*p:%d\n", *p);//断错误 } int mai ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
随机推荐
- CSS水平居中
三种情况:1.行内元素(文本.图片等) 给父元素设置text-align:center;来实现 2.定宽块状元素 <style> div{ border:1px solid blue; w ...
- LeetCode Flatten 2D Vector
原题链接在这里:https://leetcode.com/problems/flatten-2d-vector/ 题目: Implement an iterator to flatten a 2d v ...
- 向ES6看齐,用更好的JavaScript(二)
本文是ES6系列的第二篇,主要介绍ES6中对现有对象方法属性的拓展,先上传送门: 1 变量部分 2 现有对象拓展 3 新增数据类型/数据结构 4 新的异步编程模式 5 类和模块 1 增加了模板字符串 ...
- MVC Action返回Json
Action [HttpPost] public ActionResult Edit(Study_CourseHourModel model) { ...
- Winform 主窗体更换 构造函数传值
制作登录窗体: 制作一个登陆窗体,实现点击按钮关闭此窗体并打开另一个窗体 直接在按钮点击事件中,实例化一个想要打开的窗体 使用show方法打开,并把登陆窗体的visible属性改为false Form ...
- linux----------纯净的centos7.0上安装lnmp环境的步骤
1.先看下screen -S lnmp 命令是否存在,不存在则安装.这个是个什么东东呢?百度一下( GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接 ...
- 用JS来控制 div的高度随浏览器变化而变化
<div id="test" style=" border: solid 1px #f00; "></div> <script t ...
- viewpaper 抽屉
引用:http://www.apkbus.com/android-18384-1-1.html 在为ViewFlipper视图切换增加动画和Android中实现视图随手势移动中实现了视图随手势切换,现 ...
- 【转】PowerShell入门(序):为什么需要PowerShell?
转至:http://www.cnblogs.com/ceachy/archive/2013/01/23/PowerShellPreface.html 曾几何时,微软的服务器操作系统因为缺乏一个强大的S ...
- mysql复制表结构及检查表、存储过程是否存在
mysql命令行复制表结构的方法: 1.只复制表结构到新表 CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2 或者 CREATE TABLE 新表 LIKE 旧表 ...