jade added a comment. In D62732#2707945 <https://reviews.llvm.org/D62732#2707945>, @jade wrote:
> In D62732#2306055 <https://reviews.llvm.org/D62732#2306055>, @labath wrote: > >> ABI plugins are one of the hardest things to test in lldb, particularly >> without actual hardware. That's why we've let them be added in the past >> without any accompanying tests. The situation is not ideal though, because >> we've accumulated various ABI plugins which are hard to change without >> breaking (or even to know if they work) because they only work with >> third-party (possibly proprietary) stubs. >> >> I'm not sure what's the state of risc-v hardware these days and how much >> resources do you have available, but if it's at all possible, I'd definitely >> recommend adding the lldb-server bits for risc-v and adding a builtbot for >> testing this configuration. >> >> Even if there's no hardware which could run the lldb test suite in a >> reasonable amount of time, the availability of an lldb-server implementation >> would enable anyone to test this via qemu -- that's the strategy we're >> pursuing for the ARM SVE stuff, and we're about to add instructions on how >> to run lldb+sve+qemu here: D82064 <https://reviews.llvm.org/D82064>. > > This is also testable with the gdbserver built into qemu, at least for kernel > debugging. It seems to work, although for some reason, step-out is broken for > me on a rust target (https://github.com/lf-/mu): > > (lldb) fin > error: Could not create return address breakpoint. > > I have yet to debug this but I think I will do so when I get more time. I have looked at this. On my bare metal target with the integrated qemu gdbserver, `bt`, in several instances, is thinking it is at level zero of the stack and thus can't find another frame to put a breakpoint at. I've made a simple bare metal project that hits this issue with the unwinder. You just need a qemu build with emulated architecture support enabled (package `qemu-arch-extra` in many distros) and a copy of clang/lld/lldb for this. These files are also available as a gist, which can be grabbed with: `git clone https://gist.github.com/e2efac2f780ed820277dbaf608805f4e lldb-riscv-repro` Makefile: QEMU = qemu-system-riscv64 TARGETFLAGS = --target=riscv64-none-unknown-elf -march=rv64imac CFLAGS = $(TARGETFLAGS) -mno-relax -fPIC -g QEMUOPTS = -machine virt -bios none -kernel kern -m 128M \ -nographic -s -S LINKFLAGS = $(TARGETFLAGS) -fuse-ld=lld -nostdlib -nodefaultlibs \ -Wl,-Tshoo.ld CC = clang kern: init.o start.o $(CC) $(LINKFLAGS) $^ -o $@ qemu: kern $(QEMU) $(QEMUOPTS) %.o: %.s $(CC) $(CFLAGS) -c $^ .PHONY: clean qemu clean: rm *.o kern `shoo.ld`: OUTPUT_ARCH("riscv64") ENTRY(_entry) SECTIONS { /* VIRT_DRAM */ . = 0x80000000; .text : { *(.text.first) *(.text .text.*) . = ALIGN(0x1000); } .rodata ALIGN(0x1000) : { . = ALIGN(16); PROVIDE(srodata = .); *(.srodata .srodata.*) . = ALIGN(16); *(.rodata .rodata.*) . = ALIGN(0x1000); PROVIDE(erodata = .); } .data ALIGN(0x1000) : { PROVIDE(srwdata = .); *(.sdata .sdata.*) . = ALIGN(16); *(.data .data.*) } .bss ALIGN(0x1000) : { . = ALIGN(16); *(.sbss .sbss.*) . = ALIGN(16); *(.bss .bss.*) } } `init.s`: // kernel entry point // largely nicked from https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/entry.S .data .globl STACKS .text .section .text.first .globl start .globl _entry // _entry(mhartid: usize, dtb: *const u8) _entry: // we arrive here, in machine mode, once qemu jumps to the start of memory // set up a stack la sp, STACKS li t0, 16384 // use 16k stacks // we want to get the pointer to the top of the (descending) stack // thus we want 16k * (hartid + 1) addi t1, a0, 1 mul t0, t0, t1 add sp, sp, t0 call startup spin: j spin // startup() will not return .text `start.c`: char STACKS[4*4096]; volatile int i1 = 0; volatile int i2 = 0; volatile int i3 = 0; void fn3(void) { i3 = 10; } void fn2(void) { i2 = 3; fn3(); } void fn1(void) { fn2(); fn2(); i1 = 18; } void startup(void) { fn1(); while (1) {} } Reproduction: $ make qemu # (in a separate window) $ lldb -a riscv64 (lldb) target create kern Current executable set to '/tmp/lldb-issue/kern' (riscv64). (lldb) gdb-remote 1234 Process 1 stopped * thread #1, stop reason = signal SIGTRAP frame #0: 0x0000000000001000 -> 0x1000: auipc t0, 0 0x1004: addi a2, t0, 40 (lldb) b fn3 Breakpoint 1: where = kern`fn3 + 2 at start.c:7:8, address = 0x0000000080000022 (lldb) c Process 1 resuming Process 1 stopped * thread #1, stop reason = breakpoint 1.1 frame #0: 0x0000000080000022 kern`fn3 at start.c:7:8 4 volatile int i3 = 0; 5 6 void fn3(void) { -> 7 i3 = 10; 8 } 9 10 void fn2(void) { kern`fn3: -> 0x80000022 <+2>: sd ra, 8(sp) 0x80000024 <+4>: sd s0, 0(sp) (lldb) bt * thread #1, stop reason = breakpoint 1.1 * frame #0: 0x0000000080000022 kern`fn3 at start.c:7:8 (lldb) fin error: Could not create return address breakpoint. Expected result: (gdb) target remote :1234 Remote debugging using :1234 0x0000000000001000 in ?? () => 0x0000000000001000: 97 02 00 00 auipc t0,0x0 (gdb) b fn3 Breakpoint 1 at 0x80000022: file start.c, line 7. (gdb) c Continuing. Breakpoint 1, fn3 () at start.c:7 7 i3 = 10; (gdb) bt #0 fn3 () at start.c:7 #1 0x0000000080000058 in fn2 () at start.c:12 #2 0x0000000080000070 in fn1 () at start.c:16 #3 0x000000008000009c in startup () at start.c:22 #4 0x000000008000001c in _entry () at init.s:23 Backtrace stopped: frame did not save the PC Another thing I've noticed while testing this patch is that the ABI names for the registers are the only ones accessible via `reg read`: `reg read x1` does not work, for instance. `lldb` has an alternate register name mechanism in `RegisterInfo`, which is used for `arg1`, `arg2`, etc, on Arm, and probably some others. It would be useful to have this for the `xN` register names in riscv. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D62732/new/ https://reviews.llvm.org/D62732 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits