There are cases when WPs disabled by `disable_triggers()` can not be re-enabled by `enable_triggers()`.
Opened this issue · 2 comments
en-sc commented
Currently, disable_triggers()
just goes through all the WPs and disables them one-by-one (the case when r->manual_hwbp_set
is false
):
riscv-openocd/src/target/riscv/riscv.c
Lines 2487 to 2499 in 5afed58
enable_triggers()
works accordingly:riscv-openocd/src/target/riscv/riscv.c
Lines 2526 to 2536 in 5afed58
Now consider the following situation:
- A target has 2 triggers. The 1-st trigger supports configurations required by WP 1, WP 2, WP 3. The 2-nd trigger only supports configuration required by WP-2.
- The users sets WP 1. WP 1 occupies the 1-st trigger.
- The user sets WP 2. WP 2 occupies the 2-nd trigger,
- The user removes WP 1, the 1-st trigger is free.
- The user sets WP 3. WP 3 occupies the 1-st trigger.
- The situation is as follows:
taget->watchpoints
points to WP 2.taget->watchpoints->next
points to WP 3.
disable_triggers()
is called (e.g. duringstep
).enable_triggers()
will try to re-enable the disabled WP, but will fail, since WP 2 will occupy 1-st trigger and 2-nd triggerdoes not support WP 3.
en-sc commented
Moreover, seems like the state
array is redundant here -- all watchpoints are enabled/disabled at once.
JanMatCodasip commented
It sounds like a reasonable fix would be to:
Keep track of watchpoint --> trigger slot mapping intarget->watchpoints
or similar data structure.- This is already in
trigger_unique_id
instruct riscv_info
.
- This is already in
- Only (temporarily) disable the watchpoints and do not remove them from the
target->watchpoints
structure in the process. - When re-enabling watchpoints, ensure they are placed back into the exact "trigger slots" as originally.