Ping 5 (was: Re: [PATCH v3] User space threads (aka 'green threads') support for `linux-thread-db`)

Niall Douglas s_sourceforge@nedprod.com
Mon Dec 16 15:17:56 GMT 2024


Ping 5

On 02/12/2024 16:13, Niall Douglas wrote:
> Ping 4
> 
> On 14/11/2024 14:58, Niall Douglas wrote:
>> Ping 3
>>
>> On 31/10/2024 14:13, Niall Douglas wrote:
>>> Ping 2. It is one month since the original patch submission.
>>>
>>> Niall
>>>
>>> On 17/10/2024 13:14, Niall Douglas wrote:
>>>> Ping.
>>>>
>>>>
>>>> On 30/09/2024 19:04, Niall Douglas (s [underscore] sourceforge {at}
>>>> nedprod [dot] com) wrote:
>>>>> From: "Niall Douglas" <s_sourceforge@nedprod.com>
>>>>>
>>>>> Changes since v2:
>>>>>
>>>>> - Rebased onto GDB 15.2 release.
>>>>> - `linux-thread-db-user-threads.h` now passes the thread sanitiser.
>>>>> - Internal code review felt that `info threads` was confusing, so
>>>>> the tag "user" and "running" have become "u_susp", "u_run" and
>>>>> "u_lwp".
>>>>>
>>>>> --- cut ---
>>>>>
>>>>> This patch extends `linux-thread-db` to support user space threads
>>>>> running in addition to LWP kernel threads. This is opted into by
>>>>> the user supplying a custom `libthread_db.so.1` using the GDB
>>>>> command `set libthread-db-search-path`. If that custom
>>>>> `libthread_db.so.1` reports threads of type `TD_THR_SYSTEM`
>>>>> (NPTL only ever reports type `TD_THR_USER`), it turns on the user
>>>>> space threading support.
>>>>>
>>>>> If that support is enabled, `linux-thread-db` will now additionally
>>>>> ask `libthread_db.so.1` about the state of the user space threads
>>>>> only using the filter `state = TD_THR_RUN`. It will add and remove
>>>>> those from the GDB thread list as needed. `info threads` will now
>>>>> show which type of thread each is, either system or user.
>>>>>
>>>>> You can use the GDB command `thread` to examine the current state
>>>>> of a suspended user space thread, including backtracing it. If
>>>>> a user space thread is currently running on a LWP, it shows as
>>>>> 'running' in the thread list.
>>>>>
>>>>> I have supplied an example implementation of how userspace would
>>>>> communicate with a custom `libthread_db.so.1` in the file:
>>>>>
>>>>> gdb/linux-thread-db-user-threads.h
>>>>>
>>>>> This aims to be race free with respect to concurrent reads of
>>>>> the inferior by GDB. Using that example implementation, a test
>>>>> exercises an inferior which creates a user space thread.
>>>>>
>>>>> The test code requires platform specific code, so I gated it to
>>>>> x64 and AArch64 only, as those are the only we care about. I
>>>>> don't actually have an AArch64 system to test this upon, so
>>>>> I would entirely understand if feedback requests removing that
>>>>> architecture.
>>>>> ---
>>>>>       gdb/linux-nat.c                               |   15 +
>>>>>       gdb/linux-thread-db-user-threads.h            | 1838 +++++++++++++++++
>>>>>       gdb/linux-thread-db.c                         |  463 ++++-
>>>>>       gdb/nat/gdb_thread_db.h                       |    2 +
>>>>>       gdb/testsuite/gdb.base/annota1.exp            |    2 +-
>>>>>       .../gdb.threads/check-libthread-db.exp        |    4 +-
>>>>>       .../gdb.threads/custom-libthread_db-shlib.c   |  488 +++++
>>>>>       .../gdb.threads/custom-libthread_db.c         |  106 +
>>>>>       .../gdb.threads/custom-libthread_db.exp       |  124 ++
>>>>>       9 files changed, 2997 insertions(+), 45 deletions(-)
>>>>>       create mode 100644 gdb/linux-thread-db-user-threads.h
>>>>>       create mode 100644 gdb/testsuite/gdb.threads/custom-libthread_db-shlib.c
>>>>>       create mode 100644 gdb/testsuite/gdb.threads/custom-libthread_db.c
>>>>>       create mode 100644 gdb/testsuite/gdb.threads/custom-libthread_db.exp
>>>>>
>>>>> diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
>>>>> index 218593c23cc..e96cd52bdec 100644
>>>>> --- a/gdb/linux-nat.c
>>>>> +++ b/gdb/linux-nat.c
>>>>> @@ -1765,6 +1765,12 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
>>>>>       			   ? strsignal (gdb_signal_to_host (signo)) : "0"),
>>>>>       			  inferior_ptid.to_string ().c_str ());
>>>>>       
>>>>> +  if (scope_ptid.tid () != 0)
>>>>> +    {
>>>>> +      linux_nat_debug_printf ("   ... not resuming as is userspace thread");
>>>>> +      return;
>>>>> +    }
>>>>> +
>>>>>         /* Mark the lwps we're resuming as resumed and update their
>>>>>            last_resume_kind to resume_continue.  */
>>>>>         iterate_over_lwps (scope_ptid, resume_set_callback);
>>>>> @@ -4514,6 +4520,15 @@ void
>>>>>       linux_nat_target::stop (ptid_t ptid)
>>>>>       {
>>>>>         LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT;
>>>>> +  if (ptid.tid () != 0)
>>>>> +    {
>>>>> +      linux_nat_debug_printf ("[%s] userspace thread is already stopped",
>>>>> +                              ptid.to_string ().c_str ());
>>>>> +      thread_info *tp = linux_target->find_thread (ptid);
>>>>> +      gdb_assert (tp != NULL);
>>>>> +      tp->set_executing (false);
>>>>> +      return;
>>>>> +    }
>>>>>         iterate_over_lwps (ptid, linux_nat_stop_lwp);
>>>>>       }
>>>>>       
>>>>> diff --git a/gdb/linux-thread-db-user-threads.h b/gdb/linux-thread-db-user-threads.h
>>>>> new file mode 100644
>>>>> index 00000000000..a012818e56d
>>>>> --- /dev/null
>>>>> +++ b/gdb/linux-thread-db-user-threads.h
>>>>> @@ -0,0 +1,1838 @@
>>>>> +/* libthread_db implementation helper library
>>>>> +
>>>>> +   Copyright (C) 1992-2024 Free Software Foundation, Inc.
>>>>> +
>>>>> +   This program is free software; you can redistribute it and/or
>>>>> +   modify it under the terms of the GNU Library General Public License
>>>>> +   as published by the Free Software Foundation; either version 2, or
>>>>> +   (at your option) any later version.
>>>>> +
>>>>> +   In addition to the permissions in the GNU Library General Public
>>>>> +   License, the Free Software Foundation gives you unlimited
>>>>> +   permission to link the compiled version of this file into
>>>>> +   combinations with other programs, and to distribute those
>>>>> +   combinations without any restriction coming from the use of this
>>>>> +   file.  (The Library Public License restrictions do apply in other
>>>>> +   respects; for example, they cover modification of the file, and
>>>>> +   distribution when not linked into a combined executable.)
>>>>> +
>>>>> +   This program is distributed in the hope that it will be useful, but
>>>>> +   WITHOUT ANY WARRANTY; without even the implied warranty of
>>>>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>>>> +   Library General Public License for more details.
>>>>> +
>>>>> +   You should have received a copy of the GNU Library General Public
>>>>> +   License along with this program; if not, write to the Free Software
>>>>> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
>>>>> +   02110-1301, USA.  */
>>>>> +
>>>>> +#ifndef LINUX_THREAD_DB_USER_THREADS_H
>>>>> +#define LINUX_THREAD_DB_USER_THREADS_H
>>>>> +
>>>>> +// #define LINUX_THREAD_DB_USER_THREADS_AM_LIBTHREAD_DB 1
>>>>> +
>>>>> +/* linux-thread-db's support for user space threads (aka 'green threads',
>>>>> +'threadlets', 'coroutines' et al) requires a custom `libthread_db.so.1`
>>>>> +to be specified to GDB using `set libthread-db-search-path` so it gets
>>>>> +found before the system libthread_db.so. The custom `libthread_db.so.1`
>>>>> +must do the following:
>>>>> +
>>>>> +1. `maint check libthread-db` must pass without error.
>>>>> +
>>>>> +2. Threads returned by `td_ta_thr_iter()` must have at least one with
>>>>> +type `TD_THR_SYSTEM` as returned by `td_thr_get_info()`. This declares
>>>>> +to GDB that this custom libthread-db supports user space threads (NPTL's
>>>>> +libthread-db always returns `TD_THR_USER` for kernel threads).
>>>>> +
>>>>> +If the above two conditions are met, linux-thread-db will now additionally
>>>>> +query `td_ta_thr_iter()` for userspace threads when it refreshes the
>>>>> +thread list. It will do this with the filter `state = TD_THR_RUN` to
>>>>> +indicate it only wants to receive threads which are runnable but not on
>>>>> +a LWP yet (NPTL's libthread-db only responds to `state = TD_THR_ANY_STATE`).
>>>>> +
>>>>> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>> +
>>>>> +A long standing problem with the Solaris `td_ta_thr_iter()` interface is
>>>>> +that it is fundamentally racy, which is why linux-thread-db doesn't use it
>>>>> +if `/proc/pid/task` is available. This header is supplied to help you
>>>>> +implement your `td_ta_thr_iter(state = TD_THR_RUN)` in a race free way
>>>
>>
> 



More information about the Gdb-patches mailing list