gdb看了大量的内存来查找损坏,这里没有seg故障

时间:2012-03-19 13:35:37

标签: c linux memory gdb

更新: 现在valgrind --tools=memcheck --track-origins=yes --leak-check=full ./prog正常运行,但如果没有此valgrind,它仍然会出错,这是怎么回事?

我在Linux上做了一个项目,它在内存中存储了大量数据,我需要知道哪个数据块被更改才能找到我程序中的问题。

更新:这是一个多线程程序,写入/读取由系统调用创建的不同线程完成。

代码就像这样

for(j=0;j<save_size;j++){
    e->blkmap_mem[blk_offset+save_offset + j] = get_mfs_hash_block();
    memcpy(e->blkmap_mem[blk_offset + save_offset +j]->data, (char *)buff + j * 4096, 4096);
    e->blkmap_mem[save_offset+j]->data = (char *)(buff + j* 4096);
    e->blkmap_mem[blk_offset+save_offset + j]->size = 4096;
    e->blkmap_addr[blk_offset+save_offset + j] = 1;

我想知道e->blkmap_mem[blk_offset+save_offset+j]->data是否在其他地方发生了变化。

我知道awatch exp中的gdb可以检查值是否发生了变化,但是这里有太多,有什么方法可以追踪它们,我的意思是它们可能接近6000个。

谢谢你们。

1 个答案:

答案 0 :(得分:7)

Reverse debugging在这里有一个很好的用例,假设你有一些方法来检测腐败一旦发生(一个seg错误就行了)。

一旦在调试会话中检测到损坏,就会在损坏的变量上放置一个监视点,然后向后运行程序,直到写入变量为止。

以下是分步指南:

  1. 像往常一样用调试符号编译程序并将其加载到gdb中。
  2. 使用start启动该程序。
    • 这会在main的最开始处设置一个断点,并运行程序直到它命中它。
  3. 现在,将断点放在检测到内存损坏的地方
    • 如果您使用seg故障检测到损坏,则无需执行此操作。
  4. 键入record以开始记录程序执行
    • 这就是我们之前调用start的原因 - 您无法记录何时没有进程正在运行。
  5. continue设置程序再次运行。
    • 录制时,程序运行速度非常慢
    • 它可能会告诉你记录缓冲区已满 - 如果发生这种情况,请告诉它包好。
  6. 当断点检测到损坏或seg故障时,程序将停止。现在将watch放在已损坏的变量上。
  7. reverse-continue向后运行程序,直到写入损坏的变量。
  8. 当观察点击中时,你发现了你的腐败现象。
    • 请注意,它并不总是该变量的第一次或唯一损坏。但是你可以继续向后跑,直到你用完反向执行历史 - 现在你已经有了一些东西需要解决。
  9. 有一个有用的教程here,它还讨论了如何控制记录缓冲区的大小,以防万一成为您的问题。