GDB remote protocol: how to analyse packets? - gdb

I have:
A proprietary prototype ARM board (Cortex-M3 based) with eCos OS
The board has the programmed RedBoot bootloader
Serial line (RS-232)
GDB debugger for ARM (arm-eabi-gdb)
Host OS is Windows/Cygwin and/or Linux (actually, doesn't matter)
Problem: GDB debugger cannot connect to the target over the serial line.
What I want: is to sniff the packets of the GDB remote protocol in order to undestand whether the GDB stub on the target is alive and operating.
Details: RedBoot has an option to pass the target's control to the built-in GDB stub. I know that the RedBoot is alive, I can connect to it and send it commands over the serial line. The RedBoot manual says that the switch to the GDB stub can be made by typing $ or + symbols (which are actually the prefixes of the GDB remote protocol packets). It seems to work for when I send those symbols the terminal dies. But I'm not sure if the RedBoot was compiled with the GDB stub support (don't ask me why :-)).
Then, when I try to connect to the board with my GDB debugger I get the following picture (on Windows):
(gdb) target remote COM3
Remote debugging using COM3
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
The port is correct, the baudrate as well. Actually the same output I get if I try to do the same with another serial port which is not connected with anything.
What I want to know is does GDB stub send back anything or not?
Intuitively I thought that probably
set verbose on
would help, but GDB manual says it has very a limited effect and my case is beyond it.
May be it is possible to compile GDB debugger with a macro which enables debug logging?

What I want to know is does GDB stub send back anything or not?
Do this (before target remote):
(gdb) set debug remote 1

Related

OpenOCD how to flash local file to remote target?

(Using STM32F767 microcontroller)
I have a remote debugging environment setup on a RPI using OpenOCD. I can connect to it just fine using GDB.
However since I am writing a bootloader I need to flash the firmware to a specific offset in flash memory. E.g bootloader starts at 0x800000 and firmware should start at 0x8010000 for example so the offset would be (0x10000).
This works fine locally using: mon flash write_bank 0 main.bin 0x10000
But since I don't have the main.bin in the RPI, is there a way I could use OpenOCD or GDB to specify my local file instead and that would be sent over the remote connection?
Note that I would not like to setup a FTP and thus am looking for an alternate solution.
Best regards
gdb should supports sending files to remote via the 'remote put '. But, when I try this in gdb, I get the response "Remote I/O error: Function not implemented". Seems like OpenOCD does not support this
Use "file" to select the file and then "load" will send the file across to the device.

Debugging with gdbserver using serial connection (Not TCP) doesn't work

I'm trying to debug a program on my board which runs an embedded linux and I have Ubuntu as host system. I have a big problem with gdbserver. You see the thing is that my board doesn't have an Ethernet interface but a serial device which I'm using for console and I noticed that you can use a serial device for debugging in gdbserver although I couldn't find an example of this considering everyone that used gdbserver in videos or books used it in TCP mode which I can't do that.
So What I did was simply running gdbserver on the board this way:
root#DM368# gdbserver /dev/ttyS0 hello
Process hello created; pid = 472
On the host side I'm using ddd program and I ran:
root#mosi-VirtualBox:~# ddd --debugger arm-linux-gdb
And in ddd window terminal I entered:
(gdb) cd /root/home/mySimpleHello/hello
(gdb) target remote /dev/ttyUSB0
(gdb) file hello
And /dev/ttyUSB0 is connected to the board's /dev/ttyS0
But I don't get anything back in gdb and there is nothing in gdbserver output which is kind of weird. I mean not a single message like a "host connected" or "remote debugging from ..." or things like that. And in ddd when I ran:
(gdb) b main
Breakpoint 1 at 0x83ac: file hello.c, line 10.
(gdb) run
Then gdb says:
the program in not being run
I tried with gdb on Ubuntu's terminal directly (whitout ddd) and the same thing happened. I even tried with eclipse and I setup a debugging profile in eclipse and I installed gdb-multiarch program and used that in eclipse with its .gdbinit file set to arm. Nothing happens and I have no idea why this simple procedure wouldn't work.
Does somebody have any idea? What am I doing wrong? How can I debug a program using a serial connection?

Why does GDB hang when using OpenOCD in remote pipe mode?

I'm using GDB and OpenOCD to debug a simple program on my STM32F4DISCOVERY board on Windows. This works fine when starting OpenOCD separately, and using TCP/IP to connect to it, with something like this:
target remote localhost:3333
When I'm done, I can shut down GDB using quit as normal. I would like, however, to use GDB in "remote pipe" mode, instead of needing to start and stop OpenOCD manually. This seems like a somewhat ideal configuration to me. When I do this, however, I cannot exit GDB, as it hangs when I attempt to exit.
The OpenOCD log file shows that the GDB connection was dropped:
Info : dropped 'gdb' connection
But GDB never exits:
(gdb) quit
A debugging session is active.
Inferior 1 [Remote target] will be detached.
Quit anyway? (y or n) y
Detaching from program: yagarto_sample.elf, Remote target
Ending remote debugging.
The disconnect command similarly hangs, never returing. Not even Ctrl-C will wake up GDB.
It turns out there is a bug in OpenOCD related to a change made by GDB. A bit of detail is here, and a patch has been submitted, and a workaround is provided:
Add this to your cfg:
$_TARGETNAME configure -event gdb-detach { shutdown }
I tested this workaround, and it does work, but in the end, pipe mode is so slow on Windows that I chose to use TCP, even though it is less convenient.

strange gdbserver output shows at my target device

when I run gdbserver on uclinux target device blackfin bfin537/stamp it work perfectly but it always generates annoying output
Request to get for unknown register 232
Request to get for unknown register 236
it is extremely annoying since each step out or step in gdb client results several of that error on the output screen terminal RS232 I was recommended to change the bfin compiler version and rebuild gdb server with different version of uclinux ,.... none of them worked and even compiling my code with different versions of bfin-uclinux-gcc didn't solve my problem.
I decided to recompile gdbserver.c and eliminate the line that generates the error but in fact that line does not exists in any of the gdbserver related files for compiling.
I decided to suppress the stderr output of gdb server by running gdbserver :3298 process 1>/dev/null 2>/dev/null but this didn't solve it
how can I configure my gdb client to asks for specific registers (bfin-uclinux-gdb) related to bfin537-stamp?
I think this error originates somewhere else in uclinux system background system processes.
I want to find which process writes in stderr,stdout which I am unaware of It and I want to suppress its outputs?
Shall I change something in the busybox shell or /bin/bash to eliminates all stderr outputs
which means if I send all the parent shell output or stderr to /dev/null
Thanks

Remote 'g' packet reply is too long

I am trying to debug Linux kernel with kvm vm. I am getting an error message "Remote 'g' packet reply is too long". My host is 64-bit and so is my vm.
My steps:
Start the VM with custom -kernel, -initrd and -append options.
Start gdb
Execute "set architecture i386:x86-64:intel"
Execute "add-symbol-file linux-3.0/vmlinux"
Execute "show arch" to verify its still "i386:x86-64:intel"
Execute "target remote localhost:1234"
Execute "continue"
Press Ctrl+C, I get the above message.
Has anyone faced this problem?
gdb doesn't work well against a cpu that switches between instruction sets at runtime. Wait for the kernel to leave early boot before connecting, and don't use qemu's -S flag.
I also faced same issue, I fixed it by modifying gdbstub.c (in qemu sources) to send 64bit registers always and hinting GDB that architecture is 64bit by passing set arch i386:x86-64
You can check the patch here:
Visit [URL no longer available]
I found a similar problem (& this question) connecting gdb very early in the boot process – as mentioned in other answers, gdb does not very much appreciate the size of registers changing out from under it. This problem can be seen by using set debug remote 1:
(gdb) set debug remote 1
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
...
Sending packet: $g#67...Ack
Packet received: 000000000000000... <~600 bytes>
(gdb) until *0x1000 # at this address we'll be in a different cpu mode
...
Sending packet: $g#67...Ack
Packet received: 10000080000000000000000000000000800000c... <~1000 bytes>
...
Remote 'g' packet reply is too long: 1000008000000000000000000...
(gdb)
Patching gdb to resize its internal buffer when it sees a too-large packet
as found on this issue in the gdb bug tracker (and elsewhere), does indeed work around the problem, as does patching QEMU to only send 64-bit-sized packets. However, the latter solution breaks debugging in non-64-bit-modes, and it seems that the former fix could be incomplete:
It sounds quite wrong to be changing the target behind
GDB's back when GDB is already debugging it. Not just the size
of the g/G packets may change inadvertently, but the layout as well.
If the target description changes with your re-configuration, it
sounds to me like GDB should fetch/recompute the whole target
description. Today, I think that can only be done with a
disconnect/reconnect.
– https://sourceware.org/ml/gdb/2014-02/msg00005.html
The disconnect/reconnect workaround mentioned at the end of the post does appear to work:
(gdb) disconnect
Ending remote debugging.
(gdb) set architecture i386:x86-64
The target architecture is assumed to be i386:x86-64
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
(gdb) info registers
rax 0x80000010 2147483664
rbx 0x0 0
...
I had accidentally omitted the binary name as an argument to gdb. So this worked for me.
$ gdb ./vmlinux
(gdb) target remote localhost:1234
And then got the Output :
Remote debugging using localhost:1234
0xffffffff81025f96 in default_idle ()
The debugger needs vmlinux so make sure you provide it. OP has a different problem, But my answer might help to those who forgot to provide argument to gdb and ended up with the same error message as OP.