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: Wed, 30 Sep 2026 11:01:29 +0100	[thread overview]
Message-ID: <87fqyrys5i.fsf@redhat.com> (raw)
In-Reply-To: <87zex0z9cv.fsf@redhat.com>

Andrew Burgess <aburgess@redhat.com> writes:

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

I had the reported try this patch and they have now confirmed that this
patch does fix their building with and old glibc issue.  They are happy
to carry this as a local patch, so there's no urgency, but thought this
was a good data point to record.

Thanks,
Andrew


      parent reply	other threads:[~2026-09-30 10:02 UTC|newest]

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

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=87fqyrys5i.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