From: Simon Marchi <simark@simark.ca>
To: Guinevere Larsen <guinevere@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH 1/1] gdb: Print linker namespace when showing a frame
Date: Wed, 13 Aug 2025 15:28:37 -0400 [thread overview]
Message-ID: <2cad9291-cebd-4074-a131-841248344fe3@simark.ca> (raw)
In-Reply-To: <20250812202142.3308633-1-guinevere@redhat.com>
On 2025-08-12 16:21, Guinevere Larsen wrote:
> When a user is stopped in a private linker namespace, the only way for
> them to realize that is using the _linker_namespace convenience
> variable. While serviceable, this is a sub-optimal solution, as most
> users are unaware of convenience variables.
>
> This commit introduces a new way for users to be informed of the linker
> namespace of a function, by printing it along with the function name.
> This is done by using the proposed syntax for symbols and locations,
> like so:
>
> #0 [[0]]::main ()
>
> This is done by exporting part of the functionality behind the
> _linker_namespace variable, namely, find the linker namespace that
> contains the given address on the current program space. Since this
> change also touched the convenience variable code, this commit fixes a
> formatting error in that function.
>
> The namespace ID is only printed if multiple namespaces are active,
> otherwise no change in behavior is expected. This commit also updates
> the test gdb.base/dlmopen-ns-ids.exp to test this functionality.
Just bear in mind that an address could be in a library that is part of
multiple namespaces. The only real occurence I know of today is the
dynamic linker itself. If you're stopped inside the dynamic linker,
with this patch, I think we would end up showing one arbitrary
namespace id.
The idea of sharing libraries between namespaces was also pitched in the
past, although it wasn't merged:
https://sourceware.org/pipermail/libc-alpha/2021-October/131818.html
I guess the right behavior would be to not show a namespace ID if the
piece of code is globally present in all namespaces, or show a list of
namespace IDs if the piece of code is visible in only some namespaces.
Perhaps it's not worth finding a solution for this right now, but I
thought I'd mention it so that we are aware of the limitations.
> ---
> gdb/solib.c | 28 ++++++++++++++---------
> gdb/solib.h | 5 ++++
> gdb/stack.c | 13 +++++++++++
> gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 12 +++++++++-
> gdb/testsuite/gdb.mi/mi-dlmopen.exp | 2 +-
> 5 files changed, 47 insertions(+), 13 deletions(-)
>
> diff --git a/gdb/solib.c b/gdb/solib.c
> index 3ec2032f012..2f32f08b645 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -1805,6 +1805,21 @@ remove_user_added_objfile (struct objfile *objfile)
> }
> }
>
> +/* See solib.h. */
> +
> +int
> +linker_namespace_contains_addr (CORE_ADDR addr)
This function name makes it sound like it's a function to check whether
a given namespace contains a given address. I would suggest
"linker_namespace_for_addr" or something like that.
> +{
> + for (const solib &so : current_program_space->solibs ())
> + if (solib_contains_address_p (so, addr))
> + {
> + if (so.ops ().supports_namespaces ())
> + return so.ops ().find_solib_ns (so);
> + }
Please combine the two ifs:
for (const solib &so : current_program_space->solibs ())
if (solib_contains_address_p (so, addr)
&& so.ops ().supports_namespaces ())
return so.ops ().find_solib_ns (so);
> diff --git a/gdb/solib.h b/gdb/solib.h
> index b9465e103bd..213f66c7ae4 100644
> --- a/gdb/solib.h
> +++ b/gdb/solib.h
> @@ -303,6 +303,11 @@ extern const char *solib_name_from_address (struct program_space *, CORE_ADDR);
>
> extern bool solib_contains_address_p (const solib &, CORE_ADDR);
>
> +/* Given the address ADDR, return which linker namespace contains
> + this address in the current program space. */
> +
> +int linker_namespace_contains_addr (CORE_ADDR addr);
If nothing in the call tree relies on the current program space, I would
prefer if the program space was passed as a parameter.
> +
> /* Return whether the data starting at VADDR, size SIZE, must be kept
> in a core file for shared libraries loaded before "gcore" is used
> to be handled correctly when the core file is loaded. This only
> diff --git a/gdb/stack.c b/gdb/stack.c
> index e6335669531..10078e06766 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -1363,6 +1363,19 @@ print_frame (struct ui_out *uiout,
> annotate_frame_function_name ();
>
> string_file stb;
> +
> + /* Print the linker namespace containing the frame, if there
> + are multiple namespaces active. */
> + LONGEST num_linker_namespaces;
> + get_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"),
> + &num_linker_namespaces);
I would really prefer some direct (C++) function call, instead of going
through the internalval mechanism. It makes it much easier to navigate
the code, find references, etc.
And because I looked at _active_linker_namespaces, I have some thoughts
about that. It's not related to this patch, but should perhaps be
addressed before the release.
First, the name "_active_linker_namespaces" insinuates that it contains
something like a list of all the active linker namespaces. It should
perhaps be "_active_linker_namespaces_count" or
"_num_active_linker_namespaces"? We already have
$_inferior_thread_count, so I guess _active_linker_namespaces_count
would be good for consistency.
Then, _active_linker_namespaces is set in
svr4_solib_ops::maybe_add_namespace, which is called when
fetching/updating/listing shared libraries. That doesn't work well with
multi-inferior for instance. Imagine you stop at a breakpoint in
inferior 1, which has 2 namespaces, _active_linker_namespaces is set to
2. Then you run inferior 2, which has 2 namespaces, stop at a
breakpoint, _active_linker_namespaces is set to 3. If you focus back to
inferior 1, _active_linker_namespaces will still have the value for
inferior 2. My feeling is that the variable should be sensitive to the
user's focus. That would probably mean calling
solib_ops::num_active_namespaces on the current program space's
solib_ops.
And then, since we're talking about that, I was wondering how to handle
_active_linker_namespaces in my "multiple solib ops" series. Imagine
you have a program space with one svr4_solib_ops and one rocm_solib_ops,
which is how I envision it will work with my patch, when debugging a
ROCm program. How would I implement _active_linker_namespaces then
(assuming you first made the change described above). Should I iterate
on all the solib_ops of the program space and sum up their
solib_ops::num_active_namespaces? In a normal scenario, that would give
me 2, which is kinda right because the linker namespace on the host side
is distinct from the linker namespace on the device side, so you
effectively have 2 of them in the program space. But is it going to
work with the uses this convenience variable is intended for? I don't
really what the intended uses are.
Simon
next prev parent reply other threads:[~2025-08-13 19:29 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-12 20:21 Guinevere Larsen
2025-08-13 19:28 ` Simon Marchi [this message]
2025-08-13 20:18 ` Guinevere Larsen
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=2cad9291-cebd-4074-a131-841248344fe3@simark.ca \
--to=simark@simark.ca \
--cc=gdb-patches@sourceware.org \
--cc=guinevere@redhat.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