Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Simon Marchi <simon.marchi@efficios.com>, gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: Re: [PATCH] gdb: use NT_386_TLS regset to access TLS GDT entries on i386 Linux
Date: Tue, 29 Sep 2026 10:37:36 +0100	[thread overview]
Message-ID: <87zex0z9cv.fsf@redhat.com> (raw)
In-Reply-To: <20260928172119.425553-1-simon.marchi@efficios.com>

Simon Marchi <simon.marchi@efficios.com> writes:

> Bug 34678 reports that a 32-bit GDB running on an x86-64 kernel can't
> make inferior function calls:
>
>     (gdb) p f()
>     Couldn't get TLS area data: Invalid argument.
>
> This happens because GDB fails to read the special registers holding the
> TLS GDT entries, added in commit 91eee81d2353 ("gdb: include NT_I386_TLS
> note in generated core files", 2025-11-20).
>
> The failure isn't specifically related to inferior function calls, but
> it is most visible there when GDB attempts to save all registers prior
> to a function call.
>
> These "registers" are read using
>
>     ptrace (PTRACE_GET_THREAD_AREA, pid, addr, data)
>
> where `addr` is not an address, but the index of a GDT entry to read.
> The valid indices depend on the arch of the kernel.  For an i386 kernel,
> the valid range is [6, 8], while for an x86-64 kernel, the valid range
> is [12, 14].
>
> As commit 91eee81d2353 properly noted, the indices really depend on the
> kernel, not on how GDB or the inferior program were built.  On an x86-64
> kernel, even when GDB and/or the inferior are 32-bit programs, we need
> to query the x86-64 indices:
>
>     /* This constant defines the first GDT (Global Descriptor Table) entry
>        that the kernel allocates for holding TLS descriptors.  There are three
>        entries, starting at this index which can be accessed using the
>        PTRACE_GET_THREAD_AREA and PTRACE_SET_THREAD_AREA ptrace calls.  This
>        constant is only valid for true i386 kernels.  For amd64 kernels
>        running in 32-bit mode (i.e. executables compiled -m32) there is a
>        different constant, see nat/amd64-linux.h.  */
>
> However, the implementation isn't quite right, since it bases the
> decision on whether GDB itself is a 32-bit or 64-bit program.  So we get
> it wrong when GDB is a 32-bit program, debugging a 32-bit program, on a
> 64-bit kernel.  GDB queries the i386 indices, which gets an EINVAL
> reply, because it should have used the x86-64 indices.
>
> Also, according to Claude (I couldn't test since I don't have a machine
> with x32 userland), PTRACE_GET_THREAD_AREA and PTRACE_SET_THREAD_AREA
> are not supported for x32 tracers: the kernel's x32_arch_ptrace doesn't
> handle them, so they would fail with EIO.  An x32 GDB debugging an i386
> program therefore couldn't read the TLS registers either.
>
> Fix both problems by using the NT_386_TLS regset instead, with
> PTRACE_GETREGSET and PTRACE_SETREGSET.  This regset contains the three
> TLS GDT entries, so accessing it doesn't require knowing their indices.
> When reading, the kernel fills the entry_number field of each entry with
> the right index.  When writing, it ignores the entry_number fields.
> This is the same data as the NT_386_TLS core file note, which these
> registers are used to produce.
>
> This also makes it possible to read the three entries with a single
> ptrace call, instead of three.
>
> Remove the i386_initial_tls_gdt constants, which are now unused, along
> with nat/amd64-linux.h, which only contained one of them.
>
> Tested by running gdb.arch/i386-tls-regs.exp on all these
> configurations:
>
>  - x86-64 kernel, 64-bit GDB, native
>  - x86-64 kernel, 64-bit GDB, gdbserver
>  - x86-64 kernel, 32-bit GDB, native
>  - x86-64 kernel, 32-bit GDB, gdbserver
>  - i386 kernel, 32-bit GDB, native
>  - i386 kernel, 32-bit GDB, gdbserver
>
> This test would previously fail in the "x86-64 kernel, 32-bit GDB"
> configs.
>
> This is a regression in GDB 18, so this patch would need to be
> cherry-picked to the gdb-18-branch.

Thanks for fixing this, and for the well written commit message.

Just today someone emailed me off-list reporting this problem:

  https://inbox.sourceware.org/binutils/CAG_eJLe_vuR93fE6H4hENPh3=R2XE72T2tL1ZaTnY93zW2J5-Q@mail.gmail.com

which did make it to the gdb-help list via a CC on a follow up post, but
unfortunately never made it into a release blocking bug.  The issue here
is that PTRACE_GET_THREAD_AREA and PTRACE_SET_THREAD_AREA don't exist
for older glibc, they were added in glibc 2.27 I believe, which is after
the glibc 2.23 the bug was reported against.

The NT_386_TLS that this patch uses instead was added in glibc 2.10, so
this patch should fix that build issue problem on older glibc too.

For both master and gdb-18-branch:

Approved-By: Andrew Burgess <aburgess@redhat.com>

Thanks,
Andrew


  reply	other threads:[~2026-09-29  9:38 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 17:21 Simon Marchi
2026-09-29  9:37 ` Andrew Burgess [this message]
2026-09-29 11:38   ` Joos, Christina

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zex0z9cv.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@efficios.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox