【发布时间】:2010-09-20 14:26:14
【问题描述】:
我正在 gdb 中运行我的 C++ 程序。我对 gdb 没有真正的经验,但我收到的消息如下:
warning: HEAP[test.exe]:
warning: Heap block at 064EA560 modified at 064EA569 past requested size of 1
我如何追踪发生这种情况的位置?查看内存并没有给我任何线索。
谢谢!
【问题讨论】:
我正在 gdb 中运行我的 C++ 程序。我对 gdb 没有真正的经验,但我收到的消息如下:
warning: HEAP[test.exe]:
warning: Heap block at 064EA560 modified at 064EA569 past requested size of 1
我如何追踪发生这种情况的位置?查看内存并没有给我任何线索。
谢谢!
【问题讨论】:
当我试图重新分配指向我的结构的指针数组时,我遇到了类似的问题,但我正在重新分配为整数数组(因为我从教程中获得了代码并忘记更改它)。编译器没有纠正我,因为它无法检查大小参数中的内容。 我的变量是:
itemsetList_t ** iteration_isets;
所以在 realloc 中而不是:
iteration_isets = realloc(iteration_isets, sizeof(itemsetList_t *) * max_elem);
我有:
iteration_isets = realloc(iteration_isets, sizeof(int) * max_elem);
这导致了我的堆问题。
【讨论】:
所以你正在破坏你的堆。这是一个很好的GDB tutorial,请牢记。
我的常规做法是在代码的已知良好部分设置中断。一旦它到达那里,直到你出错。通常,您可以通过这种方式确定问题。
因为你遇到了一个堆错误,我认为它与你放在堆上的东西有关,所以要特别注意变量(我认为你可以在 GDB 中使用 print 来确定它的内存地址以及可能能够将您与出错的位置同步)。您还应该记住,输入函数和从函数返回与堆有关,因此它们可能是您的问题所在(特别是如果您在从函数返回之前弄乱了堆)。
【讨论】:
您可以尝试一件事,因为这与标准 libc 相同,配置了 MALLOC_CHECK_ 环境变量 (man libc)。
如果您不退出 gdb(如果您的应用程序退出,只需使用“r”重新运行它),您可以在该地址设置内存断点“hbreak 0x64EA569”,也可以使用“help hbreak”进行配置条件或其他断点启用/禁用选项,以防止过度进入该断点......
您可以只配置一个日志文件,设置日志...在每个中断设置一个堆栈跟踪,“display/bt -4”,然后按 r,然后按住 enter 键并让它滚动 “或使用 c ## 继续 x 次......等等......”,最终你会看到相同的断言,然后你现在将拥有(由于显示/bt)一个堆栈跟踪,你可以将其关联到正在修改的代码在那个地址...
【讨论】:
如果您可以使用其他工具,我强烈建议您尝试Valgrind。它是一个检测框架,可以以允许它通常在导致错误的确切指令处停止的方式运行您的代码。通过这种方式,通常很容易发现堆错误。
【讨论】:
您可能可以使用一种称为“观察点”的功能。这就像一个断点,但是当内存被修改时调试器会停止。
我对如何在 answer 中针对不同的问题给出了一个粗略的想法。
【讨论】: