From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id vQMfIIrnnGixrgIAWB0awg (envelope-from ) for ; Wed, 13 Aug 2025 15:29:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=simark.ca; s=mail; t=1755113354; bh=FFUHTbdDYyH0+X2TFgDPeZOs75Kw7qZReNvqX/mUHw4=; h=Date:Subject:To:References:From:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=WEdIMraUW4koNc/tK02etyCseoIru90Zc5UzpN/xrLZWnNNglEEOfivEqGikkRE2s TirSnqTHv1s+WQHvQm2CrcVHMVYTQVhI3ardh5f0tO3Wwj3TSmx1fgGLpwmdS04mKd tgSpdXnodTS973DcN7id3KEddF3jCgm03BBfzTLI= Received: by simark.ca (Postfix, from userid 112) id 7359A1E0B3; Wed, 13 Aug 2025 15:29:14 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=simark.ca header.i=@simark.ca header.a=rsa-sha256 header.s=mail header.b=lInCICat; dkim-atps=neutral Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id B71A31E087 for ; Wed, 13 Aug 2025 15:29:10 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 405013858D3C for ; Wed, 13 Aug 2025 19:29:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 405013858D3C Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=simark.ca header.i=@simark.ca header.a=rsa-sha256 header.s=mail header.b=lInCICat Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 2C92B3858D20 for ; Wed, 13 Aug 2025 19:28:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2C92B3858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=simark.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=simark.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2C92B3858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1755113318; cv=none; b=QIr9NHcMKREK8nmx6yrjRyoJZ/voU47ElFQsYfrSz/FNytpyB34TJSej5bMoQBa5m68e4voN9VivvVzjJa6NCWuD4q+1PWJ+5uIv78Q/eph7wetRChzZMKY1hocbwXz7vo1PImcSjcItbv9jYe0a9iQ87plPM0rMtHOruaSkLlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1755113318; c=relaxed/simple; bh=FFUHTbdDYyH0+X2TFgDPeZOs75Kw7qZReNvqX/mUHw4=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=CQydU8fHrK3lGEMF2fUoXzqzN9P7UqPHHDkJ0Ist563g8NqK7LmA8Y32eAOo3ZTd0KS9DSvi382GhoSUaXJK7UCCQju7wQYb+9fOJP2QYMdpL4GPN5l13/2qg+h8Uf5VO7D5O9DjKn+nH8mnSRhv8+xWPwEAwL0WkyGhtkR0zoM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C92B3858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=simark.ca; s=mail; t=1755113317; bh=FFUHTbdDYyH0+X2TFgDPeZOs75Kw7qZReNvqX/mUHw4=; h=Date:Subject:To:References:From:In-Reply-To:From; b=lInCICatDebHRPXR0RMcaJ9+7oEYe4YhNNVwTxnB5FxlqlRV9A0I9nFN+e9z0/gEw KHzNvRKjvGtUJCZ2KTUIhUfl/ig/rtspUZHemUzWGUeK3FJdz27pvfKAGG3xmHbXq6 ty0+0RClEPYwOznNB5MRa+iBd2Kav2pu4R1PJjC0= Received: by simark.ca (Postfix) id B7D2B1E087; Wed, 13 Aug 2025 15:28:37 -0400 (EDT) Message-ID: <2cad9291-cebd-4074-a131-841248344fe3@simark.ca> Date: Wed, 13 Aug 2025 15:28:37 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 1/1] gdb: Print linker namespace when showing a frame To: Guinevere Larsen , gdb-patches@sourceware.org References: <20250812202142.3308633-1-guinevere@redhat.com> Content-Language: en-US From: Simon Marchi In-Reply-To: <20250812202142.3308633-1-guinevere@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org 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