Skip to content

using the qemu remote gdb interface

Francesco Lavra edited this page Aug 29, 2020 · 3 revisions

start qemu without starting (-S) with gdbserver on localhost:1234 (-s)

Note: Breakpoints are currently working only in noaccel mode.

qemu-system-x86_64 -device pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x3 -device pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x3.0x1 -device pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x3.0x2 -device virtio-scsi-pci,bus=pci.2,addr=0x0,id=scsi0 -device scsi-hd,bus=scsi0.0,drive=hd0 -no-reboot -cpu max -machine q35 -device isa-debug-exit -m 2G -drive file=/share/src/nanovms/signals2/output/image/disk.raw,format=raw,if=none,id=hd0 -device virtio-net,bus=pci.3,addr=0x0,netdev=n0 -netdev user,id=n0,hostfwd=tcp::8080-:8080,hostfwd=tcp::9090-:9090,hostfwd=udp::5309-:5309 -display none -serial stdio -s -S

start gdb in root of nanos tree

$ gdb
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
The target architecture is assumed to be i386:x86-64
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x000000000000fff0 in ?? ()
1: x/i $pc
=> 0xfff0:	add    %al,(%rax)
(gdb) 

set a breakpoint, continue, backtrace, inspect registers

(gdb) b debug_syscall
Function "debug_syscall" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b syscall_debug
Breakpoint 1 at 0x7f022f80: file /share/src/nanovms/signals2/src/unix/syscall.c, line 1883.
(gdb) c
Continuing.

