blob: 91c280da2b11373fa75ddefa68e29c1ebec17b70 [file]
# Copyright (C) 2010-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 <http://www.gnu.org/licenses/>.
# This file is part of the GDB testsuite. It tests automagic loading of
# scripts specified in the .debug_gdb_scripts section.
require is_elf_target
require allow_python_tests
standard_testfile
# Make this available to gdb before the program starts, it is
# automagically loaded by gdb.
set remote_python_file [gdb_remote_download host \
${srcdir}/${subdir}/${testfile}.py]
set quoted_name "\"$remote_python_file\""
# Helper proc to 'set auto-load safe-path ...'. Build the new path value by
# joining ARGS together with an appropriate path separator character.
proc set_auto_load_safe_path { args } {
if {[ishost *-*-mingw*]} {
set remote_pathsep ";"
} else {
set remote_pathsep ":"
}
set safe_path [join $args $remote_pathsep]
gdb_test_no_output "set auto-load safe-path $safe_path" \
"set auto-load safe-path"
}
foreach_with_prefix variant {plain compressed} {
set the_testfile $testfile-$variant
set the_binfile [standard_output_file $the_testfile]
set flags [list debug \
additional_flags=-I${srcdir}/../../include \
additional_flags=-DSCRIPT_FILE=$quoted_name]
if {$variant == "compressed"} {
lappend flags additional_flags=-Wa,--compress-debug-sections=zlib-gabi
lappend flags additional_flags=-Wl,--compress-debug-sections=zlib-gabi
}
if {[build_executable "build executable" $the_testfile $srcfile $flags] == -1} {
return
}
if {$variant == "compressed"} {
set objdump_program [gdb_find_objdump]
set debug_sect [exec $objdump_program -j .debug_gdb_scripts -s "$the_binfile"]
set debug_sect_decompressed [exec $objdump_program -j .debug_gdb_scripts \
-s "$the_binfile" --decompress]
if {$debug_sect == $debug_sect_decompressed} {
fail ".debug_gdb_scripts in $the_binfile is not compressed"
}
}
clean_restart
# Try first with a restrictive safe-path.
gdb_test_no_output "set auto-load safe-path /restricted" \
"set restricted auto-load safe-path"
gdb_load ${the_binfile}
# Verify gdb did not load the scripts.
gdb_test_multiple "info auto-load python-scripts" "verify scripts not loaded" {
-re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" {
fail $gdb_test_name
}
-re -wrap "No.*${testfile}.py.*No.*inlined-script.*" {
pass $gdb_test_name
}
}
# Try again with a working safe-path.
clean_restart
# Get the name of the binfile on the host; on a remote host this means
# stripping off any directory prefix.
if {[is_remote host]} {
set remote_binfile [file tail ${the_binfile}]
} else {
set remote_binfile ${the_binfile}
}
set_auto_load_safe_path $remote_python_file $remote_binfile
gdb_load ${the_binfile}
# Verify gdb loaded each script and they appear once in the list.
gdb_test_multiple "info auto-load python-scripts" "verify scripts loaded" {
-re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" {
pass $gdb_test_name
}
-re -wrap "${testfile}.py.*${testfile}.py.*" {
fail $gdb_test_name
}
-re -wrap "inlined-script.*inlined-script.*" {
fail $gdb_test_name
}
}
# Again, with a regexp this time.
gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*"
# Again, with a regexp that matches no scripts.
gdb_test "info auto-load python-scripts no-script-matches-this" \
"No auto-load scripts matching no-script-matches-this."
if {![runto_main]} {
return
}
gdb_test "b [gdb_get_line_number {break to inspect}]" \
".*Breakpoint.*"
gdb_test "continue" ".*Breakpoint.*"
gdb_test "print ss" " = a=<1> b=<2>"
gdb_test "test-cmd 1 2 3" "test-cmd output, arg = 1 2 3"
# eu-strip creates NOBITS .debug_gdb_scripts sections in the debug
# files, and leaves a useful copy of .debug_gdb_scripts in the
# executable. Make sure the NOBITS copy in the separate debug file is
# ignored silently.
with_test_prefix "sepdebug from eu-strip" {
clean_restart
set eu_strip_binfile [standard_output_file ${the_testfile}-eu-strip]
file copy -force $the_binfile $eu_strip_binfile
set result [catch {exec eu-strip -g -f ${eu_strip_binfile}.debug ${eu_strip_binfile}} output]
verbose "result is $result"
verbose "output is $output"
if {$result != 0 || $output != ""} {
unsupported "cannot produce separate debug info files"
return
}
set_auto_load_safe_path $remote_python_file $eu_strip_binfile
gdb_test_multiple "file $eu_strip_binfile" "load sepdebug" {
-re -wrap "\r\nwarning: Invalid entry in \\.debug_gdb_scripts section.*" {
fail $gdb_test_name
}
-re -wrap "" {
pass $gdb_test_name
}
}
# Verify gdb loaded each script and they appear once in the list.
gdb_test_multiple "info auto-load python-scripts" "verify scripts loaded" {
-re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" {
pass $gdb_test_name
}
-re -wrap "${testfile}.py.*${testfile}.py.*" {
fail $gdb_test_name
}
-re -wrap "inlined-script.*inlined-script.*" {
fail $gdb_test_name
}
}
# Again, with a regexp this time.
gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*"
# Again, with a regexp that matches no scripts.
gdb_test "info auto-load python-scripts no-script-matches-this" \
"No auto-load scripts matching no-script-matches-this."
}
# Unlike eu-strip, objcopy moves the .debug_gdb_scripts into the .debug
# file, removing it from the executable. GDB should still load the
# script though, just when it loads the symbol file, not the main
# executable.
with_test_prefix "sepdebug from objcopy" {
clean_restart
set objcopy_testfile ${the_testfile}-objcopy
set objcopy_binfile [standard_output_file $objcopy_testfile]
file copy -force $the_binfile $objcopy_binfile
if { [gdb_gnu_strip_debug $objcopy_binfile] != 0 } {
fail "strip $objcopy_testfile debuginfo"
return
}
# Add the directory containing OBJCOPY_BINFILE because the scripts
# section will be auto-loaded from the separate .debug file (not the
# main executable), which resides alongside it.
set_auto_load_safe_path $remote_python_file \
[file dirname ${objcopy_binfile}]
gdb_load $objcopy_binfile
# Verify gdb loaded each script and they appear once in the list.
gdb_test_multiple "info auto-load python-scripts" "verify scripts loaded" {
-re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" {
pass $gdb_test_name
}
-re -wrap "${testfile}.py.*${testfile}.py.*" {
fail $gdb_test_name
}
-re -wrap "inlined-script.*inlined-script.*" {
fail $gdb_test_name
}
}
# Again, with a regexp this time.
gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*"
# Again, with a regexp that matches no scripts.
gdb_test "info auto-load python-scripts no-script-matches-this" \
"No auto-load scripts matching no-script-matches-this."
}
}