riscvarchive / riscv-binutils-gdb

RISC-V backports for binutils-gdb. Development is done upstream at the FSF.
GNU General Public License v2.0
148 stars 233 forks source link

continue function not working??? #272

Open yuyang-ok opened 1 year ago

yuyang-ok commented 1 year ago

I am using gdb to debug my program. I think continue not working. image

yuyang-ok commented 1 year ago

I am debugging a jit program , I think the current pc can't find in dwarf file. is this the reason why continuing not working.

T-J-Teru commented 1 year ago

The repeated SIGTRAPs are being caused by the ebreak instruction. What are you expecting to happen when that instruction is encountered? That the current pc is not covered by any DWARF information is why you are seeing ?? in the output, but that is not why you keep hitting the SIGTRAP - that's caused by the ebreak instruction.

yuyang-ok commented 1 year ago

I am assuming skip ebreak instruction and continue executing. I think ebreak has beed executed.

T-J-Teru commented 1 year ago

For sure ebreak has been executed, that's what's causing the trap. GDB uses the ebreak instruction for its software breakpoint implementation, so when you resume execution GDB will be trying to restart execution starting from the $pc of the ebreak instruction.

My original question was, why is there an ebreak instruction at this address to begin with? You mention JIT in your original question, so, why are you generating the ebreak?

yuyang-ok commented 1 year ago

because I cannot set breakpoint at a jit generated memory position.

In my memory gdb would say can't find the memory location. gdb will ask me if this is a shared library. ask me if set a breakpoint on future load.

yuyang-ok commented 1 year ago

if certain memory position contains an ebreak instruction, can gdb skip it??

yuyang-ok commented 1 year ago

because the origin of the memory position is ebreak have been gdb captured , should skip it and continue executing.

T-J-Teru commented 1 year ago

If you create a breakpoint over the top of the ebreak instruction, then GDB should correctly spot that this is a "fixed" breakpoint location, and should then skip over it. In this case you'd do break *0x4043a8d098, then everything should "just work".

Of course, this would lead me to ask why you say:

because I cannot set breakpoint at a jit generated memory position.

When you could just use the break *0xADDRESS syntax to place a breakpoint within the generated code - of course, you can only do this once the code in question has actually been generated, but that would seem like a reasonable restriction.

Your final choice for skipping the ebreak would be to just adjust the $pc value, as in set $pc = 0x..... using the address for the first instruction after the ebreak. When GDB resumes it should pick up at the next instruction.

yuyang-ok commented 1 year ago

I think gdb not skiping the "fixed" breakpoint.

T-J-Teru commented 1 year ago

The functionality seems to work fine for me. Maybe you should paste in your session, then folk can offer more help. Here's my session:

$ cat /tmp/ebreak.c 
int
main ()
{
  asm ("nop");
  asm ("nop");
  asm ("nop");
  asm ("ebreak");
  asm ("nop");
  asm ("nop");
  asm ("nop");

  return 0;
}
$ riscv32-unknown-elf-gcc -o /tmp/ebreak.rv32imfc.x /tmp/ebreak.c
$ gdb -q /tmp/ebreak.rv32imfc.x 
Reading symbols from /tmp/ebreak.rv32imfc.x...
(gdb) target remote | riscv-simulator --stdin
Remote debugging using | riscv32-simulator --stdin
0x00000000 in ?? ()
(gdb) load
Loading section .text, size 0x392 lma 0x10074
Loading section .eh_frame, size 0x4 lma 0x11408
Loading section .init_array, size 0x4 lma 0x1140c
Loading section .fini_array, size 0x4 lma 0x11410
Loading section .data, size 0x428 lma 0x11418
Loading section .sdata, size 0x8 lma 0x11840
Start address 0x00010074, load size 1998
Transfer rate: 114 KB/sec, 153 bytes/write.
(gdb) disassemble main
Dump of assembler code for function main:
   0x0001012e <+0>: addi    sp,sp,-16
   0x00010130 <+2>: sw  s0,12(sp)
   0x00010132 <+4>: addi    s0,sp,16
   0x00010134 <+6>: nop
   0x00010136 <+8>: nop
   0x00010138 <+10>:    nop
   0x0001013a <+12>:    ebreak
   0x0001013c <+14>:    nop
   0x0001013e <+16>:    nop
   0x00010140 <+18>:    nop
   0x00010142 <+20>:    li  a5,0
   0x00010144 <+22>:    mv  a0,a5
   0x00010146 <+24>:    lw  s0,12(sp)
   0x00010148 <+26>:    addi    sp,sp,16
   0x0001014a <+28>:    ret
End of assembler dump.
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0001013a in main ()
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0001013a in main ()
(gdb)  break *0x0001013a
Breakpoint 1 at 0x1013a
(gdb) c
Continuing.
[Inferior 1 (Remote target) exited normally]

This all seems to be working just fine here. If you are seeing different behaviour then you should try to give more details so we can help you, the target you're running on, the precise architecture type you're using, the version of GDB you are using. And, importantly, include an entire GDB session so we can check you are using the correct commands in the correct way.