我有一个应用程序的堆损坏崩溃,所以我从gflags打开了页面堆并收集了该应用程序的崩溃转储文件。
从转储文件中我发现它是由于双重释放内存。
这是一个例子,从调用堆栈我发现了这个
msvcr100!free(void * pBlock = "**Address**")
然后我做了这个
!heap -p -a <address>
address found in
_HEAP @
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
Address 000a 0000 [02] address 00003 - **(free )**
Trace: <1>
<2>
<3>
所以我们可以看到它试图加倍释放内存并导致崩溃。我的问题是,我们可以看到在此操作之前更改或释放该内存的调用堆栈吗?可能吗?
我可以在!heap -p -a命令下面看到一条跟踪释放内存的命令?如果是这样的话,我只能看到调用堆栈的某些部分,有没有什么方法可以看到总调用堆栈或手动遍历调用堆栈以查看哪个操作释放了该内存块。
答案 0 :(得分:1)
如果您有源代码,可以使用自己的函数替换delete / free函数,这些函数可以在发布实际发生之前捕获堆栈。
在Windows上,您可以使用函数CaptureStackBackTrace
获取调用堆栈,但是此函数会返回一组指针,您需要将它们转换为符号名称。
为此,您可以使用SymInitialize
,然后对于每个指针,您可以使用SymFromAddr
来获取符号的名称。名称是您要搜索的实际功能。
然而,在Windows上使用调试器会更容易。还有Application Verifier
这是一个来自microsoft的应用程序,它可以帮助您捕获堆损坏(与visual studio调试器一起使用时)。
希望这会有所帮助 勒兹。
答案 1 :(得分:0)
如果您运行调试版本,您很可能会看到更多的调用堆栈。
另见link