您的位置:首页 > 运维架构 > Linux

linux中的段错误

2015-11-12 16:23 543 查看
1. 段错误是什么?

段错误:Segmentation Fault,简单说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址、访问了系统保护的内存地址、访问了只读的内存地址等情况。这里贴出“段错误的准确定义:

A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the
operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (e.g., attempts to write to a read-only
location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.

On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft
Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.

2. 段错误产生的原因

(1)访问不存在的内存地址

#include <stdio.h>
int main()
{
int *ptr = NULL;
*ptr = 0;
}
(2) 访问系统保护的内存地址

#include <stdio.h>
int main()
{
int *ptr = (int*)0;
*ptr = 100;
}
(3)访问了只读的内存地址

#include <stdio.h>
#include <string.h>
int main()
{
int *ptr = "test";
strcpy(ptr, "TEST");
}
(4)栈溢出

#include <stdio.h>
int main()
{
main();
}


3. 段错误信息的获取

(1)dmesg

dmesg可以在应用程序crash掉时,显示内核中保存的相关信息。

通过dmesg可以查看发送段错误的程序名称、引起段错误发送的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等。

(2.3)的错误如下:

Process 3199(a.out) has RLIMIT_CORE set to 0
Aborting core
a.out[3251]: segfault at bf289ffc ip 080484a6 sp bf28a000 error 6 in a.out[8048000+1000]
Process 3251(a.out) has RLIMIT_CORE set to 0
Aborting core
a.out[3285]: segfault at 8048590 ip 080484b0 sp bfc81af8 error 7 in a.out[8048000+1000]
Process 3285(a.out) has RLIMIT_CORE set to 0
Aborting core
Process 3306(a.out) has RLIMIT_CORE set to 0
Aborting core
a.out[3332]: segfault at 8048590 ip 080484b0 sp bf97a108 error 7 in a.out[8048000+1000]
a.out[3361]: segfault at 8048590 ip 080484b0 sp bfc41178 error 7 in a.out[8048000+1000]
a.out[3385]: segfault at 80485d0 ip 080484f9 sp bff79e10 error 7 in a.out[8048000+1000]
a.out[3443]: segfault at 8048590 ip 080484b0 sp bf9cd278 error 7 in a.out[8048000+1000]
(2) -g

用gdb查看

(3)nm命令,可以帮助查看哪里发送段错误

(4)ldd命令,可以查看二进制程序的共享链接库依赖,包括库名称、起始地址,用于确定段错误是发生在自己程序中还是依赖的共享库中。

4. 调试方法

(1)printf输出信息

(2)使用gdb调试程序

程序2.3中结果是

Program received signal SIGSEGV, Segmentation fault.
0x080484b0 in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.166.el6_7.1.i686 libgcc-4.4.7-16.el6.i686 libstdc++-4.4.7-16.el6.i686
(3)生成core文件。

在一些linux版本下默认不产生core文件,查看下系统core文件的大小限制:

@: ulimit -c
0
@:ulimit -c 1024
@:ulimit -c
1024

再运行程序即可产生core

5. 最后注意事项

(1) 出现段错误时,首先应该想到段错误的定义,从它出发考虑引发错误的原因。

(2) 在使用指针时,定义了指针后记得初始化指针,在使用的时候记得判断是否为NULL

(3) 在使用数组时,注意数组是否被初始化,数组下标是否越界,数组元素是否存在等。

(4) 在访问变量时,注意变量所占地址空间是否已经被程序释放掉。

(5) 在处理变量时,注意变量的格式控制是否合理等。

原文地址http://blog.163.com/longsu2010@yeah/blog/static/17361234820122761525799/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: