Ref: https://sourceware.org/ml/gdb-patches/2017-07/msg00162.html
Debugging x86-64 GNU/Linux programs currently crashes GDB in
tdesc_use_registers during gdbarch initialization:
Program received signal SIGSEGV, Segmentation fault.
0x0000000001093eaf in htab_remove_elt_with_hash (htab=0x2ef9fa0, element=0x26af960, hash=557151073) at src/libiberty/hashtab.c:728
728 if (*slot == HTAB_EMPTY_ENTRY)
(top-gdb) p slot
$1 = (void **) 0x0
(top-gdb) bt
#0 0x0000000001093eaf in htab_remove_elt_with_hash (htab=0x2ef9fa0, element=0x26af960, hash=557151073) at src/libiberty/hashtab.c:728
#1 0x0000000001093e79 in htab_remove_elt (htab=0x2ef9fa0, element=0x26af960) at src/libiberty/hashtab.c:714
#2 0x00000000009121b0 in tdesc_use_registers (gdbarch=0x3001240, target_desc=0x2659cb0, early_data=0x2881cb0)
at src/gdb/target-descriptions.c:1328
#3 0x000000000047c93e in i386_gdbarch_init (info=..., arches=0x0) at src/gdb/i386-tdep.c:8634
#4 0x0000000000818d5f in gdbarch_find_by_info (info=...) at src/gdb/gdbarch.c:5394
#5 0x00000000007198a8 in set_gdbarch_from_file (abfd=0x2f48250) at src/gdb/arch-utils.c:618
#6 0x00000000007f21cb in exec_file_attach (filename=0x7fffffffddb0 "/home/pedro/gdb/tests/threads", from_tty=1) at src/gdb/exec.c:380
#7 0x0000000000865c18 in catch_command_errors_const (command=0x7f1d83 <exec_file_attach(char const*, int)>, arg=0x7fffffffddb0 "/home/pedro/gdb/tests/threads",
from_tty=1) at src/gdb/main.c:403
#8 0x00000000008669cf in captured_main_1 (context=0x7fffffffd860) at src/gdb/main.c:1035
#9 0x0000000000866de2 in captured_main (data=0x7fffffffd860) at src/gdb/main.c:1142
#10 0x0000000000866e24 in gdb_main (args=0x7fffffffd860) at src/gdb/main.c:1160
#11 0x000000000041312d in main (argc=3, argv=0x7fffffffd968) at src/gdb/gdb.c:32
The direct cause of the crash is that we tried to remove an element
from the hash which supposedly exists, but does not. (htab_remove_elt
shouldn't really crash in this case, but that's secondary.)
The real problem is that early_data passed to tdesc_use_registers
includes regs from a target description that is not the target_desc,
which violates its assumptions. The registers in question are the
fs_base/gs_base registers, added by amd64_init_abi:
tdesc_numbered_register (feature, tdesc_data_segments,
AMD64_FSBASE_REGNUM, "fs_base");
tdesc_numbered_register (feature, tdesc_data_segments,
AMD64_GSBASE_REGNUM, "gs_base");
and that happens because amd64_linux_init_abi uses amd64_init_abi as
helper, but they don't coordinate on which fallback tdesc to use.
amd64_init_abi does:
if (! tdesc_has_registers (tdesc))
tdesc = tdesc_amd64;
and then adds the fs_base/gs_base registers of the "tdesc_amd64" tdesc
to the tdesc_arch_data.
After amd64_init_abi returns, amd64_linux_init_abi does:
if (! tdesc_has_registers (tdesc))
tdesc = tdesc_amd64_linux;
tdep->tdesc = tdesc;
and we end up tdesc_amd64_linux installed in tdep->tdesc.
The fix is to make sure that amd64_linux_init_abi and amd64_init_abi
agree on default tdesc, by adding a "default tdesc" parameter to
amd64_init_abi, instead of having amd64_init_abi hardcode a default.
With this, amd64_init_abi creates the fs_base/gs_base registers using
the tdesc_amd64_linux tdesc.
Tested on x86-64 GNU/Linux, -m64. I don't have an x32 setup handy.
Thanks to John Baldwin, Yao Qi and Simon Marchi for the investigation.
gdb/ChangeLog:
2017-07-13 Pedro Alves <palves@redhat.com>
* amd64-darwin-tdep.c (x86_darwin_init_abi_64): Pass tdesc_amd64
as default tdesc.
* amd64-dicos-tdep.c (amd64_dicos_init_abi):
* amd64-fbsd-tdep.c (amd64fbsd_init_abi):
* amd64-linux-tdep.c (amd64_linux_init_abi): Pass
tdesc_amd64_linux as default tdesc. Get final tdesc from the
tdep.
(amd64_x32_linux_init_abi): Pass tdesc_x32_linux as default tdesc.
Get final tdesc from the tdep.
* amd64-nbsd-tdep.c (amd64nbsd_init_abi): Pass tdesc_amd64 as
default tdesc.
* amd64-obsd-tdep.c (amd64obsd_init_abi): Likewise.
* amd64-sol2-tdep.c (amd64_sol2_init_abi): Likewise.
* amd64-tdep.c (amd64_init_abi): Add 'default_tdesc' parameter.
Use it as default tdesc.
(amd64_x32_init_abi): Add 'default_tdesc' parameter, and pass it
down to amd_init_abi. No longer handle fallback tdesc here.
* amd64-tdep.h (tdesc_x32): Declare.
(amd64_init_abi, amd64_x32_init_abi): Add 'default_tdesc'
parameter.
* amd64-windows-tdep.c (amd64_windows_init_abi): Pass tdesc_amd64
as default tdesc.
The bsd-uthread target supports an old thread library ("libc_r") that
was last included in FreeBSD release 6.4 released in 2008. However,
this library has not been used as the default library since FreeBSD
5.0 (2003) and 4.11 (2005). Thread support for modern FreeBSD binaries
is provided via "normal" LWP support in core files and the native
FreeBSD target.
gdb/ChangeLog:
* amd64-fbsd-tdep.c: Remove "bsd-uthread.h" include.
(amd64fbsd_jmp_buf_reg_offset): Remove.
(amd64fbsd_supply_uthread): Remove function.
(amd64fbsd_collect_uthread): Remove function.
(amd64fbsd_init_abi): Don't set bsd-uthread callbacks.
* configure.tgt (i[34567]86-*-freebsd*): Remove bsd-uthread.o.
(x86_64-*-freebsd*): Remove bsd-uthread.o.
(fbsd-nat.c): Update comment.
* i386-fbsd-tdep.c: Remove "bsd-uthread.h" include.
(i386fbsd_jmp_buf_reg_offset): Remove.
(i386fbsd_supply_uthread): Remove function.
(i386fbsd_collect_uthread): Remove function.
(i386fbsd_init_abi): Don't set bsd-uthread callbacks.
This applies the second part of GDB's End of Year Procedure, which
updates the copyright year range in all of GDB's files.
gdb/ChangeLog:
Update copyright year range in all GDB files.