From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id yQedDjio3WdtqBYAWB0awg (envelope-from ) for ; Fri, 21 Mar 2025 13:56:08 -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=RpNtTjWM; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 267571E100; Fri, 21 Mar 2025 13:56:08 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HTML_MESSAGE,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 5EC8A1E0C0 for ; Fri, 21 Mar 2025 13:56:03 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 015883857365 for ; Fri, 21 Mar 2025 17:55:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 015883857365 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=RpNtTjWM 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 F12AF3858C60 for ; Fri, 21 Mar 2025 17:55:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F12AF3858C60 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 F12AF3858C60 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=1742579712; cv=none; b=oW94ueF9iGj5c3ZGRGWPnX6sVVEEoNPormJCRJdwBDp5Ai4Cs6MM93BjZPgh+BBmd9IenV6xDdKFJE04rp7HhPFDgwvIRlEF11KjLIROnA89yekrLtRVY37Tggzul1QiHxZCpOe2/pM1zff9LA6YUT1ctmuPgaw1BrRuNZt+yx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742579712; c=relaxed/simple; bh=8C0jsHO2GcHLnSY9GKdHh1ZrEoBRLw0LaxqrtsRKPfg=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=Q9h+qlq7k4r1oiWH8+lMr7USkHsOEzi7Huyh7JNJeuq85OXyrUn5gB3Qx3QYEnL4J9gAdXUDbP3X+wbGH9FD/X/LU+prh9YqcM9rcPsZyALczoRLJ06W5BDLNCyWITO0wE63p6mEWAPTBGOMWPfLCJNmZSxy1xtlfzyvIqEos1E= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F12AF3858C60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1742579711; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=w+TFn+BKX4R3zSZjAUnatsJ68x3b1RyUFvX+JD0QFgo=; b=RpNtTjWMfCERn/0clFTWzI5aXIQJ34jP6tovRErA1ofDKRedEGpV1N+61xvnAlMTH/DC/x CEQ2co0yhzVf5LQX0+h5wDa46B3UKbEFqCL+uO7tcFkFX7GwzmJ8pDZeuSszWE+6ArTvoI PujMgUernf5lxAGMb8mboUcgMoba7mc= Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-678-S2r64jXnNkib_ihQmxv74g-1; Fri, 21 Mar 2025 13:55:10 -0400 X-MC-Unique: S2r64jXnNkib_ihQmxv74g-1 X-Mimecast-MFC-AGG-ID: S2r64jXnNkib_ihQmxv74g_1742579709 Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-224191d9228so44319285ad.3 for ; Fri, 21 Mar 2025 10:55:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742579708; x=1743184508; h=in-reply-to:from:content-language:references:to:subject:user-agent :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=w+TFn+BKX4R3zSZjAUnatsJ68x3b1RyUFvX+JD0QFgo=; b=MCtZXMR2PtCsledfo0tcg52vTOLeWGFzrmD9XV4cJZGCXjZ5N6k8MJEye3osG72Lh3 ZZQuWxOqKIr/XhCcbKe6gsBP6LBvl92cTAlUM4SjaOHMtRICnT6gQzHsRjKKMeGviw3P oi9DYQfut5haOFtNyc4jYw4ulx0t+TYJaD9HHyvRwuSwjExOK2CP4d8Rgq4Qr6brYwPw xQtPHk+DZ+xNy150PJELKtGmH3OrKUtS6ja604fxWkzOTstBmYl/GKge12Vra5v84eoj advYXM9SUHAg9ARKKmJymg2l+xybYZouI8lN8T04eY/6IQ4D9X4Lz74bgq143+B1KDBD EOYg== X-Gm-Message-State: AOJu0YwVd3moqL+ZhWnECYrZJlekaxXKl3yNlenuDAAvXGASvbrNX2F8 yVPLMlfY3f9pF5G3RWQxIDGPno2FGsLyonMCLGvMk+6uujT9WdxFD1fCg0/UnBZTwqO6ZEzUHlg JHNmKxWffksQPP1Nb0xdoVDAIO2aEtVrlfAsFujFbskE/doZJABTgMwFpSdt8eqEp6l90iQ9JM7 XOpTmoIiKwftGQwK9LAHO4IpCrZGrQ290bLwkPg9aBytA4 X-Gm-Gg: ASbGncvCUgN/sEWdm5evAojb/IlLFixq2LOGPsxOEd3JWumlwKkIoBbo3eMrycc01pi r17tvBOpIhREKgC7THPrcuS5ZeDeeQ5OM3aU5v07MBNjweBofqu1P/Esbf+i/L7+BGIHMG0TiGs j+0DQ17Nb/o7GHbeYSDJo1uTxBKg6FyRzgvpBKWiPq7HWHR8jIaIHrbUPHiv+UlDi/P+OCnqa9k i6vguR17DHYc55gc2QBiQMWUh1KMhqFOZt/ePuTdaIdMuEBK8IuYM+T54A2exyrLgNd8eAKas4J aIwLu1sKCBzVvMHkS4kdzWvftHU= X-Received: by 2002:a05:6a00:3929:b0:736:ab21:8a69 with SMTP id d2e1a72fcca58-73905635469mr7910536b3a.0.1742579708145; Fri, 21 Mar 2025 10:55:08 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHd/guVAyHlvqi7pJTx4K4mmQBvhQn8DD87fqu5sIzQ1c2Ow2fIG2D1a8TAENVEQmRynbmHlA== X-Received: by 2002:a05:6a00:3929:b0:736:ab21:8a69 with SMTP id d2e1a72fcca58-73905635469mr7910470b3a.0.1742579707511; Fri, 21 Mar 2025 10:55:07 -0700 (PDT) Received: from ?IPV6:2804:14d:8084:9a69::1002? ([2804:14d:8084:9a69::1002]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73906156066sm2325754b3a.131.2025.03.21.10.55.05 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 21 Mar 2025 10:55:06 -0700 (PDT) Message-ID: <84bfb517-945b-4ac0-94f7-9469c9b04501@redhat.com> Date: Fri, 21 Mar 2025 14:55:04 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] gdb: Introduce user-friendly namespace identifier for "info shared" To: gdb-patches@sourceware.org References: <20250313170004.3362207-2-guinevere@redhat.com> <20250319123035.1563282-2-guinevere@redhat.com> From: Guinevere Larsen In-Reply-To: <20250319123035.1563282-2-guinevere@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: mEYSFI_MKk8yf2bhjFb9PIoxtK5vHmPYmOR5lmKXbVI_1742579709 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="------------Zh2bX0apnSrGvNEejOOzUrBN" Content-Language: en-US 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 This is a multi-part message in MIME format. --------------Zh2bX0apnSrGvNEejOOzUrBN Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 3/19/25 9:30 AM, Guinevere Larsen wrote: > GDB has had basic support for linkage namespaces for some time already, > but only in the sense of managing multiple copies of the same shared > object being loaded, and a very fragile way to find the correct copy of > a symbol (see PR shlibs/32054). > > This commit is the first step in improving the user experience around > multiple namespace support. It introduces a user-friendly identifier for > namespaces, in the format #, that will keep consistent between > dlmopen and dlclose calls. The plan is for this identifier to be usable > in expressions like `print #1::var` to find a specific instance of a > symbol, and so the identifier must not be a valid C++ or Ada namespace > identifier, otherwise disambiguation becomes a problem. Support for > those expressions has not been implemented yet, it is only mentioned to > explain why the identifier looks like this. While doing some more development on the next patch for this series, it occurred to me that we also identify frames with #N, so this would be overlap of the meaning of #. This will eventually be somewhat confusing as we could possibly have the following: (gdb) bt #0  #1::roll () at random.c:6 #1  0x00000000004011b8 in #1::hit (chance=0, acc_boost=0, evasion_boost=0) at random.c:9 #2  0x000000000040126c in #0::main () at random.c:20 My question is: is this confusing enough that we should figure out a different syntax? and if so, what other invalid character should I use for a namespace? Also I have an unrelated note about my patch inlined. > > The namespace identifiers are stored via a vector inside svr4_info > object. The vector stores the address of the r_debug objects used by > glibc to identify each namespace, and the user-friendly ID is the index > of the r_debug in the vector. This commit also introduces a set storing > the indices of active namespaces. The glibc I used to develop this patch > (glibc 2.40 on Fedora 41) doesn't allow an SO to be loaded into a > deactivated namespace, and requesting a new namespace when a namespace > was previously closed will reuse that namespace. Because of how this is > implemented, this patch lets GDB easily track the exact namespace IDs > that the inferior will see. > > Finally, two new solib_ops function pointers were added, find_solib_ns > and num_active_namespaces, to allow code outside of solib-svr4 to find > and use the namespace identifiers and the number of namespaces, > respectively. As a sanity check, the command `info sharedlibrary` has > been changed to display the namespace identifier when the inferior has > more than one active namespace. With this final change, a couple of tests > had to be tweaked to handle the possible new column, and a new test has > been created to make sure that the column appears and disappears as > needed, and that GDB can track the value of the LMID for namespaces. > > --- > diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp > new file mode 100644 > index 00000000000..890ee091be9 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp > @@ -0,0 +1,108 @@ > +# This testcase is part of GDB, the GNU debugger. > +# > +# Copyright 2025 Free Software Foundation, Inc. > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# 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 General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see. > +# > +# > +# Test several things related to handling linker namespaces: > +# * That the user-facing namespace ID is consistent; > + > +require allow_dlmopen_tests > + > +standard_testfile -main.c -lib.c > + > +set srcfile_lib $srcfile2 > +set binfile_lib [standard_output_file dlmopen-lib.so] > + > +if { [build_executable "build shlib" $binfile_lib $srcfile_lib \ > + [list debug shlib]] == -1 } { > + return > +} > + > +if { [build_executable "failed to build" $testfile $srcfile \ > + [list additional_flags=-DDSO_NAME=\"$binfile_lib\" \ > + shlib_load debug]] } { > + return > +} > + > +# Run the command "info sharedlibrary" and get the first namespace > +# for the so > +proc get_first_so_ns {} { > + set ns -1 > + gdb_test_multiple "info sharedlibrary" "get SO namespace" -lbl { > + -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" { > + exp_continue > + } > + -re "^$::hex\\s+$::hex\\s+\#($::decimal)\\s+\[^\r\n]+$::binfile_lib.*" { > + set ns $expect_out(1,string) > + } > + -re "^$::gdb_prompt $" { > + } > + -re "^\[^\r\n\]+\r\n" { > + exp_continue > + } > + } > + return $ns > +} > + > +# Run the tests relating to the command "info sharedlibrary", to > +# verify that the namespace ID is consistent. > +proc test_info_shared {} { > + clean_restart $::binfile > + > + if { ![runto_main] } { > + return > + } > + > + # First test that we don't print a namespace column at the start. > + gdb_test "info sharedlibrary" \ > + "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \ > + "before loading anything" > + > + gdb_test_no_output "set wait_for_gdb = 0" This is leftover from an earlier version where I thought about using attach, but decided against it since dlmopen already tests it. I've removed this from my local branch -- Cheers, Guinevere Larsen She/Her/Hers > + > + gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"] > + gdb_continue_to_breakpoint "TAG: first dlclose" > + > + # Next, test that we *do* print a namespace column after loading SOs. > + gdb_test "info sharedlibrary" \ > + "From\\s+To\\s+NS\\s+Syms\\s+Read\\s+Shared Object Library.*" \ > + "after loading everything" > + > + gdb_assert {[get_first_so_ns] == 1} "before closing any library" > + > + gdb_test "next" ".*second dlclose.*" "close first library" > + gdb_assert {[get_first_so_ns] == 2} "after closing one library" > + > + gdb_test "next" ".*third dlclose.*" "close second library" > + gdb_assert {[get_first_so_ns] == 3} "before closing two libraries" > + > + gdb_breakpoint [gdb_get_line_number "TAG: fourth dlclose"] > + gdb_continue_to_breakpoint "TAG: fourth dlclose" > + # As of writing this test, glibc's LMID is just an index on an array of > + # namespaces. After closing a namespace, requesting a new one will > + # return the index of the lowest-closed namespace, so this will likely > + # be namespace 1, and because of glibc's reuse of the r_debug object, > + # GDB should be able to assign the same number. > + gdb_assert {[get_first_so_ns] == [get_integer_valueof "lmid" "-1"]} \ > + "reopen a namespace" > + > + gdb_test "next" ".*return 0.*" "final namespace inactive" > + gdb_test "info sharedlibrary" \ > + "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \ > + "after unloading everything" > +} > + > +test_info_shared > diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp > index a8e3b08c016..6f8a3bc9de4 100644 > --- a/gdb/testsuite/gdb.base/dlmopen.exp > +++ b/gdb/testsuite/gdb.base/dlmopen.exp > @@ -106,7 +106,7 @@ proc check_dso_count { dso num } { > > set count 0 > gdb_test_multiple "info shared" "info shared" { > - -re "$hex $hex Yes \[^\r\n\]*$dso\r\n" { > + -re "$hex $hex \(\#$::decimal\\s+\)\?Yes \[^\r\n\]*$dso\r\n" { > # use longer form so debug remote does not interfere > set count [expr $count + 1] > exp_continue > @@ -233,12 +233,12 @@ proc get_dyld_info {} { > set dyld_count 0 > set dyld_start_addr "" > gdb_test_multiple "info sharedlibrary" "" { > - -re "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\r\n" { > + -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" { > exp_continue > } > - -re "^($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\r\n" { > + -re "^($::hex)\\s+$::hex\\s+\(\#$::decimal\\s+\)?\[^/\]+(/\[^\r\n\]+)\r\n" { > set addr $expect_out(1,string) > - set lib $expect_out(2,string) > + set lib $expect_out(3,string) > > if { [is_dyln $lib] } { > # This looks like it might be the dynamic linker. > diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp > index a5743f83bb8..c0208ebcc51 100644 > --- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp > +++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp > @@ -81,12 +81,12 @@ proc get_dyld_info {} { > set dyld_count 0 > set dyld_start_addr "" > gdb_test_multiple "info sharedlibrary" "" { > - -re "~\"From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" { > + -re "~\"From\\s+To(\\s+NS)?\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" { > exp_continue > } > - -re "^~\"($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" { > + -re "^~\"($::hex)\\s+${::hex}(\\s+$::decimal)?\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" { > set addr $expect_out(1,string) > - set lib $expect_out(2,string) > + set lib $expect_out(3,string) > > if { [is_dyln $lib] } { > # This looks like it might be the dynamic linker. > > base-commit: 82455bdab80f9a4d4f94a6e8590a1bdc58c4010e --------------Zh2bX0apnSrGvNEejOOzUrBN Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 3/19/25 9:30 AM, Guinevere Larsen wrote:
GDB has had basic support for linkage namespaces for some time already,
but only in the sense of managing multiple copies of the same shared
object being loaded, and a very fragile way to find the correct copy of
a symbol (see PR shlibs/32054).

