vs正常Linux越界,Linux內存越界檢測方法——valgrind



Linux內存越界檢測方法——valgrind

一.Valgrind

1.下載安裝

#configure

#make

#make install

2.使用

2.1內在越界

寫一段有內存訪問越界的代碼,如下:

#include 

#include 

#include 

int main()

{

char *p = NULL;

char *temp = NULL;

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

if (NULL == p)

{

perror("Cannot allocate memory.");

return -1;

}

temp[0] = p[6];

free(p);

p = NULL;

return 0;

}

保存文件test.c

在上面的代碼中,我們給p分配了一個字節的空間,后面卻要訪問p[6],看看會出現什么情況。

2.1.1帶DEBUG編譯

#gcc t-g test.c -o test

2.1.2運行分析

首先直接運行

#./test

段錯誤 (core dumped)

直接報錯退出。

使用valgrind加載運行test

#valgrind --tool=memcheck --leak-check=full ./test

==17686== Memcheck, a memory error detector

==17686== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.

==17686== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info

==17686== Command: ./test

==17686==

==17686==Invalid read of size 1

==17686==    at 0x40059A: main (test.c:19)

==17686==  Address 0x4c22046 is 5 bytes after a block of size 1 alloc'd

==17686==    at 0x4A0720A: malloc (vg_replace_malloc.c:296)

==17686==    by 0x400575: main (test.c:10)

==17686==

==17686== Invalid write of size 1

==17686==    at 0x4005A1: main (test.c:19)

==17686==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

==17686==

==17686==

==17686== Process terminating with default action of signal 11 (SIGSEGV)

==17686==  Access not within mapped region at address 0x0

==17686==    at 0x4005A1: main (test.c:19)

==17686==  If you believe this happened as a result of a stack

==17686==  overflow in your program's main thread (unlikely but

==17686==  possible), you can try to increase the size of the

==17686==  main thread stack using the --main-stacksize= flag.

==17686==  The main thread stack size used in this run was 10485760.

==17686==

==17686== HEAP SUMMARY:

==17686==     in use at exit: 1 bytes in 1 blocks

==17686==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated

==17686==

==17686== LEAK SUMMARY:

==17686==    definitely lost: 0 bytes in 0 blocks

==17686==    indirectly lost: 0 bytes in 0 blocks

==17686==      possibly lost: 0 bytes in 0 blocks

==17686==    still reachable: 1 bytes in 1 blocks

==17686==         suppressed: 0 bytes in 0 blocks

==17686== Reachable blocks (those to which a pointer was found) are not shown.

==17686== To see them, rerun with: --leak-check=full --show-leak-kinds=all

==17686==

==17686== For counts of detected and suppressed errors, rerun with: -v

==17686== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)

段錯誤 (core dumped)

我們看到,valgrind共報了兩個錯誤,見上面紅色部分,我們分別分析一下:

==17686== Invalid read of size 1

==17686==    at 0x40059A: main (test.c:19)

==17686==  Address 0x4c22046 is 5 bytes after a block of size 1 alloc'd

==17686==    at 0x4A0720A: malloc (vg_replace_malloc.c:296)

==17686==    by 0x400575: main (test.c:10)

這個是讀錯誤,指出在test.c的第19行,在第10行(p = (char*)malloc(sizeof(char));)正常分配給地址(0x4A0720A)1個字節,讀的地址(0x4c22046)卻是之后的5個字節處(我們訪問的p[6])。

再分析第二個錯誤:

==17686== Invalid write of size 1

==17686==    at 0x4005A1: main (test.c:19)

==17686==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Valgrind報怨我們沒有分配就開始使用,說的應該是temp了。

2.2內存泄露

2.2.1代碼修改

對於內存泄露,valgrind也可以很好地檢查出來,在上例中,做如下修改:

#include 

#include 

#include 

int main()

{

char *p = NULL;

char *temp = NULL;

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

if (NULL == p)

{

perror("Cannot allocate memory.");

return -1;

}

//temp[0] = p[6];

//free(p);

p = NULL;

return 0;

}

注釋內存訪問越界和釋放內存的代碼。

2.2.2編譯並運行

編譯(見上)。

先直接運行:

#./test

沒有任何提示。

再次使用Valgrind加載。

valgrind --tool=memcheck --leak-check=full ./test

==17793== Memcheck, a memory error detector

==17793== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.

==17793== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info

==17793== Command: ./test

==17793==

==17793==

==17793== HEAP SUMMARY:

==17793==     in use at exit: 1 bytes in 1 blocks

==17793==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated

==17793==

==17793== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1

==17793==    at 0x4A0720A: malloc (vg_replace_malloc.c:296)

==17793==    by 0x400525: main (test.c:10)

==17793==

==17793== LEAK SUMMARY:

==17793==    definitely lost: 1 bytes in 1 blocks

==17793==    indirectly lost: 0 bytes in 0 blocks

==17793==      possibly lost: 0 bytes in 0 blocks

==17793==    still reachable: 0 bytes in 0 blocks

==17793==         suppressed: 0 bytes in 0 blocks

==17793==

==17793== For counts of detected and suppressed errors, rerun with: -v

==17793== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

2.2.3分析

在上面標紅的描述中,告訴我們1個字節初分配,但未釋放,這1個字節是在test.c的第10行(p = (char*)malloc(sizeof(char));)分配的。

3.總結

由於HEAP SUMMARY是在程序正常退出時統計的內存泄露,所以如果程序異常退出,只能對已經運行的內存進行越界檢查,無法進行內存泄露的統計。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值