19
votes

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:

  1. Start the VM with custom -kernel, -initrd and -append options.
  2. Start gdb
  3. Execute "set architecture i386:x86-64:intel"
  4. Execute "add-symbol-file linux-3.0/vmlinux"
  5. Execute "show arch" to verify its still "i386:x86-64:intel"
  6. Execute "target remote localhost:1234"
  7. Execute "continue"
  8. Press Ctrl+C, I get the above message.

Has anyone faced this problem?

4
My vm runs ubuntu and host is running debian - contemplatingzombie
If I see the gdb code, remote.c /* Description of the remote protocol registers. */ long sizeof_g_packet; is not matching with expected. Looks like your gdbserver is not configured properly ( I am not very sure though). Are you initiating GDB server ? If yes does your GDB and GDBSERVER version match ? - Kamath

4 Answers

13
votes

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.

10
votes

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]

7
votes

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
...
2
votes

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.