From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id we3hAZCim2gZ0gEAWB0awg (envelope-from ) for ; Tue, 12 Aug 2025 16:22:40 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XuKZaJP/; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id DA3141E0B3; Tue, 12 Aug 2025 16:22:39 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,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 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 D9FE21E093 for ; Tue, 12 Aug 2025 16:22:38 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 644FD3858C83 for ; Tue, 12 Aug 2025 20:22:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 644FD3858C83 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XuKZaJP/ Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 6F6893858D37 for ; Tue, 12 Aug 2025 20:22:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6F6893858D37 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6F6893858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1755030121; cv=none; b=mdi9ADQqWW1rcJw/CZlEVJGSe5tHyZ0/7IlVn9IDZOXM3JvN6cPZzRtmtkOoaGu+jFroPLgvA3AERztdV3/HzLJCgfQ/0ikMEH2CdydF0bfL0yIstQPJYtWTNNz55gG4GcDf0oBu5RmuhtBuA0B1rtAkz3GJFVN5YfP1UgXy7wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1755030121; c=relaxed/simple; bh=pk6OBQCPMLpgqXYA+YDtWc5evjPl1oa2EfyV5WNAqbU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=g0tTV5mnCIyZXW3lRh9WUWTov0vjG4a7VMPZ/cmKg2sr+ztT9SedtkXNAq3TXR0fVWMdcW4ZfqYQv/cgYkrCOMgvtzCxirIbOOPjtUiPQZPzrj+dqkch0d+xhHuLfOl9q8vOOGDH6yKToaHBidHJ3JVRJhH8wgZgZBVMZKEPAmg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F6893858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755030121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qTD5UNJ2k+/8Pu0HCmbJFUH8rJTDfA2k79BPTLWEeJ0=; b=XuKZaJP/OvLu0huc75WYakKid2D4l3o5bcNrkke2HgjEh+cazCPUxWxkHzQZlOAQW6WsKU Ts8dD3/h51FPHsVa7PdnjEHw/zqiAqrkJ6Aika4PwxxGqv1w/p9FN3JivxQ6hX7MdY2bAj 1zW8wbAOWHPKqwAbfHWaMJ3Ff9adHmQ= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-306-ZeherloOOSOVDZkOhDoUtA-1; Tue, 12 Aug 2025 16:21:59 -0400 X-MC-Unique: ZeherloOOSOVDZkOhDoUtA-1 X-Mimecast-MFC-AGG-ID: ZeherloOOSOVDZkOhDoUtA_1755030117 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B9391195608F for ; Tue, 12 Aug 2025 20:21:57 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.96.134.49]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B31E2300145B; Tue, 12 Aug 2025 20:21:55 +0000 (UTC) From: Guinevere Larsen To: gdb-patches@sourceware.org Cc: Guinevere Larsen Subject: [PATCH 1/1] gdb: Print linker namespace when showing a frame Date: Tue, 12 Aug 2025 17:21:42 -0300 Message-ID: <20250812202142.3308633-1-guinevere@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ja3gbg2ZktdBxpqEiFbRwjlDOUDjelBqOQXNrL90BCg_1755030117 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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 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. --- 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) +{ + 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); + } + + return 0; +} + /* Implementation of the linker_namespace convenience variable. This returns the GDB internal identifier of the linker namespace, @@ -1813,19 +1828,10 @@ remove_user_added_objfile (struct objfile *objfile) static value * linker_namespace_make_value (gdbarch *gdbarch, internalvar *var, - void *ignore) + void *ignore) { - int nsid = 0; CORE_ADDR curr_pc = get_frame_pc (get_selected_frame ()); - - for (const solib &so : current_program_space->solibs ()) - if (solib_contains_address_p (so, curr_pc)) - { - if (so.ops ().supports_namespaces ()) - nsid = so.ops ().find_solib_ns (so); - - break; - } + int nsid = linker_namespace_contains_addr (curr_pc); /* If the PC is not in an SO, or the solib_ops doesn't support linker namespaces, the inferior is in the default namespace. */ 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); + /* 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); + if (pc_p && num_linker_namespaces > 1) + { + LONGEST curr_namespace = linker_namespace_contains_addr (pc); + std::string s = string_printf ("[[%ld]]::", curr_namespace); + gdb_puts (s.c_str (), &stb); + } + gdb_puts (funname ? funname.get () : "??", &stb); uiout->field_stream ("func", stb, function_name_style.style ()); uiout->wrap_hint (3); diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp index 4d3e8eba2ab..a88ad817dc1 100644 --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp @@ -107,6 +107,8 @@ proc test_info_shared {} { # Run all tests related to the linkage namespaces convenience # variables, _active_namespaces and _current_namespaces. +# Also tests that the namespace ID is only printed at the correct +# times. proc_with_prefix test_conv_vars {} { clean_restart $::binfile @@ -124,6 +126,11 @@ proc_with_prefix test_conv_vars {} { gdb_test "print \$_linker_namespace" ".* = 0" \ "Still in the default namespace" + # There should be no namespace ID visible, since there's + # only one namespace loaded. + gdb_test "backtrace" "\#0\\s+main .*" \ + "No namespace ID in backtrace" + gdb_breakpoint "inc" allow-pending gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"] @@ -132,11 +139,14 @@ proc_with_prefix test_conv_vars {} { gdb_test "print \$_linker_namespace" ".* = $dl" \ "Verify we're in namespace $dl" + + gdb_test "frame" "\#0\\s+\\\[\\\[$dl\\\]\\\]::inc.*" \ + "Namespace ID in the frame" } # Check that we display the namespace of the selected # frame, not the lowermost one. - gdb_test "up" "\#1.*in main.*" + gdb_test "up" "\#1.*in \\\[\\\[0\\\]\\\]::main.*" gdb_test "print \$_linker_namespace" ".* = 0" \ "print namespace of selected frame" diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp index c0208ebcc51..3070f879d17 100644 --- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp +++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp @@ -146,7 +146,7 @@ proc check_solib_unload_events {} { -disp keep -func main -file ".*$::srcfile" -line $::bp_main # Run past all the dlopen and dlmopen calls. - mi_execute_to "exec-continue" "breakpoint-hit" main "" ".*" $::bp_loaded \ + mi_execute_to "exec-continue" "breakpoint-hit" {\[\[0\]\]::main} "" ".*" $::bp_loaded \ {"" "disp=\"keep\""} "continue until all libraries are loaded" # Check that the dynamic linker has now been loaded multiple times. -- 2.50.1