On 11/28/25 5:09 AM, Alvin Chang wrote:
The do_trigger_action() receives index of fired trigger as second
parameter. However, in current implementation, the argument is hardcoded
as DBG_ACTION_BP which is 0. This is a bug because we may match/fire any
breakpoints or watchpoints at other index than 0.
Fix this bug by iterating cpu_breakpoint[] and cpu_watchpoint[] to
compare and match necessary checkpoints. The index of the fired
cpu_breakpoint or the cpu_watchpoint is the index of the trigger we want
to provide to do_trigger_action().
Signed-off-by: Alvin Chang <[email protected]>
Reviewed-by: Yu-Ming Chang <[email protected]>
---
Reviewed-by: Daniel Henrique Barboza <[email protected]>
target/riscv/debug.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 5664466..f3bca8e 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -929,11 +929,24 @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
if (cs->watchpoint_hit) {
if (cs->watchpoint_hit->flags & BP_CPU) {
- do_trigger_action(env, DBG_ACTION_BP);
+ /* Search fired trigger and do its action */
+ for (int i = 0; i < ARRAY_SIZE(env->cpu_watchpoint); i++) {
+ if (cs->watchpoint_hit == env->cpu_watchpoint[i]) {
+ do_trigger_action(env, i);
+ break;
+ }
+ }
}
} else {
if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
- do_trigger_action(env, DBG_ACTION_BP);
+ /* Search fired trigger and do its action */
+ for (int i = 0; i < ARRAY_SIZE(env->cpu_breakpoint); i++) {
+ CPUBreakpoint *bp = env->cpu_breakpoint[i];
+ if (bp && bp->pc == env->pc && (bp->flags & BP_CPU)) {
+ do_trigger_action(env, i);
+ break;
+ }
+ }
}
}
}