linux 内存异常,linux下常见内存异常查证工具和方法介绍(示例代码)

本文详细介绍了Linux系统中常见的内存异常问题,包括空指针异常、函数栈溢出、动态内存越界和重复释放等。通过coredump、gdb、Electric Fence等工具及相应的编译选项,提供了实用的查证方法和案例分析,助您快速定位和解决内存问题。
摘要由CSDN通过智能技术生成

linux下常见内存异常查证工具和方法介绍

内存异常导致的异常往往很难查证,本文介绍在linux下的各种常见内存异常的查证工具和方法。

1、访问空指针/未初始化指针

这个是最简单的内存异常了,只要能够生成coredump文件,可以快速定位问题代码。

开启coredump

部分环境下默认不会生成coredump,需要运行如下命令:

ulimit -c unlimited //unlimited表示不限制coredump文件大小,也可以指定一个最大文件大小。

定制core文件名

默认的coredump文件名为core,如果想自己定制core文件名,可以运行如下命令:

echo “./core-%e-%p-%t” > /proc/sys/kernel/core_pattern

可以在core_pattern模板中使用变量还很多,见下面的列表:

%% 单个%字符

%p 所dump进程的进程ID

%u 所dump进程的实际用户ID

%g 所dump进程的实际组ID

%s 导致本次core dump的信号

%t core dump的时间 (由1970年1月1日计起的秒数)

%h 主机名

%e 程序文件名

使用gdb定位代码行

问题代码int main()

{

int *p=0;

*p=6;

return 0;

}

使用gcc -g编译后运行出现异常,通过gdb即可定位出错代码行[email protected]:/home/zte/test# gcc null.cc -g

[email protected]:/home/zte/test# ./a.out

Segmentation fault (core dumped)

[email protected]:/home/zte/test# gdb a.out core

.......

Core was generated by `./null‘.

Program terminated with signal SIGSEGV, Segmentation fault.

#0 0x00000000004004fd in main () at null.cc:4

4 *p=6;

2、函数栈溢出

局部变量的写越界可能会破坏函数栈帧导致程序coredump,由于默认不会在越界的第一现场coredump,导致问题查证非常困难。

幸运的是我们可以通过gcc的编译选项-fstack-protector 和 -fstack-protector-all在函数栈被破坏的第一现场就coredump,从而可以方便地定位问题。

示例int main()

{

int a=5;

int *p=&a;

p[3]=6;

return 0;

}

上面代码会破坏函数栈,如果我们用gcc直接编译运行,不会抛异常。但是加了编译参数-fstack-protector 和 -fstack-protector-all后,再运行就会抛异常。下面是具体命令执行结果。[email protected]:/home/zte/test# gcc t.c

[email protected]:/home/zte/test# ./a.out

[email protected]:/home/zte/test# gcc t.c -fstack-protector -fstack-protector-all -g

[email protected]:/home/zte/test# ./a.out

*** stack smashing detected ***: ./a.out terminated

Aborted (core dumped)

可以进一步用gdb的bt命令定位出问题的函数。[email protected]:/home/zte/test# gdb a.out core

。。。。。。。。

Core was generated by `./a.out‘.

Program terminated with signal SIGABRT, Aborted.

#0 0x00007f6bcfab5c37 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56

56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.

(gdb) bt

#0 0x00007f6bcfab5c37 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56

#1 0x00007f6bcfab9028 in __GI_abort () at abort.c:89

#2 0x00007f6bcfaf22a4 in __libc_message ([email protected]=1, [email protected]=0x7f6bcfc01d70 "*** %s ***: %s terminated\n")

at ../sysdeps/posix/libc_fatal.c:175

#3 0x00007f6bcfb8d83c in __GI___fortify_fail (msg=, [email protected]=0x7f6bcfc01d58 "stack smashing detected")

at fortify_fail.c:38

#4 0x00007f6bcfb8d7e0 in __stack_chk_fail () at stack_chk_fail.c:28

#5 0x00000000004005aa in main () at t.c:7

(gdb) q

3、越界读写动态分配内存/读写已释放动态分配内存

动态分配内存读写越界、读写已释放动态分配内存系统默认可能不会抛异常,我们可以使用electric-fence来使得读写越界内存立刻抛异常,加速问题定位。

安装Electric fence

sudo apt-get install electric-fence

使用Electric fence

下面是越界写代码#include

int main()

{

int *p = (int*)malloc(sizeof(int));

p[1] = 6;

return 0;

}

如果使用gcc直接编译运行,不会抛异常。

我们可以加上参数 -lefence -g编译后运行,就会抛异常。通过gdb的bt打印即可定位到问题代码行。[email protected]:/home/zte/test# gcc malloc_read_free.cc -lefence -g

[email protected]:/home/zte/test# ./a.out

Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens

Segmentation fault (core dumped)

4、动态分配内存重复释放

默认会抛异常,通过gdb和coredump即可定位。

generated by haroopad

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值