mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-29 10:30:46 +00:00
Commits: commitaaad5a3254Author: Tom de Vries <tdevries@suse.de> Date: Fri Sep 5 15:36:23 2025 +0200 [gdb/testsuite] Fix clean_restart <absolute filename> in gdb.base, part 3 commit2e61486fceAuthor: Tom de Vries <tdevries@suse.de> Date: Fri Sep 5 15:36:23 2025 +0200 [gdb/testsuite] Fix clean_restart <absolute filename> in gdb.base, part 2 commit202beb3feeAuthor: Tom de Vries <tdevries@suse.de> Date: Fri Sep 5 15:36:23 2025 +0200 [gdb/testsuite] Fix clean_restart <absolute filename> in gdb.base, part 1 were made to work around the changes to clean_restart in commit: commitcba778b944Date: Sun Sep 7 11:53:30 2025 +0200 [gdb/testsuite] Error out on clean_restart <absolute filename> These commits added a lot of calls to gdb_load which can be removed in many cases by passing $testfile to clean_restart, or by switching to use prepare_for_testing to compile the test executable. In this commit I've gone through the gdb.base/ directory and removed as many of the gdb_load calls as possible. I was only looking for places where the gdb_load call immediately follows the call to clean_restart. And I did skip a few where it was not as simple as just passing $testfile. Where possible I've updated tests to use calls to prepare_for_testing, and simply removed the clean_restart call altogether (this is done as part of prepare_for_testing). This is, I think, the best solution. In other cases I've removed the gdb_load call, and passed $testfile to clean_restart. I've preferred $::testfile to adding a 'global' declaration, and in some cases switching to testfile has allowed me to remove the 'global binfile' as an additional cleanup. I ran the complete set of tests that I touched and I didn't see any regressions, so I don't believe I broke anything. I know that there are probably gdb_load calls that can be cleaned up in other testsuite sub-directories, if/when this patch is merged I'll take a look at those too. Reviewed-By: Tom de Vries <tdevries@suse.de>
317 lines
10 KiB
Plaintext
317 lines
10 KiB
Plaintext
# 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 so_name dlmopen-lib.so
|
|
set binfile_lib [standard_output_file $so_name]
|
|
|
|
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
|
|
}
|
|
|
|
# Return a list of shared libraries extract from the "info sharedlibrary"
|
|
# command. Each item in the list is itself a list with the following items:
|
|
#
|
|
# - "from" address
|
|
# - "to" address
|
|
# - namespace ID
|
|
# - name (file path)
|
|
|
|
proc get_info_shared {} {
|
|
set from_re "($::hex)\\s+"
|
|
set to_re "($::hex)\\s+"
|
|
set ns_re "(?:($::decimal)\\s+)?"
|
|
set syms_read_re "(Yes( \\(\\*\\))?|No)\\s+"
|
|
set name_re "(\[^\r\n\]+)"
|
|
set libs {}
|
|
|
|
gdb_test_multiple "info sharedlibrary" "" {
|
|
-re {From\s+To\s+(Linker NS\s+)?Syms Read\s+Shared Object Library\r\n} {
|
|
exp_continue
|
|
}
|
|
|
|
-re "^${from_re}${to_re}${ns_re}${syms_read_re}${name_re}\r\n" {
|
|
set from $expect_out(1,string)
|
|
set to $expect_out(2,string)
|
|
set ns $expect_out(3,string)
|
|
set name $expect_out(4,string)
|
|
|
|
lappend libs [list $from $to $ns $name]
|
|
exp_continue
|
|
}
|
|
|
|
-re {^\(\*\): Shared library is missing debugging information\.\r\n} {
|
|
exp_continue
|
|
}
|
|
|
|
-re "^$::gdb_prompt " {
|
|
pass $gdb_test_name
|
|
}
|
|
}
|
|
|
|
return $libs
|
|
}
|
|
|
|
# Verify that "info sharedlibrary" does not contain duplicate entries.
|
|
|
|
proc check_no_duplicates {} {
|
|
with_test_prefix "check no duplicates" {
|
|
set libs [get_info_shared]
|
|
array set seen {}
|
|
set seen_duplicate 0
|
|
|
|
foreach lib $libs {
|
|
if {[info exists seen($lib)]} {
|
|
verbose -log "already seen: $lib"
|
|
set seen_duplicate 1
|
|
}
|
|
|
|
set seen($lib) 1
|
|
}
|
|
|
|
gdb_assert {!$seen_duplicate} "no duplicates"
|
|
}
|
|
}
|
|
|
|
# Run the command "info sharedlibrary" and get the first namespace
|
|
# for the so
|
|
proc get_first_so_ns {} {
|
|
set ns -1
|
|
set lib_regexp [string_to_regexp ${::binfile_lib}]
|
|
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)" {
|
|
if {$ns == -1} {
|
|
set ns $expect_out(1,string)
|
|
}
|
|
exp_continue
|
|
}
|
|
-re -wrap "" {
|
|
}
|
|
}
|
|
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 $::testfile
|
|
|
|
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_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+Linker NS\\s+Syms\\s+Read\\s+Shared Object Library.*" \
|
|
"after loading everything"
|
|
|
|
check_no_duplicates
|
|
|
|
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"
|
|
}
|
|
|
|
# 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 $::testfile
|
|
|
|
gdb_test "print \$_linker_namespace_count" "0" \
|
|
"0 namespace before starting inferior"
|
|
gdb_test "print \$_linker_namespace" "No registers." \
|
|
"No current namespace before starting inferior"
|
|
|
|
if { ![runto_main] } {
|
|
return
|
|
}
|
|
|
|
gdb_test "print \$_linker_namespace_count" "1" \
|
|
"Before activating namespaces"
|
|
gdb_test "print \$_linker_namespace" ".* = 0" \
|
|
"Still in the default namespace"
|
|
|
|
gdb_breakpoint "inc" allow-pending
|
|
gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
|
|
|
|
foreach_with_prefix dl {3 2 1} {
|
|
gdb_continue_to_breakpoint "inc"
|
|
|
|
gdb_test "print \$_linker_namespace" ".* = $dl" \
|
|
"Verify we're in namespace $dl"
|
|
}
|
|
|
|
# Check that we display the namespace of the selected
|
|
# frame, not the lowermost one.
|
|
gdb_test "up" "\#1.*in main.*"
|
|
gdb_test "print \$_linker_namespace" ".* = 0" \
|
|
"print namespace of selected frame"
|
|
|
|
gdb_continue_to_breakpoint "first dlclose"
|
|
gdb_test "print \$_linker_namespace_count" "4" "all SOs loaded"
|
|
|
|
gdb_test "next" ".*second dlclose.*" "close one SO"
|
|
gdb_test "print \$_linker_namespace_count" "3" "one SOs unloaded"
|
|
gdb_test "next" ".*third dlclose.*" "close another SO"
|
|
gdb_test "print \$_linker_namespace_count" "2" "two SOs unloaded"
|
|
|
|
# Restarting GDB so that we can test setting a breakpoint
|
|
# using the convenience variable, while a proper bp syntax
|
|
# isn't implemented for namespaces
|
|
clean_restart $::testfile
|
|
if {![runto_main]} {
|
|
return
|
|
}
|
|
|
|
# We need to load one SO because you can't have confitional
|
|
# breakpoints and pending breakpoints at the same time with
|
|
# gdb_breakpoint.
|
|
gdb_test "next" ".*assert.*" "load the first SO"
|
|
gdb_breakpoint "inc if \$_linker_namespace == 2"
|
|
gdb_continue_to_breakpoint "inc"
|
|
gdb_continue_to_end "" continue 1
|
|
}
|
|
|
|
# Run several tests relating to the command "info namespaces".
|
|
proc test_info_linker_namespaces {} {
|
|
clean_restart $::testfile
|
|
|
|
# Check that "info linker-namespaces" while the inferior is not running
|
|
# doesn't crash.
|
|
gdb_test "info linker-namespaces" \
|
|
"Current inferior does not support linker namespaces\\. Use \"info sharedlibrary\" instead\\." \
|
|
"info linker-namespaces before running"
|
|
|
|
if { ![runto_main] } {
|
|
return
|
|
}
|
|
|
|
with_test_prefix "info linker-namespaces" {
|
|
gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
|
|
gdb_continue_to_breakpoint "TAG: first dlclose"
|
|
}
|
|
|
|
# First, test printing a single namespace, and ensure all of
|
|
# them are correct, using both syntaxes.
|
|
set n_libraries 999
|
|
|
|
gdb_test_multiple "info linker-namespaces \[\[0\]\]" "print namespace 0" {
|
|
-re -wrap "($::decimal) librar(?:y|ies) loaded in linker namespace 0:.*" {
|
|
set n_libraries $expect_out(1,string)
|
|
}
|
|
}
|
|
|
|
# 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"
|
|
|
|
set binfile_lib_re [string_to_regexp $::binfile_lib]
|
|
|
|
foreach_with_prefix ns {1 2 3} {
|
|
set found_test_so false
|
|
set n_libraries 999
|
|
|
|
gdb_test_multiple "info linker-namespaces $ns" "print namespace $ns" {
|
|
-re ".*($::decimal) librar(?:y|ies) loaded in linker namespace $ns:\r\n" {
|
|
set n_libraries $expect_out(1,string)
|
|
exp_continue
|
|
}
|
|
|
|
-re -wrap "${binfile_lib_re}.*" {
|
|
set found_test_so true
|
|
}
|
|
}
|
|
|
|
# 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, the test SO, and maybe up to 2
|
|
# more libraries.
|
|
gdb_assert {$n_libraries <= 4} "the correct number of libraries was reported"
|
|
gdb_assert {$found_test_so} "this testfile's SO was reported"
|
|
}
|
|
|
|
# These patterns are simpler, and purposefully glob multiple lines.
|
|
# The point is to ensure that we find and display all the namespaces,
|
|
# without worrying about the libraries printed, since that was tested
|
|
# above.
|
|
gdb_test "info linker-namespaces" \
|
|
[multi_line "There are 4 linker namespaces loaded\\." \
|
|
"" \
|
|
"$::decimal librar(y|ies) loaded in linker namespace 0:" \
|
|
".*" \
|
|
"$::decimal librar(y|ies) loaded in linker namespace 1:" \
|
|
".*" \
|
|
"$::decimal librar(y|ies) loaded in linker namespace 2:" \
|
|
".*" \
|
|
"$::decimal librar(y|ies) loaded in linker namespace 3:" \
|
|
".*" ] "print namespaces with no argument"
|
|
}
|
|
|
|
test_info_shared
|
|
test_conv_vars
|
|
test_info_linker_namespaces
|