From: Simon Marchi <simark@simark.ca>
To: Matthieu Longo <matthieu.longo@arm.com>, gdb-patches@sourceware.org
Cc: Luis Machado <luis.machado@amd.com>,
Luis Machado <luis.machado.foss@gmail.com>,
Andrew Burgess <aburgess@redhat.com>,
Yury Khrustalev <yury.khrustalev@arm.com>,
Pedro Alves <pedro@palves.net>, Tom Tromey <tom@tromey.com>
Subject: Re: [PATCH v1 02/10] gdb: rely on the first alive thread TPID when reading Linux procfs files
Date: Thu, 9 Jul 2026 10:24:45 -0400 [thread overview]
Message-ID: <590655c1-abed-4a16-b8cc-762f1d8e6093@simark.ca> (raw)
In-Reply-To: <20260707154900.94542-3-matthieu.longo@arm.com>
On 2026-07-07 11:48, Matthieu Longo wrote:
> On Linux, /proc/<pid> is keyed by the thread-group leader PID. When
> the leader has exited, some /proc/<pid>/... entries become unavailable
> even though another thread is still alive. This can happen, for instance,
> when the main thread calls pthread_exit() and another thread continues
> the execution (existing test: gcore-stale-thread).
>
> This causes GDB to fail to read procfs entries such as cmdline, cwd,
> exe, maps, and smaps when it uses 'current_inferior ()->pid' after the
> thread-group leader has exited.
>
> Fix this by adding inferior::first_alive_thread(), which returns the
> PTID of the first non-exited thread of the inferior. Use its LWP ID
> when accessing procfs entries that only need a representative live LWP
> belonging to the process.
>
> Update linux_info_proc, linux_process_address_in_memtag_page, and
> linux_find_memory_regions_full to use this live-thread LWP ID instead
> of the inferior PID when constructing procfs paths.
First comment, can we have a test for this? I think it would be
straightforward to write.
This is an improvement, but I can still imagine some cases it would
fail. A thread could have exited, gdb (or gdbserver) could have reaped
it status already, but the information might not have made it all the
way to the core yet. So the "first alive thread" you select might not
actually be alive on the system. I can't think of a way to fix that
problem generally, especially in the remote case. If GDB checks in
advance "is this thread alive" and then tries to access is, I feel like
there will always be a TOCTOU problem.
I'm not opposed to merging a simple fix like this that takes care of the
most obvious cases (the main thread has exited, all threads are stopped,
and it obviously doesn't work). But I think we should capture the
shortcomings we know about as comments in the code.
Then, I wondered if everything we access through /proc is going to give
the same response when we access them through another thread than the
leader. I asked ChatGPT for a summary:
Entry Scope Notes
----------------- ---------------- --------------------------------------
cmdline Process-wide Same for all threads; comes from the
shared address space (mm_struct).
cwd Per-thread Usually shared, but can differ if
threads use unshare(CLONE_FS).
environ Process-wide Same for all threads; comes from the
shared address space (mm_struct).
exe Process-wide Same executable for all threads.
maps Process-wide Describes the shared address space
(mm_struct); same for all threads.
status Mixed Contains both per-thread fields
(Pid, State, SigPnd, etc.) and
thread-group fields (VmSize, Threads,
etc.).
stat Per-thread Describes the specific task
(/proc/<tid>/stat).
smaps Process-wide Same mappings as maps; based on the
shared address space.
coredump_filter Process-wide Stored in the shared memory descriptor;
same for all threads.
For most of the info it should be fine, as they are shared between all
threads.
For cwd, it's shared unless some threads call `unshared(CLONE_FS)`, I
don't know if it's common to do that.
For stat and status it looks a bit odd, because we print "process
<pid>", and then the line right below it (Process with a capital P),
which comes from /proc/<tid>/stat, gives a different number.
(gdb) info proc stat
process 1989928
Process: 1991838
Exec file: a.out
State: t
Parent process: 1989898
Process group: 1989928
Session id: 126340
...
In any case, we could perhaps improve the "process <pid>" line that we
print to indicate which thread we obtained the information from, in the
"auto-select a thread" case.
Finally, linux_fill_prpsinfo still uses the ptid.pid():
pid = inferior_ptid.pid ();
xsnprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
Should it be changed too?
And linux_address_in_shadow_stack_mem_range too?
Perhaps it would be useful to have a function "read me a whole file from
/proc" that takes an `inferior *` and returns a string, encapsulating
the logic of finding a thread to read from.
> diff --git a/gdb/inferior.h b/gdb/inferior.h
> index 9c031035a23..305b1d31830 100644
> --- a/gdb/inferior.h
> +++ b/gdb/inferior.h
> @@ -513,6 +513,15 @@ class inferior : public refcounted_object,
> /* Find (non-exited) thread PTID of this inferior. */
> thread_info *find_thread (ptid_t ptid);
>
> + /* Return the first (non-exited) thread PTID of this inferior.
> +
> + This method should be used in place of current_inferior ()->pid for any
> + features relying only on the PID like the reading of procfs files.
> + On Linux, /proc/<pid> is keyed by the thread-group leader PID. When the
> + leader has exited, some /proc/<pid>/... entries become unavailable even
> + though another thread is still alive. */
> + ptid_t first_alive_thread () const;
I think this comment is too specific to Linux and the problem at hand in
particular for this location. It should just say "return the first
non-exited thread of the inferior" or something like that.
Function any_thread_of_inferior already does more or less what you want,
but it prefers the currently selected thread, which might not be what we
want (we perhaps want to prefer the leader). That function could be
renamed to any_non_exited_thread_of_inferior to be clearer.
I would prefer if you renamed first_alive_thread to
first_non_exited_thread, that's the terminology we use elsewhere.
"live" makes me think of the "target_thread_alive" target function,
which actually pokes the target to see if the thread is alive right now,
that's different.
Simon
next prev parent reply other threads:[~2026-07-09 14:25 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-07 15:48 [PATCH v1 00/10] gdb: bugfix 31207 and various refactoring in linux-tdep Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 01/10] gdb/linux-tdep: change linux_fill_prpsinfo to return bool Matthieu Longo
2026-07-09 6:26 ` Thiago Jung Bauermann
2026-07-09 12:23 ` Simon Marchi
2026-07-27 14:38 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 02/10] gdb: rely on the first alive thread TPID when reading Linux procfs files Matthieu Longo
2026-07-09 6:29 ` Thiago Jung Bauermann
2026-07-13 9:11 ` Matthieu Longo
2026-07-09 14:24 ` Simon Marchi [this message]
2026-07-14 15:47 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 03/10] target_fileio_read_stralloc: add an optional length parameter Matthieu Longo
2026-07-09 6:30 ` Thiago Jung Bauermann
2026-07-13 15:26 ` Matthieu Longo
2026-07-24 2:50 ` Thiago Jung Bauermann
2026-07-27 14:52 ` Matthieu Longo
2026-07-29 1:57 ` Thiago Jung Bauermann
2026-07-21 21:28 ` Luis
2026-07-27 14:48 ` Matthieu Longo
2026-07-27 14:53 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 04/10] gdb support: add gdb::replace algorithm for iterators and ranges Matthieu Longo
2026-07-09 6:30 ` Thiago Jung Bauermann
2026-07-10 21:21 ` Kevin Buettner
2026-07-13 15:51 ` Matthieu Longo
2026-07-21 21:33 ` Luis
2026-07-27 14:58 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 05/10] gdb: introduce helper class file_reader_t Matthieu Longo
2026-07-09 6:33 ` Thiago Jung Bauermann
2026-07-13 17:17 ` Matthieu Longo
2026-07-10 21:43 ` Kevin Buettner
2026-07-13 16:31 ` Matthieu Longo
2026-07-13 15:50 ` Schimpe, Christina
2026-07-13 17:12 ` Matthieu Longo
2026-07-22 16:36 ` Joos, Christina
2026-07-27 15:13 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 06/10] gdb/linux-tdep: migrate linux_info_proc to file_reader_t Matthieu Longo
2026-07-09 6:35 ` Thiago Jung Bauermann
2026-07-13 17:20 ` Matthieu Longo
2026-07-21 21:43 ` Luis
2026-07-27 17:11 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 07/10] gdb/linux-tdep: migrate linux_find_memory_regions_full " Matthieu Longo
2026-07-09 6:36 ` Thiago Jung Bauermann
2026-07-14 8:40 ` Matthieu Longo
2026-07-24 2:51 ` Thiago Jung Bauermann
2026-07-21 21:47 ` Luis
2026-07-27 17:14 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 08/10] gdb/linux-tdep: migrate parse_smaps_data " Matthieu Longo
2026-07-09 6:41 ` Thiago Jung Bauermann
2026-07-14 8:49 ` Matthieu Longo
2026-07-24 2:52 ` Thiago Jung Bauermann
2026-07-21 21:49 ` Luis
2026-07-27 17:17 ` Matthieu Longo
2026-07-07 15:48 ` [PATCH v1 09/10] gdb/linux-tdep: parse ProtectionKey in /proc/PID/smaps Matthieu Longo
2026-07-09 6:42 ` Thiago Jung Bauermann
2026-07-14 9:12 ` Matthieu Longo
2026-07-14 9:29 ` Matthieu Longo
2026-07-24 2:58 ` Thiago Jung Bauermann
2026-07-24 10:27 ` Yury Khrustalev
2026-07-25 6:40 ` Thiago Jung Bauermann
2026-07-27 8:22 ` Yury Khrustalev
2026-07-29 1:10 ` Thiago Jung Bauermann
2026-07-21 21:57 ` Luis
2026-07-27 17:54 ` Matthieu Longo
2026-07-07 15:49 ` [PATCH v1 10/10] gdb/linux: add helpers to read AT_HWCAP3 and AT_HWCAP4 Matthieu Longo
2026-07-09 6:44 ` Thiago Jung Bauermann
2026-07-21 21:58 ` Luis
2026-07-27 17:32 ` Matthieu Longo
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=590655c1-abed-4a16-b8cc-762f1d8e6093@simark.ca \
--to=simark@simark.ca \
--cc=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=luis.machado.foss@gmail.com \
--cc=luis.machado@amd.com \
--cc=matthieu.longo@arm.com \
--cc=pedro@palves.net \
--cc=tom@tromey.com \
--cc=yury.khrustalev@arm.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