Breakpoint 1, syscall_debug () at /share/src/nanovms/signals2/src/unix/syscall.c:1883
1883	{
(gdb) bt
#0  syscall_debug () at /share/src/nanovms/signals2/src/unix/syscall.c:1883
#1  0x000000007f0002d2 in syscall_enter ()
#2  0x0000000000000000 in ?? ()
(gdb) info reg
rax            0x7f022f80	2130849664
rbx            0xc	12
rcx            0x5000184e9	21474936041
rdx            0x773fffa8	2000682920
rsi            0x45a1c0	4563392
rdi            0x0	0
rbp            0x400040	0x400040
rsp            0x7faa3fe8	0x7faa3fe8
r8             0x0	0
r9             0x0	0
r10            0x0	0
r11            0x246	582
r12            0xa	10
r13            0x500001f20	21474844448
r14            0x1	1
r15            0x1000	4096
rip            0x7f022f80	0x7f022f80 <syscall_debug>
eflags         0x2	[ ]
cs             0x8	8
ss             0x10	16
ds             0x10	16
es             0x10	16
fs             0x0	0
gs             0x10	16
(gdb) 

inspect data and set watchpoints

(gdb) b read
Breakpoint 1 at 0x7f024a10: file /share/src/nanovms/signals2/src/unix/syscall.c, line 475.
(gdb) c
Continuing.

Breakpoint 1, read (fd=3, dest=0x6f5ff5a8 "", length=832) at /share/src/nanovms/signals2/src/unix/syscall.c:475
475	{
(gdb) set output-radix 16
Output radix now set to decimal 16, hex 10, octal 20.
(gdb) p *current
$1 = {frame = {0x3, 0x6f5ff5a0, 0x0, 0x340, 0x6f5ff5a8, 0x3, 0x6f5ff510, 0x6f5ff4b8, 0x0, 0x6f5ff58f, 0x6f5ff5a0, 0x0, 
    0x500225170, 0x340, 0x6f5ff58f, 0x0, 0x5000191d7, 0x202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10040d000, 0x0, 0x0, 0x0}, 
  syscall = 0x0, p = 0x101804000, uh = {kh = {pages = 0x7f056ba0 <bootstrap_region>, 
      physical = 0x7f056d18 <bootstrap_region+376>, virtual_huge = 0x7f057030 <bootstrap_region+1168>, 
      virtual_page = 0x7f057348 <bootstrap_region+1960>, backed = 0x7f057660 <bootstrap_region+2752>, 
      general = 0x7f0576c8 <bootstrap_region+2856>}, file_cache = 0x101000e00, epoll_cache = 0x101000f00, 
    epollfd_cache = 0x101001000, epoll_blocked_cache = 0x101001100, pipe_cache = 0x101001200, socket_cache = 0x101001400, 
    processes = 0x100200a80}, select_epoll = 0x0, clear_tid = 0x0, tid = 0x1, name = '\000' <repeats 15 times>, 
  run = 0x10040d020, log = {0x0 <repeats 64 times>}, blocked_on = 0x0, dummy_blockq = 0x100200e80, signals = {pending = 0x0, 
    mask = 0x0, saved = 0x0, ignored = 0x8410000, heads = {{prev = 0x1018053c8, next = 0x1018053c8}, {prev = 0x1018053d8, 
        next = 0x1018053d8}, {prev = 0x1018053e8, next = 0x1018053e8}, {prev = 0x1018053f8, next = 0x1018053f8}, {
        prev = 0x101805408, next = 0x101805408}, {prev = 0x101805418, next = 0x101805418}, {prev = 0x101805428, 
        next = 0x101805428}, {prev = 0x101805438, next = 0x101805438}, {prev = 0x101805448, next = 0x101805448}, {
        prev = 0x101805458, next = 0x101805458}, {prev = 0x101805468, next = 0x101805468}, {prev = 0x101805478, 
        next = 0x101805478}, {prev = 0x101805488, next = 0x101805488}, {prev = 0x101805498, next = 0x101805498}, {
        prev = 0x1018054a8, next = 0x1018054a8}, {prev = 0x1018054b8, next = 0x1018054b8}, {prev = 0x1018054c8, 
        next = 0x1018054c8}, {prev = 0x1018054d8, next = 0x1018054d8}, {prev = 0x1018054e8, next = 0x1018054e8}, {
        prev = 0x1018054f8, next = 0x1018054f8}, {prev = 0x101805508, next = 0x101805508}, {prev = 0x101805518, 
        next = 0x101805518}, {prev = 0x101805528, next = 0x101805528}, {prev = 0x101805538, next = 0x101805538}, {
        prev = 0x101805548, next = 0x101805548}, {prev = 0x101805558, next = 0x101805558}, {prev = 0x101805568, 
        next = 0x101805568}, {prev = 0x101805578, next = 0x101805578}, {prev = 0x101805588, next = 0x101805588}, {
        prev = 0x101805598, next = 0x101805598}, {prev = 0x1018055a8, next = 0x1018055a8}, {prev = 0x1018055b8, 
        next = 0x1018055b8}, {prev = 0x1018055c8, next = 0x1018055c8}, {prev = 0x1018055d8, next = 0x1018055d8}, {
        prev = 0x1018055e8, next = 0x1018055e8}, {prev = 0x1018055f8, next = 0x1018055f8}, {prev = 0x101805608, 
        next = 0x101805608}, {prev = 0x101805618, next = 0x101805618}, {prev = 0x101805628, next = 0x101805628}, {
        prev = 0x101805638, next = 0x101805638}, {prev = 0x101805648, next = 0x101805648}, {prev = 0x101805658, 
        next = 0x101805658}, {prev = 0x101805668, next = 0x101805668}, {prev = 0x101805678, next = 0x101805678}, {
        prev = 0x101805688, next = 0x101805688}, {prev = 0x101805698, next = 0x101805698}, {prev = 0x1018056a8, 
        next = 0x1018056a8}, {prev = 0x1018056b8, next = 0x1018056b8}, {prev = 0x1018056c8, next = 0x1018056c8}, {
        prev = 0x1018056d8, next = 0x1018056d8}, {prev = 0x1018056e8, next = 0x1018056e8}, {prev = 0x1018056f8, 
        next = 0x1018056f8}, {prev = 0x101805708, next = 0x101805708}, {prev = 0x101805718, next = 0x101805718}, {
        prev = 0x101805728, next = 0x101805728}, {prev = 0x101805738, next = 0x101805738}, {prev = 0x101805748, 
        next = 0x101805748}, {prev = 0x101805758, next = 0x101805758}, {prev = 0x101805768, next = 0x101805768}, {
        prev = 0x101805778, next = 0x101805778}, {prev = 0x101805788, next = 0x101805788}, {prev = 0x101805798, 
        next = 0x101805798}, {prev = 0x1018057a8, next = 0x1018057a8}, {prev = 0x1018057b8, next = 0x1018057b8}}}, 
  dispatch_sigstate = 0x0, rax_saved = 0x0, sigframe = {0x0 <repeats 30 times>}}
(gdb) watch *current->frame[16]
Hardware watchpoint 2: *current->frame[16]
(gdb) c
Continuing.

Hardware watchpoint 2: *current->frame[16]

Old value = 0xf0013d48
New value = 0xf0003d48
0x000000007f0002bb in syscall_enter ()
(gdb) 

golang support

It is said that golang support in gdb is quite lacking (https://golang.org/doc/gdb), however it is possible to do some inspection:

$ gdb
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
The target architecture is assumed to be i386:x86-64
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x000000000000fff0 in ?? ()
1: x/i $pc
=> 0xfff0:	add    %al,(%rax)
(gdb) symbol-file output/test/runtime/bin/webg
Load new symbol table from "output/test/runtime/bin/webg"? (y or n) y
Reading symbols from output/test/runtime/bin/webg...done.
Loading Go Runtime support.
(gdb) info goroutines
(gdb) c
Continuing.
  C-c C-c
Program received signal SIGINT, Interrupt.
0x000000007f033dd4 in ?? ()
(gdb) info goroutines
  1 waiting  runtime.gopark
  2 waiting  runtime.gopark
  3 waiting  runtime.gopark
  4 waiting  runtime.gopark
  5 waiting  runtime.gopark
(gdb) goroutine 1 bt
#0  runtime.gopark (unlockf=<optimized out>, lock=0x70c8054178, reason=13 '\r', traceEv=23 '\027', traceskip=3)
    at /usr/local/go-1.12.7/src/runtime/proc.go:302
#1  0x00000000004074fa in runtime.goparkunlock (lock=<optimized out>, reason=<optimized out>, traceEv=<optimized out>, 
    traceskip=<optimized out>) at /usr/local/go-1.12.7/src/runtime/proc.go:307
#2  runtime.chanrecv (c=0x70c8054120, ep=0x0, block=true, selected=<optimized out>, received=<optimized out>)
    at /usr/local/go-1.12.7/src/runtime/chan.go:524
#3  0x00000000004071fb in runtime.chanrecv1 (c=0x70c8054120, elem=0x0) at /usr/local/go-1.12.7/src/runtime/chan.go:406
#4  0x000000000065a130 in main.main () at /share/src/nanovms/signals2/test/runtime/webg.go:103
#5  0x000000000042e83c in runtime.main () at /usr/local/go-1.12.7/src/runtime/proc.go:200
#6  0x0000000000458a21 in runtime.goexit () at /usr/local/go-1.12.7/src/runtime/asm_amd64.s:1337
#7  0x0000000000000000 in ?? ()
(gdb) 

caveat emptor