【linux】Valgrind工具集详解(十):SGCheck(检查栈和全局数组溢出)

一、概述

SGCheck是一种用于检查栈中和全局数组溢出的工具。它的工作原理是使用一种启发式方法,该方法源于对可能的堆栈形式和全局数组访问的观察。
栈中的数据:例如函数内声明数组int a[10],而不是malloc分配的,malloc分配的内存是在堆中。
SGCheck和Memcheck是互补的:它们的功能不重叠。
Memcheck对堆数组(如malloc分配的内存)执行边界检查和使用后检查。它还可以检查堆或栈分配创建的未初始化值(值的有效性检查)。但它不会对栈或全局数组执行边界检查。
SGCheck只对栈或全局数组进行边界检查,不做其它检查。

二、使用

1、SGCheck没有命令行参数,使用方法如下:

valgrind --tool=exp-sgcheck ./a.out

2、例子
main.c源码

int main()
{
	int i;
	int a[10];
	for (i=0; i<=10; ++i)//当i=10时,越界
	{
		a[i] = i;
	}
	return 0;
}

编译:gcc -g main.c
检查:$ valgrind --tool=exp-sgcheck ./a.out
错误信息

==3228== exp-sgcheck, a stack and global array overrun detector
==3228== NOTE: This is an Experimental-Class Valgrind Tool
==3228== Copyright (C) 2003-2013, and GNU GPL'd, by OpenWorks Ltd et al.
==3228== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==3228== Command: ./a.out
==3228== 
==3228== Invalid write of size 4
==3228==    at 0x400502: main (main.c:7)
==3228==  Address 0xfff0003b8 expected vs actual:
==3228==  Expected: stack array "a" of size 40 in this frame
==3228==  Actual:   unknown
==3228==  Actual:   is 0 after Expected
==3228== 
==3228== 
==3228== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

如果使用Memcheck无法检查处栈中数组越界的错误

$ valgrind ./a.out
==4212== Memcheck, a memory error detector
==4212== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4212== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4212== Command: ./a.out
==4212== 
==4212== 
==4212== HEAP SUMMARY:
==4212==     in use at exit: 0 bytes in 0 blocks
==4212==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4212== 
==4212== All heap blocks were freed -- no leaks are possible
==4212== 
==4212== For counts of detected and suppressed errors, rerun with: -v
==4212== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

三、SGCheck的缺点

SGCheck是一个实验性的工具,并不完善,使用时有以下限制:
1、遗漏错误
第一次使用栈或全局数组时就溢出了,该情况无法检查。因为内存引用指令对栈或全局数组的第一次访问时,在该指令和数组之间创建了一个关联,在后续访问中才做检查,直到函数退出,所以无法在检查第一次使用栈或全局数组时就溢出的问题。
2、误报
如对下面代码的检查,可以肯定下面代码没有错误,但是SGCheck会报告错误。解决办法就是,使用抑制错误。

int main()
{
        int a[10], b[10], *p, i;
        int q=0;
        for(i=0; i<10; i++)
        {
                p=(q==0)?&a[i]:&b[i];
                if (q==0)
                        q = 1;
                else
                        q = 0;
                *p = 42;
        }
}

编译:gcc -g main.c
检查:$ valgrind --tool=exp-sgcheck ./a.out
错误信息

$ valgrind --tool=exp-sgcheck ./a.out
==10724== exp-sgcheck, a stack and global array overrun detector
==10724== NOTE: This is an Experimental-Class Valgrind Tool
==10724== Copyright (C) 2003-2013, and GNU GPL'd, by OpenWorks Ltd et al.
==10724== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==10724== Command: ./a.out
==10724== 
==10724== Invalid write of size 4
==10724==    at 0x400549: main (main.c:12)
==10724==  Address 0xfff000394 expected vs actual:
==10724==  Expected: stack array "a" of size 40 in this frame
==10724==  Actual:   stack array "b" of size 40 in this frame
==10724==  Actual:   is 12 after Expected
==10724== 
==10724== Invalid write of size 4
==10724==    at 0x400549: main (main.c:12)
==10724==  Address 0xfff000368 expected vs actual:
==10724==  Expected: stack array "b" of size 40 in this frame
==10724==  Actual:   stack array "a" of size 40 in this frame
==10724==  Actual:   is 40 before Expected
==10724== 
==10724== 
==10724== ERROR SUMMARY: 9 errors from 2 contexts (suppressed: 4 from 4)

3、性能
SGCheck的运行速度比Memcheck慢。

4、平台
栈或全局数组检查在PowerPC、ARM或S390X平台上无法正常工作,仅适用于X86和AMD64平台。

你可能感兴趣的:(GDB,linux)