This commit is the first step in improving the user experience around
multiple namespace support. It introduces a user-friendly identifier for
namespaces, in the format #<number>, that will keep consistent between
dlmopen and dlclose calls. The plan is for this identifier to be usable
in expressions like `print #1::var` to find a specific instance of a
symbol, and so the identifier must not be a valid C++ or Ada namespace
identifier, otherwise disambiguation becomes a problem. Support for
those expressions has not been implemented yet, it is only mentioned to
explain why the identifier looks like this.

While doing some more development on the next patch for this series, it occurred to me that we also identify frames with #N, so this would be overlap of the meaning of #. This will eventually be somewhat confusing as we could possibly have the following:

(gdb) bt
#0  #1::roll () at random.c:6
#1  0x00000000004011b8 in #1::hit (chance=0, acc_boost=0, evasion_boost=0) at random.c:9
#2  0x000000000040126c in #0::main () at random.c:20

My question is: is this confusing enough that we should figure out a different syntax? and if so, what other invalid character should I use for a namespace?

Also I have an unrelated note about my patch inlined.


The namespace identifiers are stored via a vector inside svr4_info
object. The vector stores the address of the r_debug objects used by
glibc to identify each namespace, and the user-friendly ID is the index
of the r_debug in the vector. This commit also introduces a set storing
the indices of active namespaces. The glibc I used to develop this patch
(glibc 2.40 on Fedora 41) doesn't allow an SO to be loaded into a
deactivated namespace, and requesting a new namespace when a namespace
was previously closed will reuse that namespace. Because of how this is
implemented, this patch lets GDB easily track the exact namespace IDs
that the inferior will see.

