From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id Gs7pCliY/GnPWx8AWB0awg (envelope-from ) for ; Thu, 07 May 2026 09:49:12 -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=YSml29/m; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 186361E067; Thu, 07 May 2026 09:49:12 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.1 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_SBL_CSS,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=no 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 A80C41E067 for ; Thu, 07 May 2026 09:49:10 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4B4694BA2E23 for ; Thu, 7 May 2026 13:49:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B4694BA2E23 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=YSml29/m 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 0A6E84BA2E24 for ; Thu, 7 May 2026 13:48:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0A6E84BA2E24 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 0A6E84BA2E24 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=1778161721; cv=none; b=RlxjDnYe8AXICzjV3LjGpuArwULxPUxMUtPxMlGiWJ1akxrB5L15I2G+iGXPgaBq21Puyxg5gGzjmZowwtTL7tiTTgd7U6Ly1uLfSguPNej+2EVJuTd5Vjw48HXjBr6IRo3FxlcqobSoBGlWWT77iYFxez2Bd8IpEII8L9xpzt0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778161721; c=relaxed/simple; bh=Mkmtev0Uh9MFzyUEtmL9Rq5xTakKRD9ChmjvQOgbKoc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=wU+U/wn0R0FoqXAFinATpMvN9DNS4osuLr0G35cH1mCgB0hwMRV3wi5y+hXg+rwy3Ex+pLTSmb8Y32tCMl1dg94oKhTOuVBN3uJMtV5x2sKJpUztGDO18EhRrx8N6PjQRldbD6AuUXlkfyFOqF7+UXYP7iAWeLxWlX0MpRAX9+M= 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=YSml29/m DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A6E84BA2E24 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778161720; 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=qzEDdvYgAtPtRLbeZ+hGZLwB7JNavz9/NncdJaI+BXI=; b=YSml29/mzGV4ekub1OWDuB48Pb1jIPGxOwP3ZY4Fm7wqE5suaRQsLDSA58V41OpMUatfEK f3hH9uQtK7dnMLhek1jg9tREhLZY1dd1srtJy57Loain/7TL2eoatViHacI6okMM24+y/c t7S6OfjTKNyp+1pkK8oPoVPyjqKBX3g= Received: from mx-prod-mc-05.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-416-svfSVYXKOfOvhf2CAae3Tw-1; Thu, 07 May 2026 09:48:36 -0400 X-MC-Unique: svfSVYXKOfOvhf2CAae3Tw-1 X-Mimecast-MFC-AGG-ID: svfSVYXKOfOvhf2CAae3Tw_1778161715 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CE6EA1956080; Thu, 7 May 2026 13:48:34 +0000 (UTC) Received: from fedora.tailb97d54.ts.net (unknown [10.96.134.116]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D7342195394A; Thu, 7 May 2026 13:48:32 +0000 (UTC) From: Guinevere Larsen To: gdb-patches@sourceware.org Cc: Guinevere Larsen , Eli Zaretskii Subject: [PATCH v8] gdb: Print linker namespace when showing a frame Date: Thu, 7 May 2026 10:48:22 -0300 Message-ID: <20260507134822.701336-1-guinevere@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ZPGPuDp1pQpOReSu-SWcAY_Gbd7XWERdSrIjU6qJV5w_1778161715 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 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 -- 2.54.0