riscv-binutils-gdb icon indicating copy to clipboard operation
riscv-binutils-gdb copied to clipboard

Compiling the gdbserver for native riscv execution

Open AntonKrug opened this issue 7 years ago • 30 comments

Hi

This is probably more a question than an issue. I'm not even sure if this is possible, but at the moment I'm trying to compile the binutils so I will get gdb-server which could be run natively on the riscv linux. My goal is to be able to debug remotely user space application inside the riscv linux.

I use the riscv-next branch and configure it with these commands:

./configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu --target=riscv64-unknown-linux-gnu

And it the end it outputs these errors:

proc-service.o: In function `ps_xfer_memory':
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `fill_gregset(regcache const*, unsigned long long (*) [32], int)'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `supply_gregset(regcache*, unsigned long long const (*) [32])'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `fill_fpregset(regcache const*, double (*) [32], int)'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `supply_fpregset(regcache*, double const (*) [32])'
collect2: error: ld returned 1 exit status
Makefile:2242: recipe for target 'gdb' failed
make[2]: *** [gdb] Error 1
make[2]: Leaving directory '/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb'
Makefile:10420: recipe for target 'all-gdb' failed
make[1]: *** [all-gdb] Error 2
make[1]: Leaving directory '/home/antonkrug/riscv-binutils-gdb-riscv-next'
Makefile:849: recipe for target 'all' failed
make: *** [all] Error 2

I attached the whole log file gdbserver-build.txt

Compiling the kernel, busybox and making my own rootfs works well, I only get stuck at step. Could somebody point me to the right direction or if this is even feasible or not?

AntonKrug avatar Jul 21 '17 11:07 AntonKrug

