22

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?

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • My vm runs ubuntu and host is running debian – contemplatingzombie Dec 29 '11 at 03:48
  • 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 Dec 29 '11 at 06:39
  • Similar on the GDB bugtracker: https://sourceware.org/bugzilla/show_bug.cgi?id=13984 – Ciro Santilli OurBigBook.com Aug 12 '15 at 13:10

5 Answers5

14

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.

Gabriel
  • 1,262
  • 12
  • 12
  • Worked perfectly for me after removing the -S option – Pratik Singhal Dec 29 '14 at 09:43
  • 7
    Yes, but *how*? I need to stop the kernel prior to it crashing; to stop it prior to crashing, I need to `gdb`. If I "wait", the kernel crashes. :P – Thanatos Aug 10 '16 at 07:03
  • 2
    @Thanatos I had the same issue, I put `mov $0,%eax ; 0: ; test %eax,%eax ; jz 0b` in a source file and called it from before the crash. Then I attach debugger and do `set $eax = 1` and continue. Horrible, but works. – doug65536 Nov 14 '16 at 20:43
10

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]

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
Samir Das
  • 111
  • 3
  • 3
    I didn't have to patch QEMU - just telling GDB `set arch i386:x86-64` was enough for it to work for me. – Jonathon Reinhart Jan 17 '15 at 03:54
  • Always sending x86-64 registers completely breaks real mode debugging. It won't disassemble correctly, and step over (next) doesn't work correctly, it is the same as step. I tried to debug an SMP trampoline today (the real mode portion), and it wasn't possible, step had no effect on thread 2. Unfortunately, the hack mentioned in this answer has been adopted into the qemu code. The real problem is gdb though, it is utterly broken when the register file changes size. GDB doesn't even support x86 if you ask me. – doug65536 Jun 17 '18 at 06:58
7

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
...
Seth P
  • 453
  • 5
  • 6
  • 3
    I get the same `Remote 'g' packet is too long' immediately after running `target remote localhost:1234` again. – Thanatos Aug 10 '16 at 07:05
  • @Thanatos it worked for me. Here is my fully detailed setup: http://stackoverflow.com/questions/4943857/linux-kernel-live-debugging-how-its-done-and-what-tools-are-used/42316607#42316607 – Ciro Santilli OurBigBook.com Feb 18 '17 at 14:47
2

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.

SloppyJoe
  • 393
  • 4
  • 7
0

when debug with simulator (gdb) add-symbol-file this command will not work correctly, make (gdb) target remote localhost:xxxx reply is too long. It will work with simulator.

use this command instead. It's worked. Refer cdt-gdb-vscode.

(gdb) -file-exec-and-symbol