5

What I'm really doing is trying to set a watchpoint on the setting or clearing of a single bit. I do that by setting a watchpoint on the word containing the bit, then making it conditional on *word & mask (for setting, or (~*word) & mask for clearing.)

The problem is that some other bit in the same word may be modified, and the condition may happen to already match. If I had the old and new values, I could set a condition of (($old ^ $new) & mask).

I looked at the python gdb.Breakpoint class, but it doesn't seem to receive this information either.

I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.

sfink
  • 1,726
  • 1
  • 17
  • 22

1 Answers1

4

There's no direct way to get these values in gdb; it's been a wish-list bug (with your exact case as the example...) for years.. The information is stored in the old_val field of the struct bpstats object associated with the breakpoint; but this is only used to print the old value and not exposed elsewhere.

One option might be to change gdb to expose this value via a convenience variable or via Python.

I suppose I could go crazy and set a command list that records the current value whenever the value of *word changes, and use that as $old. But half the time I'm using this, I'm actually using it through rr, so I might be going backwards.

This seems doable. Your script could check the current execution direction. The main difficulty is remembering to reset the saved value when making this watchpoint, or after disabling and then re-enabling it.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
  • I have a function that happens to have `++depth` as its first line, and `--depth` as its last (void function, no other return). I'd like my Python code (subclass of `gdb.Breakpoint`) to run at this function's start and end. None of the tricks to [set breakpoint where the function returns](https://stackoverflow.com/questions/3649468/) seemed to work for me, so I thought setting a watchpoint on my variable `depth` might work—it does, but I cannot distinguish between `++depth` and `--depth` (function enter and exit). Is there some workaround? – ShreevatsaR Aug 24 '17 at 14:27
  • I did figure out a trick where I set both a breakpoint at function begin and a watchpoint on the `depth` variable, and maintain global state (a stack basically) that keeps track of all the times either of these have triggered. In the function breakpoint push `(` onto the stack; in the watchpoint, if the last trigger was the function, then push `|` onto the stack (and you know you're entering the function), else pop twice (as you know you're exiting it), etc. But I imagine there exists something less crazy. :-) – ShreevatsaR Aug 26 '17 at 02:18
  • Looks like there was no movement on the bug, correct? In my case, I'm trying to watch a register and ignore the value changes due to "context switches". – Dan M. May 25 '23 at 08:09