Finally, two new solib_ops function pointers were added, find_solib_ns
and num_active_namespaces, to allow code outside of solib-svr4 to find
and use the namespace identifiers and the number of namespaces,
respectively. As a sanity check, the command `info sharedlibrary` has
been changed to display the namespace identifier when the inferior has
more than one active namespace. With this final change, a couple of tests
had to be tweaked to handle the possible new column, and a new test has
been created to make sure that the column appears and disappears as
needed, and that GDB can track the value of the LMID for namespaces.

---
<snipping for convenience>
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
new file mode 100644
index 00000000000..890ee091be9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -0,0 +1,108 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2025 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Test several things related to handling linker namespaces:
+# * That the user-facing namespace ID is consistent;
+
+require allow_dlmopen_tests
+
+standard_testfile -main.c -lib.c
+
+set srcfile_lib $srcfile2
+set binfile_lib [standard_output_file dlmopen-lib.so]
+
+if { [build_executable "build shlib" $binfile_lib $srcfile_lib \
+	  [list debug shlib]] == -1 } {
+    return
+}
+
+if { [build_executable "failed to build" $testfile $srcfile \
+	  [list additional_flags=-DDSO_NAME=\"$binfile_lib\" \
+	       shlib_load debug]] } {
+    return
+}
+
+# Run the command "info sharedlibrary" and get the first namespace
+# for the so
+proc get_first_so_ns {} {
+    set ns -1
+    gdb_test_multiple "info sharedlibrary" "get SO namespace" -lbl {
+	-re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" {
+	    exp_continue
+	}
+	-re "^$::hex\\s+$::hex\\s+\#($::decimal)\\s+\[^\r\n]+$::binfile_lib.*" {
+	    set ns $expect_out(1,string)
+	}
+	-re "^$::gdb_prompt $" {
+	}
+	-re "^\[^\r\n\]+\r\n" {
+	    exp_continue
+	}
+    }
+    return $ns
+}
+
+# Run the tests relating to the command "info sharedlibrary", to
+# verify that the namespace ID is consistent.
+proc test_info_shared {} {
+    clean_restart $::binfile
+
+    if { ![runto_main] } {
+	return
+    }
+
+    # First test that we don't print a namespace column at the start.
+    gdb_test "info sharedlibrary" \
+	"From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+	"before loading anything"
+
+    gdb_test_no_output "set wait_for_gdb = 0"

This is leftover from an earlier version where I thought about using attach, but decided against it since dlmopen already tests it.

I've removed this from my local branch

-- 
Cheers,
Guinevere Larsen
She/Her/Hers
+
+    gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
+    gdb_continue_to_breakpoint "TAG: first dlclose"
+
+    # Next, test that we *do* print a namespace column after loading SOs.
+    gdb_test "info sharedlibrary" \
+	"From\\s+To\\s+NS\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+	"after loading everything"
+
+    gdb_assert {[get_first_so_ns] == 1} "before closing any library"
+
+    gdb_test "next" ".*second dlclose.*" "close first library"
+    gdb_assert {[get_first_so_ns] == 2} "after closing one library"
+
+    gdb_test "next" ".*third dlclose.*" "close second library"
+    gdb_assert {[get_first_so_ns] == 3} "before closing two libraries"
+
+    gdb_breakpoint [gdb_get_line_number "TAG: fourth dlclose"]
+    gdb_continue_to_breakpoint "TAG: fourth dlclose"
+    # As of writing this test, glibc's LMID is just an index on an array of
+    # namespaces.  After closing a namespace, requesting a new one will
+    # return the index of the lowest-closed namespace, so this will likely
+    # be namespace 1, and because of glibc's reuse of the r_debug object,
+    # GDB should be able to assign the same number.
+    gdb_assert {[get_first_so_ns] == [get_integer_valueof "lmid" "-1"]} \
+	"reopen a namespace"
+
+    gdb_test "next" ".*return 0.*" "final namespace inactive"
+    gdb_test "info sharedlibrary" \
+	"From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+	"after unloading everything"
+}
+
+test_info_shared
diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp
index a8e3b08c016..6f8a3bc9de4 100644
--- a/gdb/testsuite/gdb.base/dlmopen.exp
+++ b/gdb/testsuite/gdb.base/dlmopen.exp
@@ -106,7 +106,7 @@ proc check_dso_count { dso num } {
 
     set count 0
     gdb_test_multiple "info shared" "info shared" {
-	-re "$hex  $hex  Yes \[^\r\n\]*$dso\r\n" {
+	-re "$hex  $hex  \(\#$::decimal\\s+\)\?Yes \[^\r\n\]*$dso\r\n" {
 	    # use longer form so debug remote does not interfere
 	    set count [expr $count + 1]
 	    exp_continue
@@ -233,12 +233,12 @@ proc get_dyld_info {} {
     set dyld_count 0
     set dyld_start_addr ""
     gdb_test_multiple "info sharedlibrary" "" {
-	-re "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\r\n" {
+	-re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" {
 	    exp_continue
 	}
-	-re "^($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\r\n" {
+	-re "^($::hex)\\s+$::hex\\s+\(\#$::decimal\\s+\)?\[^/\]+(/\[^\r\n\]+)\r\n" {
 	    set addr $expect_out(1,string)
-	    set lib $expect_out(2,string)
+	    set lib $expect_out(3,string)
 
 	    if { [is_dyln $lib] } {
 		# This looks like it might be the dynamic linker.
diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp
index a5743f83bb8..c0208ebcc51 100644
--- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp
+++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp
@@ -81,12 +81,12 @@ proc get_dyld_info {} {
     set dyld_count 0
     set dyld_start_addr ""
     gdb_test_multiple "info sharedlibrary" "" {
-	-re "~\"From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" {
+	-re "~\"From\\s+To(\\s+NS)?\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" {
 	    exp_continue
 	}
-	-re "^~\"($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" {
+	-re "^~\"($::hex)\\s+${::hex}(\\s+$::decimal)?\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" {
 	    set addr $expect_out(1,string)
-	    set lib $expect_out(2,string)
+	    set lib $expect_out(3,string)
 
 	    if { [is_dyln $lib] } {
 		# This looks like it might be the dynamic linker.

base-commit: 82455bdab80f9a4d4f94a6e8590a1bdc58c4010e
--------------Zh2bX0apnSrGvNEejOOzUrBN--