[Lldb-commits] [lldb] a111af7 - [lldb][test] Fix TestWriteOverSoftwareBreakpoint (#231850)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 14 03:33:26 PDT 2026
Author: David Spickett
Date: 2026-10-14T10:33:19Z
New Revision: a111af730a345868b8b8d0b180a939e8796ae59f
URL: https://github.com/llvm/llvm-project/commit/a111af730a345868b8b8d0b180a939e8796ae59f
DIFF: https://github.com/llvm/llvm-project/commit/a111af730a345868b8b8d0b180a939e8796ae59f.diff
LOG: [lldb][test] Fix TestWriteOverSoftwareBreakpoint (#231850)
After the changes made in #230518. They are correct, but broke an
assumption that I had made that there would be no live code between the
set of nops and the breakpoint location.
Before:
730: d503201f nop
734: 14000001 b 738 <place_break_here>
0000000000000738 <place_break_here>:
That "b" is dead code, but -
After:
73c: d503201f nop
740: 14000001 b 744 <foo+0x30>
744: b9400fe0 ldr w0, [sp, #12]
0000000000000748 <place_break_here>:
748: d503201f nop
That "ldr" is not.
To fix this, use a single inline asm block so we
can control the layout. The only drawback to that
is we have to spell out the branch over the
dead code.
Turns out most architectures are just "b" though.
Only tested on AArch64 but I did check that the
instructions assembled for the other targets.
Added:
Modified:
lldb/test/API/functionalities/breakpoint/write_over_software_breakpoint/main.c
Removed:
################################################################################
diff --git a/lldb/test/API/functionalities/breakpoint/write_over_software_breakpoint/main.c b/lldb/test/API/functionalities/breakpoint/write_over_software_breakpoint/main.c
index 4c9100dda604a..ca3e28f2bb762 100644
--- a/lldb/test/API/functionalities/breakpoint/write_over_software_breakpoint/main.c
+++ b/lldb/test/API/functionalities/breakpoint/write_over_software_breakpoint/main.c
@@ -1,22 +1,29 @@
+#if defined(__x86_64__) || defined(__i386__)
+#define BRANCH_FWD "jmp 1f\n"
+#elif defined(__aarch64__) || defined(__arm__) || defined(__powerpc64__) || \
+ defined(__powerpc__) || defined(__s390x__) || defined(__loongarch__)
+#define BRANCH_FWD "b 1f\n"
+#elif defined(__riscv)
+#define BRANCH_FWD "j 1f\n"
+#else
+#error Do not know unconditional branch mnemonic for this architecture.
+#endif
+
volatile int always_false;
int foo() {
- // This nop is deliberately dead code so that we have an instruction
- // immediately prior to the breakpoint that we are allowed to corrupt.
- if (always_false) {
- // This dead code must be at least 4 bytes even on an architecture where
- // nop is 1 byte.
- asm volatile("nop\n"
- "nop\n"
- "nop\n"
- "nop\n");
- }
- // We are assuming that there are no instructions placed between the dead code
- // above and the assembly below. This is not guaranteed but it's safer than
- // assuming that this function will have no prologue instructions or breaking
- // in the very first instruction of foo and hoping whatever comes before is
- // not important.
- asm volatile(".globl place_break_here\n"
+ asm volatile(BRANCH_FWD
+ // This is dead code that we are allowed to corrupt.
+ // There are 4 so that even if nop is 1 byte, we have 4 bytes
+ // we can overwrite safely.
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ // No live code should be between the dead code above
+ // and the breakpoint location below.
+ "1:\n"
+ ".globl place_break_here\n"
"place_break_here:\n"
// The test will repeatedly add and remove a breakpoint here.
"nop");
More information about the lldb-commits
mailing list