gdb:获取值的最后更改

发布于 2025-01-17 03:12:21 字数 355 浏览 0 评论 0原文

我有一个有错误的 C 应用程序:有一个值(在静态数组中的特定位置;因此地址是众所周知的)在某些时候具有意外值。我已经尝试过这些事情:

  • 使用地址清理程序:它没有检测到任何内容
  • 使用观察点:不幸的是,该值可以以有效的方式多次更改,直到更改无效。即使最终值也可能会出现多次(这是有效的)。因此不可能检查特定值。

一旦该值是“意外”,应用程序就会挂起(基本上自旋锁将永远循环)。如果发生这种情况,我想获取特定地址的最新更改。

是否有可能用 gdb 来做到这一点?

非常感谢

-编辑-

当值更改并自动继续时始终转储堆栈跟踪就已经足够了。我不确定 gdb 是否可以轻松实现这一点。

I have a C-application which has a bug: There's a value (at a specific location in an static array; so the address is well-known) which has at some point an unexpected value. I've tried these things:

  • Using address sanitizer: It did not detect anything
  • Using watch-point: Unfortunately the value can change many many times in a valid way until the change is invalid. Even the final value might an will appear many times (which is valid). So it's not possible to check for a specific value.

As soon as the value is "unexpected", the application will hang (basically a spin-lock will loop forever). If this happens I would like to get the last changes for the specific address.

Is it somehow possible to do this with gdb?

Thank you very much

-edit-

It would already be sufficient to always dump the stacktrace when the value changes and automatically continue. I'm not sure if that's easily possible with gdb.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半﹌身腐败 2025-01-24 03:12:21

在 Linux 上,调试此类问题的最佳方法是使用可逆调试器,例如 rr

例如,它允许您运行直到崩溃或损坏,然后设置观察点并执行“reverse-cont”以返回到上次更新值的位置。

这适用于您的情况 - 损坏是可重复的,在随机内存损坏的情况下 - 因为 rr 准确地重播运行 >,反向执行期间没有变化。

On Linux, the best way to debug a problem like this is by using reversible debugger, such as rr.

It allows you to e.g. run until crash or corruption, then set watch point and do reverse-cont to go back to where the value was last updated.

This works in your case -- where corruption is repeatable, and also in the case where random memory is corrupted -- since rr replays the run exactly, there is no variability during reverse execution.

迷乱花海 2025-01-24 03:12:21

使用观察点:不幸的是,该值可以以有效的方式多次更改,直到更改无效。即使最终值也可能会出现多次(这是有效的)。因此无法检查特定值。

GDB 观察点不仅在特定内存地址处的值更改为特定值时支持中断。它还支持更复杂的条件表达式,例如:

enable_break && intended_value != actual_value

在注释部分,您声明预期的更改是微不足道的,并且您确定该值是从非预期来源修改的。因此,如果 actual_value 是从非预期来源修改的值,那么您可以引入一个具有 static 生命周期的新变量,称为 intended_value,每当您有意更改此变量的值时,您都将其设置为与 actual_value 相同的值。

然而,单独使用表达式

intended_value != actual_value

会存在一个问题,即无法同时为两个变量设置新值,并且依次修改变量会触发观察点。

为了防止每当更改这些变量的值时触发观察点,您可以将表达式更改为以下内容:

enable_break && intended_value != actual_value

变量 enable_break 应该是 bool,其中 >static 生命周期,指定观察点是否应处于活动状态。

每当您想要为 intended_valueactual_value 分配新值时,您可以将 enable_break 设置为 false,同时设置变量更改为新值,然后通过将 enable_break 设置为 true 来重新启用观察点。这样,当您有意为这些变量分配新值时,观察点将永远不会触发。

但请注意,根据有关观察点的 GDB 文档,软件观察点可能无法检测另一个线程是否更改了观察点的表达式。

Using watch-point: Unfortunately the value can change many many times in a valid way until the change is invalid. Even the final value might an will appear many times (which is valid). So it's not possible to check for a specific value.

A GDB watchpoint does not only support breaks if the value at a particular memory address changes to a particular value. It also supports more complex conditional expressions, such as:

enable_break && intended_value != actual_value

In the comments section, you stated that the intended changes are trivial and that you are sure that the value is being modified from an unintended source. Therefore, if actual_value is the value that is being modified from an unintended source, then you could introduce a new variable with static lifetime called intended_value, which you set to the same value as actual_value whenever you intentionally change the value of this variable.

However, using the expression

intended_value != actual_value

by itself would have the problem that you cannot set a new value for both variables at the same time, and modifying the variables one after the other would trigger the watchpoint.

In order to prevent the watchpoint from triggering whenever you change the value of these variables, you can change the expression to the following:

enable_break && intended_value != actual_value

The variable enable_break should be a bool with static lifetime, which specifies whether the watchpoint should be active or not.

Whenever you want to assign a new value to intended_value and actual_value, you can set enable_break to false, set both variables to the new values, and then reenable the watchpoint by setting enable_break to true. That way, the watchpoint will never trigger when you intentionally assign a new value to these variables.

Note however that according to the GDB documentation on watchpoints, software watchpoints may not detect if another thread changes the expression of the watchpoint.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文