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

Reply via email to