These are defined in gdb/riscv-linux-nat.c and gdb/gdbserver/riscv-linux-low.c and should be getting picked up from one of those (depending on if you're building GDB or gdbserver). I don't think anyone has tried this in a while, so it's probably just some build system drift. Does something like this

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index ef575cad10..d63e13ba28 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2636,6 +2636,7 @@ ALLDEPFILES = \
 	ravenscar-thread.c \
 	remote-sim.c \
 	riscv-tdep.c \
+	riscv-linux-nat.c \
 	riscv-linux-tdep.c \
 	rl78-tdep.c \
 	rs6000-lynx178-tdep.c \
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 4e0080ef1e..d42ef8e75e 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -170,6 +170,7 @@ SFILES = \
 	$(srcdir)/linux-nios2-low.c \
 	$(srcdir)/linux-ppc-low.c \
 	$(srcdir)/linux-s390-low.c \
+	$(srcdir)/linux-riscv-low.c \
 	$(srcdir)/linux-sh-low.c \
 	$(srcdir)/linux-sparc-low.c \
 	$(srcdir)/linux-tile-low.c \

work?

palmer-dabbelt avatar Jul 21 '17 15:07 palmer-dabbelt

Thank you very much Palmer.

I couldn't apply the patch directly, so I did it by hand and run it again. Sadly I got the same error:

rm -f gdb
riscv64-unknown-linux-gnu-g++  -g -O2   -static-libstdc++ -static-libgcc    \
        -o gdb gdb.o riscv-tdep.o riscv-linux-tdep.o glibc-tdep.o linux-tdep.o solib-svr4.o ser-base.o ser-unix.o ser-pipe.o ser-tcp.o inf-ptrace.o fork-child.o fork-inferior.o proc-service.o linux-thread-db.o linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o linux-namespaces.o ax-gdb.o ax-general.o ctf.o dcache.o remote.o remote-fileio.o remote-notif.o tracefile.o tracefile-tfile.o tracepoint.o  cli-cmds.o cli-decode.o cli-dump.o cli-interp.o cli-logging.o cli-script.o cli-setshow.o cli-utils.o mi-cmd-break.o mi-cmd-catch.o mi-cmd-disas.o mi-cmd-env.o mi-cmd-file.o mi-cmd-info.o mi-cmd-stack.o mi-cmd-target.o mi-cmd-var.o mi-cmds.o mi-console.o mi-getopt.o mi-interp.o mi-main.o mi-out.o mi-parse.o mi-symbol-cmds.o stub-termcap.o python.o guile.o elfread.o stap-probe.o dtrace-probe.o posix-hdep.o posix-strerror.o environ-selftests.o function-view-selftests.o offset-type-selftests.o optional-selftests.o ptid-selftests.o scoped_restore-selftests.o ada-exp.o c-exp.o cp-name-parser.o d-exp.o f-exp.o go-exp.o m2-exp.o p-exp.o rust-exp.o ada-lang.o ada-tasks.o ada-typeprint.o ada-valprint.o ada-varobj.o addrmap.o agent.o annotate.o arch-utils.o auto-load.o auxv.o bcache.o bfd-target.o block.o blockframe.o break-catch-sig.o break-catch-syscall.o break-catch-throw.o breakpoint.o btrace.o btrace-common.o buffer.o build-id.o buildsym.o c-lang.o c-typeprint.o c-valprint.o c-varobj.o charset.o cleanups.o cli-out.o coff-pe-read.o coffread.o common-agent.o common-debug.o common-exceptions.o job-control.o common-regcache.o common-utils.o complaints.o completer.o continuations.o copying.o corefile.o corelow.o cp-abi.o cp-namespace.o cp-support.o cp-valprint.o d-lang.o d-namespace.o d-valprint.o dbxread.o debug.o demangle.o dfp.o dictionary.o disasm.o disasm-selftests.o doublest.o dummy-frame.o dwarf2-frame.o dwarf2-frame-tailcall.o dwarf2expr.o dwarf2loc.o dwarf2read.o environ.o errors.o eval.o event-loop.o event-top.o exceptions.o exec.o expprint.o extension.o f-lang.o f-typeprint.o f-valprint.o fileio.o filestuff.o filesystem.o findcmd.o findvar.o format.o frame.o frame-base.o frame-unwind.o gcore.o gdb_bfd.o gdb-dlfcn.o gdb_obstack.o gdb_regex.o gdb_usleep.o gdb_vecs.o gdbarch.o gdbarch-selftests.o gdbtypes.o gnu-v2-abi.o gnu-v3-abi.o go-lang.o go-typeprint.o go-valprint.o inf-child.o inf-loop.o infcall.o infcmd.o inferior.o infrun.o inline-frame.o interps.o jit.o language.o linespec.o location.o m2-lang.o m2-typeprint.o m2-valprint.o macrocmd.o macroexp.o macroscope.o macrotab.o main.o maint.o mdebugread.o mem-break.o memattr.o memory-map.o memrange.o mi-common.o minidebug.o minsyms.o mipsread.o namespace.o new-op.o objc-lang.o objfiles.o observer.o opencl-lang.o osabi.o osdata.o p-lang.o p-typeprint.o p-valprint.o parse.o print-utils.o printcmd.o probe.o progspace.o progspace-and-thread.o prologue-value.o psymtab.o ptid.o record.o record-btrace.o record-full.o regcache.o reggroups.o registry.o reverse.o rsp-low.o run-time-clock.o rust-lang.o selftest.o selftest-arch.o sentinel-frame.o ser-event.o serial.o signals.o signals-state-save-restore.o skip.o solib.o solib-target.o source.o stabsread.o stack.o std-regs.o symfile.o symfile-debug.o symmisc.o symtab.o target.o target-dcache.o target-descriptions.o target-memory.o thread.o thread-fsm.o tid-parse.o top.o trad-frame.o tramp-frame.o typeprint.o ui-file.o ui-out.o user-regs.o utils.o utils-selftests.o valarith.o valops.o valprint.o value.o varobj.o vec.o version.o waitstatus.o xml-builtin.o xml-support.o xml-syscall.o xml-tdesc.o xml-utils.o compile.o compile-c-support.o compile-c-symbols.o compile-c-types.o compile-loc2c.o compile-object-load.o compile-object-run.o inflow.o    init.o \
           ../readline/libreadline.a ../opcodes/libopcodes.a ../bfd/libbfd.a -L./../zlib -lz  ../libiberty/libiberty.a ../libdecnumber/libdecnumber.a    -ldl -lmcheck -ldl -lm -ldl     ../libiberty/libiberty.a  build-gnulib/import/libgnu.a  -ldl -Wl,--dynamic-list=./proc-service.list
proc-service.o: In function `ps_xfer_memory':
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `fill_gregset(regcache const*, unsigned long long (*) [32], int)'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `supply_gregset(regcache*, unsigned long long const (*) [32])'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `fill_fpregset(regcache const*, double (*) [32], int)'
/home/antonkrug/riscv-binutils-gdb-riscv-next/gdb/proc-service.c:89: undefined reference to `supply_fpregset(regcache*, double const (*) [32])'
collect2: error: ld returned 1 exit status
Makefile:2243: recipe for target 'gdb' failed
make: *** [gdb] Error 1

But now I see the riscv-linux-nat included into the linking. The linker is searching for:

fill_gregset(regcache const*, unsigned long long (*) [32], int)

while the riscv-linux-nat has it implemented with following arguments:

void fill_gregset (const struct regcache *regcache, gdb_gregset_t *gregsetp, int regno)

AntonKrug avatar Jul 24 '17 09:07 AntonKrug

I realised that I don't need gdb to run natively, the only gdbserver would be enough. So I went to the gdb/gdbserver directory. Run the ./configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu --target=riscv64-unknown-linux-gnu

And then make was failing on a missing include which linux-riscv-low includes:

riscv64-unknown-linux-gnu-g++ -x c++  -g -O2    -I. -I. -I./../common -I./../regformats -I./.. -I./../../include -I./../gnulib/import -Ibuild-gnulib-gdbserver/import  -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wno-error=maybe-uninitialized -Werror -DGDBSERVER -c -o linux-riscv-low.o -MT linux-riscv-low.o -MMD -MP -MF .deps/linux-riscv-low.Tpo linux-riscv-low.c
linux-riscv-low.c:23:10: fatal error: arch/abi.h: No such file or directory
 #include <arch/abi.h>
          ^~~~~~~~~~~~
compilation terminated.
Makefile:562: recipe for target 'linux-riscv-low.o' failed

AntonKrug avatar Jul 24 '17 15:07 AntonKrug

Looks like you just want host to build gdbserver: https://sourceware.org/gdb/wiki/BuildingCrossGDBandGDBserver#For_GDBserver

palmer-dabbelt avatar Jul 24 '17 16:07 palmer-dabbelt

Thank you very much for your answer. I deleted the whole directory (this reverted the patch as well), started fresh, made separate directories for the builds as the instructions advised, used host only for the gdbserver. But still same error:

riscv64-unknown-linux-gnu-g++ -x c++  -g -O2    -I. -I../gdb/gdbserver -I../gdb/gdbserver/../common -I../gdb/gdbserver/../regformats -I../gdb/gdbserver/.. -I../gdb/gdbserver/../../include -I../gdb/gdbserver/../gnulib/import -Ibuild-gnulib-gdbserver/import  -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wno-error=maybe-uninitialized -Werror -DGDBSERVER -c -o linux-riscv-low.o -MT linux-riscv-low.o -MMD -MP -MF .deps/linux-riscv-low.Tpo ../gdb/gdbserver/linux-riscv-low.c
../gdb/gdbserver/linux-riscv-low.c:23:10: fatal error: arch/abi.h: No such file or directory
 #include <arch/abi.h>
          ^~~~~~~~~~~~
compilation terminated.
Makefile:561: recipe for target 'linux-riscv-low.o' failed

AntonKrug avatar Jul 24 '17 17:07 AntonKrug

I don't want to over-complicate things too much and I don't understand the topic good enough, but would the be possible or better to cross compile the GCC so that could run native and maybe under the Linux compile the gdb natively? Or I'm making the things worse?

AntonKrug avatar Jul 25 '17 13:07 AntonKrug

You could try, but it probably won't fix the problem. IIRC there's support in riscv-gnu-toolchain for this sort of cross compile, we do it to generate the Windows binaries.

palmer-dabbelt avatar Jul 26 '17 04:07 palmer-dabbelt

Is there maybe something else I could do? As you probably noticed my toolchain knowledge is limited. Personally, I don't mind any type of process if it will produce a working native binary.

AntonKrug avatar Jul 26 '17 08:07 AntonKrug

So about a year ago we (Fedora) were able to get gdb built and running as a RISC-V executable. It turned out to not be especially useful because neither "target native" nor "target core" worked; "target remote" did, but if you want to debug remotely you don't need to be on the target.

That was a year ago, it's possible the native and core targets have been implemented since then. Meanwhile I've learned a couple things about interpreting core dumps in hex editors…

sorear avatar Jul 26 '17 09:07 sorear

GDB yes, but what about gdb-server? You mean that I don't need the gdbserver running on the target to remotely debug an application?

AntonKrug avatar Jul 26 '17 09:07 AntonKrug

To my current knowledge, gdb-server doesn't work at all no matter where you run it.

I could easily have missed this being fixed. My knowledge is, again, a year old.

sorear avatar Jul 26 '17 09:07 sorear

Thank you very much for your insights.

AntonKrug avatar Jul 26 '17 09:07 AntonKrug

It's a little bit strange that if we have riscv-linux works, neither native gdb nor gdb-server works. Does it's related to the undefined debug spec? If we want to debug a program (fork) instead of the whole linux system, we would need either gdb-server (as a fork and attach target fork) or gdb-stub supported by linux kernel. I am not sure whether there is any plan to support that? Then we could avoid to create our own.

soberl avatar Jul 27 '17 02:07 soberl

This has nothing to do with the debug spec. The debug spec is ONLY for debugging systems.

You can debug user mode programs currently using qemu-user's gdb stub. Just not under riscv-linux.

sorear avatar Jul 27 '17 03:07 sorear

Personally I would prefer the gdb-server over the gdb-stub. Probably the gdb-server it's not high enough priority at the moment?

AntonKrug avatar Jul 27 '17 08:07 AntonKrug

FWIW the correct patch to fix this is:

--- riscv-binutils-gdb-riscv-binutils-2.29/gdb/Makefile.in.old	2017-12-04 22:15:15.000000000 +0000
+++ riscv-binutils-gdb-riscv-binutils-2.29/gdb/Makefile.in	2017-12-27 19:39:11.348372955 +0000
@@ -1797,6 +1797,7 @@
 	reggroups.o \
 	registry.o \
 	reverse.o \
+	riscv-linux-nat.o \
 	rsp-low.o \
 	run-time-clock.o \
 	rust-lang.o \

rwmjones avatar Dec 27 '17 19:12 rwmjones

Patch committed via pull request #126 fixing building native gdb. I didn't check native gdbserver, it didn't configure for me.

jim-wilson avatar Dec 29 '17 00:12 jim-wilson

gdbserver only configures for native builds. I hacked around this to try a canadian cross build, but it fails because of a missing arch/abi.h header file which I see was already mentioned. I think this linux-riscv-low.c was copied from linux-tile-low.c and is useless as is. Note for instance the reference to tilegx near the bottom of the linux-tile-low.c file, which makes sense, and the reference to riscvgx near the bottom of the linux-riscv-low.c file which makes no sense. This is just a simple string replacement which was never tested.

Someone will have to do a gdbserver port from scratch before we will be able to build it, though you can probably use the existing linux-riscv-low.c file as a template to start with.

We will still need the gdbserver/Makefile.in patch Palmer suggested, to add linux-riscv-low.c to SFILES.

jim-wilson avatar Dec 29 '17 01:12 jim-wilson

Anybody know if there's been any update/change in the status of gdbserver for RISC-V? If it's still not ported/working then how are people managing to debug RISC-V Linux apps with gdb? Are they running gdb (and the gcc tools?) ON RISC-V itself or something?

TommyMurphyTM1234 avatar Feb 08 '18 13:02 TommyMurphyTM1234

@jim-wilson Was there a specific use case you needed to do the Canadian cross build?

AntonKrug avatar Feb 08 '18 15:02 AntonKrug

The only use case is responding to bug reports. I saw a bug report that native gdb and gdbserver would not build. I did a canadian cross build to reproduce the native gdb problem and fix it. But gdbserver does not configure in a canadian cross build, so I hacked the configure scripts to work around this, and then discovered that we don't actually have a gdbserver port, just some useless code pretending to be a gdbserver port, so I stopped looking at gdbserver. Someone needs to do a port from scratch.

Embecosm has been working on improving the gdb port, with the eventual goal of upstreaming it, but I haven't seen any progress reports from them, so I don't know what is happening there. I don't know if they have looked at gdbserver.

I haven't tried running native gdb. I haven't needed it as yet. I've only done some debugging with printf. But now that we have hardware, I may have a need for gdb soon, and may have to take a look at this.

jim-wilson avatar Feb 08 '18 15:02 jim-wilson

Thanks Jim I assumed (and hoped) that somebody was using and maybe working on gdbserver. Doesn't sound like it unfortunately.

TommyMurphyTM1234 avatar Feb 08 '18 20:02 TommyMurphyTM1234

When I was starting the Go runtime bringup I was using gdb with the qemu-riscv64 gdb stub. However, that doesn't work well at all with multithreaded programs, so once the runtime was working well enough to start threads I switched back to prints.

I was never able to get gdb to work with a native or core target. Additionally, it seems likely that riscv linux ptrace() and core dump functionality has seen close to zero testing, so fixes there may be needed in addition to gdb work.

sorear avatar Feb 09 '18 00:02 sorear

Thanks sorear - so it sounds like proper/adequate RISC-V linux app debug support may be a long way off at the moment if people are forced to use printf "debugging" right now. Pity... :-(

TommyMurphyTM1234 avatar Feb 09 '18 09:02 TommyMurphyTM1234

Thanks @jim-wilson and @sorear for clarifications. It's a problem, but at least it's good to know it's real problem. In the beginning, when I was opening this ticket I was not even sure if the fault is on my side because I just don't understand it and my skills are lacking, while somebody else is happily debugging with his gdbserver. After the presentation with the RISC-V and the Quake is clear the Linux is getting closer. And I would say the gdbserver is an important part for the toolchain to be supporting Linux targets properly.

AntonKrug avatar Feb 09 '18 10:02 AntonKrug

gdbserver is quite useful when a kernel port begins to work, but in the meantime, I used to debug userspace applications via 'normal' gdb (gdb used to debug any bare applications) with a small 'hack' :

1/ Launch your kernel (via qemu with -s option) 2/ Before starting you userspace application, go to gdb and break on the linux kernel function named 'start_thread' (this function is arch specific and is the last function called by load_elf_binary) 3/ Launch your userspace application and you should break in start_thread 4/ Get the 'main' function address of your userspace application via nm $ nm YOURAPP | grep main 5/ In gdb, do : (gdb) add-symbol-file YOURAPP @main_address 6/ In gdb, add a breakpoint on main and continue.

Finally, you should break into the main function of your app and you can debug it as you would do with a userspace gdb. This approach has some limitations:

  • sometimes you will want to access memory that is not mapped yet and gdb would moan, but in that case, break on do_page_fault waiting for the MMU to be populated and you're good.
  • symbols in dynamic libraries are not available easily !

Alex

AlexGhiti avatar Mar 17 '18 12:03 AlexGhiti

RISC-V Linux native support is now present in upstream FSF gdb, and will appear in riscv-binutils-gdb when the upstream FSF gdb port replaces our local port.

gdbserver support is still missing.

jim-wilson avatar Sep 28 '18 22:09 jim-wilson

That is great news :)

AntonKrug avatar Sep 28 '18 23:09 AntonKrug

Maciej (macro) of WDC has posted patches for riscv linux gdbserver support to the FSF gdb-patches mailing list. It is looking good so far and should be accepted upstream within a few days. That would put it in the next FSF gdb release, which is probably a few months away.

jim-wilson avatar Jan 24 '20 20:01 jim-wilson

Thanks for heads up, will have to give it a try.

truhlikfredy avatar Jan 24 '20 21:01 truhlikfredy