linux大名鼎鼎的段错误解决之道(1)

段错误原因

1)、段错误究根到底就是访问了非法内存:

// 例子1:解引用空指针 
int *p=NULL; printf("%d\n",*p); //因为内存低地址为代码段,不可访问?

// 例子2:访问含有非法值得内存 
register int p =10; printf("%d\n",*p); //由于register关键字使变量存储到内核寄存器中,因此不能访问。

// 野指针:即定义指针时并未对其初始化,其指向的的位置式未知的。
// 对野指针解引用可能造成段错误或者导致程序崩溃。
// 防止方案:
/*
  1;定义时初始化为NULL 
  2;解引用前赋值 
  3;使用完后指向NULL 每次使用指针之前记得赋值就好了
*/

2)、数组越界

// 堆中
p = malloc(256); p[-1] = 0; p[256] = 0; //访问了未知空间的内存

// 栈中
int *p=NULL; 
int a[6]; 
p=a; 
for(int i=0;i<10;i++)
    {*p++=i;} //stack smashing detected 访问了未知空间的内存

3 )、scanf错误使用

int b; scanf("%d",b);//应为scanf("%d",&b);

4)、指针访问只读内存区

// 默认为const 指针
char *p=“abcddf”; *p=‘A’; //其实本质上错误原因和解引用空指针类似

5)、内存操作相关函数参数使用错误

memset(p1,p2,size); // p1或p2为 null或非法指针, size < 0 或 大于可操作区域 

首先遇到这个问题,不要怀疑是系统原因,一定要仔细分析自已的代码,对于有内存或指针操作的函数,一定要仔细检查,一般来说都是以上原因,几乎没有意外了。

解决步骤

1)确认是否崩溃

查看系统日志, 如果程序真的崩溃了,会在系统中留下痕迹,

路径:/var/log/messages

一般的信息如下

程序名[2374]: segfault at7f0ed0bfbf70 ip00007f0edd646fe7 sp 00007f0ed3603978 error 4 inlibc-2.17.so[7f0edd514000+1b6000]

如果查不到,则表示是由别人发送指令或程序自行正常关闭的,可以不用管了。

2)找到崩溃具体库名称

libc-2.17.so[7f0edd514000+1b6000]可以看出错误发生在libc上,libc在此程序中映射的内存基址为7f0edd514000;

segfault at和error 4这两条信息可以得出是内存读出错,4的意义如下,可以对照参考:

bit2:值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界

bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界

bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址

2)计算库偏移地址

3、7f0ed0bfbf70,00007f0edd646fe7,00007f0ed3603978这三个值:第一个值为出错的地址,用处不大;第二个值为发生错误时指令的地址,这个值在有些错误时是错误的,下面会讲一下,第三个值为堆栈指针。

指令地址为:00007f0edd646fe7,libc指令的基地址为:7f0edd514000,可以根据这两个值相计算一下该指令的相对地址为132FE7,下面我们需要找到相对代码段地址为132FE7的地方为什么函数。

2)找到库文件所在目录,使用如下反汇编指令

objdump-tT libc-2.17.so | grep 132 (132为相对地址前几位,由于相对地址计算的位置可能不准确)

00000000000bf370l F .text 0000000000000132 __statfs_link_max

0000000000132080l F .text 0000000000000068 __nss_gshadow_lookup

0000000000132f50l F.text 0000000000000fd9 __strncmp_sse42

00000000001320f0l F.text 00000000000000a5 __strchr_sse42

0000000000132020l F .text 000000000000005e __nss_aliases_lookup

132f50和132fe7很接近,很大可能是这个函数出现,而且又是读地址非法,这个函数有可能会出错这个问题,__strncmp_sse42这个函数是被strncmp调用的,看到这个函数基本上可以确定应该是这个函数惹得祸,其它函数同理。

3)查找相关函数处理

一、在代码中重点对上述提示函数进行排查,不放过上述函数的任何一个参数,即使不是指针。

二、通过对以上函数的形参打log方法排查导常;

三、分析代码逻辑,重点排查内存使用函数;

通过以上排查后,问题基本上可以得到解决,祝大家好运~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值