Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)

上传人:tia****nde 文档编号:36843570 上传时间:2018-04-03 格式:DOC 页数:6 大小:42KB
返回 下载 相关 举报
Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)_第1页
第1页 / 共6页
Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)_第2页
第2页 / 共6页
Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)_第3页
第3页 / 共6页
Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)_第4页
第4页 / 共6页
Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)》由会员分享,可在线阅读,更多相关《Linux下的段错误(Segmentationfault)产生的原因及调试方法(经典)(6页珍藏版)》请在金锄头文库上搜索。

1、Linux 下的段错误(Segmentation fault)产生的原因及调试方法(经典) 2009-04-05 11:25简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就 不存在对应的物理内存,尤其常见的是访问0地址.一 般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这 个值是由 gdtr 来保存的,他是一个48位的寄存器,其中的32位是保存由它指 向的 gdt 表, 后13位保存相应于 gdt 的下标,最后3位包括了程序是否在内存中以及程序的在 cpu 中的运 行级别,指向的 gdt 是由以64位为一个单位的 表,在这张表中就保存着程序运行的代

2、码段以 及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的 信息。一旦一个程序发生了 越界访问,cpu 就会产生相应的异常保护,于是 segmentation fault 就出现了.在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的1)访问系统数据区,尤其是往 系统保护的内存地址写数据最常见就是给一个指针以0地址 2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域解决方法我 们在用 C/C+语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。实际 上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难 免会在此处犯些

3、小 错误,而通常这些错误又是那么的浅显而易于消除。但是手工“除虫”(debug) ,往往是效率 低下且让人厌烦的,本文将就“段错误“这个 内存访问越界的错误谈谈如何快速定位这些“段 错误“的语句。 下面将就以下的一个存在段错误的程序介绍几种调试方法:1 dummy_function (void)2 3 unsigned char *ptr = 0x00;4 *ptr = 0x00;5 67 int main (void)8 9 dummy_function ();1011 return 0;12 作为一个熟练的 C/C+程序员,以上代码的 bug 应该是很清楚的,因为它尝试操作地址为0 的内存

4、区域,而这个内存区域通常是不可访问的禁区,当然就会出错了。我们尝试编译运行 它:xiaosuogentux test $ ./a.out段错误果然不出所料,它出错并退出了。 1.利用利用 gdb 逐步查找段错误逐步查找段错误: 这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程 序,所以我们加上“-g -rdynamic“的参数进行编译,然后用 gdb 调试运行这个新编译的程序, 具体步骤如下:xiaosuogentux test $ gcc -g -rdynamic d.cxiaosuogentux test $ gdb ./a.outGNU gdb 6.5Co

5、pyright (C) 2006 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type “show copying“ to see the conditions.There is absolutely no warranty for GDB. Type “show warran

6、ty“ for details.This GDB was configured as “i686-pc-linux-gnu“.Using host libthread_db library “/lib/libthread_db.so.1“.(gdb) rStarting program: /home/xiaosuo/test/a.outProgram received signal SIGSEGV, Segmentation fault.0x08048524 in dummy_function () at d.c:44 *ptr = 0x00;(gdb) 哦?!好像不用一步步调试我们就找到了出

7、错位置 d.c 文件的第4行,其实就是如此的简单。从这里我们还发现进程是由于收到了 SIGSEGV 信号而结束的。通过进一步的查阅文档(man 7 signal),我们知道 SIGSEGV 默认 handler 的动作是打印”段错误“的出错信息,并产生 Core 文件,由此我们又产生了方法二。 2.分析分析 Core 文件:文件: Core 文件是什么呢?The default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file contai

8、ning an image of the processs memory at the time of termination. A list of the signals which cause a process to dump core can be found in signal(7).以 上资料摘自 man page(man 5 core)。不过奇怪了,我的系统上并没有找到 core 文件。后来, 忆起为了渐少系统上的拉圾文件的数量(本人有些洁癖,这也是我喜欢 Gentoo 的原因 之一) ,禁止了 core 文件的生成,查看了以下果真如此,将系统的 core 文件的大小限制在512

9、K 大 小,再试:xiaosuogentux test $ ulimit -c0xiaosuogentux test $ ulimit -c 1000xiaosuogentux test $ ulimit -c1000xiaosuogentux test $ ./a.out段错误 (core dumped)xiaosuogentux test $ lsa.out core d.c f.c g.c pango.c test_iconv.c test_regex.ccore 文件终于产生了,用 gdb 调试一下看看吧:xiaosuogentux test $ gdb ./a.out coreGNU

10、 gdb 6.5Copyright (C) 2006 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type “show copying“ to see the conditions.There is absolutely no warranty for GDB. Type “s

11、how warranty“ for details.This GDB was configured as “i686-pc-linux-gnu“.Using host libthread_db library “/lib/libthread_db.so.1“.warning: Cant read pathname for load map: 输入/输出错误.Reading symbols from /lib/libc.so.6.done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2.done.L

12、oaded symbols for /lib/ld-linux.so.2Core was generated by ./a.out.Program terminated with signal 11, Segmentation fault.#0 0x08048524 in dummy_function () at d.c:44 *ptr = 0x00;哇,好历害,还是一步就定位到了错误所在地,佩服一下 Linux/Unix 系统的此类设计。 接着考虑下去,以前用 windows 系统下的 ie 的时侯,有时打开某些网页,会出现“运行时错 误”,这个时侯如果恰好你的机器上又装有 windows

13、的编译器的话,他会弹出来一个对话框, 问你是否进行调试,如果你选择是,编译器将被打开,并进入调试状态,开始调试。 Linux 下如何做到这些呢?我的大脑飞速地旋转着,有了,让它在 SIGSEGV 的 handler 中调 用 gdb,于是第三个方法又诞生了: 3.段错误时启动调试段错误时启动调试:#include #include #include #include void dump(int signo)char buf1024;char cmd1024;FILE *fh;snprintf(buf, sizeof(buf), “/proc/%d/cmdline“, getpid();if(!

14、(fh = fopen(buf, “r“)exit(0);if(!fgets(buf, sizeof(buf), fh)exit(0);fclose(fh);if(bufstrlen(buf) - 1 = n)bufstrlen(buf) - 1 = 0;snprintf(cmd, sizeof(cmd), “gdb %s %d“, buf, getpid();system(cmd);exit(0);voiddummy_function (void)unsigned char *ptr = 0x00;*ptr = 0x00;intmain (void)signal(SIGSEGV, dummy

15、_function ();return 0;编译运行效果如下:xiaosuogentux test $ gcc -g -rdynamic f.cxiaosuogentux test $ ./a.outGNU gdb 6.5Copyright (C) 2006 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certai

16、n conditions.Type “show copying“ to see the conditions.There is absolutely no warranty for GDB. Type “show warranty“ for details.This GDB was configured as “i686-pc-linux-gnu“.Using host libthread_db library “/lib/libthread_db.so.1“.Attaching to program: /home/xiaosuo/test/a.out, process 9563Reading symbols from /lib/libc.so.6.done.Loaded symbols for /

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 试题/考题

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号