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.
Related
The following workflow worked for me at one point, and then it suddenly stopped working. I'd like to figure out why and get it to work again.
on the host, build binary for target system with debug information
send the stripped version of the binary to the target system
on the target, run the binary with gdbserver :6006 mybinary args...
on the host, run gdb-multiarch mybinary. This is the unstripped version. It shows that it loaded symbols from the local binary.
At the gdb prompt, run target remote <ip_of_target>:6006
Then, if I say b main, it inserts a breakpoint at an unrelocated address like 0x621730, which is the offset of the main function in the local binary, whereas it should be added on top of the VM address the remote binary is loaded at (0x5555555000 in this case.) Obviously the unrelocated address doesn't work.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work. Help would be appreciated.
Version of gdbserver and that of host gdb are both Ubuntu 8.1.1-0ubuntu1. The remote system is aarch64.
So step 6 was working at one point. I don't know what I'm doing now differently to make the relocation no longer work.
I suspect that you have upgraded your toolchain, and that your upgraded toolchain produces a Position-Independent Executable mybinary by default, where the old toolchain didn't.
Try adding -no-pie to the link line of mybinary.
Obviously the unrelocated address doesn't work.
Actually, this does work for local debugging -- GDB is smart enough to realize that the code got loaded at a different address:
gdb -q a.out
Reading symbols from a.out...
(gdb) b main
Breakpoint 1 at 0x112d: file t.c, line 1. <<< Note: unrelocated address
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at t.c:1
1 int main() {return 0; }
(gdb) p/x $pc
$1 = 0x55555555512d <<< Note: breakpoint worked.
It's possible that remote debugging doesn't work, although this worked fine for me using GDB-10.0:
strip a.out -o b.out
gdbserver :6006 ./b.out
Process ./b.out created; pid = 239653
Listening on port 6006
... in another window:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) target remote :6006
Remote debugging using :6006
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/a8/97a1105e21dd270bd418fe58c441700a6d8ec5.debug...
0x00007ffff7fe4940 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x55555555512d: file t.c, line 1.
I am trying to use gdbserver...
I have an application with binary path /user/bin/foo running with pid 19767.
Started the gdbserver on remote:
gdbserver --remote-debug --multi 0:12347
Started gdb on client and connected it to remove server
target extended-remote 192.168.1.84:12347
Attached gdb on pid
attach 19767
It shows:
warning: Could not load vsyscall page because no executable was specified
try using the "file" command first.
0x00007f207550043c in ?? ()
Also, current thread information it is showing is incorrect. Like info threads shows 1 thread , but my app has 10 threads-
(gdb) info threads
* 1 Thread 19767.19767 0x00007f207550043c in ?? ()
How can I ask gdb to load symbol from remote file /user/bin/foo? How to make it show correct info?
How can I ask gdb to load symbol from remote file /user/bin/foo
You can't. Copy remote /usr/bin/foo locally (or mount the filesystem it's on), and then invoke gdb like this: gdb /path/to/copy/of/foo, or just use the file command.
As of gdb 7.10, you can use
set sysroot target:
to make gdb retrieve files from the remote filesystem. See https://sourceware.org/gdb/onlinedocs/gdb/Files.html#Files
I am remote debugging a Stellaris Launchpad. I use OpenOCD to connect to the stellaris and then connect GDB to the server provided by openOCD. I use Open On-Chip Debugger 0.10.0-dev-00002-g79fdeb3 (2015-07-09-23:28). GDB is the one from arm-gcc-none-eabi, the 4_9-2015q1 release.
I invoke openOCD like this:
/usr/local/bin/openocd --file \
/usr/local/share/openocd/scripts/board/ek-lm4f120xl.cfg \
>> openocdLog.txt 2>&1 &
And then GDB like this:
arm-none-eabi-gdb proj//debug/exec -x gdb//gdb.script
gdb/gdb.script contains:
set remotetimeout 10000
target extended-remote :3333
monitor reset halt
load
monitor reset init
The problem is that whenever I hit control+c GDB disconnects. Normally this would halt the remote, but GDB just disconnects:
(gdb) cont
Continuing.
^CError detected on fd 6
Remote communication error. Target disconnected.: Interrupted system call.
(gdb)
OpenOCD has the following things to say, this one while GDB is launching:
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1258). Workaround: increase "set remotetimeout" in GDB
Which is weird, considering the gdb/gdb.script file forces remotetimeout to an insanly large number.
And when pressing control+c openOCD says:
Debug: 2602 5089 hla_interface.c:119 hl_interface_quit(): hl_interface_quit
So, how do I resolve this? How can I make GDB halt the remote instead of disconnecting when pressing control+c?
The problem was OpenOCD being too bleeding edge. I had issues with 0.6.1, but version 0.7.0 of OpenOCD works great.
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).
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.