如何检查堆栈是否已损坏

时间:2015-10-02 02:57:43

标签: c++ gdb stack-overflow icc

我遇到代码损坏的问题,我需要一种方法来检查本地堆栈是不是搞乱了。我注意到有些东西覆盖了this变量(好吧,这就是gdb似乎显示的内容。它将this指针显示为0x1959或其他一些似乎错误的小16位值), 所以我在代码中加入了一堆assert(VALID_RAM_MEMORY(this))这个定义

#define VALID_RAM_POINTER(x) (( (uint64_t)x & 0xFFFFFFFF00000000) == 0x7fff00000000ULL)

(我的代码中的所有指针都解决了这个问题,即以7FFF开头...)。但是,编译器似乎已经优化了此检查。例如,如果我有

void* a = suspicious_call();
assert(VALID_RAM_POINTER(this));
assert(VALID_RAM_POINTER(a));      //<<-- this one
assert(VALID_RAM_POINTER(this));

我发现调试器(gdb)捕获标记为&#34;这个&#34;的断言,并检查athis的值,我发现 both < / em> athis是虚假值,如0xabcd,而不是0x7FFFE1484580。似乎编译器认为thisconst,因此不必多次检查它。我想将this投射为volatile,但这是不可能的(我尝试过)。而且你不能取this的地址(它不是左值)。

 1): warning #191: type qualifier is meaningless on cast type
              assert(VALID_MEM_POINTER((volatile decltype(this))this));

我该怎么办?使用icc和gdb。

2 个答案:

答案 0 :(得分:1)

阻止编译器优化代码的一种方法是使用函数并确保函数不是内联函数。

声明:

#ifdef _DEBUG
void check_valid_ram_pointer(const void* ptr);
#else
#define check_valid_ram_pointer(x)
#endif

实施,在.cpp文件中:

#define VALID_RAM_POINTER(x) (( (uint64_t)x & 0xFFFFFFFF00000000) == 0x7fff00000000ULL)

#ifdef _DEBUG
void check_valid_ram_pointer(const void* ptr)
{
   assert(VALID_RAM_POINTER(ptr));
}
#endif

然后使用函数:

void* a = suspicious_call();
check_valid_ram_pointer(this);
check_valid_ram_pointer(a);
check_valid_ram_pointer(this);

答案 1 :(得分:0)

在发出可疑电话之前。 获取函数的第一个参数的地址。 &安培;声明的函数的最后一个局部变量。这是为此指针分配的堆栈范围+ 2个额外的地址空间&amp;退货地址。使用调试器,您可以在调用之前看到该内存范围的内容。通话结束后。如果你研究该范围内的(+ - )2个内存字,你也可以找到这个指针的内容。