1

我有一个应用程序的堆损坏崩溃,因此我从 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 命令下方看到一条痕迹是释放内存的那个吗?如果是这样,我只能看到调用堆栈的一部分,有什么方法可以查看总调用堆栈或手动遍历调用堆栈以查看哪个操作释放了该内存块。

4

2 回答 2

1

如果你有源代码,你可以用你自己的函数替换删除/释放函数,这些函数可以在发布实际发生之前捕获堆栈。

在 Windows 上,您可以使用该函数获取调用堆栈,CaptureStackBackTrace但是此函数返回一组指针,您需要将它们转换为符号名称。为此,您可以使用SymInitialize,然后对于每个指针,您可以使用它SymFromAddr来获取符号的名称。这些名称是您正在搜索的实际功能。

但是,在 Windows 上使用调试器会更容易。还有Application Verifier一个来自 microsoft 的应用程序,可以帮助您捕获堆损坏(与 Visual Studio 调试器一起使用时)。

希望这对拉兹万有所帮助。

于 2013-10-25T15:46:51.483 回答
0

如果您运行调试版本,您很有可能会看到更多的调用堆栈。

另请参阅此链接

于 2013-10-25T16:53:46.833 回答