Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4583997
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: C/C++

2015-03-13 19:00:45

原文地址:http://blog.csdn.net/hejinjing_tom_com/article/details/7597888

////////////////////////////////////////////////////////////////////

// author: hjjdebug

////////////////////////////////////////////////////////////////////

segment fault 是内存访问错误。

如果想不怕segment fault, 就要主动克服它。了解对付它的方法。

由应用引起的segment fault, 是轻量级的,因为当你非法读时, 或者非法写时,系统都及时给了你提示,找到代码行修改错误即可。

当出现内存访问错误时,

较好的情况是: 此时函数调用栈没有遭到破坏,此时系统可以直接给出是什么位置引起异常。

较糟的情况是: 堆栈段已经被破坏(非法驱动引起死机,重启等),系统仅能给出最底层或根本给不出引起异常的准确位置。 虽然这种情况更难下手,

但可以断定是不久前有人非法清理或覆盖了堆栈内存。

下面仅就第一种情况给出一个例子及定位方法。

1. 创造一个会引起segment fault 的程序。如下例:
  1. gitserver@gitserver-desktop:~/share/hjj$ cat crash.cpp  
  2. #include   
  3.   
  4. int test_crash2(int *p)  
  5. {  
  6.         int i;  
  7.         i=*p;  // 此句会引起segment fault  
  8.         return i;  
  9. }  
  10.   
  11. int test_crash(int *p)  
  12. {  
  13.         int j;  
  14.         j=test_crash2(p);  
  15.         return j;  
  16. }  
  17.   
  18. int main(int argc, char *argv[])  
  19. {  
  20.         printf("hello\n");  
  21.         int k = test_crash(0);  // 传入一个非法地址  
  22.         printf("k is %d\n",k);  
  23.         return 0;  
  24. }  

这里面有一个非法访问内存问题,会引起segment fault 错误。

2. 编译:
gitserver@gitserver-desktop:~/share/hjj$ gcc -g -o crash crash.cpp 
3. 准备:
gitserver@gitserver-desktop:~/share/hjj$ sudo dmesg -c
目的: 清理内核ring buffer, 使得更易于观察segment fault 时内核记录的消息
4. 执行:
gitserver@gitserver-desktop:~/share/hjj$ ./crash 
hello
Segmentation fault

5.  处理:
内存崩溃,系统不会坐视不管,它在/var/log 下会有记录,具体可能在kern.log 或sys.log 下
5.1 输入命令 dmesg
gitserver@gitserver-desktop:~/share/hjj$ dmesg
[238213.905770] crash[31448]: segfault at 0 ip 0804841d sp bf8f568c error 4 in crash[8048000+1000]

5.2运用addr2line 工具分析
gitserver@gitserver-desktop:~/share/hjj$ addr2line -e crash 0x804841d -f
_Z11test_crash2Pi
/home/gitserver/share/hjj/crash.cpp:6

得到结果:
是crash.cpp 第6行, 在test_crash2 函数中

