From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id zCPFDnCcOWqB3BMAWB0awg (envelope-from ) for ; Mon, 22 Jun 2026 16:34:56 -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=dOQYifeP; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 240401E098; Mon, 22 Jun 2026 16:34:56 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.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 autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (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 4226D1E070 for ; Mon, 22 Jun 2026 16:34:54 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 08C114BA2E08 for ; Mon, 22 Jun 2026 20:34:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 08C114BA2E08 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=dOQYifeP 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 0F1884BA2E08 for ; Mon, 22 Jun 2026 20:34:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0F1884BA2E08 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 0F1884BA2E08 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782160464; cv=none; b=cpnedL+YdDB5WpJnFHJ8QavvFBP90yw/SzwJH0TymNZcT92Nh6Ztltt/RG0pr9P3PNxCdtEc9GF4X7FwWjii82YQI3b8GEJvgz0rw+PpSFC8WzZI77ZmDJsmOBlWWj5AZXYlSl0mTmN3Fk/qOPr4qY3BQsdTaau6ciTzS3kG7wk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782160464; c=relaxed/simple; bh=D4ZhBbsCej9FtuVJnXXPxZmxAF2y+1a5djQIp844H8s=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=oq4S86Bg63iAI5TJI2EzvmiQiED8DJs6W9njm/XhR9x4Rz3NWNBocCy8noOX5+b9xxA0UpiH8Fpc6IItBnGyIzTeRDHMGG9HZkITOLSbkm/MtbBW/snV7942dXXyFwirwYQsjHA1FGvq9hCMZkoDPC6oVYJcM4nVsEXVgbCirTA= ARC-Authentication-Results: i=1; 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=dOQYifeP DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0F1884BA2E08 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782160463; 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: in-reply-to:in-reply-to:references:references; bh=eEMy1kBMOOvTnFqWFmNdKiwMuybaXJ7J2PBHcUKfPYk=; b=dOQYifePcm+hDOkh5Wi+q0QGTQW7EGyZ+YizR8xY9H4z+u8+4UXCMbW5tppqScj9p2wYHB en+XQKLeC9H9VkBhB5bllbTWxfwfjzni+aaZfujMjPoRNYcxXx2g1KTNTlcLQdAIyxyX3M XN1OE+cmkSoBUNBX3MezfyyvZYV9r/I= Received: from mail-vs1-f69.google.com (mail-vs1-f69.google.com [209.85.217.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-520-qRAhKUe5MG-Pnnsn0vufNA-1; Mon, 22 Jun 2026 16:34:20 -0400 X-MC-Unique: qRAhKUe5MG-Pnnsn0vufNA-1 X-Mimecast-MFC-AGG-ID: qRAhKUe5MG-Pnnsn0vufNA_1782160460 Received: by mail-vs1-f69.google.com with SMTP id ada2fe7eead31-71b5daaf011so2993549137.3 for ; Mon, 22 Jun 2026 13:34:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782160460; x=1782765260; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=eEMy1kBMOOvTnFqWFmNdKiwMuybaXJ7J2PBHcUKfPYk=; b=hUBgPGj2C964KV/gKXRvtL1Vy9NCvVlo46dMCGT2/PgqOtQ253oKXPiYj16sxCGUqQ cn7e/ScqMqWM0WZn+NJABsuFvXld6AD0MyFT5cVkxHmAbVMkAwFJI3eonWh5vxJQWZ/f PwbTQwdju8xmHQgjm85BhfdLz88tIeCWAVLhKrayT2falXGxRCFd8J1nv7DFHvslRux7 WyuyWIkUtWmj/R7Lacg5KCFGfO/RMpBQJzjsKtCrgy7ykxUO/iMOiAOn5Az+CNo55XHg pn3RTVM64uqpLpq1i0WSPKsHRgTvhHLK2fhGbLmuofq96y10i24UlROta5u1vE4r6e1q /u2w== X-Gm-Message-State: AOJu0YxLuVZCTmw/mFhoXb+v5l9e/hYwGpvbEYzE+3odej0m4ke7ElHo b3kB90RcS2Ynl0PIfI+dYloeBSzafRz5xW6beTB9G4R8c8rW43Ih7alrDlZifzxjLYGYeGRlbQ4 WPTFf1m0mqtrv9UeDK5fHGi5vjCfMCxoQGB/tpPEbei5jqEbHKP5uXUhefSqpwMJi9wyRlqtpFK AE7JLHSsWLKO4oVuQFfkp5v/4MJF1lRRxMePIUJPrAyP8zE6Ua X-Gm-Gg: AfdE7clMlga2LVOll9t/6qp93OjZRiYaYeqN+XmzrNP/78VdzWLFzhB/wgKw87DdGom TK6d5IgQXsJZ570Qe1l0tunhLsCrfzEMpiSjJThYs6bGKuRl8OBs+q/scUWzbc9bZxcZ1V2uaaI lX5SP9QPHh1rlgmZWS84Nxc3X93mtRZcjDgnHj/IUl7RTJbukEQaGWG20yCDSS4unO3eHHZGpGD lgzEgu6CFJBfAaKKv4ZHR20+0NS+Ub5KF/fNh+aEUaimLtu2pndayj6e/D5CE2o3bb79yNTEp4d sxq8mpwRR8FdhDsFsN+TPHXLOtVzN1UYN0HhIu3GLDil755ivtOiPZ5IWb38TnOHRekPMbCQcy0 5wk+FSwLu+QgDUkFFUVm/ X-Received: by 2002:a05:6102:8017:b0:605:ead:8f38 with SMTP id ada2fe7eead31-72b67c11c64mr6205434137.29.1782160459998; Mon, 22 Jun 2026 13:34:19 -0700 (PDT) X-Received: by 2002:a05:6102:8017:b0:605:ead:8f38 with SMTP id ada2fe7eead31-72b67c11c64mr6205391137.29.1782160459063; Mon, 22 Jun 2026 13:34:19 -0700 (PDT) Received: from ?IPV6:2804:14d:8084:993e::75d? ([2804:14d:8084:993e::75d]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-72ba22997ccsm6895019137.3.2026.06.22.13.34.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 22 Jun 2026 13:34:18 -0700 (PDT) Message-ID: <9bdde366-1efd-4802-8158-8be60bcd3614@redhat.com> Date: Mon, 22 Jun 2026 17:34:13 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PING][PATCH v8] gdb: Print linker namespace when showing a frame To: gdb-patches@sourceware.org, Guinevere Larsen Cc: Eli Zaretskii References: <20260507134822.701336-1-guinevere@redhat.com> From: Guinevere Larsen In-Reply-To: <20260507134822.701336-1-guinevere@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Ez93PZIm5WmEQy0JXxbVAPiZ5jfkGjD-FnOvmjA4JUU_1782160460 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed 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 Ping :) On 5/7/26 10:48 AM, 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 introducing a new function on solib.h, > linker_namespace_prefix, that returns either an empty string (if only > one namespace is active, or we can't determine the PC for the frame), or > the correct identifier. This should be printed manually every time GDB > will print a frame, so that we don't confuse other systems that look at > function names. > > A previous revision would break GDB's ability to strip the parameters of > C++ symbols, so this commit also adds a C++ SO to the test. However, > libstdc++ never gets unloaded, so many changes were required to make the > rest of the test still valid. > > Reviewed-By: Eli Zaretskii > --- > gdb/NEWS | 4 + > gdb/doc/gdb.texinfo | 9 +++ > gdb/solib.c | 43 ++++++++--- > gdb/solib.h | 13 ++++ > gdb/stack.c | 2 + > .../gdb.base/dlmopen-ns-ids-framefilter.py | 31 ++++++++ > .../gdb.base/dlmopen-ns-ids-libc++.cc | 36 +++++++++ > gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c | 19 ++++- > gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 74 ++++++++++++++++--- > gdb/testsuite/gdb.mi/mi-dlmopen.exp | 2 +- > 10 files changed, 206 insertions(+), 27 deletions(-) > create mode 100644 gdb/testsuite/gdb.base/dlmopen-ns-ids-framefilter.py > create mode 100644 gdb/testsuite/gdb.base/dlmopen-ns-ids-libc++.cc > > diff --git a/gdb/NEWS b/gdb/NEWS > index 480e1854002..941178c06a4 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -78,6 +78,10 @@ > * The Windows native target now supports non-stop mode. This feature > requires Windows 10 or later. > > +* When debugging an inferior with multiple linker namespaces, functions > + will be printed like so [[N]]::foo, where N is the namespace that > + contains foo. For example [[0]]::main. > + > * New targets > > GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux* > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index ab0216ff477..98a43f3a57e 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -22431,6 +22431,15 @@ possibility that those objects may cross-talk. Each set of isolated > shared objects is said to belong to a ``namespace'', and linker related > actions such as relocations do not cross namespace boundaries. > > +When multiple linker namespaces are active, @value{GDBN} will print the > +identifier of the namespace that contains the function, when a function > +is printed. It will look like this: > + > +@smallexample > +#0 [[1]]::inc (n=0) at dlmopen-ns-ids-lib.c > +#1 0x0000000000400591 in [[0]]::main () at dlmopen-ns-ids-main.c > +@end smallexample > + > @kindex info dll > @item info dll @var{regex} > This is an alias of @code{info sharedlibrary}. > diff --git a/gdb/solib.c b/gdb/solib.c > index 782b844aa2f..add842b5771 100644 > --- a/gdb/solib.c > +++ b/gdb/solib.c > @@ -1796,6 +1796,36 @@ solib_linker_namespace_count (program_space *pspace) > return 0; > } > > +/* See solib.h. */ > + > +int > +linker_namespace_for_addr (CORE_ADDR addr, program_space *pspace) > +{ > + for (const solib &so : pspace->solibs ()) > + if (solib_contains_address_p (so, addr)) > + { > + if (so.ops ().supports_namespaces ()) > + return so.ops ().find_solib_ns (so); > + break; > + } > + > + return 0; > +} > + > +/* See solib.h. */ > + > +std::string > +linker_namespace_prefix (const frame_info_ptr &frame) > +{ > + std::optional pc = get_frame_pc_if_available (frame); > + program_space *pspace = get_frame_program_space (frame); > + if (!pc.has_value () || solib_linker_namespace_count (pspace) <= 1) > + return std::string (""); > + > + return string_printf ("[[%d]]::", linker_namespace_for_addr (pc.value (), > + pspace)); > +} > + > /* Implementation of the linker_namespace convenience variable. > > This returns the GDB internal identifier of the linker namespace, > @@ -1804,19 +1834,10 @@ solib_linker_namespace_count (program_space *pspace) > > 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_for_addr (curr_pc, current_program_space); > > /* 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 564655c4a57..39931bb1b93 100644 > --- a/gdb/solib.h > +++ b/gdb/solib.h > @@ -334,6 +334,19 @@ 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 PSPACE. If ADDR is present in multiple namespaces, > + an arbitrary one is returned. If ADDR is not present in any > + namespace, or if the target doesn't support linker namespaces, > + returns 0. */ > + > +extern int linker_namespace_for_addr (CORE_ADDR addr, program_space *pspace); > + > +/* Calculate the linker namespace identifier, and turn it into a prefix > + to be used to print a frame. */ > + > +extern std::string linker_namespace_prefix (const frame_info_ptr &frame); > + > /* 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 7329430adab..ac270718a91 100644 > --- a/gdb/stack.c > +++ b/gdb/stack.c > @@ -1306,6 +1306,7 @@ print_frame (struct ui_out *uiout, > annotate_frame_function_name (); > > string_file stb; > + gdb_puts (linker_namespace_prefix (frame).c_str (), &stb); > gdb_puts (funname ? funname.get () : "??", &stb); > uiout->field_stream ("func", stb, function_name_style.style ()); > uiout->wrap_hint (3); > @@ -1466,6 +1467,7 @@ info_frame_command_core (const frame_info_ptr &fi, bool selected_frame_p) > fputs_styled ("", metadata_style.style (), gdb_stdout); > > gdb_stdout->wrap_here (3); > + gdb_puts (linker_namespace_prefix (fi).c_str ()); > if (funname.get () != nullptr) > { > gdb_puts (" in "); > diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-framefilter.py b/gdb/testsuite/gdb.base/dlmopen-ns-ids-framefilter.py > new file mode 100644 > index 00000000000..11d96fcfbc4 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-framefilter.py > @@ -0,0 +1,31 @@ > +# Copyright (C) 2026 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 . > + > + > +# This file is part of the GDB testsuite. It tests if printing the > +# linker namespace id is affected by a null frame filter > + > +import gdb > + > + > +class NullFilter: > + def __init__(self): > + self.name = "null filter" > + self.priority = 100 > + self.enabled = True > + gdb.frame_filters[self.name] = self > + > + def filter(self, iterator): > + return iterator > diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-libc++.cc b/gdb/testsuite/gdb.base/dlmopen-ns-ids-libc++.cc > new file mode 100644 > index 00000000000..9abf3f25096 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-libc++.cc > @@ -0,0 +1,36 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2025-2026 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 . > + > +*/ > + > +int gdb_dlmopen_glob = 0; > + > +int > +cpp_inc (int n) > +{ > + int amount = gdb_dlmopen_glob; > + return n + amount; /* bp.inc. */ > +} > + > +extern "C" { > + __attribute__((visibility ("default"))) > + int > + inc (int n) > + { > + return cpp_inc (n); > + } > +} > diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c > index 4f08a5135b2..f13eb9168de 100644 > --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c > +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c > @@ -27,7 +27,7 @@ > int > main (void) > { > - void *handle[4]; > + void *handle[5]; > int (*fun) (int); > Lmid_t lmid; > int dl; > @@ -41,20 +41,31 @@ main (void) > handle[2] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL); > assert (handle[2] != NULL); > > + /* We open the C++ SO on the main namespace because libstdc++ marks a > + lot of objects as GNU_UNIQUE meaning that they effectively can't be > + unloaded, so the final namespace would never be fully unloaded. */ > + handle[3] = dlmopen (LM_ID_BASE, CPP_DSO_NAME, RTLD_LAZY | RTLD_LOCAL); > + assert (handle[3] != NULL); > + > for (dl = 2; dl >= 0; dl--) > { > fun = dlsym (handle[dl], "inc"); > fun (dl); > } > + /* C++ call, to make sure the linker namespace doesn't break anything > + of the C++ handling of symbols. */ > + fun = dlsym (handle[3], "inc"); > + fun (-1); > > dlclose (handle[0]); /* TAG: first dlclose */ > dlclose (handle[1]); /* TAG: second dlclose */ > dlclose (handle[2]); /* TAG: third dlclose */ > + dlclose (handle[3]); /* TAG: fourth dlclose */ > > - handle[3] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL); > - dlinfo (handle[3], RTLD_DI_LMID, &lmid); > + handle[4] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL); > + dlinfo (handle[4], RTLD_DI_LMID, &lmid); > > - dlclose (handle[3]); /* TAG: fourth dlclose */ > + dlclose (handle[4]); /* TAG: final dlclose */ > > return 0; > } > diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp > index e40bc213454..cc1696f4229 100644 > --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp > +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp > @@ -21,20 +21,29 @@ > > require allow_dlmopen_tests > > -standard_testfile -main.c -lib.c > +standard_testfile -main.c -lib.c -framefilter.py -libc++.cc > > set srcfile_lib $srcfile2 > +set srcfile_libcpp $srcfile4 > set so_name dlmopen-lib.so > +set cpp_so_name dlmopen-libc++.so > set binfile_lib [standard_output_file $so_name] > +set binfile_libcpp [standard_output_file $cpp_so_name] > > if { [build_executable "build shlib" $binfile_lib $srcfile_lib \ > [list debug shlib]] == -1 } { > return > } > > +if { [build_executable "build shlib" $binfile_libcpp $srcfile_libcpp \ > + [list debug shlib c++]] == -1 } { > + return > +} > + > if { [build_executable "failed to build" $testfile $srcfile \ > [list additional_flags=-DDSO_NAME=\"$binfile_lib\" \ > - shlib_load debug]] } { > + additional_flags=-DCPP_DSO_NAME=\"$binfile_libcpp\" \ > + shlib_load debug]] } { > return > } > > @@ -107,11 +116,13 @@ proc check_no_duplicates {} { > proc get_first_so_ns {} { > set ns -1 > set lib_regexp [string_to_regexp ${::binfile_lib}] > + set libcpp_regexp [string_to_regexp ${::binfile_libcpp}] > + set both_regexp "($lib_regexp|$libcpp_regexp)" > gdb_test_multiple "info sharedlibrary $::so_name" "get SO namespace" -lbl { > -re "\r\nFrom\\s+To\\s+\(Linker NS\\s+\)?Syms\\s+Read\\s+Shared Object Library(?=\r\n)" { > exp_continue > } > - -re "\r\n$::hex\\s+$::hex\\s+($::decimal)\\s+\[^\r\n]+${lib_regexp}(?=\r\n)" { > + -re "\r\n$::hex\\s+$::hex\\s+($::decimal)\\s+\[^\r\n]+${both_regexp}(?=\r\n)" { > if {$ns == -1} { > set ns $expect_out(1,string) > } > @@ -155,8 +166,8 @@ proc test_info_shared {} { > 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" > + gdb_breakpoint [gdb_get_line_number "TAG: final dlclose"] > + gdb_continue_to_breakpoint "TAG: final 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 > @@ -192,6 +203,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"] > > @@ -200,14 +216,41 @@ 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" > > + gdb_test "backtrace" [multi_line \ > + "\#0\\s+\\\[\\\[1\\\]\\\]::inc \[^\r\n\]*" \ > + "\#1\\s+$::hex in \\\[\\\[0\\\]\\\]::main \[^\r\n\]*" ] \ > + "raw backtrace" > + > + set remote_python_file [gdb_remote_download host \ > + $::srcdir/$::subdir/$::srcfile3] > + gdb_test_no_output "source $remote_python_file" "load frame filter" > + gdb_test "backtrace" [multi_line \ > + "\#0\\s+\\\[\\\[1\\\]\\\]::inc \[^\r\n\]*" \ > + "\#1\\s+$::hex in \\\[\\\[0\\\]\\\]::main \[^\r\n\]*" ] \ > + "With null frame filter" > + > + # Ensure that the code for identifying and removing parameters for > + # C++ symbols still works with linker namespace IDs. > + gdb_continue_to_breakpoint "inc on c++ SO" > + gdb_test "step" "\\\[\\\[0\\\]\\\]::cpp_inc \\\(n=-1\\\).*" "step into c++ symbol" > + gdb_test "backtrace" [multi_line \ > + "\#0\\s+\\\[\\\[0\\\]\\\]::cpp_inc \\\(n=-1\\\)\[^\r\n\]*" \ > + "\#1\\s+$::hex in \\\[\\\[0\\\]\\\]::inc \\\(n=-1\\\)\[^\r\n\]*" \ > + "\#2\\s+$::hex in \\\[\\\[0\\\]\\\]::main \[^\r\n\]*" ] \ > + "bt through c++ symbols" > + > + # Check that everything still works as we close namespaces. > gdb_continue_to_breakpoint "first dlclose" > gdb_test "print \$_linker_namespace_count" "4" "all SOs loaded" > > @@ -264,15 +307,23 @@ proc test_info_linker_namespaces {} { > > # Some systems may add libc and libm to every loaded namespace, > # others may load only one or neither, because the SO doesn't > - # actually use either library. The best we can do is check if > - # we found the dynamic linker, and up to 2 more libraries. > - gdb_assert {$n_libraries <= 3} "the correct number of libraries was reported" > + # actually use either library. Similarly, because of the c++ > + # SO, libstdc++ and libgcc_s may be included. The best we can > + # do is check if we found the dynamic linker, the SO, and up to > + # 4 more libraries. Ensuring that only the right one shows up is > + # in the foreach block. > + gdb_assert {$n_libraries <= 6} "the correct number of libraries was reported" > > set binfile_lib_re [string_to_regexp $::binfile_lib] > > - foreach_with_prefix ns {1 2 3} { > + foreach_with_prefix ns {1 2 3 0} { > set found_test_so false > set n_libraries 999 > + set expected_libs 4 > + if {$ns == 0} { > + set expected_libs 6 > + set binfile_lib_re [string_to_regexp $::binfile_libcpp] > + } > > gdb_test_multiple "info linker-namespaces $ns" "print namespace $ns" { > -re ".*($::decimal) librar(?:y|ies) loaded in linker namespace $ns:\r\n" { > @@ -290,7 +341,8 @@ proc test_info_linker_namespaces {} { > # actually use either library. The best we can do is check if > # we found the dynamic linker, the test SO, and maybe up to 2 > # more libraries. > - gdb_assert {$n_libraries <= 4} "the correct number of libraries was reported" > + gdb_assert {$n_libraries <= $expected_libs} \ > + "the correct number of libraries was reported" > gdb_assert {$found_test_so} "this testfile's SO was reported" > } > > diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp > index ff854ac7dd4..832c6ea6fe6 100644 > --- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp > +++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp > @@ -156,7 +156,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. > > base-commit: 9e6e0c3cd9e6d5ee4953f72a805cff5f150aa2fd -- Cheers, Guinevere Larsen it/its she/her (deprecated)