首页 > 解决方案 > 遍历链表gdb时不断更新watchpoint

问题描述

假设我有以下简化的代码来循环链接列表。每个节点都有一个数据指针和下一个指针。

1 while (pNode->next != NULL)
2 {
3    pNode->data = newData;
4
5    pNode = pNode->next;
6 }

我将如何在当前地址上自动设置观察点并在pNode->data每次 pNode 更改时更新它?因此,在第 1 行删除观察点并设置一个新的观察点pNode->data。然后由于这并不总是发生,我需要在之后清除所有观察点,所以我不会不必要地停止,所以在第 7 行清除所有观察点。

此代码在多线程应用程序中运行,并且 pNode 列表是共享的,因此我试图找出谁在第 3 行和第 5 行之间更改我的 pNode->data。我确实有一个锁存器,应该防止在我迭代时更改列表但是由于这个错误,我们必须在没有闩锁的地方更改它,我想找出在哪里。

标签: cgdb

解决方案


我试图找出谁在第 3 行和第 5 行之间更改我的 pNode->data。

是什么让您认为data在第 3 行和第 5 行之间进行了修改?
如果列表是共享的,pNode->data可以在 5 次迭代后修改,或者在循环已经完成时修改。

通常,使用调试器调试多线程程序很困难。您确实需要通过构造来证明程序是正确的,即:您需要确认每次pNode->data修改时都持有一些互斥锁(我假设这就是您所说的“闩锁”)。

也就是说,您可以实现您的要求。

在第 3 行结束后立即找到指令的地址,并在该指令上设置断点(用于b *0xaddress这样做)。将命令附加到该断点:

commands 1
silent
watch -l pNode->data
cont
end

同样,找到之前pNode在第 5 行分配的指令并在那里设置断点。附加命令:

commands 2
silent
delete $bpnum
cont
end

这使用$bpnum了方便变量,该变量设置为最后设置的断点数。


推荐阅读