qemu-system-x86_64+gdb: unable to correctly disassemble "real mode" (i8086) instructions after attaching to QEMU started with "-S -s" options

This bug has been copied automatically from: https://bugs.launchpad.net/qemu/+bug/1686170
Reported by 'Alain Kalker' on 2017-04-25 :

OS: Void Linux x86_64 (glibc)
QEMU version: 2.9.0
GDB version: 7.12.1

Problem description:

After I updated QEMU from version 2.8.1 to 2.9.0, I found that when I try
to connect GDB to a running QEMU and try to debug Real mode machine code,
I can no longer set architecture to 'i8086'.
To be able to connect to QEMU from GDB at all, I have to specify one of
the 64 bit architectures, which among other things leads to incorrect
disassembly listings. This makes debugging Real mode bootloaders,
bootsectors and BIOS code much more difficult.

Steps to reproduce:

- Run QEMU
- In another terminal, run GDB
- In GDB, connect to QEMU
- In GDB, disassemble some Real mode machine code.

Expected results (from QEMU version 2.8.1):

    [terminal #1]
    $ qemu-system-x86_64 -S -s

    [terminal #2]
    (gdb) set architecture i8086
    warning: A handler for the OS ABI "GNU/Linux" is not built
    into this configuration
    of GDB.  Attempting to continue with the default i8086 settings.

    The target architecture is assumed to be i8086
    (gdb) target remote :1234
    Remote debugging using :1234
    warning: No executable has been specified and target does not support
    determining executable automatically.  Try using the "file" command.
    0x0000fff0 in ?? ()
    (gdb) x/i $cs*16+$eip
       0xffff0: ljmp   $0xf000,$0xe05b

Actual results:

    [terminal #1]
    $ qemu-system-x86_64 -S -s

    [terminal #2]
    $ gdb -q
    (gdb) set architecture i8086
    warning: A handler for the OS ABI "GNU/Linux" is not built into this
configuration
    of GDB.  Attempting to continue with the default i8086 settings.

    The target architecture is assumed to be i8086
    (gdb) target remote :1234
    Remote debugging using :1234
    warning: No executable has been specified and target does not support
    determining executable automatically.  Try using the "file" command.
    Remote 'g' packet reply is too long:
    [..snip..]

Workarounds tried:

  - Try different architecures
    (gdb) set architecture i386:intel
    The target architecture is assumed to be i386:intel
    (gdb) target remote :1234
    Remote debugging using :1234
    warning: No executable has been specified and target does not support
    determining executable automatically.  Try using the "file" command.
    Remote 'g' packet reply is too long:
    [..snip..]
    (gdb) set architecture i386:x86-64
    The target architecture is assumed to be i386:x86-64
    (gdb) target remote :1234
    Remote debugging using :1234
    warning: No executable has been specified and target does not support
    determining executable automatically.  Try using the "file" command.
    0x000000000000fff0 in ?? ()

The last try finally allowed me to connect to QEMU, but as can be expected
from using an incorrect architecture setting, disassembly output is
complete gibberish:

    (gdb) x/10i $cs*16+$rip
       0xffff0: (bad)
       0xffff1: pop    %rbx
       0xffff2: loopne 0xffff4
       0xffff4: lock xor %dh,(%rsi)
       0xffff7: (bad)
       0xffff8: xor    (%rbx),%dh
       0xffffa: (bad)
       0xffffb: cmp    %edi,(%rcx)
       0xffffd: add    %bh,%ah
       0xfffff: add    %al,(%rax)

Discussion:

I think I've traced the problem to the following commit: "x86: Fix x86_64
'g' packet response to gdb from 32-bit mode."[1].
While I admire the effort to make life for people using GDB to debug QEMU
VMs, I think the problem here is with GDB and can't be fixed entirely from
the side of QEMU without breaking other features.

In fact, there is a well-known workaround to this problem published on
OSDev Wiki (Workaround #1)[2] which doesn't require patching either QEMU
or GDB. This workaround has worked for me using several previous versions
of QEMU.

    $ gdb -q
    (gdb) set architecture i8086
    (gdb) target remote :1234
    (gdb) break some_breakpoint_in_32_bit_or_64_bit_code
    (gdb) continue
    [...]
    Remote 'g' packet reply is too long: [...]
    (gdb) disconnect # IMPORTANT STEP #1
    (gdb) set architecture i386:x86-64
    (gdb) target remote :1234 # IMPORTANT STEP #2
    (gdb) continue

[1]:
http://git.qemu.org/?p=qemu.git;a=commit;h=e3592bc9d841c397eeda87f0019fab94ff71004b
[2]:
http://wiki.osdev.org/QEMU_and_GDB_in_long_mode#Workaround_1:_Reconnecting
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information