005 Linux系统内存错误产生的原因及调试方法(段错误|core dumped)
Linux系统内存错误产生的原因及调试方法(段错误|core dumped)[转]
Posted on 2008-09-05 14:52 猫头鹰 阅读(84) 评论(0) 编辑 收藏 引用 所属分类: 软件技巧
产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址。
一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,它是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序在cpu中的运行级别,指向的gdt是以64位为一个单位的表,在这张表中就保存着程序运行的代码段、数据段的起始地址、与此相应的段限和页面交换、程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了.
在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的:
1)访问系统数据区,尤其是往系统保护的内存地址写数据,最常见的就是给一个指针以0地址;
2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域。
解决方法
我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富, 难免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就“段错误”这个 内存访问越界的错误谈谈如何快速定位这些“段错误”的语句。
下面将就以下的一个存在段错误的程序介绍几种调试方法:
1 dummy_function (void) 2 { 3 unsigned char *ptr = 0x00; 4 *ptr = 0x00; 5 } 6 7 int main (void) 8 { 9 dummy_function (); 10 11 return 0; 12 } |
xiaosuo@gentux test $ ./a.out 段错误 |
这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程序,所以我们加上“-g -rdynamic"的参数进行编译,然后用gdb调试运行这个新编译的程序,具体步骤如下:
xiaosuo@gentux test $ gcc -g -rdynamic d.c xiaosuo@gentux test $ gdb ./a.out GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome 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 warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) r Program received signal SIGSEGV, Segmentation fault. |
从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。通过进一步的查阅文档(man 7 signal),我们知道SIGSEGV默认的处理动作是打印“段错误”的出错信息,并产生Core文件,由此我们又产生了方法二。
Core文件是什么呢?
The default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file containing an image of the process's memory at the time of termination. A list of the signals which cause a process to dump core can be found in signal(7). |
xiaosuo@gentux test $ ulimit -c 0 xiaosuo@gentux test $ ulimit -c 1000 xiaosuo@gentux test $ ulimit -c 1000 xiaosuo@gentux test $ ./a.out 段错误 (core dumped) xiaosuo@gentux test $ ls a.out core d.c f.c g.c pango.c test_iconv.c test_regex.c |
xiaosuo@gentux test $ gdb ./a.out core GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome 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 warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1". warning: Can't read pathname for load map: 输入/输出错误. |
接着考虑下去,以前用windows系统下的ie的时侯,有时打开某些网页,会出现“运行时错误”,这个时侯如果恰好你的机器上又装有windows的编译器的话,他会弹出来一个对话框,问你是否进行调试,如果你选择是,编译器将被打开,并进入调试状态,开始调试。
3.段错误时启动调试:
#include #include #include #include void dump(int signo) snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid()); exit(0); void int return 0; |
xiaosuo@gentux test $ gcc -g -rdynamic f.c xiaosuo@gentux test $ ./a.out GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome 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 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 9563 |
#include #include #include #include /* A dummy function to make the backtrace more interesting. */ void dump(int signo) size = backtrace (array, 10); printf ("Obtained %zd stack frames.n", size); for (i = 0; i < size; i++) free (strings); exit(0); int return 0; |
xiaosuo@gentux test $ gcc -g -rdynamic g.c xiaosuo@gentux test $ ./a.out Obtained 5 stack frames. ./a.out(dump+0x19) [0x80486c2] [0xffffe420] ./a.out(main+0x35) [0x804876f] /lib/libc.so.6(__libc_start_main+0xe6) [0xb7e02866] ./a.out [0x8048601] |
xiaosuo@gentux test $ objdump -d a.out |
8048765: e8 02 fe ff ff call 804856c |
005 Linux系统内存错误产生的原因及调试方法(段错误|core dumped)相关推荐
- linux内存不足+段错误,Linux系统内存错误产生的原因及调试方法(段错误|core dumped)[转]...
产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来 ...
- linux程序运行段错误,Linux下的段错误产生的原因及调试方法
Linux下的段错误产生的原因及调试方法 简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来 说,段错误就是指访问的内存超出 ...
- 转Linux环境下段错误的产生原因及调试方法小结
Linux环境下段错误的产生原因及调试方法小结 转载于:https://www.cnblogs.com/objectDetect/p/7575659.html
- Linux环境下段错误的产生原因及调试方法小结
From:http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基 ...
- [转]Linux环境下段错误的产生原因及调试方法小结
最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的"段错误"(Segme ...
- Linux环境下段错误的产生原因及调试方法
1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个对于" ...
- linux 内存出错位置,Linux系统内存错误产生的原因及调试方法
而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由g ...
- Linux下的段错误产生的原因及调试方法-转
分类: Linux--Ubuntu入门级 重学C/C++2011-10-19 22:13 332人阅读 评论(0) 收藏 举报 因为你调用了glibc的fputs 检查你传进去的char* +++++ ...
- linux at24c 前几个字节错误,Linux下的段错误产生的原因及调试方法
简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址. 一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由 ...
最新文章
- python代码块使用缩进表示-Python 为什么抛弃累赘的花括号,使用缩进来划分代码块?...
- 支持向量机ModuleNotFoundError: No module named ‘sklearn.datasets.samples_generator‘
- 前端基础(一):js数据类型
- 除了TensorFlow、PyTorch,还有哪些深度学习框架值得期待?
- java 字符串转成图片_java 转换图片为字符串,将字符串转换成图片显示
- 一加6html查看程序,一加6T评测:极速屏下指纹,解锁你想要的轻快顺滑
- [转载] Python的生成器
- php break 用法,PHP break语句
- HDU 3695 Computer Virus on Planet Pandora (AC自己主动机)
- .NET 5中的EF Core 5数据迁移:在单独的库中并自动部署
- 金融产品经理的能力修炼精进指南
- 以后咱家客厅就得装修成这样!
- 2021年北京高考成绩排名查询,北京2021高考成绩排名榜单,北京各高中高考成绩喜报...
- 金武彩印机械设备有限公司仓储管理系统设计与实现
- ES选举:Elasticsearch中Master选举完全解读
- windows系统背景淡绿护眼色设置
- [周鸿祎] 与其苟且活着,不如奋起抗争
- 解读群体机器人合力协作精神
- 软件测试周刊(第36期):为什么你要当程序员?
- 时间序列分析简介(一)