I'm remotely-debugging an x86_64 executable on x86_64 target, but gdbserver seemingly reports debugging an i386 executable:
On the target:
# gdbserver --attach :9999 12345
Attached; pid = 12345
Listening on port 9999
On the host:
# gdb
<normal GDB banner>
(gdb) target remote 10.0.0.1:9999
Remote debugging using 10.0.0.1:9999
0x773660d8 in ?? ()
(gdb) show architecture
The target architecture is set automatically (currently i386)
Is it gdb (at the host) or gdbserver (at the target), who determines the architecture wrongly? Why could this happen, and how to fix it?
TIA for any insights.
Problem solved:
> Is it gdb (at the host) or gdbserver (at the target), who determines the architecture wrongly?
It is gdbserver.
> Why could this happen?
I was using a gdbserver binary, built for the wrong architecture (i386).
Related
I'm having issues when trying to debug a cross compiled binary on my WSL2 host and only end up with backtraces with addresses in ?? (), any hint's on what to verify and change are welcome!
file mybin shows:
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=..., with debug_info, not stripped
The application is started in WSL2 via qemu-i386(based on output from ps)
NOTE: I was wondering a bit about this because in my prev dev env using vm-ware and ubuntu 18.04 i was not seeing qemu-i386 used but did not think more about it based on WSL2 issues regarding 32bit application support referring to qemu and binfmt solving it.
I'm running gdb-multiarch (GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2)
Loading the executable and listing symbols with info functions <a_regex> works fine but when attaching and breaking i get bt's like this (NOTE output below is taken from VSCode with a few logging flags enabled, hence the -exec bt thing for example):
-exec bt
1: (777701) <-1183-interpreter-exec console "bt"
1: (777704) ->~"#0 0x000000000047a4ea in ?? ()\n"
1: (777707) ->~"#1 0x00007ffd2dcdb1c0 in ?? ()\n"
1: (777709) ->~"#2 0x0000000000467efc in ?? ()\n"
1: (777711) ->~"#3 0x0000000000000000 in ?? ()\n"
NOTE: When attaching i get the following warning:
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
setting architecture to i386:x86-64 is accepted by gdb but makes no difference
Setting a breakpoint gives the following error:
1: (40020) ->&"Cannot insert breakpoint 1.\n"
1: (40020) ->&"Cannot access memory at address 0xbce346f\n"
1: (40020) ->&"\n"
1: (40023) ->^error,msg="Command aborted."
UPDATE: SOLVED
Thought installing gcc-multilib solved it but it seems more likely the issue was because of a bug in Docker Desktop which has been fixed in v3.2.2. See description in my own answer below.
The qemu-i386 thing was bugging me so I decided to try compiling a simple .c with -m32 flag to check if it also would trigger being run via qemu, got errors because I was missing gcc-multilib so I installed it.
Started the buildt binary and noticed that it did not run via qemu-i386.
Started my original application again and this time it did also not start via qemu.
Started gdb-multiarch, loaded the bin and attached to the process and now suddenly everything worked fine, got a nice proper backtrace!
How do I attach gdb to ARM Qemu board with each smp running different kernels? When I use gdb options, I can only specify one kernel with the file option in gdb.
Qemu Command :
qemu-system-aarch64 -M virt -smp 2 \
-display none -nographic \
-device loader,file=f1.axf,cpu-num=0 \
-device loader,file=f2.axf,cpu-num=1 -s -S
gdb commands ran:
gdb-multiarch
target remote localhost:1234
file f1.axf
After this, gdb shows two threads, both showing debug source as f1.axf.
If I pass f2.axf in file option, both thread show source and debug info from f2.axf.
There is no error message from gdb
Setup:
Host: Ubuntu 18.04, 64bits
Guest: Qemu Arm
GDB Multiarch: Running on Host machine(Ubuntu)
I had to add each smp cpu as an Arm Cpucluster in my Qemu board file. Make sure that you assign different cluster index to each cpu, else they will attach to same GDB. So for N number of clusters, you can attach N gdbs. After that gdb can be attached to Qemu listening on port 1234, using following commands:
gdb-multiarch
target extended :1234
file f1.axf
add-inferior
inferior 2
attach 2
file f2.axf
info thread
Add as many inferiors as many cpu clusters you have. To attach to cluster 4, add command attach 4 in gdb.
I'm trying to exploit the binaries from Damn vulnerable Router Firmware but I have issues with debuggging with gdb.
to run the program i use this command :
sudo chroot . ./qemu-mipsel-static ./pwnable/Intro/stack_bof_01
and it works but when i try to run gdb with :
sudo chroot . ./qemu-mipsel-static gdb ./pwnable/Intro/stack_bof_01
I have that :
(gdb) r
Starting program: /pwnable/Intro/stack_bof_01
qemu: Unsupported syscall: 4026
Cannot exec /bin/bash: No such file or directory.
qemu: Unsupported syscall: 4026
Could not open /proc/12532/status
I tried to copy the binary in a qemu VM but I don't have the whole system so it don't work.
So , please , what's is the best way to debug a program from a firmware on a different architecture than x86 ?
In qemu user mode, run the program using the command with the option -g:
sudo chroot . ./qemu-mipsel-static -g 1234 ./pwnable/Intro/stack_bof_01
then start the gdb-multiarch (or gdb that corresponds to that architecture), and attach to it like this:
target remote 127.0.0.1:1234
then you can debug it happily.
I use this (http://cs.baylor.edu/~donahoo/tools/gdb/tutorial.html) guide to learn how GDB works.
After compiling and uploading the code to my embedded linux arm platform I use a remote connection to connect with the gdbserver on my target:
Target:
root#zedboard-zynq7:/Software# gdbserver HOST:1234 broken
Process broken created; pid = 1103
Listening on port 1234
Remote debugging from host 192.168.178.32
Host (Ubuntu 14.04 running in a virtual machine):
Remote debugging using 192.168.178.33:1234
warning: A handler for the OS ABI "GNU/Linux" is not built into this
configuration of GDB. Attempting to continue with the default arm settings.
Cannot access memory at address 0x0
0x43330d40 in ?? ()
(gdb)
I set the breakpoint to line 43 and continue the program until it stops at the breakpoint:
(gdb) b 43
Breakpoint 1 at 0x8b68: file broken.cpp, line 43.
(gdb) continue
Continuing.
Breakpoint 1, main () at broken.cpp:43
43 double seriesValue = ComputeSeriesValue(x, n);
(gdb)
But after a step call on my host I got this error:
Host:
warning: Remote failure reply: E01
Ignoring packet error, continuing...
Target:
ptrace: Input/output error.
input_interrupt, count = 1 c = 36 ('$')
What does it mean and how can I fix it?
Thanks for help.
Host (Ubuntu 14.04 running in a virtual machine):
Remote debugging using 192.168.178.33:1234
warning: A handler for the OS ABI "GNU/Linux" is not built into this
configuration of GDB. Attempting to continue with the default arm settings.`
This says that your (host) GDB has not been built with support for the target you want to debug.
What does it mean and how can I fix it?
You need to either get a different build of (host) GDB, or build one yourself with correct --target setting.
Usually a correct host GDB is included with the cross-gcc that you use to build for your target. So a fix may be as simple as running /path/to/cross-gdb instead of gdb.
I have two identical 64 bit Centos 5 machines, that are networked, and share their /home mount. I compile a simple Hello World program on one, and then I have figured out how to use gdb on one machine to remotely debug it running on the other machine. That seems to work fine when everyone defaults to 64 bitness.
However, if I compile my Hello World with -m32 to generate a 32 bit binary, the way our full up system is being compiled, then I cannot figure out how to get gdb and gdbserver to correctly connect. Before I try it on our full up system, I figure I should get it working with hello. Depending on how I try connecting gdb and gdbserver, I either get messages about badly formatted registers, warnings about architecture mismatches, or illegal memory references.
I seem to have little understanding of what the implications of -m32 are in my compile and no idea of how to start gdb and gdbserver or the right order to specify architecture or files or something. :(
What does it take to use gdb and gdbserver on a 32 bit (-m32) executable on a 64 bit linux box?
Examples below, and thank you,
Jerry
hello.cpp:
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Hello World." << std::endl;
return -1;
}
Here are three runs:
In gdb, set architecture i386 / then connect to gdbserver => bad architecture
In gdb, set architecture i386 / file hello / then connect to gdbserver => bad architecture
In gdb, set architecture (incorrectly) i386:x86-64 / file hello / then connect to gdbserver => Cannot access memory
Or in a bit more detail:
==============================
For each run, the remote gdbserver said:
$ gdbserver --multi rdev6:2010 hello
Process hello created; pid = 32603
Listening on port 2010
Remote debugging from host 134.51.26.149
readchar: Got EOF
Remote side has terminated connection. GDBserver will reopen the connection.
Listening on port 2010
And on our local:
==============================
Assuming it is i386 32 bit, setting archi to i386, then connecting
note: on the gdb side, the executable hasn't been specified or loaded
$ gdb
GNU gdb Fedora (6.8-37.el5)
his GDB was configured as "x86_64-redhat-linux-gnu".
(gdb) set archi i386
The target architecture is assumed to be i386
(gdb) target extended-remote rdev6:2010
Remote debugging using rdev6:2010
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
Remote register badly formatted: T0506:0000000000000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
here: 0000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
Try to load the executable by `file' first,
you may also check `set/show architecture'.
(gdb)
==============================
Assuming it is i386 32 bit, setting archi to i386, then connecting
note: on the gdb side, the executable has been loaded with file
$ gdb
GNU gdb Fedora (6.8-37.el5)
his GDB was configured as "x86_64-redhat-linux-gnu".
(gdb) set archi i386
The target architecture is assumed to be i386
(gdb) file hello
Reading symbols from /home/j/hello...done.
(gdb) target extended-remote rdev6:2010
Remote debugging using rdev6:2010
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
Remote register badly formatted: T0506:0000000000000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
here: 0000000;07:b0dcdfff00000000;10:1018620000000000;thread:7f5b;
Try to load the executable by `file' first,
you may also check `set/show architecture'.
(gdb) sho archi
The target architecture is assumed to be i386
(gdb)
==============================
Assuming (which should be incorrect) that it is i386:x86-64, setting archi to i386:x86-64, then connecting
note: on the gdb side, the executable has been loaded with file
$ gdb
GNU gdb Fedora (6.8-37.el5)
This GDB was configured as "x86_64-redhat-linux-gnu".
(gdb) set archi i386:x86-64
The target architecture is assumed to be i386:x86-64
(gdb) file hello
Reading symbols from /home/j/hello...done.
(gdb) show archi
The target architecture is assumed to be i386:x86-64
(gdb) target extended-remote rdev6:2010
Remote debugging using rdev6:2010
[New Thread 32667]
Cannot access memory at address 0x800000008
(gdb)
If you want to debug 32-bit process using 64-bit gdb/gdbserver, you need a newer version of GDB. In particular, you need this:
gdbserver/ChangeLog:
2009-05-12 Doug Evans <dje#google.com>
Biarch support for i386/amd64 gdbserver.
Alternatively, you can build gdb/gdbserver you already have from source in 32-bit mode by running
./configure CC='gcc -m32'
and use gdb32/gdbserver32 to debug your processes. I don't see any advantage of doing this though -- newer versions of GDB have many fixes, speedups, and STL pretty printers are nice.