Skip to content
This repository has been archived by the owner on Aug 17, 2022. It is now read-only.

Compiling the gdbserver for native riscv execution #96

Open
AntonKrug opened this issue Jul 21, 2017 · 30 comments
Open

Compiling the gdbserver for native riscv execution #96

AntonKrug opened this issue Jul 21, 2017 · 30 comments

Comments

@AntonKrug
Copy link

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?

@palmer-dabbelt
Copy link
Contributor

palmer-dabbelt commented Jul 21, 2017

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?

@AntonKrug
Copy link
Author

AntonKrug commented Jul 24, 2017

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
Copy link
Author

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

@palmer-dabbelt
Copy link
Contributor

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

@AntonKrug
Copy link
Author

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 AntonKrug changed the title Compiling the binutils for native riscv execution Compiling the gdbserver for native riscv execution Jul 24, 2017
@AntonKrug
Copy link
Author

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?

@palmer-dabbelt
Copy link
Contributor

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.

@AntonKrug
Copy link
Author

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.

@sorear
Copy link

sorear commented Jul 26, 2017

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…

@AntonKrug
Copy link
Author

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?

@sorear
Copy link

sorear commented Jul 26, 2017

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.

@AntonKrug
Copy link
Author

Thank you very much for your insights.

@soberl
Copy link

soberl commented Jul 27, 2017

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.

@sorear
Copy link

sorear commented Jul 27, 2017

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.

@AntonKrug
Copy link
Author

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

@rwmjones
Copy link

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 \

@jim-wilson
Copy link
Collaborator

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

@jim-wilson
Copy link
Collaborator

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.

rwmjones added a commit to rwmjones/fedora-riscv-bootstrap that referenced this issue Jan 4, 2018
@TommyMurphyTM1234
Copy link

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?

@AntonKrug
Copy link
Author

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

@jim-wilson
Copy link
Collaborator

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.

@TommyMurphyTM1234
Copy link

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

@sorear
Copy link

sorear commented Feb 9, 2018

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.

@TommyMurphyTM1234
Copy link

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... :-(

@AntonKrug
Copy link
Author

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.

@AlexGhiti
Copy link

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

@jim-wilson
Copy link
Collaborator

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.

@AntonKrug
Copy link
Author

That is great news :)

@jim-wilson
Copy link
Collaborator

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.

@truhlikfredy
Copy link

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants