From a4242dc3f5fa34a1686237c8b40a29d5fad1bcea Mon Sep 17 00:00:00 2001 From: Hui Li Date: Thu, 6 Feb 2025 20:29:56 +0800 Subject: gdb: LoongArch: Improve the handling of atomic sequence In the current code, when using software single-step to debug atomic instruction sequence, the execution of the atomic instruction sequence may not be completed normally. Here is a test with setting a software watchpoint to execute in software single-step mode: $ cat test.c int a = 0; int main() { a = 1; return 0; } $ gcc -g test.c -o test $ gdb test .. (gdb) start .. Temporary breakpoint 1, main () at test.c:4 4 a = 1; (gdb) set can-use-hw-watchpoints 0 (gdb) n 5 return 0; (gdb) watch a Watchpoint 2: a (gdb) c Continuing. At this point, the program continues to execute and can not exit normally because it incorrectly handled the following ll/sc atomic sequence in __run_exit_handlers () from /lib64/libc.so.6 during software single-step execution. 0x00007ffff7df7a48 <+408>: ld.d $t1, $s2, 1776 0x00007ffff7df7a4c <+412>: ll.w $t0, $t1, 0 => 0x00007ffff7df7a50 <+416>: bne $t0, $zero, 20 # 0x7ffff7df7a64 <__run_exit_handlers+436> 0x00007ffff7df7a54 <+420>: or $t3, $zero, $s4 0x00007ffff7df7a58 <+424>: sc.w $t3, $t1, 0 0x00007ffff7df7a5c <+428>: beq $zero, $t3, -16 # 0x7ffff7df7a4c <__run_exit_handlers+412> 0x00007ffff7df7a60 <+432>: b 8 # 0x7ffff7df7a68 <__run_exit_handlers+440> 0x00007ffff7df7a64 <+436>: dbar 0x700 0x00007ffff7df7a68 <+440>: slli.w $t0, $t0, 0x0 The root cause of this problem is that a breakpoint was inserted in the middle of ll/sc atomic sequence during software single-step execution. The execution result of the atomic instruction sequence is disrupted, causing the program unable to complete the execution of the atomic instruction sequence normally. Further explanation, if the current pc is 0x00007ffff7df7a50, it is a conditional branch instruction, breakpoint should only be set at the jump destination address (0x00007ffff7df7a64, which is outside of the ll/sc atomic instruction sequence) and should not set at the address of pc + 4 (0x00007ffff7df7a54, which is in the middle of ll/sc atomic sequence). Modify a judgment condition in loongarch_deal_with_atomic_sequence() to ensure that breakpoints can not be inserted in the middle of ll/sc atomic sequence to address such issues. Signed-off-by: Hui Li Signed-off-by: Tiezhu Yang --- gdb/loongarch-tdep.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gdb') diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 1cab29b..00c72d1 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -351,11 +351,13 @@ loongarch_deal_with_atomic_sequence (struct regcache *regcache, CORE_ADDR cur_pc { return {}; } - /* Look for a conditional branch instruction, put a breakpoint in its destination address. */ + /* Look for a conditional branch instruction, put a breakpoint in its destination address + which is outside of the ll/sc atomic instruction sequence. */ else if (loongarch_insn_is_cond_branch (insn)) { next_pc = loongarch_next_pc (regcache, cur_pc); - next_pcs.push_back (next_pc); + if (next_pc != cur_pc + insn_len) + next_pcs.push_back (next_pc); } /* Look for a Store Conditional instruction which closes the atomic sequence. */ else if (loongarch_insn_is_sc (insn)) -- cgit v1.1