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是一个实验性的工具,并不完善,使用时有以下限制:
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平台。