addr2line 还可有定位内核模块代码, 例如。 调试romfs64.ko 模块时遇到内存崩溃。
--------------------------------------------------------------------------------
[  349.754982] BUG: unable to handle kernel paging request at 000000005e6d9000
[  349.754985] IP: [] romfs_lookup+0xc8/0x200 [romfs64]
[  349.754990] PGD 7ad70067 PUD 0 
[  349.754992] Oops: 0000 [#1] SMP 
[  349.754994] last sysfs file: /sys/devices/virtual/block/loop0/queue/rotational
[  349.754997] CPU 1 
[  349.754998] Modules linked in: romfs64 nfsd lockd nfs_acl auth_rpcgss exportfs autofs4 sunrpc ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables binfmt_misc uinput ppdev parport_pc parport psmouse serio_raw i2c_i801 evbug dcdbas pcspkr iTCO_wdt iTCO_vendor_support e1000e snd_hda_codec_analog snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc intel_agp usbhid hid radeon ttm drm_kms_helper drm i2c_algo_bit [last unloaded: speedstep_lib]
[  349.755025] Pid: 2502, comm: gvfsd-trash Not tainted 2.6.32 #2 OptiPlex 780                 
[  349.755026] RIP: 0010:[]  [] romfs_lookup+0xc8/0x200 [romfs64]
[  349.755030] RSP: 0018:ffff88007a8e3bc8  EFLAGS: 00010282
[  349.755031] RAX: 000000005e6d9000 RBX: 0000000000000040 RCX: 0000000000000000
[  349.755033] RDX: 0000000000000017 RSI: ffff8800377b5170 RDI: 0000000000000021
[  349.755034] RBP: ffff88007a8e3c38 R08: ffff8800377b5000 R09: 0000000000000000
[  349.755036] R10: 0000000000000005 R11: 0000000000000000 R12: ffff88005bf14000
[  349.755037] R13: ffff88005bf0e540 R14: ffff88005bf0e5e0 R15: ffff880037a93e00
[  349.755039] FS:  00007f971ad0a7a0(0000) GS:ffff880003a40000(0000) knlGS:0000000000000000
[  349.755041] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  349.755043] CR2: 000000005e6d9000 CR3: 000000007ad45000 CR4: 00000000000406e0
[  349.755044] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  349.755046] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  349.755048] Process gvfsd-trash (pid: 2502, threadinfo ffff88007a8e2000, task ffff8800797396d0)
[  349.755049] Stack:
[  349.755050]  0000000000000006 ffffffff8114ebe7 ffff88007a8e3be8 0000000003800880
[  349.755053] <0> 0000000000000089 0000000000000040 0000000000000000 00000000ffffff09
[  349.755056] <0> ffff88007a8e3c38 ffff88005bf0e540 ffff88007a8e3d18 ffff88007a8e3dd8
[  349.755059] Call Trace:
[  349.755064]  [] ? d_alloc+0x27/0x1c0
[  349.755067]  [] do_lookup+0x18b/0x220
[  349.755070]  [] __link_path_walk+0x755/0xfa0
[  349.755073]  [] ? path_to_nameidata+0x45/0x60
[  349.755075]  [] ? __link_path_walk+0xa8b/0xfa0
[  349.755077]  [] path_walk+0x6a/0xe0
[  349.755080]  [] do_path_lookup+0x5b/0xa0
[  349.755082]  [] user_path_at+0x57/0xa0
[  349.755086]  [] ? idr_get_empty_slot+0x108/0x2c0
[  349.755089]  [] ? _spin_lock+0xe/0x20
[  349.755092]  [] ? __fsnotify_update_child_dentry_flags+0x109/0x120
[  349.755095]  [] vfs_fstatat+0x3c/0x80
[  349.755097]  [] ? path_put+0x31/0x40
[  349.755099]  [] vfs_lstat+0x1e/0x20
[  349.755101]  [] sys_newlstat+0x24/0x50
[  349.755105]  [] ? audit_syscall_entry+0x24a/0x270
[  349.755108]  [] system_call_fastpath+0x16/0x1b
[  349.755110] Code: 31 c9 49 8b 00 4c 89 c6 48 8b 00 48 83 e0 e0 48 39 d8 75 23 e9 8c 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 48 8b 46 10 48 83 c6 10 <48> 8b 00 48 83 e0 e0 48 39 d8 74 6c 83 c2 01 39 fa 7c e5 f6 45
[  349.755133] RIP  [] romfs_lookup+0xc8/0x200 [romfs64]
[  349.755136]  RSP
[  349.755137] CR2: 000000005e6d9000
[  349.755139] ---[ end trace 8183515136c1a034 ]---
[  356.456806] Bridge firewalling registered
[  357.154018] Enter romfs_statfs()
[  357.154021] Leave romfs_statfs()
[  362.537033] ip_tables: (C) 2000-2006 Netfilter Core Team

--------------------------------------------------------------------------------
[root@hjj ~/software/romfs]# cat /sys/module/romfs64/sections/.text
0xffffffffa0068000

ffffffffa00685b8 - 0xffffffffa0068000 = 0x5b8
[root@hjj ~/software/romfs]# addr2line -e romfs64.ko  0x5b8 -f
romfs_lookup
/root/software/romfs/super.c:299


oop 也是一种segment fault, 但这是轻量级的内存错误,系统可以跟踪定位。

另有一种重量级内存错误,例如调试驱动时,堆栈毁坏或溢出, 会令你一时无从下手。

仅能依赖于对代码的熟悉程度及自己的智能判断。 就需要更高的积淀。

阅读(1638) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~