diff options
Diffstat (limited to 'gdb/testsuite')
1364 files changed, 24453 insertions, 8798 deletions
diff --git a/gdb/testsuite/Makefile.in b/gdb/testsuite/Makefile.in index 0d5ad90..fa2d9eb 100644 --- a/gdb/testsuite/Makefile.in +++ b/gdb/testsuite/Makefile.in @@ -386,7 +386,17 @@ check-all-boards: all $(abs_builddir)/site.exp ${abs_srcdir}/make-check-all.sh --keep-results \ --host-user "$(GDB_HOST_USERNAME)" \ --target-user "$(GDB_TARGET_USERNAME)" \ - "$(TESTS)" + "$(TESTS)" \ + result=$$?; \ + if test -d check-all; then \ + $(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh \ + `find check-all -name gdb.sum -print` > check-all/gdb.sum; \ + $(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh -L \ + `find check-all -name gdb.log -print` > check-all/gdb.log; \ + sed -n '/=== gdb Summary ===/,$$ p' check-all/gdb.sum; \ + fi; \ + exit $$result + force:; @@ -440,14 +450,15 @@ expect-read1 expect-readmore: # function, making it read one byte at a time. Running the testsuite # with this catches racy tests. read1.so: lib/read1.c - $(ECHO_CC) $(CC) -o $@ ${srcdir}/lib/read1.c -Wall -g -shared -fPIC $(CFLAGS) + $(ECHO_CC) $(CC) -o $@ ${srcdir}/lib/read1.c -Wall -g -shared -fPIC \ + $(filter-out -fsanitize=%,$(CFLAGS)) # Build the readmore.so preload library. This overrides the `read' # function, making it try harder to read more at a time. Running the # testsuite with this catches racy tests. readmore.so: lib/read1.c $(ECHO_CC) $(CC) -o $@ ${srcdir}/lib/read1.c -Wall -g -shared -fPIC \ - $(CFLAGS) -DREADMORE + $(filter-out -fsanitize=%,$(CFLAGS)) -DREADMORE # Build the read1 machinery. .PHONY: read1 readmore diff --git a/gdb/testsuite/analyze-racy-logs.py b/gdb/testsuite/analyze-racy-logs.py index e7c5647..f24bea9 100755 --- a/gdb/testsuite/analyze-racy-logs.py +++ b/gdb/testsuite/analyze-racy-logs.py @@ -62,7 +62,6 @@ sum_matcher = re.compile("^(.?(PASS|FAIL)): (.*)$") def parse_sum_line(line: str, dic: dict[str, set[str]]): """Parse a single LINE from a sumfile, and store the results in the dictionary referenced by DIC.""" - global sum_matcher line = line.rstrip() m = re.match(sum_matcher, line) @@ -96,7 +95,6 @@ def read_sum_files(files: list[str]): """Read the sumfiles (passed as a list in the FILES variable), and process each one, filling the FILES_AND_TESTS global dictionary with information about them.""" - global files_and_tests for x in files: with open(x, "r") as f: @@ -115,7 +113,6 @@ def identify_racy_tests(): This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.), and then print a sorted list (without duplicates) of all the tests that were found to be racy.""" - global files_and_tests # First, construct two dictionaries that will hold one set of # testcases for each state (PASS, FAIL, etc.). diff --git a/gdb/testsuite/boards/cc-with-dwz-5.exp b/gdb/testsuite/boards/cc-with-dwz-5.exp new file mode 100644 index 0000000..b254f91 --- /dev/null +++ b/gdb/testsuite/boards/cc-with-dwz-5.exp @@ -0,0 +1,28 @@ +# 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/>. + +# This file is a dejagnu "board file" and is used to run the testsuite +# with contrib/cc-with-tweaks.sh -5. +# +# NOTE: We assume dwz is in $PATH. +# +# Example usage: +# bash$ cd $objdir +# bash$ make check-gdb \ +# RUNTESTFLAGS='--target_board=cc-with-dwz-5' +# + +set CC_WITH_TWEAKS_FLAGS "-5" +load_board_description "cc-with-tweaks" diff --git a/gdb/testsuite/boards/native-extended-gdbserver.exp b/gdb/testsuite/boards/native-extended-gdbserver.exp index 3299e31..22d8782 100644 --- a/gdb/testsuite/boards/native-extended-gdbserver.exp +++ b/gdb/testsuite/boards/native-extended-gdbserver.exp @@ -58,7 +58,7 @@ proc mi_gdb_start { args } { global gdbserver_reconnect_p # Spawn GDB. - set res [eval extended_gdbserver_mi_gdb_start $args] + set res [extended_gdbserver_mi_gdb_start {*}$args] if { $res } { return $res } diff --git a/gdb/testsuite/gdb.ada/array_bounds.exp b/gdb/testsuite/gdb.ada/array_bounds.exp index 3675c9f..ab50da7 100644 --- a/gdb/testsuite/gdb.ada/array_bounds.exp +++ b/gdb/testsuite/gdb.ada/array_bounds.exp @@ -28,7 +28,7 @@ clean_restart ${testfile} set bp_location [gdb_get_line_number "START" ${testdir}/bar.adb] if {![runto "bar.adb:$bp_location"]} { return -} +} gdb_test "print itable'first" \ "= 2" diff --git a/gdb/testsuite/gdb.ada/array_long_idx.exp b/gdb/testsuite/gdb.ada/array_long_idx.exp new file mode 100644 index 0000000..13a4d3d --- /dev/null +++ b/gdb/testsuite/gdb.ada/array_long_idx.exp @@ -0,0 +1,36 @@ +# 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 that long array index types work. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile main + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { + return +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number STOP ${testdir}/main.adb] +if {![runto "main.adb:$bp_location"]} { + return +} + +gdb_test "print some_regular_access.all" \ + [string_to_regexp " = (-2147483648 => (-9223372036854775808 => 1, 2, 3), (-9223372036854775808 => 4, 5, 6))"] diff --git a/gdb/testsuite/gdb.ada/array_long_idx/main.adb b/gdb/testsuite/gdb.ada/array_long_idx/main.adb new file mode 100644 index 0000000..6c4971f --- /dev/null +++ b/gdb/testsuite/gdb.ada/array_long_idx/main.adb @@ -0,0 +1,31 @@ +-- 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/>. + +with Pck; use Pck; + +procedure Main is + + type Shorter_Integer is range -2147483648 .. 2147483647; + type Longer_Integer is range -9223372036854775808 .. 9223372036854775807; + type My_Array is array (Shorter_Integer range <>, + Longer_Integer range <>) of Integer; + + type My_Reg_Acc is access all My_Array; + + Some_Regular_Access : My_Reg_Acc := new My_Array'((1, 2, 3), (4, 5, 6)); + +begin + Do_Nothing (Some_Regular_Access'Address); -- STOP +end Main; diff --git a/gdb/testsuite/gdb.ada/array_long_idx/pck.adb b/gdb/testsuite/gdb.ada/array_long_idx/pck.adb new file mode 100644 index 0000000..54ddf5c --- /dev/null +++ b/gdb/testsuite/gdb.ada/array_long_idx/pck.adb @@ -0,0 +1,21 @@ +-- Copyright 2012-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/>. + +package body Pck is + procedure Do_Nothing (A : System.Address) is + begin + null; + end Do_Nothing; +end Pck; diff --git a/gdb/testsuite/gdb.ada/array_long_idx/pck.ads b/gdb/testsuite/gdb.ada/array_long_idx/pck.ads new file mode 100644 index 0000000..db7c0a8 --- /dev/null +++ b/gdb/testsuite/gdb.ada/array_long_idx/pck.ads @@ -0,0 +1,19 @@ +-- Copyright 2012-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/>. + +with System; +package Pck is + procedure Do_Nothing (A : System.Address); +end Pck; diff --git a/gdb/testsuite/gdb.ada/array_of_variant.exp b/gdb/testsuite/gdb.ada/array_of_variant.exp index 7b35bb0..84239a7 100644 --- a/gdb/testsuite/gdb.ada/array_of_variant.exp +++ b/gdb/testsuite/gdb.ada/array_of_variant.exp @@ -24,7 +24,7 @@ set old_gcc [gnat_version_compare < 8] proc gdb_test_with_xfail { cmd re re_xfail msg } { global scenario old_gcc - set have_xfail [expr $old_gcc && [string equal "$scenario" "minimal"]] + set have_xfail [expr {$old_gcc && [string equal "$scenario" "minimal"]}] gdb_test_multiple $cmd $msg { -re -wrap $re { diff --git a/gdb/testsuite/gdb.ada/array_subscript_addr/p.adb b/gdb/testsuite/gdb.ada/array_subscript_addr/p.adb index eaa35c5..057d7a0 100644 --- a/gdb/testsuite/gdb.ada/array_subscript_addr/p.adb +++ b/gdb/testsuite/gdb.ada/array_subscript_addr/p.adb @@ -14,11 +14,12 @@ -- along with this program. If not, see <http://www.gnu.org/licenses/>. procedure P is - type Table is array (1 .. 3) of Integer; + -- Make this large enough to force it into memory with gnat-llvm. + type Table is array (1 .. 15) of Integer; function Create (I : Integer) return Table is begin - return (4 + I, 8 * I, 7 * I + 4); + return (4 + I, 8 * I, 7 * I + 4, others => 72); end Create; A : Table := Create (7); diff --git a/gdb/testsuite/gdb.ada/arrayidx.exp b/gdb/testsuite/gdb.ada/arrayidx.exp index 9481d28..b29a2a7 100644 --- a/gdb/testsuite/gdb.ada/arrayidx.exp +++ b/gdb/testsuite/gdb.ada/arrayidx.exp @@ -34,7 +34,7 @@ runto "p.adb:$bp_location" gdb_test_no_output "set print array-indexes off" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print one_two_three" \ @@ -57,21 +57,21 @@ gdb_test "print p_one_two_three" \ "= \\(false, true, true\\)" \ "print p_one_two_three, indexes off" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print few_reps" \ "= \\(1, 2, 3, 3, 3, 3, 3, 4, 5\\)" \ "print few_reps, indexes off" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print many_reps" \ "= \\(1, 2, 3 <repeats 12 times>, 4, 5\\)" \ "print many_reps, indexes off" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print empty" \ @@ -82,7 +82,7 @@ gdb_test "print empty" \ gdb_test_no_output "set print array-indexes on" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print one_two_three" \ @@ -100,19 +100,19 @@ gdb_test "print u_one_two_three" \ gdb_test "print p_one_two_three" \ "= \\(one => false, two => true, three => true\\)" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print few_reps" \ "= \\(1 => 1, 2 => 2, 3 => 3, 4 => 3, 5 => 3, 6 => 3, 7 => 3, 8 => 4, 9 => 5\\)" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print many_reps" \ "= \\(1 => 1, 2 => 2, 3 => 3 <repeats 12 times>, 15 => 4, 16 => 5\\)" -if $old_gcc { +if {$old_gcc} { setup_xfail "*-*-*" } gdb_test "print empty" \ diff --git a/gdb/testsuite/gdb.ada/bp_inlined_func.exp b/gdb/testsuite/gdb.ada/bp_inlined_func.exp index 6593d1e..04cf755 100644 --- a/gdb/testsuite/gdb.ada/bp_inlined_func.exp +++ b/gdb/testsuite/gdb.ada/bp_inlined_func.exp @@ -41,8 +41,10 @@ gdb_test "break read_small" \ for {set i 0} {$i < 4} {incr i} { with_test_prefix "iteration $i" { + # gnat-llvm may emit a call to an out-of-line copy, so allow + # for this here. gdb_test "continue" \ - "Breakpoint $bkptno_num_re, b\\.read_small \\(\\).*" \ + "Breakpoint $bkptno_num_re, ($hex in )?b\\.read_small \\(\\).*" \ "stopped in read_small" } } diff --git a/gdb/testsuite/gdb.ada/call_pn.exp b/gdb/testsuite/gdb.ada/call_pn.exp index 7e01523..4d9c26e 100644 --- a/gdb/testsuite/gdb.ada/call_pn.exp +++ b/gdb/testsuite/gdb.ada/call_pn.exp @@ -38,7 +38,7 @@ if {![runto "foo.adb:$bp_location"]} { gdb_test_no_output {maint expand-symtabs "\(pck\|foo\)\.adb"} set gcc_major_version [gcc_major_version] -set have_xfail [expr $gcc_major_version >= 8 && $gcc_major_version <= 9] +set have_xfail [expr {$gcc_major_version >= 8 && $gcc_major_version <= 9}] # The xfail is for PR gcc/94469, which occurs with target board # unix/-flto/-O0/-flto-partition=none/-ffat-lto-objects and gcc-8 and later. diff --git a/gdb/testsuite/gdb.ada/complete.exp b/gdb/testsuite/gdb.ada/complete.exp index c8fcc47..18548c7 100644 --- a/gdb/testsuite/gdb.ada/complete.exp +++ b/gdb/testsuite/gdb.ada/complete.exp @@ -164,7 +164,7 @@ test_gdb_complete "external_ident" \ [multi_line "p external_identical_one" \ "p external_identical_two" ] -# Complete on the name of package. +# Complete on the name of package. test_gdb_complete "pck" \ [multi_line_with_optional \ "(p pck)?" \ diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset.exp b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp new file mode 100644 index 0000000..f8a4363 --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp @@ -0,0 +1,79 @@ +# 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/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile exam + +set flags {debug} +if {[ada_minimal_encodings]} { + lappend flags additional_flags=-fgnat-encodings=minimal +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 +} + +# GCC needs to have fixes: +# - 809b46d2ccc ("Partially lift restriction from loc_list_from_tree_1") +# - d7f24e37d4b ("Fix oversight about big-endian targets in latest change") +set have_xfail [gnat_version_compare <= {16 1}] + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb] +runto "exam.adb:$bp_location" + +set re_pass \ + [string_to_regexp \ + " = (discr => 3, array_field => (-5, -6, -7), field => -5, another_field => -6)"] +set re_xfail_le \ + [string_to_regexp \ + " = (discr => 3, array_field => (-5, -6, -7), field => -4, another_field => -4)"] +set re_xfail_be \ + [string_to_regexp \ + " = (discr => 3, array_field => (-5, -6, -7), field => -6, another_field => -6)"] + +gdb_test_multiple "print spr" "" { + -re -wrap $re_pass { + pass $gdb_test_name + } + -re -wrap $re_xfail_le|$re_xfail_be { + if { $have_xfail } { + xfail $gdb_test_name + } else { + fail $gdb_test_name + } + } +} + +set re_pass " = -5" +set re_xfail_le " = -4" +set re_xfail_be " = -6" + +gdb_test_multiple "print spr.field" "" { + -re -wrap $re_pass { + pass $gdb_test_name + } + -re -wrap $re_xfail_le|$re_xfail_be { + if { $have_xfail } { + xfail $gdb_test_name + } else { + fail $gdb_test_name + } + } +} diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb new file mode 100644 index 0000000..5c7f70b --- /dev/null +++ b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb @@ -0,0 +1,45 @@ +-- 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/>. + +procedure Exam is + type Small is range -7 .. -4; + for Small'Size use 2; + + type Packed_Array is array (Integer range <>) of Small; + pragma pack (Packed_Array); + + subtype Range_Int is Natural range 0 .. 7; + + type Some_Packed_Record (Discr : Range_Int := 3) is record + Array_Field : Packed_Array (1 .. Discr); + Field: Small; + case Discr is + when 3 => + Another_Field : Small; + when others => + null; + end case; + end record; + pragma Pack (Some_Packed_Record); + pragma No_Component_Reordering (Some_Packed_Record); + + SPR : Some_Packed_Record := (Discr => 3, + Field => -5, + Another_Field => -6, + Array_Field => (-5, -6, -7)); + +begin + null; -- STOP +end Exam; diff --git a/gdb/testsuite/gdb.ada/exec_changed.exp b/gdb/testsuite/gdb.ada/exec_changed.exp index c52757e..31add11 100644 --- a/gdb/testsuite/gdb.ada/exec_changed.exp +++ b/gdb/testsuite/gdb.ada/exec_changed.exp @@ -84,7 +84,7 @@ if { [gdb_start_cmd] < 0 } { # Try again, this time with just changing the file time of first. -clean_restart "${binfile}$EXEEXT" +clean_restart "${::testfile}$EXEEXT" # Ensure we don't accidentally use the main symbol cache. gdb_test_no_output "mt set symbol-cache-size 0" diff --git a/gdb/testsuite/gdb.ada/extended-access.c b/gdb/testsuite/gdb.ada/extended-access.c new file mode 100644 index 0000000..9a1b299 --- /dev/null +++ b/gdb/testsuite/gdb.ada/extended-access.c @@ -0,0 +1,38 @@ +/* This test program 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/>. */ + +int array_data[] = { 23, 24, 25, 26, 27 }; + +struct bounds +{ + int LB0; + int UB0; +}; + +struct extended_access_ptr +{ + int (*P_ARRAY)[]; + struct bounds BOUNDS; +}; + +struct extended_access_ptr the_array = { &array_data, { 93, 97 } }; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.ada/extended-access.exp b/gdb/testsuite/gdb.ada/extended-access.exp new file mode 100644 index 0000000..7c02ad7 --- /dev/null +++ b/gdb/testsuite/gdb.ada/extended-access.exp @@ -0,0 +1,29 @@ +# 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/>. + +require allow_ada_tests + +standard_testfile + +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { + return +} + +# The test case is written in C, because it was easy to make the +# required type there without requiring a new version of GNAT. +gdb_test_no_output "set lang ada" + +gdb_test "print the_array.all" \ + [string_to_regexp " = (93 => 23, 24, 25, 26, 27)"] diff --git a/gdb/testsuite/gdb.ada/file-then-restart.exp b/gdb/testsuite/gdb.ada/file-then-restart.exp index faa9962..6e8e058 100644 --- a/gdb/testsuite/gdb.ada/file-then-restart.exp +++ b/gdb/testsuite/gdb.ada/file-then-restart.exp @@ -36,7 +36,7 @@ if {[gdb_compile_ada "${srcfile2}" "${binfile2}" executable {debug}] != ""} { } foreach_with_prefix scenario {kill no-kill} { - clean_restart $binfile + clean_restart $::testfile # Start the program, we should land in the program main procedure if {[gdb_start_cmd] < 0} { diff --git a/gdb/testsuite/gdb.ada/finish-var-size.exp b/gdb/testsuite/gdb.ada/finish-var-size.exp index e038ed4..6365c95 100644 --- a/gdb/testsuite/gdb.ada/finish-var-size.exp +++ b/gdb/testsuite/gdb.ada/finish-var-size.exp @@ -22,7 +22,13 @@ require {expr [gcc_major_version] >= 12} standard_ada_testfile p -if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != ""} { +set opts {} +lappend opts debug +if { [ada_fvar_tracking] } { + lappend opts additional_flags=-fvar-tracking +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $opts] != ""} { return -1 } diff --git a/gdb/testsuite/gdb.ada/fixed_points.exp b/gdb/testsuite/gdb.ada/fixed_points.exp index 8bb9e10..0e65004 100644 --- a/gdb/testsuite/gdb.ada/fixed_points.exp +++ b/gdb/testsuite/gdb.ada/fixed_points.exp @@ -90,6 +90,10 @@ foreach_gnat_encoding scenario flags {all minimal} { # This only started working in GCC 11. if {$scenario == "minimal" && [gnat_version_compare >= 11]} { gdb_test "print fp5_var" " = 3e-19" + + gdb_test "print Float(Object_Fixed) = Float(Semicircle_Delta * 5)" \ + " = true" \ + "examine object_fixed" } # This failed before GCC 10. diff --git a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb index adab614..94a41b9 100644 --- a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb +++ b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb @@ -64,6 +64,12 @@ procedure Fixed_Points is for Another_Type'size use 64; Another_Fixed : Another_Type := Another_Delta * 5; + Semicircle_Delta : constant := 1.0/(2**31); + type Semicircle_Type is delta Semicircle_Delta range -1.0 .. (1.0 - Semicircle_Delta); + for Semicircle_Type'small use Semicircle_Delta; + for Semicircle_Type'size use 32; + Object_Fixed : Semicircle_Type := Semicircle_Delta * 5; + begin Base_Object := 1.0/16.0; -- Set breakpoint here Subtype_Object := 1.0/16.0; @@ -75,4 +81,5 @@ begin Do_Nothing (FP4_Var'Address); Do_Nothing (FP5_Var'Address); Do_Nothing (Another_Fixed'Address); + Do_Nothing (Object_Fixed'Address); end Fixed_Points; diff --git a/gdb/testsuite/gdb.ada/formatted_ref.exp b/gdb/testsuite/gdb.ada/formatted_ref.exp index c63f847..d473554 100644 --- a/gdb/testsuite/gdb.ada/formatted_ref.exp +++ b/gdb/testsuite/gdb.ada/formatted_ref.exp @@ -16,8 +16,8 @@ # Author: P. N. Hilfinger, AdaCore Inc. # Note: This test is essentially a transcription of gdb.cp/formatted-ref.exp, -# and is thus much more wordy than it needs to be. There are fewer -# tests because only a few parameter types in Ada are required to be +# and is thus much more wordy than it needs to be. There are fewer +# tests because only a few parameter types in Ada are required to be # passed by reference, and there is no equivalent of &(&x) for reference # values. # This also tests that some other arithmetic operations on references @@ -54,7 +54,7 @@ proc test_p_x { var val addr } { gdb_test_multiple "$test" $test { -re "\\$\[0-9\]+ = [string_to_regexp $val].*$gdb_prompt $" { pass $test - } + } -re "\\$\[0-9\]+ = $addr.*$gdb_prompt $" { fail "$test (prints just address)" } diff --git a/gdb/testsuite/gdb.ada/frame_args.exp b/gdb/testsuite/gdb.ada/frame_args.exp index 4ffc3d1..e6cf868 100644 --- a/gdb/testsuite/gdb.ada/frame_args.exp +++ b/gdb/testsuite/gdb.ada/frame_args.exp @@ -32,7 +32,7 @@ set sp "\[ \t\]*" if {![runto break_me]} { return -} +} # First, print all the arrays without indexes diff --git a/gdb/testsuite/gdb.ada/fun_in_declare.exp b/gdb/testsuite/gdb.ada/fun_in_declare.exp index 9ababcf..a5f6f63 100644 --- a/gdb/testsuite/gdb.ada/fun_in_declare.exp +++ b/gdb/testsuite/gdb.ada/fun_in_declare.exp @@ -27,7 +27,7 @@ clean_restart ${testfile} if {![runto_main]} { return -} +} # Some variables used to simplify the maintenance of some of # the regular expressions below. diff --git a/gdb/testsuite/gdb.ada/huge.exp b/gdb/testsuite/gdb.ada/huge.exp index 9a86804..fa94fa0 100644 --- a/gdb/testsuite/gdb.ada/huge.exp +++ b/gdb/testsuite/gdb.ada/huge.exp @@ -34,7 +34,7 @@ set opts {} lappend opts debug set compilation_succeeded 0 -for { set size $max } { $size >= $min } { set size [expr $size / 2] } { +for { set size $max } { $size >= $min } { set size [expr {$size / 2}] } { set try_opts [concat $opts [list additional_flags=-gnateDCRASHGDB=$size]] # Use gdb_compile_ada_1 to prevent failed compilations from producing a # FAIL. diff --git a/gdb/testsuite/gdb.ada/import.exp b/gdb/testsuite/gdb.ada/import.exp index ab3a1c9..51ce7fa 100644 --- a/gdb/testsuite/gdb.ada/import.exp +++ b/gdb/testsuite/gdb.ada/import.exp @@ -54,6 +54,9 @@ gdb_test "print pkg.imported_var_ada" " = 42" gdb_test "print pkg.exported_var_ada" " = 99" gdb_test "print exported_var_ada" " = 99" +gdb_breakpoint "local_imported_func" message +gdb_test "print copy" " = 42" + # This passes with gcc 10 but fails with gcc 9. With gcc 9, we have: # <1><1659>: Abbrev Number: 4 (DW_TAG_subprogram) # <165a> DW_AT_external : 1 @@ -76,19 +79,16 @@ gdb_test "print exported_var_ada" " = 99" # The fact that things start to work when adding the DW_AT_declaration is # consistent with what is described in commit ff9baa5f1c5, so xfail this # (without pinpointing it to a specific gcc PR or commit). -if { [gcc_major_version] < 10 } { - setup_xfail *-*-* -} -gdb_breakpoint "pkg.imported_func_ada" message -gdb_breakpoint "imported_func" message -if { [gcc_major_version] < 10 } { - setup_xfail *-*-* +foreach func {"pkg.imported_func_ada" "imported_func"} { + clean_restart $testfile + if { [gcc_major_version] < 10 } { + setup_xfail *-*-* + } + gdb_breakpoint $func message } -gdb_breakpoint "imported_func_ada" message -gdb_breakpoint "local_imported_func" message -gdb_breakpoint "pkg.exported_func_ada" message -gdb_breakpoint "exported_func_ada" message -gdb_breakpoint "exported_func" message - -gdb_test "print copy" " = 42" +foreach func {"imported_func_ada" "pkg.exported_func_ada" \ + "exported_func_ada" "exported_func"} { + clean_restart $testfile + gdb_breakpoint $func message +} diff --git a/gdb/testsuite/gdb.ada/limited-length.exp b/gdb/testsuite/gdb.ada/limited-length.exp index 7172c37..a5001fa 100644 --- a/gdb/testsuite/gdb.ada/limited-length.exp +++ b/gdb/testsuite/gdb.ada/limited-length.exp @@ -70,7 +70,7 @@ with_test_prefix "with standard max-value size" { # Set the max-value-size so we can only print 33 elements. set elements 33 set elem_size [get_valueof "/d" "(Large_1d_Array(1)'Size + 7) / 8" "*unknown*"] -gdb_test_no_output "set max-value-size [expr $elem_size * $elements]" +gdb_test_no_output "set max-value-size [expr {$elem_size * $elements}]" with_test_prefix "with reduced max-value size" { # GNAT historically named this type, but as the array type is diff --git a/gdb/testsuite/gdb.ada/mi_catch_assert.exp b/gdb/testsuite/gdb.ada/mi_catch_assert.exp index 1b4609a..c3dbfca 100644 --- a/gdb/testsuite/gdb.ada/mi_catch_assert.exp +++ b/gdb/testsuite/gdb.ada/mi_catch_assert.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile ################################################### # 2. Try catching conditionnal failed assertion. # diff --git a/gdb/testsuite/gdb.ada/mi_catch_ex.exp b/gdb/testsuite/gdb.ada/mi_catch_ex.exp index da3d340..0837028 100644 --- a/gdb/testsuite/gdb.ada/mi_catch_ex.exp +++ b/gdb/testsuite/gdb.ada/mi_catch_ex.exp @@ -30,7 +30,7 @@ set any_nb "\[0-9\]+" load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile #################################### # 1. Try catching all exceptions. # diff --git a/gdb/testsuite/gdb.ada/mi_catch_ex_hand.exp b/gdb/testsuite/gdb.ada/mi_catch_ex_hand.exp index 00e8f6e..0c50f59 100644 --- a/gdb/testsuite/gdb.ada/mi_catch_ex_hand.exp +++ b/gdb/testsuite/gdb.ada/mi_catch_ex_hand.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile ############################################# # 1. Try catching all exceptions handlers. # diff --git a/gdb/testsuite/gdb.ada/mi_dyn_arr.exp b/gdb/testsuite/gdb.ada/mi_dyn_arr.exp index c0e9f7f..b01f3e9 100644 --- a/gdb/testsuite/gdb.ada/mi_dyn_arr.exp +++ b/gdb/testsuite/gdb.ada/mi_dyn_arr.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_ex_cond.exp b/gdb/testsuite/gdb.ada/mi_ex_cond.exp index 53ace22..43caf76 100644 --- a/gdb/testsuite/gdb.ada/mi_ex_cond.exp +++ b/gdb/testsuite/gdb.ada/mi_ex_cond.exp @@ -30,7 +30,7 @@ set any_nb "\[0-9\]+" load_lib mi-support.exp set MIFLAGS "-i=mi" -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.ada/mi_exc_info.exp b/gdb/testsuite/gdb.ada/mi_exc_info.exp index b9d0072..a95fb23 100644 --- a/gdb/testsuite/gdb.ada/mi_exc_info.exp +++ b/gdb/testsuite/gdb.ada/mi_exc_info.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_interface.exp b/gdb/testsuite/gdb.ada/mi_interface.exp index 630353d..f25adf0 100644 --- a/gdb/testsuite/gdb.ada/mi_interface.exp +++ b/gdb/testsuite/gdb.ada/mi_interface.exp @@ -28,7 +28,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_prot.exp b/gdb/testsuite/gdb.ada/mi_prot.exp index 7f68ca8..4edc93b 100644 --- a/gdb/testsuite/gdb.ada/mi_prot.exp +++ b/gdb/testsuite/gdb.ada/mi_prot.exp @@ -28,7 +28,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \ load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_ref_changeable.exp b/gdb/testsuite/gdb.ada/mi_ref_changeable.exp index 315e2b3..c69f615 100644 --- a/gdb/testsuite/gdb.ada/mi_ref_changeable.exp +++ b/gdb/testsuite/gdb.ada/mi_ref_changeable.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_string_access.exp b/gdb/testsuite/gdb.ada/mi_string_access.exp index 25c0490..e29e17d 100644 --- a/gdb/testsuite/gdb.ada/mi_string_access.exp +++ b/gdb/testsuite/gdb.ada/mi_string_access.exp @@ -29,7 +29,7 @@ foreach_gnat_encoding scenario flags {all minimal} { return -1 } - mi_clean_restart $binfile-$scenario + mi_clean_restart $::testfile-$scenario if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_task_arg.exp b/gdb/testsuite/gdb.ada/mi_task_arg.exp index 018e3bc..6c222ff 100644 --- a/gdb/testsuite/gdb.ada/mi_task_arg.exp +++ b/gdb/testsuite/gdb.ada/mi_task_arg.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional load_lib mi-support.exp set MIFLAGS "-i=mi" -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.ada/mi_task_info.exp b/gdb/testsuite/gdb.ada/mi_task_info.exp index aa05a02..9895cfe 100644 --- a/gdb/testsuite/gdb.ada/mi_task_info.exp +++ b/gdb/testsuite/gdb.ada/mi_task_info.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional load_lib mi-support.exp set MIFLAGS "-i=mi" -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.ada/mi_var_access.exp b/gdb/testsuite/gdb.ada/mi_var_access.exp index 9bfaeff..b595780 100644 --- a/gdb/testsuite/gdb.ada/mi_var_access.exp +++ b/gdb/testsuite/gdb.ada/mi_var_access.exp @@ -26,7 +26,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != "" } { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_var_array.exp b/gdb/testsuite/gdb.ada/mi_var_array.exp index a04673c..0ba90e7 100644 --- a/gdb/testsuite/gdb.ada/mi_var_array.exp +++ b/gdb/testsuite/gdb.ada/mi_var_array.exp @@ -29,7 +29,7 @@ foreach_gnat_encoding scenario flags {none all minimal} { return -1 } - mi_clean_restart $binfile-$scenario + mi_clean_restart $::testfile-$scenario if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_var_union.exp b/gdb/testsuite/gdb.ada/mi_var_union.exp index 99882cf..b198800 100644 --- a/gdb/testsuite/gdb.ada/mi_var_union.exp +++ b/gdb/testsuite/gdb.ada/mi_var_union.exp @@ -31,7 +31,7 @@ foreach_gnat_encoding scenario flags {none all minimal} { return -1 } - mi_clean_restart $binfile-$scenario + mi_clean_restart $::testfile-$scenario if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mi_variant.exp b/gdb/testsuite/gdb.ada/mi_variant.exp index 4c71f16..18693ce 100644 --- a/gdb/testsuite/gdb.ada/mi_variant.exp +++ b/gdb/testsuite/gdb.ada/mi_variant.exp @@ -30,7 +30,7 @@ foreach_gnat_encoding scenario flags {none all minimal} { return -1 } - mi_clean_restart $binfile-$scenario + mi_clean_restart $::testfile-$scenario if {[mi_runto_main] < 0} { return 0 diff --git a/gdb/testsuite/gdb.ada/mod_from_name.exp b/gdb/testsuite/gdb.ada/mod_from_name.exp index 6384f39..e97eb5a 100644 --- a/gdb/testsuite/gdb.ada/mod_from_name.exp +++ b/gdb/testsuite/gdb.ada/mod_from_name.exp @@ -31,7 +31,7 @@ foreach_gnat_encoding scenario flags {all minimal} { set bp_location [gdb_get_line_number "START" ${testdir}/foo.adb] if {![runto "foo.adb:$bp_location"]} { return - } + } # GNAT 9 and 10 are known to fail. if {$scenario == "minimal" diff --git a/gdb/testsuite/gdb.ada/negative-bit-offset.exp b/gdb/testsuite/gdb.ada/negative-bit-offset.exp new file mode 100644 index 0000000..c5fcae1 --- /dev/null +++ b/gdb/testsuite/gdb.ada/negative-bit-offset.exp @@ -0,0 +1,36 @@ +# 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 negative DW_AT_bit_offset. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile prog + +# This particular output is only generated with -gdwarf-4. +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \ + {debug additional_flags=-gdwarf-4}] != ""} { + return +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/prog.adb] +runto "prog.adb:$bp_location" + +gdb_test "print xp" \ + [string_to_regexp "(x => 21, y => (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10))"] diff --git a/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb b/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb new file mode 100644 index 0000000..e3c1775 --- /dev/null +++ b/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb @@ -0,0 +1,36 @@ +-- 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/>. + +procedure Prog is + + type Small is range -32 .. 31; + for Small'Size use 6; + + type SomeArray is array (POSITIVE range <>) of Small; + + type SomePackedArray is array (POSITIVE range <>) of Small; + pragma Pack (SomePackedArray); + + type SomePackedRecord is record + X: Small; + Y: SomePackedArray (1 .. 10); + end record; + pragma Pack (SomePackedRecord); + + XP: SomePackedRecord := (21, (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10)); + +begin + null; -- STOP +end; diff --git a/gdb/testsuite/gdb.ada/null_array.exp b/gdb/testsuite/gdb.ada/null_array.exp index 82c1923..851a0a6 100644 --- a/gdb/testsuite/gdb.ada/null_array.exp +++ b/gdb/testsuite/gdb.ada/null_array.exp @@ -30,7 +30,7 @@ runto "foo.adb:$bp_location" if {[gnat_version_compare <= {4 4}]} { # Ada array bounds are missing in older GCCs. - setup_xfail *-*-* + setup_xfail *-*-* } gdb_test "print my_table" \ "= \\(\\)" diff --git a/gdb/testsuite/gdb.ada/null_overload/foo.adb b/gdb/testsuite/gdb.ada/null_overload/foo.adb index 002238f..55d3fd6 100644 --- a/gdb/testsuite/gdb.ada/null_overload/foo.adb +++ b/gdb/testsuite/gdb.ada/null_overload/foo.adb @@ -13,6 +13,8 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. +with pck; use pck; + procedure Foo is type R_Type is null record; @@ -38,5 +40,5 @@ procedure Foo is U_Ptr : U_P_T := null; begin - null; -- START + Do_Nothing (U_Ptr'Address); -- START end Foo; diff --git a/gdb/testsuite/gdb.ada/null_overload/pck.adb b/gdb/testsuite/gdb.ada/null_overload/pck.adb new file mode 100644 index 0000000..95bd90a --- /dev/null +++ b/gdb/testsuite/gdb.ada/null_overload/pck.adb @@ -0,0 +1,23 @@ +-- Copyright 2020-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/>. + +package body Pck is + + procedure Do_Nothing (A : System.Address) is + begin + null; + end Do_Nothing; + +end Pck; diff --git a/gdb/testsuite/gdb.ada/null_overload/pck.ads b/gdb/testsuite/gdb.ada/null_overload/pck.ads new file mode 100644 index 0000000..114aee0 --- /dev/null +++ b/gdb/testsuite/gdb.ada/null_overload/pck.ads @@ -0,0 +1,22 @@ +-- Copyright 2020-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/>. + +with System; + +package Pck is + + procedure Do_Nothing (A : System.Address); + +end Pck; diff --git a/gdb/testsuite/gdb.ada/operator_call.exp b/gdb/testsuite/gdb.ada/operator_call.exp index e96107b..dc7f679 100644 --- a/gdb/testsuite/gdb.ada/operator_call.exp +++ b/gdb/testsuite/gdb.ada/operator_call.exp @@ -71,6 +71,12 @@ proc test_with_menu {command result} { fail $command } } + "Argument to arithmetic operation not a number or boolean." { + fail $command + } + -re "No definition of \".*\" in current context." { + fail $command + } timeout { fail "$command (timeout)" } diff --git a/gdb/testsuite/gdb.ada/packed_record_2.exp b/gdb/testsuite/gdb.ada/packed_record_2.exp new file mode 100644 index 0000000..d0bcdbd --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2.exp @@ -0,0 +1,61 @@ +# 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/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile exam + +set flags {debug} +if {[ada_minimal_encodings]} { + lappend flags additional_flags=-fgnat-encodings=minimal +} + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb] +runto "exam.adb:$bp_location" + +set spr_contents "discr => 3, field => -4, array_field => \\(-5, -6, -7\\)" + +gdb_test "print spr" " = \\($spr_contents\\)" + +gdb_test "print spr.discr" " = 3" + +# See PR ada/32880 -- gdb should probably print array (1 .. 3) here, +# but instead shows array (<>). However as this isn't totally +# relevant to this test, we just accept it. +gdb_test "ptype spr" \ + [multi_line \ + "type = tagged record" \ + " discr: range 1 .. 8;" \ + " field: range -7 .. -4;" \ + " array_field: array \\(<>\\) of exam.small <packed: 2-bit elements>;" \ + "end record"] + +gdb_test_multiple "print sc" "" { + -re " \\($spr_contents, outer => 2, another_array => \\(-7, -6\\)\\)" { + pass $gdb_test_name + } + -re " \\($spr_contents, outer => $decimal, another_array => \\(.*\\)\\)" { + # Other output is a known GCC bug. + xfail $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.ada/packed_record_2/exam.adb b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb new file mode 100644 index 0000000..e528ecf --- /dev/null +++ b/gdb/testsuite/gdb.ada/packed_record_2/exam.adb @@ -0,0 +1,51 @@ +-- 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/>. + +procedure Exam is + type Small is range -7 .. -4; + for Small'Size use 2; + + type Range_Int is range 1 .. 8; + for Range_Int'Size use 3; + + type Packed_Array is array (Range_Int range <>) of Small; + pragma pack (Packed_Array); + + type Some_Packed_Record (Discr : Range_Int) is tagged record + Field: Small; + Array_Field : Packed_Array (1 .. Discr); + end record; + pragma Pack (Some_Packed_Record); + + type Sub_Class (Inner, Outer : Range_Int) + is new Some_Packed_Record (Inner) with + record + Another_Array : Packed_Array (1 .. Outer); + end record; + pragma Pack (Sub_Class); + + SPR : Some_Packed_Record := (Discr => 3, + Field => -4, + Array_Field => (-5, -6, -7)); + + SC : Sub_Class := (Inner => 3, + Outer => 2, + Field => -4, + Array_Field => (-5, -6, -7), + Another_Array => (-7, -6)); + +begin + null; -- STOP +end Exam; diff --git a/gdb/testsuite/gdb.ada/ref_param.exp b/gdb/testsuite/gdb.ada/ref_param.exp index d1d8960..1ae1d97 100644 --- a/gdb/testsuite/gdb.ada/ref_param.exp +++ b/gdb/testsuite/gdb.ada/ref_param.exp @@ -27,7 +27,7 @@ clean_restart ${testfile} if {![runto pck.adb:20]} { return -} +} gdb_test_no_output "set print frame-arguments all" diff --git a/gdb/testsuite/gdb.ada/return-small-char-array.exp b/gdb/testsuite/gdb.ada/return-small-char-array.exp new file mode 100644 index 0000000..75c781e --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array.exp @@ -0,0 +1,40 @@ +# 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/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile proc + +if { [gdb_compile_ada $srcfile $binfile executable debug] != "" } { + return -1 +} + +clean_restart $testfile + +set bp_location [gdb_get_line_number "STOP" $testdir/proc.adb] +runto "proc.adb:$bp_location" + +gdb_test "print Value.Name(My_Value)" \ + { = "abcd"} + +# Step into the function. +gdb_test "step 2" \ + "return Of_Value;" + +# and finish. +gdb_test "finish" \ + { = "abcd"} diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb b/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb new file mode 100644 index 0000000..b18d9fe --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb @@ -0,0 +1,22 @@ +-- 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/>. + +with Value; +procedure Proc is + My_Value : Value.T := "abcd"; +begin + null; -- STOP + My_Value := Value.Name(My_Value); +end; diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/value.adb b/gdb/testsuite/gdb.ada/return-small-char-array/value.adb new file mode 100644 index 0000000..2dd9faa --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/value.adb @@ -0,0 +1,21 @@ +-- 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/>. + +package body Value is + function Name (Of_Value : T) return T is + begin + return Of_Value; + end Name; +end Value; diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/value.ads b/gdb/testsuite/gdb.ada/return-small-char-array/value.ads new file mode 100644 index 0000000..16b171e --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/value.ads @@ -0,0 +1,20 @@ +-- 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/>. + +package Value is + type T is new String (1 .. 4); + + function Name (Of_Value : T) return T; +end; diff --git a/gdb/testsuite/gdb.ada/scalar_storage.exp b/gdb/testsuite/gdb.ada/scalar_storage.exp index 52a85cd..a380541 100644 --- a/gdb/testsuite/gdb.ada/scalar_storage.exp +++ b/gdb/testsuite/gdb.ada/scalar_storage.exp @@ -48,7 +48,7 @@ if {![runto "storage.adb:$bp_location"]} { set re "value => 126, another_value => 12, color => green" # This requires a compiler fix that is in GCC 14. -set have_xfail [expr ![gnat_version_compare >= 14]] +set have_xfail [expr {![gnat_version_compare >= 14]}] set re_color "(red|green|blue|$decimal)" set re_xfail \ "value => $decimal, another_value => $decimal, color => $re_color" diff --git a/gdb/testsuite/gdb.ada/taft_type.exp b/gdb/testsuite/gdb.ada/taft_type.exp index ac7b258..875718f 100644 --- a/gdb/testsuite/gdb.ada/taft_type.exp +++ b/gdb/testsuite/gdb.ada/taft_type.exp @@ -28,7 +28,7 @@ clean_restart ${testfile} set bp_location [gdb_get_line_number "START" ${testdir}/p.adb] if {![runto "p.adb:$bp_location"]} { return -} +} gdb_test "print w.e.all" \ "= \\(month => 8, year => 1974\\)" diff --git a/gdb/testsuite/gdb.ada/task_switch_in_core.exp b/gdb/testsuite/gdb.ada/task_switch_in_core.exp index 3aafc2b..bded377 100644 --- a/gdb/testsuite/gdb.ada/task_switch_in_core.exp +++ b/gdb/testsuite/gdb.ada/task_switch_in_core.exp @@ -15,7 +15,7 @@ load_lib "ada.exp" -require allow_ada_tests +require allow_ada_tests gcore_cmd_available standard_ada_testfile crash diff --git a/gdb/testsuite/gdb.ada/type-tick-size/prog.adb b/gdb/testsuite/gdb.ada/type-tick-size/prog.adb index 34a9fca..a7457fd 100644 --- a/gdb/testsuite/gdb.ada/type-tick-size/prog.adb +++ b/gdb/testsuite/gdb.ada/type-tick-size/prog.adb @@ -50,6 +50,8 @@ procedure Prog is Rec_Type_Size : Integer := Rec'Object_Size; begin + Do_Nothing (Simple_Val'Address); + Do_Nothing (Rec_Val'Address); Do_Nothing (Static_Blob'Address); Do_Nothing (Dynamic_Blob'Address); null; -- STOP diff --git a/gdb/testsuite/gdb.ada/unchecked_union.exp b/gdb/testsuite/gdb.ada/unchecked_union.exp index 89c0593..5d29e28b 100644 --- a/gdb/testsuite/gdb.ada/unchecked_union.exp +++ b/gdb/testsuite/gdb.ada/unchecked_union.exp @@ -26,7 +26,7 @@ proc multi_line_string {str} { foreach line [split $str \n] { lappend result [string_to_regexp $line] } - return [eval multi_line $result] + return [multi_line {*}$result] } set inner_string { case ? is diff --git a/gdb/testsuite/gdb.ada/var_arr_typedef/pack.adb b/gdb/testsuite/gdb.ada/var_arr_typedef/pack.adb index 2f9114a..80cfac1 100644 --- a/gdb/testsuite/gdb.ada/var_arr_typedef/pack.adb +++ b/gdb/testsuite/gdb.ada/var_arr_typedef/pack.adb @@ -20,6 +20,6 @@ package body Pack is return I; end Identity; - procedure Do_Nothing (A : Array_Type) is null; + procedure Do_Nothing (A : System.Address) is null; end Pack; diff --git a/gdb/testsuite/gdb.ada/var_arr_typedef/pack.ads b/gdb/testsuite/gdb.ada/var_arr_typedef/pack.ads index 2ceb071..353ec48 100644 --- a/gdb/testsuite/gdb.ada/var_arr_typedef/pack.ads +++ b/gdb/testsuite/gdb.ada/var_arr_typedef/pack.ads @@ -13,6 +13,8 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. +with System; use System; + package Pack is type Rec_Type is record I : Integer; @@ -23,7 +25,7 @@ package Pack is type Array_Type is array (Positive range <>) of Vec_Type; - procedure Do_Nothing (A : Array_Type); + procedure Do_Nothing (A : System.Address); function Identity (I : Integer) return Integer; end Pack; diff --git a/gdb/testsuite/gdb.ada/var_arr_typedef/var_arr_typedef.adb b/gdb/testsuite/gdb.ada/var_arr_typedef/var_arr_typedef.adb index 4a7f4cb..86609a8 100644 --- a/gdb/testsuite/gdb.ada/var_arr_typedef/var_arr_typedef.adb +++ b/gdb/testsuite/gdb.ada/var_arr_typedef/var_arr_typedef.adb @@ -24,5 +24,5 @@ procedure Var_Arr_Typedef is A : constant Array_Type (1 .. Identity (4)) := (VA, VA, VB, VB); begin - Do_Nothing (A); -- BREAK + Do_Nothing (A'Address); -- BREAK end Var_Arr_Typedef; diff --git a/gdb/testsuite/gdb.ada/verylong.exp b/gdb/testsuite/gdb.ada/verylong.exp index e695ddd..de5fd04 100644 --- a/gdb/testsuite/gdb.ada/verylong.exp +++ b/gdb/testsuite/gdb.ada/verylong.exp @@ -44,10 +44,10 @@ gdb_test_multiple "ptype Long_Long_Long_Integer" "" { require {expr $lll_int_size == 8 || $lll_int_size == 16} gdb_test "print x" " = $max" -gdb_test "print x / 2" " = [expr $max / 2]" -gdb_test "print (x / 4) * 2" " = [expr ($max / 4) * 2]" +gdb_test "print x / 2" " = [expr {$max / 2}]" +gdb_test "print (x / 4) * 2" " = [expr {($max / 4) * 2}]" gdb_test "print x - x" " = 0" -gdb_test "print x - 99 + 1" " = [expr $max - 99 + 1]" +gdb_test "print x - 99 + 1" " = [expr {$max - 99 + 1}]" gdb_test "print -x" " = -$max" gdb_test "print +x" " = $max" diff --git a/gdb/testsuite/gdb.ada/whatis_array_val.exp b/gdb/testsuite/gdb.ada/whatis_array_val.exp index 2ccac34..becc9b8 100644 --- a/gdb/testsuite/gdb.ada/whatis_array_val.exp +++ b/gdb/testsuite/gdb.ada/whatis_array_val.exp @@ -28,7 +28,7 @@ clean_restart ${testfile} set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] if {![runto "foo.adb:$bp_location"]} { return -} +} # Accept "foo." prefix for older versions of GNAT. gdb_test "whatis full" \ diff --git a/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.c b/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.c new file mode 100644 index 0000000..44ed3e8 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.c @@ -0,0 +1,62 @@ +/* Copyright 2025 Free Software Foundation, Inc. + + This file is part of GDB. + + 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/>. */ + +volatile void dummy () {} + +long test_function(void) +{ + __asm__ volatile ( + /* Zero d0 (64-bit vector register part of v0). */ + "movi d0, #0\n\t" + + /* Move the frame pointer (x29) to d0 using fmov. */ + "fmov d0, x29\n\t" + + /* Describe CFI: Frame pointer is now in d0. */ + ".cfi_register x29, d0\n\t" + + /* Clobber list: Specify all modified registers. */ + : /* No output operands. */ + : /* No input operands. */ + : "d0" + ); + + dummy (); /* break-here */ + + __asm__ volatile ( + /* Restore the frame pointer (x29) from d0 using fmov. */ + "fmov x29, d0\n\t" + + /* Describe CFI: Frame pointer is restored. */ + ".cfi_restore x29\n\t" + + /* Clobber list: Specify all modified registers. */ + : /* No output operands. */ + : /* No input operands. */ + : "x29", "d0" + ); + + return 0; +} + +int +main () +{ + long result = test_function (); + dummy (); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.exp b/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.exp new file mode 100644 index 0000000..2d710bc --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-frameptr-vecreg-unwind.exp @@ -0,0 +1,33 @@ +# 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/>. + +require is_aarch64_target + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile}" {debug}] } { + return -1 +} + +if {![runto_main]} { + return +} + +gdb_breakpoint [gdb_get_line_number "break-here"] +gdb_continue_to_breakpoint "break-here" +gdb_test "with confirm off --return -1" "result = test_function \\(\\);" +gdb_test "step" "dummy \\(\\);" +gdb_test "print result" "= -1" diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-core.c b/gdb/testsuite/gdb.arch/aarch64-gcs-core.c new file mode 100644 index 0000000..f3362cb --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-core.c @@ -0,0 +1,123 @@ +/* This test program 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/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/auxv.h> +#include <linux/prctl.h> +#include <sys/syscall.h> + +/* Feature check for Guarded Control Stack. */ +#ifndef HWCAP_GCS +#define HWCAP_GCS (1ULL << 32) +#endif + +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#define PR_SET_SHADOW_STACK_STATUS 75 +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#endif + +/* We need to use a macro to call prctl because after GCS is enabled, it's not + possible to return from the function which enabled it. This is because the + return address of the calling function isn't on the GCS. */ +#define my_syscall2(num, arg1, arg2) \ + ({ \ + register long _num __asm__("x8") = (num); \ + register long _arg1 __asm__("x0") = (long)(arg1); \ + register long _arg2 __asm__("x1") = (long)(arg2); \ + register long _arg3 __asm__("x2") = 0; \ + register long _arg4 __asm__("x3") = 0; \ + register long _arg5 __asm__("x4") = 0; \ + \ + __asm__ volatile ("svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc"); \ + _arg1; \ + }) + +#define get_gcspr(void) \ + ({ \ + unsigned long *gcspr; \ + \ + /* Get GCSPR_EL0. */ \ + asm volatile ("mrs %0, S3_3_C2_C5_1" : "=r"(gcspr) : : "cc"); \ + \ + gcspr; \ + }) + +/* Corrupt the return address to see if GDB will report a SIGSEGV with the + expected $_siginfo.si_code. */ +static void __attribute__ ((noinline)) +function (unsigned long *gcspr) +{ + /* x30 holds the return address. */ + register long x30 __asm__("x30") __attribute__ ((unused)); + + /* Print GCSPR to stdout so that the testcase can capture it. */ + printf ("%p\n", get_gcspr ()); + fflush (stdout); + + /* Cause a GCS exception. */ + x30 = 0xbadc0ffee; + __asm__ volatile ("ret\n"); +} + +int +main (void) +{ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS)) + { + fprintf (stderr, "GCS support not found in AT_HWCAP\n"); + return EXIT_FAILURE; + } + + /* Force shadow stacks on, our tests *should* be fine with or + without libc support and with or without this having ended + up tagged for GCS and enabled by the dynamic linker. We + can't use the libc prctl() function since we can't return + from enabling the stack. Also lock GCS if not already + locked so we can test behaviour when it's locked. */ + unsigned long gcs_mode; + int ret = my_syscall2 (__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) + { + gcs_mode = PR_SHADOW_STACK_ENABLE; + ret = my_syscall2 (__NR_prctl, PR_SET_SHADOW_STACK_STATUS, gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to configure GCS: %d\n", ret); + return EXIT_FAILURE; + } + } + + unsigned long *gcspr = get_gcspr (); + + /* Pass gscpr to function just so it's used for something. */ + function (gcspr); /* Break here. */ + + /* Avoid returning, in case libc doesn't understand GCS. */ + exit (EXIT_SUCCESS); +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-core.exp b/gdb/testsuite/gdb.arch/aarch64-gcs-core.exp new file mode 100644 index 0000000..9c4b7d5 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-core.exp @@ -0,0 +1,116 @@ +# 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 reading and writing the core dump of a binary that uses a Guarded +# Control Stack. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return +} + +set linespec ${srcfile}:[gdb_get_line_number "Break here"] + +if ![runto $linespec] { + return +} + +# Obtain an OS-generated core file. Save test program output to +# ${binfile}.out. +set core_filename [core_find $binfile {} {} "${binfile}.out"] +set core_generated [expr {$core_filename != ""}] + +# Make sure GDB can read the given core file correctly. +proc check_core_file {core_filename saved_gcspr} { + global decimal hex + + # Load the core file. + if [gdb_test "core $core_filename" \ + [multi_line \ + "Core was generated by .*\\." \ + "Program terminated with signal SIGSEGV, Segmentation fault" \ + "Guarded Control Stack error\\." \ + "#0 function \\(gcspr=$hex\\) at .*aarch64-gcs-core.c:$decimal" \ + "$decimal.*__asm__ volatile \\(\"ret\\\\n\"\\);"] \ + "load core file"] { + return -1 + } + + # Check the value of GCSPR in the core file. + gdb_test "print/x \$gcspr" "\\$\[0-9\]+ = $saved_gcspr" \ + "gcspr contents from core file" +} + +if {!$core_generated} { + untested "unable to create or find corefile" +} + +if {$core_generated} { + clean_restart + gdb_load $binfile + + with_test_prefix "OS corefile" { + # Read GCSPR value from saved output of the test program. + set out_id [open ${binfile}.out "r"] + set gcspr_in_core [gets $out_id] + close $out_id + + check_core_file $core_filename $gcspr_in_core + } +} + +if ![gcore_cmd_available] { + unsupported "target does not support gcore command." + return +} + +clean_restart +gdb_load $binfile + +if ![runto $linespec] { + return +} + +# Continue until a crash. The line with the hex number is optional because +# it's printed by the test program, and doesn't appear in the Expect buffer +# when testing a remote target. +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "($hex\r\n)?" \ + "Program received signal SIGSEGV, Segmentation fault" \ + "Guarded Control Stack error\\." \ + "function \\(gcspr=$hex\\) at .*aarch64-gcs-core.c:$decimal" \ + {.*__asm__ volatile \("ret\\n"\);}] \ + "continue to SIGSEGV" + +set gcspr_in_gcore [get_valueof "/x" "\$gcspr" "*unknown*"] + +# Generate the gcore core file. +set gcore_filename [standard_output_file "${testfile}.gcore"] +set gcore_generated [gdb_gcore_cmd "$gcore_filename" "generate gcore file"] + +gdb_assert { $gcore_generated } "gcore corefile created" +if {$gcore_generated} { + clean_restart + gdb_load $binfile + + with_test_prefix "gcore corefile" { + check_core_file $gcore_filename $gcspr_in_gcore + } +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c new file mode 100644 index 0000000..754fda1 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.c @@ -0,0 +1,140 @@ +/* This test program 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/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/auxv.h> +#include <sys/syscall.h> +#include <linux/prctl.h> + +/* Feature check for Guarded Control Stack. */ +#ifndef HWCAP_GCS +#define HWCAP_GCS (1ULL << 32) +#endif + +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#define PR_SET_SHADOW_STACK_STATUS 75 +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#endif + +/* We need to use a macro to call prctl because after GCS is enabled, it's not + possible to return from the function which enabled it. This is because the + return address of the calling function isn't on the GCS. */ +#define my_syscall2(num, arg1, arg2) \ + ({ \ + register long _num __asm__("x8") = (num); \ + register long _arg1 __asm__("x0") = (long)(arg1); \ + register long _arg2 __asm__("x1") = (long)(arg2); \ + register long _arg3 __asm__("x2") = 0; \ + register long _arg4 __asm__("x3") = 0; \ + register long _arg5 __asm__("x4") = 0; \ + \ + __asm__ volatile("svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc"); \ + _arg1; \ + }) + +#define get_gcspr(void) \ + ({ \ + unsigned long *gcspr; \ + \ + /* Get GCSPR_EL0. */ \ + asm volatile("mrs %0, S3_3_C2_C5_1" : "=r"(gcspr) : : "cc"); \ + \ + gcspr; \ + }) + +static int __attribute__ ((noinline)) +function2 (void) +{ + return EXIT_SUCCESS; +} + +/* Put branch and link instructions being tested into their own functions so + that the program returns one level up in the stack after the displaced + stepped instruction. This tests that GDB doesn't leave the GCS out of sync + with the regular stack. */ + +static int __attribute__ ((noinline)) +function_bl (void) +{ + register int x0 __asm__("x0"); + + __asm__ ("bl function2\n" + : "=r"(x0) + : + : "x30"); + + return x0; +} + +static int __attribute__ ((noinline)) +function_blr (void) +{ + register int x0 __asm__("x0"); + + __asm__ ("blr %1\n" + : "=r"(x0) + : "r"(&function2) + : "x30"); + + return x0; +} + +int +main (void) +{ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS)) + { + fprintf (stderr, "GCS support not found in AT_HWCAP\n"); + return EXIT_FAILURE; + } + + /* Force shadow stacks on, our tests *should* be fine with or + without libc support and with or without this having ended + up tagged for GCS and enabled by the dynamic linker. We + can't use the libc prctl() function since we can't return + from enabling the stack. */ + unsigned long gcs_mode; + int ret = my_syscall2 (__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) + { + gcs_mode = PR_SHADOW_STACK_ENABLE; + ret = my_syscall2 (__NR_prctl, PR_SET_SHADOW_STACK_STATUS, gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to configure GCS: %d\n", ret); + return EXIT_FAILURE; + } + } + + int ret1 = function_bl (); + int ret2 = function_blr (); + + /* Avoid returning, in case libc doesn't understand GCS. */ + exit (ret1 + ret2); +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp new file mode 100644 index 0000000..2359d96 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-disp-step.exp @@ -0,0 +1,86 @@ +# 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 displaced stepping in a program that uses a Guarded Control Stack. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +if ![runto_main] { + return +} + +gdb_test_no_output "set breakpoint auto-hw off" +gdb_test_no_output "set displaced-stepping on" + +# Get address of the branch and link instructions of interest. +set addr_bl 0 +set test "get address of bl instruction" +gdb_test_multiple "disassemble function_bl" $test -lbl { + -re "\r\n\\s+($hex) <\\+${decimal}>:\\s+bl\\s+${hex} <function2>(?=\r\n)" { + set addr_bl $expect_out(1,string) + exp_continue + } + -re -wrap "" { + gdb_assert { $addr_bl != 0 } $test + } +} + +set addr_blr 0 +set test "get address of blr instruction" +gdb_test_multiple "disassemble function_blr" $test -lbl { + -re "\r\n\\s+($hex) <\\+${decimal}>:\\s+blr\\s+x${decimal}(?=\r\n)" { + set addr_blr $expect_out(1,string) + exp_continue + } + -re -wrap "" { + gdb_assert { $addr_blr != 0 } $test + } +} + +if { $addr_bl == 0 || $addr_blr == 0 } { + return +} + +gdb_test "break *$addr_bl" \ + "Breakpoint $decimal at $hex: file .*aarch64-gcs-disp-step.c, line ${decimal}." \ + "set breakpoint at bl instruction" + +gdb_test "break *$addr_blr" \ + "Breakpoint $decimal at $hex: file .*aarch64-gcs-disp-step.c, line ${decimal}." \ + "set breakpoint at blr instruction" + +gdb_test "continue" \ + [multi_line \ + {Continuing\.} \ + "" \ + "Breakpoint $decimal, function_bl \\(\\) at .*aarch64-gcs-disp-step.c:${decimal}(?: \\\[GCS error\\\])?" \ + {[^\r\n]+"bl function2\\n"}] \ + "continue to breakpoint at bl" + +gdb_test "continue" \ + [multi_line \ + {Continuing\.} \ + "" \ + "Breakpoint $decimal, $hex in function_blr \\(\\) at .*aarch64-gcs-disp-step.c:${decimal}(?: \\\[GCS error\\\])?" \ + {[^\r\n]+"blr %1\\n"}] \ + "continue to breakpoint at blr" + +gdb_continue_to_end diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-return.c b/gdb/testsuite/gdb.arch/aarch64-gcs-return.c new file mode 100644 index 0000000..c062fea --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-return.c @@ -0,0 +1,105 @@ +/* This test program 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/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/auxv.h> +#include <sys/syscall.h> +#include <linux/prctl.h> + +/* Feature check for Guarded Control Stack. */ +#ifndef HWCAP_GCS +#define HWCAP_GCS (1ULL << 32) +#endif + +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#define PR_SET_SHADOW_STACK_STATUS 75 +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#endif + +/* We need to use a macro to call prctl because after GCS is enabled, it's not + possible to return from the function which enabled it. This is because the + return address of the calling function isn't on the GCS. */ +#define my_syscall2(num, arg1, arg2) \ + ({ \ + register long _num __asm__("x8") = (num); \ + register long _arg1 __asm__("x0") = (long)(arg1); \ + register long _arg2 __asm__("x1") = (long)(arg2); \ + register long _arg3 __asm__("x2") = 0; \ + register long _arg4 __asm__("x3") = 0; \ + register long _arg5 __asm__("x4") = 0; \ + \ + __asm__ volatile("svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc"); \ + _arg1; \ + }) + +static int __attribute__ ((noinline)) +call2 () +{ + return 42; /* Break call2. */ +} + +static int __attribute__ ((noinline)) +call1 () +{ + return call2 (); /* Break call1. */ +} + +int +main () +{ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS)) + { + fprintf (stderr, "GCS support not found in AT_HWCAP\n"); + return EXIT_FAILURE; + } + + /* Force shadow stacks on, our tests *should* be fine with or + without libc support and with or without this having ended + up tagged for GCS and enabled by the dynamic linker. We + can't use the libc prctl() function since we can't return + from enabling the stack. Also lock GCS if not already + locked so we can test behaviour when it's locked. */ + unsigned long gcs_mode; + int ret = my_syscall2 (__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) + { + gcs_mode = PR_SHADOW_STACK_ENABLE; + ret = my_syscall2 (__NR_prctl, PR_SET_SHADOW_STACK_STATUS, gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to configure GCS: %d\n", ret); + return EXIT_FAILURE; + } + } + + call1 (); /* Break begin. */ + + /* Avoid returning, in case libc doesn't understand GCS. */ + exit (EXIT_SUCCESS); +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-return.exp b/gdb/testsuite/gdb.arch/aarch64-gcs-return.exp new file mode 100644 index 0000000..6f695da --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-return.exp @@ -0,0 +1,132 @@ +# 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 the GDB return command in a program that uses a Guarded Control Stack. +# Based on the return tests in gdb.arch/amd64-shadow-stack-cmds.exp. +# Note that potential GCS violations often only occur after resuming normal +# execution. Therefore, it is important to test normal program +# completion after testing the return command. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +set begin_line [gdb_get_line_number "Break begin"] +set call1_line [gdb_get_line_number "Break call1"] +set call2_line [gdb_get_line_number "Break call2"] + +if ![runto ${begin_line}] { + return +} + +proc restart_and_run_infcall_call2 {} { + global binfile call2_line + clean_restart + gdb_load $binfile + if ![runto_main] { + return + } + set inside_infcall_str "The program being debugged stopped while in a function called from GDB" + gdb_breakpoint ${call2_line} + gdb_continue_to_breakpoint "Break call2" ".*Break call2.*" + gdb_test "call (int) call2()" \ + "Breakpoint \[0-9\]*, call2.*$inside_infcall_str.*" +} + +with_test_prefix "test inferior call and continue" { + gdb_breakpoint ${call1_line} + gdb_continue_to_breakpoint "Break call1" ".*Break call1.*" + + gdb_test "call (int) call2()" "= 42" + + gdb_continue_to_end +} + +with_test_prefix "test return inside an inferior call" { + restart_and_run_infcall_call2 + + gdb_test "return" "\#0.*call2.*" \ + "Test GCS return inside an inferior call" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end +} + +with_test_prefix "test return 'above' an inferior call" { + restart_and_run_infcall_call2 + + gdb_test "frame 2" "call2 ().*" "move to frame 'above' inferior call" + + gdb_test "return" "\#0.*call1.*" \ + "Test GCS return 'above' an inferior call" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end +} + +clean_restart +gdb_load $binfile +if ![runto ${begin_line}] { + return +} + +# Extract GCS pointer inside main, call1 and call2 function. +gdb_breakpoint ${call1_line} +gdb_breakpoint ${call2_line} +set gcspr_main [get_valueof /x "\$gcspr" 0 "get value of gcspr in main"] +gdb_continue_to_breakpoint "Break call1" ".*Break call1.*" +set gcspr_call1 [get_valueof /x "\$gcspr" 0 "get value of gcspr in call1"] +gdb_continue_to_breakpoint "Break call2" ".*Break call2.*" +set gcspr_call2 [get_valueof /x "\$gcspr" 0 "get value of gcspr in call2"] + +with_test_prefix "test frame level update" { + gdb_test "up" "call1.*" "move to frame 1" + gdb_test "print /x \$gcspr" "= $gcspr_call1" "check gcspr of frame 1" + gdb_test "up" "main.*" "move to frame 2" + gdb_test "print /x \$gcspr" "= $gcspr_main" "check gcspr of frame 2" + gdb_test "frame 0" "call2.*" "move to frame 0" + gdb_test "print /x \$gcspr" "= $gcspr_call2" "check gcspr of frame 0" +} + +with_test_prefix "test return from current frame" { + gdb_test "return (int) 1" "#0.*call1.*" \ + "Test GCS return from current frame" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end +} + +clean_restart +gdb_load $binfile +if ![runto_main] { + return +} + +with_test_prefix "test return from past frame" { + gdb_breakpoint ${call2_line} + gdb_continue_to_breakpoint "Break call2" ".*Break call2.*" + + gdb_test "frame 1" ".*in call1.*" + + gdb_test "return (int) 1" "#0.*main.*" \ + "Test GCS return from past frame" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-tdesc-without-linux.xml b/gdb/testsuite/gdb.arch/aarch64-gcs-tdesc-without-linux.xml new file mode 100644 index 0000000..056ab58 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-tdesc-without-linux.xml @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<!DOCTYPE target SYSTEM "gdb-target.dtd"> +<target> + <architecture>aarch64</architecture> + <feature name="org.gnu.gdb.aarch64.core"> + <flags id="cpsr_flags" size="4"> + <field name="SP" start="0" end="0" type="bool"/> + <field name="EL" start="2" end="3" type="uint32"/> + <field name="nRW" start="4" end="4" type="bool"/> + <field name="F" start="6" end="6" type="bool"/> + <field name="I" start="7" end="7" type="bool"/> + <field name="A" start="8" end="8" type="bool"/> + <field name="D" start="9" end="9" type="bool"/> + <field name="BTYPE" start="10" end="11" type="uint32"/> + <field name="SSBS" start="12" end="12" type="bool"/> + <field name="IL" start="20" end="20" type="bool"/> + <field name="SS" start="21" end="21" type="bool"/> + <field name="PAN" start="22" end="22" type="bool"/> + <field name="UAO" start="23" end="23" type="bool"/> + <field name="DIT" start="24" end="24" type="bool"/> + <field name="TCO" start="25" end="25" type="bool"/> + <field name="V" start="28" end="28" type="bool"/> + <field name="C" start="29" end="29" type="bool"/> + <field name="Z" start="30" end="30" type="bool"/> + <field name="N" start="31" end="31" type="bool"/> + </flags> + <reg name="x0" bitsize="64" type="int" regnum="0"/> + <reg name="x1" bitsize="64" type="int" regnum="1"/> + <reg name="x2" bitsize="64" type="int" regnum="2"/> + <reg name="x3" bitsize="64" type="int" regnum="3"/> + <reg name="x4" bitsize="64" type="int" regnum="4"/> + <reg name="x5" bitsize="64" type="int" regnum="5"/> + <reg name="x6" bitsize="64" type="int" regnum="6"/> + <reg name="x7" bitsize="64" type="int" regnum="7"/> + <reg name="x8" bitsize="64" type="int" regnum="8"/> + <reg name="x9" bitsize="64" type="int" regnum="9"/> + <reg name="x10" bitsize="64" type="int" regnum="10"/> + <reg name="x11" bitsize="64" type="int" regnum="11"/> + <reg name="x12" bitsize="64" type="int" regnum="12"/> + <reg name="x13" bitsize="64" type="int" regnum="13"/> + <reg name="x14" bitsize="64" type="int" regnum="14"/> + <reg name="x15" bitsize="64" type="int" regnum="15"/> + <reg name="x16" bitsize="64" type="int" regnum="16"/> + <reg name="x17" bitsize="64" type="int" regnum="17"/> + <reg name="x18" bitsize="64" type="int" regnum="18"/> + <reg name="x19" bitsize="64" type="int" regnum="19"/> + <reg name="x20" bitsize="64" type="int" regnum="20"/> + <reg name="x21" bitsize="64" type="int" regnum="21"/> + <reg name="x22" bitsize="64" type="int" regnum="22"/> + <reg name="x23" bitsize="64" type="int" regnum="23"/> + <reg name="x24" bitsize="64" type="int" regnum="24"/> + <reg name="x25" bitsize="64" type="int" regnum="25"/> + <reg name="x26" bitsize="64" type="int" regnum="26"/> + <reg name="x27" bitsize="64" type="int" regnum="27"/> + <reg name="x28" bitsize="64" type="int" regnum="28"/> + <reg name="x29" bitsize="64" type="int" regnum="29"/> + <reg name="x30" bitsize="64" type="int" regnum="30"/> + <reg name="sp" bitsize="64" type="data_ptr" regnum="31"/> + <reg name="pc" bitsize="64" type="code_ptr" regnum="32"/> + <reg name="cpsr" bitsize="32" type="cpsr_flags" regnum="33"/> + </feature> + <feature name="org.gnu.gdb.aarch64.gcs"> + <reg name="gcspr" bitsize="64" type="data_ptr" regnum="90" group="system"/> + </feature> +</target> diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.c b/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.c new file mode 100644 index 0000000..10cf749 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.c @@ -0,0 +1,26 @@ +/* This test program 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/>. */ + +#include <stdio.h> + +int +main (void) +{ + printf ("Hello, world!\n"); + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.exp b/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.exp new file mode 100644 index 0000000..f0508cd --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs-wrong-tdesc.exp @@ -0,0 +1,48 @@ +# 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 that GDB complains when given a target description with the GCS feature +# but not the GCS Linux feature. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +set xml_path "${srcdir}/${subdir}/aarch64-gcs-tdesc-without-linux.xml" + +gdb_test "set tdesc filename ${xml_path}" \ + "warning: Incomplete GCS support in the target: missing Linux part. GCS feature disabled." \ + "warn about incomplete GCS support" + +# We can't test a debugging session on a remote target because with the +# wrong tdesc, GDB expects a g packet reply with the wrong size. +if {[gdb_protocol_is_remote]} { + return +} + +if ![runto_main] { + return +} + +gdb_test "print \$gcspr" " = <unavailable>" "GCSPR is unavailable" + +# Now check that we can continue the debugging session normally. +gdb_test "next" + +gdb_continue_to_end diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs.c b/gdb/testsuite/gdb.arch/aarch64-gcs.c new file mode 100644 index 0000000..9eb2e9e --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs.c @@ -0,0 +1,180 @@ +/* This test program 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/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/auxv.h> +#include <sys/syscall.h> +#include <linux/prctl.h> + +/* Feature check for Guarded Control Stack. */ +#ifndef HWCAP_GCS +#define HWCAP_GCS (1ULL << 32) +#endif + +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#define PR_SET_SHADOW_STACK_STATUS 75 +#define PR_SHADOW_STACK_ENABLE (1UL << 0) +#endif + +/* We need to use a macro to call prctl because after GCS is enabled, it's not + possible to return from the function which enabled it. This is because the + return address of the calling function isn't on the GCS. */ +#define my_syscall2(num, arg1, arg2) \ + ({ \ + register long _num __asm__("x8") = (num); \ + register long _arg1 __asm__("x0") = (long)(arg1); \ + register long _arg2 __asm__("x1") = (long)(arg2); \ + register long _arg3 __asm__("x2") = 0; \ + register long _arg4 __asm__("x3") = 0; \ + register long _arg5 __asm__("x4") = 0; \ + \ + __asm__ volatile ("svc #0\n" \ + : "=r"(_arg1) \ + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ + "r"(_arg5), "r"(_num) \ + : "memory", "cc"); \ + _arg1; \ + }) + +#define get_gcspr(void) \ + ({ \ + unsigned long *gcspr; \ + \ + /* Get GCSPR_EL0. */ \ + asm volatile ("mrs %0, S3_3_C2_C5_1" : "=r"(gcspr) : : "cc"); \ + \ + gcspr; \ + }) + +static unsigned long *handler_gcspr = 0; + +static void +handler (int sig) +{ + handler_gcspr = get_gcspr (); +} + +static int __attribute__ ((unused)) +called_from_gdb (int val) +{ + return val + 1; +} + +/* Corrupt the return address to see if GDB will report a SIGSEGV with the + expected $_siginfo.si_code. */ +static void __attribute__ ((noinline)) +normal_function2 (void) +{ + /* x30 holds the return address. */ + register unsigned long x30 __asm__("x30") __attribute__ ((unused)); + + /* Cause a GCS exception. */ + x30 = 0xbadc0ffee; + /* Use explicit ret so that we can verify that a SIGSEGV was generated + exactly on the return instruction. */ + __asm__ volatile ("ret\n"); +} + +static inline void __attribute__ ((__always_inline__)) +inline_function2 (void) +{ + normal_function2 (); +} + +static void __attribute__ ((noinline)) +normal_function1 (void) +{ + inline_function2 (); +} + +/* First in a sequence of inline and normal functions, to test GDB + backtrace. */ +static inline void __attribute__ ((__always_inline__)) +inline_function1 (void) +{ + normal_function1 (); +} + +/* Trivial function, just so that GDB can test return with wrong GCSPR. */ +static void __attribute__ ((noinline)) +normal_function0 (void) +{ + /* Use explicit ret so that we can verify that a SIGSEGV was generated + exactly on the return instruction. */ + __asm__ volatile ("ret\n"); +} + +int +main (void) +{ + if (!(getauxval (AT_HWCAP) & HWCAP_GCS)) + { + fprintf (stderr, "GCS support not found in AT_HWCAP\n"); + return EXIT_FAILURE; + } + + /* Force shadow stacks on, our tests *should* be fine with or + without libc support and with or without this having ended + up tagged for GCS and enabled by the dynamic linker. We + can't use the libc prctl() function since we can't return + from enabling the stack. Also lock GCS if not already + locked so we can test behaviour when it's locked. */ + unsigned long gcs_mode; + int ret = my_syscall2 (__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to read GCS state: %d\n", ret); + return EXIT_FAILURE; + } + + if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) + { + gcs_mode = PR_SHADOW_STACK_ENABLE; + ret = my_syscall2 (__NR_prctl, PR_SET_SHADOW_STACK_STATUS, gcs_mode); + if (ret) + { + fprintf (stderr, "Failed to configure GCS: %d\n", ret); + return EXIT_FAILURE; + } + } + + /* Regular function call. */ + normal_function0 (); + + /* This is used by GDB. */ + __attribute__((unused)) unsigned long *gcspr = get_gcspr (); + + struct sigaction act = { 0 }; + + act.sa_handler = &handler; /* Break here. */ + if (sigaction (SIGUSR1, &act, NULL) == -1) + { + perror ("sigaction"); + exit (EXIT_FAILURE); + } + + raise (SIGUSR1); + +/* Call sequence of inline and normal functions, to test GDB backtrace. */ + inline_function1 (); + + /* Avoid returning, in case libc doesn't understand GCS. */ + exit (EXIT_SUCCESS); +} diff --git a/gdb/testsuite/gdb.arch/aarch64-gcs.exp b/gdb/testsuite/gdb.arch/aarch64-gcs.exp new file mode 100644 index 0000000..b09e010 --- /dev/null +++ b/gdb/testsuite/gdb.arch/aarch64-gcs.exp @@ -0,0 +1,99 @@ +# 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 a binary that uses a Guarded Control Stack. + +require allow_aarch64_gcs_tests + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +set linespec ${srcfile}:[gdb_get_line_number "Break here"] + +if ![runto ${linespec}] { + return +} + +gdb_test "print \$gcs_features_enabled" \ + [string_to_regexp { = [ PR_SHADOW_STACK_ENABLE ]}] \ + "GCS is enabled" + +gdb_test "print \$gcspr" ". = \\(void \\*\\) $hex" "GDB knows about gcspr" +gdb_test "print \$gcspr == gcspr" ". = 1" "GDB has the correct gcspr value" +gdb_test_no_output "set \$gcspr_in_main = \$gcspr" \ + "save gcspr value in main for later" + +# If the inferior function call fails, we don't want the tests following it +# to be affected. +gdb_test_no_output "set unwindonsignal on" +gdb_test "print called_from_gdb (41)" ". = 42" "call inferior function" + +gdb_test "break handler" "Breakpoint \[0-9\]+ .*aarch64-gcs.c, line \[0-9\]+\\." +gdb_test "handle SIGUSR1 nostop" \ + ".*\r\nSIGUSR1\\s+No\\s+Yes\\s+Yes\\s+User defined signal 1" \ + "let the inferior receive SIGUSR1 uninterrupted" +gdb_test "continue" \ + ".*\r\nBreakpoint \[0-9\]+, handler \\(sig=10\\) at .*aarch64-gcs.c.*handler_gcspr = get_gcspr \\(\\);" \ + "continue to signal handler" + +gdb_test_no_output "set \$gcspr_in_handler = \$gcspr" \ + "save gcspr value in handler for later" +# Select the frame above the <signal handler called> frame, which makes GDB +# unwind the gcspr from the signal frame GCS context. +gdb_test "frame 2" "#2 ($hex in )?\\S+ \\(.*\\) (at|from) \\S+.*" \ + "reached frame 2" +gdb_test "print \$gcspr" ". = \\(void \\*\\) $hex" "gcspr in frame level 2" +gdb_test "print \$gcspr == \$gcspr_in_handler + 8" ". = 1" \ + "gcspr unwound from signal context is correct" + +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Program received signal SIGSEGV, Segmentation fault" \ + "Guarded Control Stack error\\." \ + "normal_function2 \\(\\) at .*aarch64-gcs.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"ret\\\\n\"\\);"] \ + "continue to SIGSEGV" + +gdb_test "print \$_siginfo.si_code" ". = 10" \ + "test value of si_code when GCS SIGSEGV happens" +# The GCS grows down, and there are two real frames until main. +gdb_test "print \$gcspr == \$gcspr_in_main - 16" ". = 1" \ + "test value of gcspr when GCS SIGSEGV happens" + +# Test writing to GCSPR. +clean_restart +gdb_load $binfile +if ![runto normal_function0] { + return +} + +gdb_test_no_output "set \$gcspr = 0xbadc0ffee" "set bogus gcspr value" +# Continue to make sure that the value was actually written to the register. +# The SIGSEGV isn't a GCS error because the problem isn't that the GCS entry +# doesn't match the return address, but rather that that GCSPR is pointing +# to an invalid address. +gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Program received signal SIGSEGV, Segmentation fault\\." \ + "normal_function0 \\(\\) at .*aarch64-gcs.c:$decimal" \ + "${decimal}\\s+__asm__ volatile \\(\"ret\\\\n\"\\);"] \ + "continue after bad gcspr" diff --git a/gdb/testsuite/gdb.arch/aarch64-mte-core.exp b/gdb/testsuite/gdb.arch/aarch64-mte-core.exp index fdaa061..7da836e 100644 --- a/gdb/testsuite/gdb.arch/aarch64-mte-core.exp +++ b/gdb/testsuite/gdb.arch/aarch64-mte-core.exp @@ -145,7 +145,8 @@ proc test_mode { mode } { # both correctly. if {$gcore_generated} { - clean_restart ${binfile} + clean_restart + gdb_load $binfile with_test_prefix "gcore corefile" { test_mte_core_file $gcore_filename $mode } @@ -154,7 +155,8 @@ proc test_mode { mode } { } if {$core_generated} { - clean_restart ${binfile} + clean_restart + gdb_load $binfile with_test_prefix "native corefile" { test_mte_core_file $core_filename $mode } diff --git a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp index 7ce1fdf..e835ddf 100644 --- a/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp +++ b/gdb/testsuite/gdb.arch/aarch64-pseudo-unwind.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -clean_restart ${binfile} +clean_restart $testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl b/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl index 44d0808..64cfd54 100644 --- a/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl +++ b/gdb/testsuite/gdb.arch/aarch64-sme-core.exp.tcl @@ -91,7 +91,8 @@ proc generate_sme_core_files { executable binfile id state vl svl} { # and the native one generated by the Linux Kernel. Make sure GDB can read # both correctly. if {$gcore_generated} { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test_no_output "set print repeats 1" \ "adjust repeat count post-crash gcore" @@ -103,7 +104,8 @@ proc generate_sme_core_files { executable binfile id state vl svl} { } if {$core_generated} { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test_no_output "set print repeats 1" \ "adjust repeat count post-crash native core" diff --git a/gdb/testsuite/gdb.arch/alpha-step.exp b/gdb/testsuite/gdb.arch/alpha-step.exp index e41bd97..bdbfeec 100644 --- a/gdb/testsuite/gdb.arch/alpha-step.exp +++ b/gdb/testsuite/gdb.arch/alpha-step.exp @@ -25,7 +25,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile proc test_stepi {function } { # Restart the program from scratch. If GDB got confused during one diff --git a/gdb/testsuite/gdb.arch/altivec-abi.exp b/gdb/testsuite/gdb.arch/altivec-abi.exp index 12f523b..fb5367d 100644 --- a/gdb/testsuite/gdb.arch/altivec-abi.exp +++ b/gdb/testsuite/gdb.arch/altivec-abi.exp @@ -47,7 +47,8 @@ proc altivec_abi_tests { extra_flags force_abi } { } } - clean_restart $binfile + clean_restart + gdb_load $::binfile # Run to `main' where we begin our tests. if {![runto_main]} { diff --git a/gdb/testsuite/gdb.arch/amd64-byte.exp b/gdb/testsuite/gdb.arch/amd64-byte.exp index ac70672..d084303 100644 --- a/gdb/testsuite/gdb.arch/amd64-byte.exp +++ b/gdb/testsuite/gdb.arch/amd64-byte.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp index 08d73d8..b11efa7 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp @@ -19,6 +19,7 @@ # instructions. require is_x86_64_m64_target have_avx +require support_displaced_stepping standard_testfile .S diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call-alarm.c b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call-alarm.c index 03b868c..0fb2904 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call-alarm.c +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call-alarm.c @@ -16,9 +16,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <unistd.h> +#include <stdlib.h> + +extern void test_call (void); + +void +unreachable (void) +{ + abort (); +} void setup_alarm (void) { alarm (300); } + +int +main () +{ + setup_alarm (); + test_call (); + unreachable (); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.S b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.S index 78a6859..20a8eb7 100644 --- a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.S +++ b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.S @@ -18,33 +18,12 @@ handling. */ .text - - .global main -main: - nop - - callq setup_alarm - - nop - -/***********************************************/ - -/* test call/ret */ - .global test_call test_call: call test_call - nop + call unreachable .global test_ret_end test_ret_end: nop -/***********************************************/ - -/* all done */ - -done: - mov $0,%rdi - call exit - hlt .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.arch/amd64-dword.exp b/gdb/testsuite/gdb.arch/amd64-dword.exp index e8a527d..cd3d76b 100644 --- a/gdb/testsuite/gdb.arch/amd64-dword.exp +++ b/gdb/testsuite/gdb.arch/amd64-dword.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-no-cfi.S b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-no-cfi.S new file mode 100644 index 0000000..39cf3e6 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-no-cfi.S @@ -0,0 +1,117 @@ +/* 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/>. */ + +/* This file is compiled from gdb.arch/amd64-extended-prologue-analysis.c + using gcc 11.4.0 with flags: -g0 -O1 -S -fno-omit-frame-pointer + -fno-asynchronous-unwind-tables. */ + + .file "amd64-extended-prologue-analysis.c" + .text + .globl bar + .type bar, @function +bar: + endbr64 + leal (%rdi,%rdi), %eax + ret + .size bar, .-bar + .globl foo + .type foo, @function +foo: + endbr64 + pushq %rbp + movq %rsp, %rbp + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %rbx + subq $280, %rsp + movl %edi, %ebx + movl %esi, %r14d + movl %edx, %r13d + movl %ecx, %r12d + movq %fs:40, %rax + movq %rax, -56(%rbp) + xorl %eax, %eax +.L3: + leal (%rbx,%rax), %ecx + movslq %eax, %rdx + movb %cl, -320(%rbp,%rdx) + addl $1, %eax + cmpl $256, %eax + jne .L3 + movl %ebx, %edi + call bar + movl %eax, %r15d + movl %r14d, %edi + call bar + leal (%r15,%rax), %r14d + movl %r13d, %edi + call bar + addl %eax, %r14d + movl %r12d, %edi + call bar + addl %r14d, %eax + addl %ebx, %eax + movq -56(%rbp), %rdx + subq %fs:40, %rdx + jne .L7 + addq $280, %rsp + popq %rbx + popq %r12 + popq %r13 + popq %r14 + popq %r15 + popq %rbp + ret +.L7: + call __stack_chk_fail@PLT + .size foo, .-foo + .globl main + .type main, @function +main: + endbr64 + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + leal (%rdi,%rdi), %ecx + leal 2(%rdi), %edx + leal 1(%rdi), %esi + call foo + movl %eax, -4(%rbp) + movl -4(%rbp), %eax + leave + ret + .size main, .-main + .ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-offset.S b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-offset.S new file mode 100644 index 0000000..ea001b3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis-offset.S @@ -0,0 +1,112 @@ +/* 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/>. */ + +/* This file is compiled from gdb.arch/amd64-extended-prologue-analysis.c + using gcc 11.4.0 with flags: -g0 -O1 -S -fomit-frame-pointer + -fno-asynchronous-unwind-tables. */ + + .file "amd64-extended-prologue-analysis.c" + .text + .globl bar + .type bar, @function +bar: + endbr64 + leal (%rdi,%rdi), %eax + ret + .size bar, .-bar + .globl foo + .type foo, @function +foo: + endbr64 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %rbp + pushq %rbx + subq $272, %rsp + movl %edi, %ebx + movl %esi, %r13d + movl %edx, %r12d + movl %ecx, %ebp + movq %fs:40, %rax + movq %rax, 264(%rsp) + xorl %eax, %eax +.L3: + leal (%rbx,%rax), %ecx + movslq %eax, %rdx + movb %cl, (%rsp,%rdx) + addl $1, %eax + cmpl $256, %eax + jne .L3 + movl %ebx, %edi + call bar + movl %eax, %r14d + movl %r13d, %edi + call bar + leal (%r14,%rax), %r13d + movl %r12d, %edi + call bar + addl %eax, %r13d + movl %ebp, %edi + call bar + addl %r13d, %eax + addl %ebx, %eax + movq 264(%rsp), %rdx + subq %fs:40, %rdx + jne .L7 + addq $272, %rsp + popq %rbx + popq %rbp + popq %r12 + popq %r13 + popq %r14 + ret +.L7: + call __stack_chk_fail@PLT + .size foo, .-foo + .globl main + .type main, @function +main: + endbr64 + subq $24, %rsp + leal (%rdi,%rdi), %ecx + leal 2(%rdi), %edx + leal 1(%rdi), %esi + call foo + movl %eax, 12(%rsp) + movl 12(%rsp), %eax + addq $24, %rsp + ret + .size main, .-main + .ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.S b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.S new file mode 100644 index 0000000..691eee0 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.S @@ -0,0 +1,143 @@ +/* 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/>. */ + +/* This file is compiled from gdb.arch/amd64-extended-prologue-analysis.c + using gcc 11.4.0 with flags: -g0 -O1 -S -fno-omit-frame-pointer. */ + + .file "amd64-extended-prologue-analysis.c" + .text + .globl bar + .type bar, @function +bar: +.LFB0: + .cfi_startproc + endbr64 + leal (%rdi,%rdi), %eax + ret + .cfi_endproc +.LFE0: + .size bar, .-bar + .globl foo + .type foo, @function +foo: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %rbx + subq $280, %rsp + .cfi_offset 15, -24 + .cfi_offset 14, -32 + .cfi_offset 13, -40 + .cfi_offset 12, -48 + .cfi_offset 3, -56 + movl %edi, %ebx + movl %esi, %r14d + movl %edx, %r13d + movl %ecx, %r12d + movq %fs:40, %rax + movq %rax, -56(%rbp) + xorl %eax, %eax +.L3: + leal (%rbx,%rax), %ecx + movslq %eax, %rdx + movb %cl, -320(%rbp,%rdx) + addl $1, %eax + cmpl $256, %eax + jne .L3 + movl %ebx, %edi + call bar + movl %eax, %r15d + movl %r14d, %edi + call bar + leal (%r15,%rax), %r14d + movl %r13d, %edi + call bar + addl %eax, %r14d + movl %r12d, %edi + call bar + addl %r14d, %eax + addl %ebx, %eax + movq -56(%rbp), %rdx + subq %fs:40, %rdx + jne .L7 + addq $280, %rsp + popq %rbx + popq %r12 + popq %r13 + popq %r14 + popq %r15 + popq %rbp + .cfi_remember_state + .cfi_def_cfa 7, 8 + ret +.L7: + .cfi_restore_state + call __stack_chk_fail@PLT + .cfi_endproc +.LFE1: + .size foo, .-foo + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + leal (%rdi,%rdi), %ecx + leal 2(%rdi), %edx + leal 1(%rdi), %esi + call foo + movl %eax, -4(%rbp) + movl -4(%rbp), %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main + .ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c new file mode 100644 index 0000000..707b4fb --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.c @@ -0,0 +1,56 @@ +/* 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/>. */ + +int __attribute__ ((noinline)) +bar (int x) +{ + return x + x; +} + +/* This function should generate a prologue in shape of: + push %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + mov %rsp, %rbp + .cfi_def_cfa_register %rbp + push %reg1 + push %reg2 + sub $XXX, %rsp + .cfi_offset %reg2, 32 + .cfi_offset %reg1, 24 + + So to be able to unwind a register, GDB needs to skip prologue past + register pushes and stack allocation (to access .cfi directives). */ +int __attribute__ ((noinline)) +foo (int a, int b, int c, int d) +{ + /* "volatile" alone isn't enough for clang to not optimize it out and + allocate space on the stack. */ + volatile char s[256]; + for (int i = 0; i < 256; i++) + s[i] = (char) (a + i); + + a += bar (a) + bar (b) + bar (c) + bar (d); + return a; +} + +int +main (int argc, char **argv) +{ + volatile int a = foo (argc, argc + 1, argc + 2, argc * 2); + return a; +} diff --git a/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.exp b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.exp new file mode 100644 index 0000000..356afc7 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-extended-prologue-analysis.exp @@ -0,0 +1,208 @@ +# 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/>. +# +# This test verifies that when placing a breakpoint on a function with a frame +# pointer, instructions that push callee-saved registers and stack allocation +# in the prologue are skipped, without debug info. When stopped on such +# breakpoint, the pushed registers should be able to be immediately unwound. +# With debug info present, GDB would try to use prologue-end markers found in +# the line table to determine where the prologue ends. +# +# It is also tested both with and without .eh_frame's .cfi directives - with +# them, GDB can only unwind a register once stopped after .cfi directive for +# that register's push. + +require is_x86_64_m64_target +standard_testfile .c -no-cfi.S .S -offset.S + +proc test_run {} { + gdb_breakpoint "foo" + gdb_continue_to_breakpoint "Continue to foo" + + gdb_test "backtrace" "#0\[^\r\n\]+in foo\[^s\]+#1\[^\r\n\]+in main\[^s\]+" \ + "Verify backtrace output in foo" + + set main_r12 [get_integer_valueof "\$r12" "null"] + gdb_assert { $main_r12 ne "null" } + + set foo_r12 [expr "$main_r12 + 2"] + gdb_test "print \$r12=$foo_r12" "$foo_r12" "Set foo's %r12=$foo_r12" + gdb_test "up" ".*main.*" "Go up a frame from foo" + gdb_test "print \$r12" "$main_r12" "foo's %r12 unwound" + gdb_test "down" ".*foo.*" "Go back down a frame to foo" + gdb_test "print \$r12" "$foo_r12" "foo's %r12 unwound back" +} + +proc offset_test_run {} { + gdb_breakpoint "*foo" + gdb_continue_to_breakpoint "Continue to entry of foo" + + set old_reg_val [get_integer_valueof "\$r12" "null"] + gdb_assert { $old_reg_val ne "null" } + + set new_reg_val [expr "$old_reg_val + 3"] + gdb_test "print \$r14=$new_reg_val" "$new_reg_val" "Set %r14=$new_reg_val" + gdb_test "print \$r13=$new_reg_val" "$new_reg_val" "Set %r13=$new_reg_val" + gdb_test "print \$r12=$new_reg_val" "$new_reg_val" "Set %r12=$new_reg_val" + + set addr_past_prologue "null" + gdb_test_multiple "disassemble" "Disassemble foo" -lbl { + -re "\r\n\\s*($::hex) <\\+($::decimal)>:\\s*mov.*(?=\r\n)" { + set addr_past_prologue $expect_out(1,string) + exp_continue + } + + -re -wrap "" { + gdb_assert { $addr_past_prologue ne "null" } $gdb_test_name + } + } + + gdb_assert { $addr_past_prologue ne "null" } + + gdb_breakpoint "*$addr_past_prologue" + gdb_continue_to_breakpoint "Continue past foo's prologue" + + gdb_test "up" ".*main.*" "Go up a frame from foo" + gdb_test "print \$r14" "$new_reg_val" "Verify %r14 value" + gdb_test "print \$r13" "$new_reg_val" "Verify %r13 value" + gdb_test "print \$r12" "$new_reg_val" "Verify %r12 value" +} + +# Tests are done for two versions (not counting with and w/o .cfi): +# - binary compiled from C source, which verifies we actually test against +# the code that compilers produce and we expect +# - binary compiled from ASM source, which verifies that we properly analyze +# prologue sequences even when compiler introduces a sudden change in how +# it generates assembly +# +# With those 2 versions, we can easily distinguish GDB breaking analyzer and +# compilers behaving differently, if there ever is an impactful change in how +# they generate prologues. +with_test_prefix "w/o .cfi directives" { + with_test_prefix "compiler gen" { + # -fno-asynchronous-unwind-tables is needed to get rid of .cfi + # directives in .eh_frame section. + if { [gdb_can_simple_compile fno-asynchronous-unwind-tables \ + { void foo () { } } object -fno-asynchronous-unwind-tables] == 0 } { + unsupported \ + "compiler doesn't support -fno-asynchronous-unwind-tables flag" + } else { + # For at least gcc 11.4/clang 14.0.0 and later, -O1 makes them more + # eager to use registers in the prologue. + # + # At least gcc 11.4 and later by default does not generate full + # debug info, "nodebug" is there for other compilers. + if { [prepare_for_testing "failed to prepare" "$testfile-no-cfi-C" \ + $srcfile { optimize=-O1 nodebug + additional_flags=-fno-asynchronous-unwind-tables + additional_flags=-fno-omit-frame-pointer}] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + test_run + } + } + + with_test_prefix "ASM source" { + if { [prepare_for_testing "failed to prepare" "$testfile-no-cfi-S" \ + $srcfile2 nodebug ] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + test_run + } +} + +with_test_prefix "with .cfi directives" { + with_test_prefix "compiler gen" { + if { [prepare_for_testing "failed to prepare" "$testfile-cfi-C" \ + $srcfile { optimize=-O1 + nodebug additional_flags=-fno-omit-frame-pointer}] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + test_run + } + + with_test_prefix "ASM source" { + if { [prepare_for_testing "failed to prepare" "$testfile-cfi-S" \ + $srcfile3 nodebug ] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + test_run + } +} + +# This section exists to verify that we properly assign offsets for functions +# w/o a frame pointer, for registers when they're pushed. If they were assigned +# in a wrong way, we might end up unwinding improper register values. +with_test_prefix "offset initialization" { + with_test_prefix "compiler gen" { + if { [gdb_can_simple_compile fno-asynchronous-unwind-tables \ + { void foo () { } } object -fno-asynchronous-unwind-tables] == 0 } { + unsupported \ + "compiler doesn't support -fno-asynchronous-unwind-tables flag" + } else { + if { [prepare_for_testing "failed to prepare" "$testfile-offset-C" \ + $srcfile { optimize=-O1 nodebug + additional_flags=-fno-asynchronous-unwind-tables + additional_flags=-fomit-frame-pointer}] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + offset_test_run + } + } + + with_test_prefix "ASM source" { + if { [prepare_for_testing "failed to prepare" "$testfile-offset-S" \ + $srcfile4 nodebug ] } { + return + } + + if { ![runto_main] } { + untested "unable to run to main" + return + } + + offset_test_run + } +} diff --git a/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.c b/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.c new file mode 100644 index 0000000..1b79a65 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.c @@ -0,0 +1,63 @@ +/* Copyright 2025 Free Software Foundation, Inc. + + This file is part of GDB. + + 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/>. */ + +volatile void dummy () {} + +long test_function(void) +{ + __asm__ volatile ( + /* Clear xmm0. */ + "vxorps %%xmm0, %%xmm0, %%xmm0\n\t" + + /* Move the frame pointer (rbp) to xmm0. */ + "movq %%rbp, %%xmm0\n\t" + + /* CFI: Frame pointer is in xmm0. */ + ".cfi_register %%rbp, %%xmm0\n\t" + + /* Clobber list: Specify all modified registers */ + : // No output operands + : // No input operands + : "xmm0" + ); + + dummy (); /* break-here */ + + /* Pseudo-epilogue: Restore rbp from xmm0. */ + __asm__ volatile ( + /* Restore rbp. */ + "movq %%xmm0, %%rbp\n\t" + + /* Describe CFI: Frame pointer is restored. */ + ".cfi_restore %%rbp\n\t" + + /* Clobber list: Specify all modified registers */ + : /* No output operands. */ + : /* No input operands. */ + : /* Despite clobbering rbp, gcc doesn't let us list it here. */ + ); + + return 0; +} + +int +main () +{ + long result = test_function (); + dummy (); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.exp b/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.exp new file mode 100644 index 0000000..3c0b319 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-frameptr-vecreg-unwind.exp @@ -0,0 +1,40 @@ +# 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/>. + +# This test verifies that we can read and write the value of a pseudo register +# in unwound frames. For the test, we choose one raw register, rbx, and one +# pseudo register that is backed by rbx, ebx. We have two frames (the inner one, +# #0 and the outer one, #1) that each set a value for rbx. We verify that we +# can read both rbx and ebx correctly for each frame, and that when we write to +# ebx, rbx for that frame is correctly updated. + +require is_x86_64_m64_target + +standard_testfile + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + "${srcfile}" {debug}] } { + return -1 +} + +if {![runto_main]} { + return +} + +gdb_breakpoint [gdb_get_line_number "break-here"] +gdb_continue_to_breakpoint "break-here" +gdb_test "with confirm off --return -1" "result = test_function \\(\\);" +gdb_test "step" "dummy \\(\\);" +gdb_test "print result" "= -1" diff --git a/gdb/testsuite/gdb.arch/amd64-init-x87-values.exp b/gdb/testsuite/gdb.arch/amd64-init-x87-values.exp index 11004fa..5bbadaf 100644 --- a/gdb/testsuite/gdb.arch/amd64-init-x87-values.exp +++ b/gdb/testsuite/gdb.arch/amd64-init-x87-values.exp @@ -24,7 +24,7 @@ standard_testfile .S set options [list debug \ additional_flags=-static \ - additional_flags=-nostartfiles] + ldflags=-nostartfiles] if { [build_executable "failed to prepare" ${testfile} ${srcfile} $options] } { return -1 } @@ -40,7 +40,7 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile} $options] } { proc_with_prefix check_x87_regs_around_init {} { global binfile - clean_restart ${binfile} + clean_restart ${::testfile} # Get things started. if {![runto_main]} { @@ -115,7 +115,7 @@ proc_with_prefix check_x87_regs_around_init {} { proc_with_prefix check_setting_mxcsr_before_enable {} { global binfile gdb_prompt - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 @@ -149,7 +149,7 @@ proc_with_prefix check_setting_mxcsr_before_enable {} { proc_with_prefix check_setting_x87_regs_before_enable {} { global binfile - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp index 03ecba6..451c84b 100644 --- a/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp +++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-middle.exp @@ -45,7 +45,7 @@ gdb_test "bt" "^#0 +breakpt *\\(\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in func5\[^\ gdb_test "bt" "^#0 +breakpt *\\(\\) \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in func5\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in func4\[^\r\n\]*\r\n#3 +0x\[0-9a-f\]+ in func3\[^\r\n\]*\r\nBacktrace stopped: Cannot access memory at address 0x\[0-9a-f\]+" \ "second backtrace, with error message" -clean_restart ${binfile} +clean_restart ${::testfile} if ![runto breakpt] { return -1 @@ -59,7 +59,7 @@ gdb_test "interpreter-exec mi \"-stack-info-depth\"" \ "\\^done,depth=\"4\"" \ "check mi -stack-info-depth command, second time" -clean_restart ${binfile} +clean_restart ${::testfile} if ![runto breakpt] { return -1 diff --git a/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp index 134dfda..b715ecf 100644 --- a/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp +++ b/gdb/testsuite/gdb.arch/amd64-invalid-stack-top.exp @@ -49,7 +49,7 @@ gdb_test "bt no-filters" "^#0 +$hex in func2 \\(\\)\r\nBacktrace stopped: Cannot gdb_test "bt no-filters" "^#0 +$hex in func2 \\(\\)\r\nBacktrace stopped: Cannot access memory at address 0x\[0-9a-f\]+" \ "second backtrace, with error message" -clean_restart ${binfile} +clean_restart ${::testfile} if ![runto breakpt] { return -1 @@ -63,7 +63,7 @@ gdb_test "interpreter-exec mi \"-stack-info-depth\"" \ "\\^done,depth=\"1\"" \ "check mi -stack-info-depth command, second time" -clean_restart ${binfile} +clean_restart ${::testfile} if ![runto breakpt] { return -1 diff --git a/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp b/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp index 04f3266..c96c0c7 100644 --- a/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp +++ b/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp @@ -14,7 +14,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. standard_testfile .S -set binfile ${binfile}.o +set testfile $testfile.o +set binfile [standard_output_file $testfile] require is_x86_64_m64_target @@ -23,7 +24,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {debug}] return } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test "break *pushrbp" " at 0x1: file .*" gdb_test "break pushrbp" " at 0x1: file .*" diff --git a/gdb/testsuite/gdb.arch/amd64-prologue-xmm.exp b/gdb/testsuite/gdb.arch/amd64-prologue-xmm.exp index 7c16238..8447973 100644 --- a/gdb/testsuite/gdb.arch/amd64-prologue-xmm.exp +++ b/gdb/testsuite/gdb.arch/amd64-prologue-xmm.exp @@ -28,7 +28,7 @@ if [info exists COMPILE] { require is_x86_64_m64_target } -if {[prepare_for_testing "failed to prepare" ${binfile} $srcfile $opts]} { +if {[prepare_for_testing "failed to prepare" ${testfile} $srcfile $opts]} { return -1 } diff --git a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp index 6333311..49721dd 100644 --- a/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp +++ b/gdb/testsuite/gdb.arch/amd64-pseudo-unwind.exp @@ -32,7 +32,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp new file mode 100644 index 0000000..0ae172d --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-cmds.exp @@ -0,0 +1,143 @@ +# Copyright 2024-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 shadow stack enabling for frame level update, the return and the +# call commands. +# As potential CET violations often only occur after resuming normal +# execution, test normal program continuation after each return or call +# commands. + +require allow_ssp_tests + +standard_testfile amd64-shadow-stack.c + +# Restart GDB an run until breakpoint in call2. + +proc restart_and_run_infcall_call2 {} { + global binfile + clean_restart ${::testfile} + if { ![runto_main] } { + return -1 + } + set inside_infcall_str "The program being debugged stopped while in a function called from GDB" + gdb_breakpoint [ gdb_get_line_number "break call2" ] + gdb_continue_to_breakpoint "break call2" ".*break call2.*" + gdb_test "call (int) call2()" \ + "Breakpoint \[0-9\]*, call2.*$inside_infcall_str.*" +} + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug additional_flags="-fcf-protection=return"}] } { + return -1 + } + + clean_restart ${::testfile} + if { ![runto_main] } { + return -1 + } + + with_test_prefix "test inferior call and continue" { + gdb_breakpoint [ gdb_get_line_number "break call1" ] + gdb_continue_to_breakpoint "break call1" ".*break call1.*" + + gdb_test "call (int) call2()" "= 42" + + gdb_continue_to_end + } + + with_test_prefix "test return inside an inferior call" { + restart_and_run_infcall_call2 + + gdb_test "return" "\#0.*call2.*" \ + "Test shadow stack return inside an inferior call" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end + } + + with_test_prefix "test return 'above' an inferior call" { + restart_and_run_infcall_call2 + + gdb_test "frame 2" "call2 ().*" "move to frame 'above' inferior call" + + gdb_test "return" "\#0.*call1.*" \ + "Test shadow stack return 'above' an inferior call" \ + "Make.*return now\\? \\(y or n\\) " "y" + + gdb_continue_to_end + } + + clean_restart ${::testfile} + if { ![runto_main] } { + return -1 + } + + set call1_line [ gdb_get_line_number "break call1" ] + set call2_line [ gdb_get_line_number "break call2" ] + + # Extract shadow stack pointer inside main, call1 and call2 function. + gdb_breakpoint $call1_line + gdb_breakpoint $call2_line + set ssp_main [get_valueof /x "\$pl3_ssp" 0 "get value of ssp in main"] + gdb_continue_to_breakpoint "break call1" ".*break call1.*" + set ssp_call1 [get_valueof /x "\$pl3_ssp" 0 "get value of ssp in call1"] + gdb_continue_to_breakpoint "break call2" ".*break call2.*" + set ssp_call2 [get_valueof /x "\$pl3_ssp" 0 "get value of ssp in call2"] + + with_test_prefix "test frame level update" { + gdb_test "up" "call1.*" "move to frame 1" + gdb_test "print /x \$pl3_ssp" "= $ssp_call1" "check pl3_ssp of frame 1" + gdb_test "up" "main.*" "move to frame 2" + gdb_test "print /x \$pl3_ssp" "= $ssp_main" "check pl3_ssp of frame 2" + gdb_test "frame 0" "call2.*" "move to frame 0" + gdb_test "print /x \$pl3_ssp" "= $ssp_call2" "check pl3_ssp of frame 0" + } + + with_test_prefix "test return from current frame" { + gdb_test "return (int) 1" "#0.*call1.*" \ + "Test shadow stack return from current frame" \ + "Make.*return now\\? \\(y or n\\) " "y" + + # Potential CET violations often only occur after resuming normal execution. + # Therefore, it is important to test normal program continuation after + # testing the return command. + gdb_continue_to_end + } + + clean_restart ${::testfile} + if { ![runto_main] } { + return -1 + } + + with_test_prefix "test return from past frame" { + gdb_breakpoint $call2_line + gdb_continue_to_breakpoint "break call2" ".*break call2.*" + + gdb_test "frame 1" ".*in call1.*" + + gdb_test "return (int) 1" "#0.*main.*" \ + "Test shadow stack return from past frame" \ + "Make.*return now\\? \\(y or n\\) " "y" + + # Potential CET violations often only occur after resuming normal execution. + # Therefore, it is important to test normal program continuation after + # testing the return command. + gdb_continue_to_end + } +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.c b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.c new file mode 100644 index 0000000..5e84793 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.c @@ -0,0 +1,46 @@ +/* This test program 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/>. */ + +#include <stdio.h> + +/* Call the return instruction before function epilogue to trigger a + control-flow exception. */ +void +function () +{ + unsigned long ssp; + #ifndef __ILP32__ + asm volatile ("xor %0, %0; rdsspq %0" : "=r" (ssp)); + #else + asm volatile ("xor %0, %0; rdsspd %0" : "=r" (ssp)); + #endif + + /* Print ssp to stdout so that the testcase can capture it. */ + printf ("%p\n", (void *) ssp); + fflush (stdout); + + /* Manually cause a control-flow exception by executing a return + instruction before function epilogue, so the address atop the stack + is not the return instruction. */ + __asm__ volatile ("ret\n"); +} + +int +main (void) +{ + function (); /* Break here. */ +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp new file mode 100644 index 0000000..039f528 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp @@ -0,0 +1,119 @@ +# Copyright 2024-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 the shadow stack pointer note in core dumps. +# Based on the corefile tests in gdb.arch/aarch64-gcs-core.exp. + +require allow_ssp_tests + +standard_testfile + +# Make sure GDB can read the given core file correctly. + +proc check_core_file {core_filename saved_pl3_ssp} { + global decimal + + # Load the core file. + if [gdb_test "core $core_filename" \ + [multi_line \ + "Core was generated by .*\\." \ + "Program terminated with signal SIGSEGV, Segmentation fault.*" \ + "#0 function \\(\\) at .*amd64-shadow-stack-corefile.c:$decimal" \ + "$decimal.*__asm__ volatile \\(\"ret\\\\n\"\\);"] \ + "load core file"] { + return + } + + # Check the value of ssp in the core file. + gdb_test "print/x \$pl3_ssp" "\\$\[0-9\]+ = $saved_pl3_ssp" \ + "pl3_ssp contents from core file $saved_pl3_ssp" +} + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ + {debug additional_flags="-fcf-protection=return"}] } { + return + } + + set linespec ${srcfile}:[gdb_get_line_number "Break here"] + + if ![runto $linespec] { + return + } + + # Obtain an OS-generated core file. Save test program output to + # ${binfile}.out. + set core_filename [core_find $binfile {} {} "${binfile}.out"] + set core_generated [expr {$core_filename != ""}] + + if {!$core_generated} { + untested "unable to create or find corefile" + } + + # Load the core file and check the value of the shadow stack pointer. + if {$core_generated} { + clean_restart $::testfile + + with_test_prefix "OS corefile" { + # Read ssp value from saved output of the test program. + set out_id [open ${binfile}.out "r"] + set ssp_in_gcore [gets $out_id] + close $out_id + check_core_file $core_filename $ssp_in_gcore + } + } + + if ![gcore_cmd_available] { + unsupported "target does not support gcore command." + return + } + + clean_restart $::testfile + + if ![runto $linespec] { + return + } + + # Continue until a crash. The line with the hex number is optional because + # it's printed by the test program, and doesn't appear in the Expect buffer + # when testing a remote target. + + gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "($hex\r\n)?" \ + "Program received signal SIGSEGV, Segmentation fault.*" \ + "function \\(\\) at .*amd64-shadow-stack-corefile.c:$decimal" \ + {.*__asm__ volatile \("ret\\n"\);}] \ + "continue to SIGSEGV" + + set ssp_in_gcore [get_valueof "/x" "\$pl3_ssp" "*unknown*"] + + # Generate the gcore core file. + set gcore_filename [standard_output_file "${testfile}.gcore"] + set gcore_generated [gdb_gcore_cmd "$gcore_filename" "generate gcore file"] + + gdb_assert { $gcore_generated } "gcore corefile created" + if { $gcore_generated } { + clean_restart $::testfile + + with_test_prefix "gcore corefile" { + check_core_file $gcore_filename $ssp_in_gcore + } + } +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp new file mode 100644 index 0000000..e4efa00 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp @@ -0,0 +1,84 @@ +# 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 continue from call instructions with shadow stack and displaced +# stepping being enabled. + +require allow_ssp_tests support_displaced_stepping + +standard_testfile amd64-shadow-stack.c + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + additional_flags="-fcf-protection=return"] } { + return + } + + # Enable displaced stepping. + gdb_test_no_output "set displaced-stepping on" + gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*" + + if { ![runto_main] } { + return + } + + # Get the address of the call to the call1 function. + set call1_addr -1 + gdb_test_multiple "disassemble main" "" { + -re -wrap "($hex) <\\+($decimal)>:\\s*call\\s*0x.*<call1>.*" { + set call1_addr $expect_out(1,string) + pass $gdb_test_name + } + } + + if { $call1_addr == -1 } { + return + } + + # Get the address of the call to the call2 function. + set call2_addr -1 + gdb_test_multiple "disassemble call1" "" { + -re -wrap "($hex) <\\+($decimal)>:\\s*call\\s*0x.*<call2>.*" { + set call2_addr $expect_out(1,string) + pass $gdb_test_name + } + } + + if { $call2_addr == -1 } { + return + } + + gdb_test "break *$call1_addr" \ + "Breakpoint $decimal at $hex.*" \ + "break at the address of the call1 instruction" + + gdb_test "break *$call2_addr" \ + "Breakpoint $decimal at $hex.*" \ + "break at the address of the call2 instruction" + + gdb_test "continue" \ + "Breakpoint $decimal, $call1_addr in main ().*" \ + "continue until call1 instruction" + + # Test continue from breakpoint at call1 and call2 instructions. + gdb_test "continue" \ + "Breakpoint $decimal, $call2_addr in call1 ().*" \ + "continue from call1 instruction" + + gdb_continue_to_end "continue from call2 instruction" +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack.c b/gdb/testsuite/gdb.arch/amd64-shadow-stack.c new file mode 100644 index 0000000..4a1ca1e --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack.c @@ -0,0 +1,40 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +static int +call2 () +{ + return 42; /* break call2. */ +} + +static int +call1 () +{ + return call2 (); /* break call1. */ +} + +int +main () +{ + /* Depending on instruction generation we might end up in the call + instruction of call1 function after "runto_main". Avoid this by + adding a nop instruction, to simplify the testing in + amd64-shadow-stack-disp-step.exp. */ + asm ("nop"); + call1 (); /* break main. */ + return 0; +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack.exp new file mode 100644 index 0000000..e9f6fa6 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack.exp @@ -0,0 +1,71 @@ +# Copyright 2024-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 accessing the shadow stack pointer register. + +require allow_ssp_tests + +standard_testfile + +# Write PL3_SSP register with invalid shadow stack pointer value. +proc write_invalid_ssp {} { + gdb_test "print /x \$pl3_ssp = 0x12345678" "= 0x12345678" "set pl3_ssp value" + gdb_test "print /x \$pl3_ssp" "= 0x12345678" "read pl3_ssp value after setting" +} + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + additional_flags="-fcf-protection=return"] } { + return + } + + if {![runto_main]} { + return + } + + with_test_prefix "invalid ssp" { + write_invalid_ssp + + # Continue until SIGSEV to test that the value is written back to HW. + gdb_test "continue" \ + [multi_line \ + "Continuing\\." \ + "" \ + "Program received signal SIGSEGV, Segmentation fault\\." \ + "$hex in main \\(\\)"] \ + "continue to SIGSEGV" + } + + clean_restart ${::testfile} + if { ![runto_main] } { + return + } + + with_test_prefix "restore original ssp" { + # Read PL3_SSP register. + set ssp_main [get_hexadecimal_valueof "\$pl3_ssp" "read pl3_ssp value"] + + write_invalid_ssp + + # Restore original value. + gdb_test "print /x \$pl3_ssp = $ssp_main" "= $ssp_main" "restore original value" + + # Now we should not see a SIGSEV, since the original value is restored. + gdb_continue_to_end + } +} diff --git a/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp b/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp index dcee040..5663b0d 100644 --- a/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp +++ b/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp @@ -58,7 +58,7 @@ gdb_test "starti" \ [multi_line \ "warning: watchpoint $num downgraded to software watchpoint" \ "" \ - "Program stopped\\." \ + "(Program|Thread \[^\r\n\]) stopped\\." \ ".*"] # Watchpoint should now have downgraded to a s/w watchpoint. diff --git a/gdb/testsuite/gdb.arch/amd64-word.exp b/gdb/testsuite/gdb.arch/amd64-word.exp index d5dfb02..8a6b28d 100644 --- a/gdb/testsuite/gdb.arch/amd64-word.exp +++ b/gdb/testsuite/gdb.arch/amd64-word.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp index 892cfba..9cbf71d 100644 --- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.exp @@ -34,7 +34,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -clean_restart ${binfile} +clean_restart $testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp index c474a99..4cbb12e 100644 --- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -clean_restart ${binfile} +clean_restart $testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.exp b/gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.exp index 15c4050..32f085a 100644 --- a/gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.exp +++ b/gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.exp @@ -33,7 +33,7 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile} \ save_vars { GDBFLAGS } { append GDBFLAGS " --readnever" - if { [clean_restart ${binfile}] == -1 } { + if { [clean_restart $testfile] == -1 } { return -1 } } diff --git a/gdb/testsuite/gdb.arch/e500-prologue.exp b/gdb/testsuite/gdb.arch/e500-prologue.exp index e8f3ebd..b1eb865 100644 --- a/gdb/testsuite/gdb.arch/e500-prologue.exp +++ b/gdb/testsuite/gdb.arch/e500-prologue.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # Insert a breakpoint in FUNCTION and verifies that the breakpoint was # inserted at the expected location. EXPECTED_LOCATION should be an diff --git a/gdb/testsuite/gdb.arch/e500-regs.exp b/gdb/testsuite/gdb.arch/e500-regs.exp index 543ce63..6d69ccc 100644 --- a/gdb/testsuite/gdb.arch/e500-regs.exp +++ b/gdb/testsuite/gdb.arch/e500-regs.exp @@ -136,7 +136,8 @@ gdb_expect_list "info vector" ".*$gdb_prompt $" { # We must restart everything, because we have set important registers to # some unusual values. -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.arch/gdb1291.exp b/gdb/testsuite/gdb.arch/gdb1291.exp index ad3b8f9..9f460c8 100644 --- a/gdb/testsuite/gdb.arch/gdb1291.exp +++ b/gdb/testsuite/gdb.arch/gdb1291.exp @@ -33,7 +33,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ""] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/gdb1431.exp b/gdb/testsuite/gdb.arch/gdb1431.exp index 34bc8d6..bc65d26 100644 --- a/gdb/testsuite/gdb.arch/gdb1431.exp +++ b/gdb/testsuite/gdb.arch/gdb1431.exp @@ -35,7 +35,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ""] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/gdb1558.exp b/gdb/testsuite/gdb.arch/gdb1558.exp index f690468..3de5723 100644 --- a/gdb/testsuite/gdb.arch/gdb1558.exp +++ b/gdb/testsuite/gdb.arch/gdb1558.exp @@ -32,7 +32,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {"add return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_test "b -q main" "Breakpoint 1.*" "set breakpoint at main" gdb_test "b -q sub1" "Breakpoint 2.*" "set breakpoint at sub1" diff --git a/gdb/testsuite/gdb.arch/i386-avx.exp b/gdb/testsuite/gdb.arch/i386-avx.exp index 8f07a3d..ba41a8c 100644 --- a/gdb/testsuite/gdb.arch/i386-avx.exp +++ b/gdb/testsuite/gdb.arch/i386-avx.exp @@ -42,7 +42,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 @@ -93,7 +93,7 @@ with_test_prefix "force-disable xml descriptions" { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set remote target-features-packet off\"" - clean_restart ${binfile} + clean_restart ${::testfile} } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.arch/i386-bp_permanent.exp b/gdb/testsuite/gdb.arch/i386-bp_permanent.exp index 1d3713f..6eb9ee6 100644 --- a/gdb/testsuite/gdb.arch/i386-bp_permanent.exp +++ b/gdb/testsuite/gdb.arch/i386-bp_permanent.exp @@ -33,7 +33,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list } -clean_restart $binfile +clean_restart $::testfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/i386-byte.exp b/gdb/testsuite/gdb.arch/i386-byte.exp index dcbcb40..1eff977 100644 --- a/gdb/testsuite/gdb.arch/i386-byte.exp +++ b/gdb/testsuite/gdb.arch/i386-byte.exp @@ -28,7 +28,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/i386-disp-step-self-call-alarm.c b/gdb/testsuite/gdb.arch/i386-disp-step-self-call-alarm.c index 03b868c..0fb2904 100644 --- a/gdb/testsuite/gdb.arch/i386-disp-step-self-call-alarm.c +++ b/gdb/testsuite/gdb.arch/i386-disp-step-self-call-alarm.c @@ -16,9 +16,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <unistd.h> +#include <stdlib.h> + +extern void test_call (void); + +void +unreachable (void) +{ + abort (); +} void setup_alarm (void) { alarm (300); } + +int +main () +{ + setup_alarm (); + test_call (); + unreachable (); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.S b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.S index 466e50c..20a8eb7 100644 --- a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.S +++ b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.S @@ -18,33 +18,12 @@ handling. */ .text - - .global main -main: - nop - - call setup_alarm - - nop - -/***********************************************/ - -/* test call/ret */ - .global test_call test_call: call test_call - nop + call unreachable .global test_ret_end test_ret_end: nop -/***********************************************/ - -/* all done */ - -done: - pushl $0 - call exit - hlt .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.arch/i386-dr3-watch.exp b/gdb/testsuite/gdb.arch/i386-dr3-watch.exp index 4fe2608..11b4773 100644 --- a/gdb/testsuite/gdb.arch/i386-dr3-watch.exp +++ b/gdb/testsuite/gdb.arch/i386-dr3-watch.exp @@ -23,7 +23,7 @@ require {is_any_target "i?86-*-*" "x86_64-*-*"} standard_testfile -if [prepare_for_testing "failed to prepare" ${binfile} ${srcfile} {debug $additional_flags}] { +if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug $additional_flags}] { return -1 } diff --git a/gdb/testsuite/gdb.arch/i386-gnu-cfi.exp b/gdb/testsuite/gdb.arch/i386-gnu-cfi.exp index b51f034..c446fae 100644 --- a/gdb/testsuite/gdb.arch/i386-gnu-cfi.exp +++ b/gdb/testsuite/gdb.arch/i386-gnu-cfi.exp @@ -40,7 +40,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfilec} ${srcdir}/${subdir}/${srcfile # Get things started. -clean_restart $binfile +clean_restart $::testfile # We should stop in abort(3). diff --git a/gdb/testsuite/gdb.arch/i386-permbkpt.exp b/gdb/testsuite/gdb.arch/i386-permbkpt.exp index b979d6e..1118cb4 100644 --- a/gdb/testsuite/gdb.arch/i386-permbkpt.exp +++ b/gdb/testsuite/gdb.arch/i386-permbkpt.exp @@ -30,7 +30,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test "break -q main" "" "first permanent break" gdb_test "break -q main" "" "second permanent break" diff --git a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c new file mode 100644 index 0000000..f55cee5 --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c @@ -0,0 +1,27 @@ +/* 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/>. */ + +#include <alloca.h> + +int +main (int argc, char **argv) +{ + volatile __attribute__ ((__aligned__ (64))) int a; + volatile char *p = (char *) alloca (argc * 12); + p[2] = 'b'; + return 1; +} diff --git a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp index eb93127..b289b84 100644 --- a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp +++ b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp @@ -19,41 +19,65 @@ # This option places an `endbr32`/`endbr64` instruction at the start of # all functions, which can interfere with prologue analysis. -standard_testfile .c -set binfile ${binfile} +standard_testfile .c -stackalign.c require {is_any_target x86_64-*-* i?86-*-*} - require supports_fcf_protection -set opts {debug additional_flags=-fcf-protection=full} +# Tests if breakpoint set on main is placed past main's entry. +proc test_run {} { + # Get start address of function main. + set main_addr [get_integer_valueof &main -1] + gdb_assert {$main_addr != -1} -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts] != "" } { - untested "failed to compile" - return -} + set bp_addr -1 -clean_restart ${binfile} + # Put breakpoint on main, get the address where the breakpoint was installed. + gdb_test_multiple "break -q main" "break on main, get address" { + -re -wrap "Breakpoint $::decimal at ($::hex).*" { + set bp_addr $expect_out(1,string) -# Get start address of function main. -set main_addr [get_integer_valueof &main -1] -gdb_assert {$main_addr != -1} + # Convert to decimal. + set bp_addr [expr $bp_addr] -set bp_addr -1 + pass $gdb_test_name + } + } -# Put breakpoint on main, get the address where the breakpoint was installed. -gdb_test_multiple "break -q main" "break on main, get address" { - -re -wrap "Breakpoint $decimal at ($hex).*" { - set bp_addr $expect_out(1,string) + # Make sure some prologue was skipped. + gdb_assert {$bp_addr != -1 && $bp_addr > $main_addr} \ + "breakpoint placed past main's entry" +} - # Convert to decimal. - set bp_addr [expr $bp_addr] +with_test_prefix "skip-cf-protection" { + set opts {debug additional_flags=-fcf-protection=full} - pass $gdb_test_name + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + $opts] != "" } { + untested "failed to compile" + return } + + clean_restart ${::testfile} + + test_run } -if { $bp_addr != -1 } { - # Make sure some prologue was skipped. - gdb_assert {$bp_addr > $main_addr} +# Now, make sure that the prologue analysis does not end up at function's entry +# when stack alignment sequence is generated right after 'endbr64'/'endbr32'. +# That could happen if GDB handled those incorrectly - there was a bug that +# checked for those two in incorrect order, which caused such issue. +with_test_prefix "skip-cf-protection-stackalign" { + # gcc is easier to make it produce the sequence of interest. + if { ![is_c_compiler_gcc] } { + unsupported "stackalign test part requires gcc compiler" + return + } + + if { [prepare_for_testing "failed to prepare" "${testfile}-stackalign" \ + $srcfile2 [list optimize=-O0 additional_flags=-fcf-protection=full]] } { + return + } + + test_run } diff --git a/gdb/testsuite/gdb.arch/i386-prologue.exp b/gdb/testsuite/gdb.arch/i386-prologue.exp index 72246f4..bfab6d1 100644 --- a/gdb/testsuite/gdb.arch/i386-prologue.exp +++ b/gdb/testsuite/gdb.arch/i386-prologue.exp @@ -53,7 +53,7 @@ proc skip_breakpoint { msg } { } -clean_restart $binfile +clean_restart $::testfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/i386-signal.exp b/gdb/testsuite/gdb.arch/i386-signal.exp index 30f212b..80d1827 100644 --- a/gdb/testsuite/gdb.arch/i386-signal.exp +++ b/gdb/testsuite/gdb.arch/i386-signal.exp @@ -30,7 +30,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart $binfile +clean_restart $::testfile runto func gdb_test "backtrace 10" \ diff --git a/gdb/testsuite/gdb.arch/i386-size-overlap.exp b/gdb/testsuite/gdb.arch/i386-size-overlap.exp index ca8383d..db88673 100644 --- a/gdb/testsuite/gdb.arch/i386-size-overlap.exp +++ b/gdb/testsuite/gdb.arch/i386-size-overlap.exp @@ -30,7 +30,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart $binfile +clean_restart $::testfile # We use gdb_run_cmd so this stands a chance to work for remote # targets too. diff --git a/gdb/testsuite/gdb.arch/i386-size.exp b/gdb/testsuite/gdb.arch/i386-size.exp index b08182f..997e629 100644 --- a/gdb/testsuite/gdb.arch/i386-size.exp +++ b/gdb/testsuite/gdb.arch/i386-size.exp @@ -35,7 +35,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart $binfile +clean_restart $::testfile # We use gdb_run_cmd so this stands a chance to work for remote # targets too. diff --git a/gdb/testsuite/gdb.arch/i386-sse.exp b/gdb/testsuite/gdb.arch/i386-sse.exp index f0aa5ec..154f5ea 100644 --- a/gdb/testsuite/gdb.arch/i386-sse.exp +++ b/gdb/testsuite/gdb.arch/i386-sse.exp @@ -40,7 +40,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/i386-unwind.exp b/gdb/testsuite/gdb.arch/i386-unwind.exp index 99acfe9..76f0a78 100644 --- a/gdb/testsuite/gdb.arch/i386-unwind.exp +++ b/gdb/testsuite/gdb.arch/i386-unwind.exp @@ -33,7 +33,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return -1 } -clean_restart $binfile +clean_restart $::testfile # Testcase for backtrace/1435. diff --git a/gdb/testsuite/gdb.arch/i386-word.exp b/gdb/testsuite/gdb.arch/i386-word.exp index 0da49c0..ed02d27 100644 --- a/gdb/testsuite/gdb.arch/i386-word.exp +++ b/gdb/testsuite/gdb.arch/i386-word.exp @@ -28,7 +28,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list return } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.arch/ia64-breakpoint-shadow.exp b/gdb/testsuite/gdb.arch/ia64-breakpoint-shadow.exp index 8e8ed9b..d6fd14c 100644 --- a/gdb/testsuite/gdb.arch/ia64-breakpoint-shadow.exp +++ b/gdb/testsuite/gdb.arch/ia64-breakpoint-shadow.exp @@ -23,7 +23,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # We need to start the inferior to place the breakpoints in the memory at all. if ![runto_main] { diff --git a/gdb/testsuite/gdb.arch/mips-fpregset-core.exp b/gdb/testsuite/gdb.arch/mips-fpregset-core.exp index aa55ede..d67cef2 100644 --- a/gdb/testsuite/gdb.arch/mips-fpregset-core.exp +++ b/gdb/testsuite/gdb.arch/mips-fpregset-core.exp @@ -79,7 +79,8 @@ set core_supported [expr {$corefile != ""}] # Generate a core file with "gcore". -clean_restart ${binfile} +clean_restart +gdb_load $binfile runto break_here @@ -116,7 +117,8 @@ proc mips_fpregset_core_test { supported corefile } { upvar host_triplet host_triplet upvar binfile binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile set test "load core file" if { $supported } { diff --git a/gdb/testsuite/gdb.arch/mips-octeon-bbit.exp b/gdb/testsuite/gdb.arch/mips-octeon-bbit.exp index 3fb6f9c..f43127d 100644 --- a/gdb/testsuite/gdb.arch/mips-octeon-bbit.exp +++ b/gdb/testsuite/gdb.arch/mips-octeon-bbit.exp @@ -86,7 +86,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ pass "compilation" -clean_restart $binfile +clean_restart +gdb_load $binfile # Native needs run. runto_main diff --git a/gdb/testsuite/gdb.arch/pa-nullify.exp b/gdb/testsuite/gdb.arch/pa-nullify.exp index 87afe7a..ad246ca 100644 --- a/gdb/testsuite/gdb.arch/pa-nullify.exp +++ b/gdb/testsuite/gdb.arch/pa-nullify.exp @@ -40,7 +40,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # In the first test, we do a "step" on a function whose last instruction # contains a branch-with-nullify. The instruction in the delay slot belongs diff --git a/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp index 13e3fd3..f95bddf 100644 --- a/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp +++ b/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp @@ -28,7 +28,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] ! return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # Insert a breakpoint in FUNCTION and verifies that the breakpoint was # inserted at the expected location. EXPECTED_LOCATION should be an diff --git a/gdb/testsuite/gdb.arch/powerpc-altivec.exp b/gdb/testsuite/gdb.arch/powerpc-altivec.exp index 987da07..bc8ff7a 100644 --- a/gdb/testsuite/gdb.arch/powerpc-altivec.exp +++ b/gdb/testsuite/gdb.arch/powerpc-altivec.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-altivec2.exp b/gdb/testsuite/gdb.arch/powerpc-altivec2.exp index 3bf7c57..6fddd34 100644 --- a/gdb/testsuite/gdb.arch/powerpc-altivec2.exp +++ b/gdb/testsuite/gdb.arch/powerpc-altivec2.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-altivec3.exp b/gdb/testsuite/gdb.arch/powerpc-altivec3.exp index ff1d79a..7b1d0c3 100644 --- a/gdb/testsuite/gdb.arch/powerpc-altivec3.exp +++ b/gdb/testsuite/gdb.arch/powerpc-altivec3.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp b/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp index 42fc51e..cb5a371 100644 --- a/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp +++ b/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {qui return -1 } -clean_restart $binfile +clean_restart $::testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/powerpc-fpscr-gcore.exp b/gdb/testsuite/gdb.arch/powerpc-fpscr-gcore.exp index a7614fa..13163d2 100644 --- a/gdb/testsuite/gdb.arch/powerpc-fpscr-gcore.exp +++ b/gdb/testsuite/gdb.arch/powerpc-fpscr-gcore.exp @@ -34,7 +34,7 @@ if {[build_executable "compile" $binfile $gen_src] == -1} { return -1 } -clean_restart $binfile +clean_restart $testfile if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp index 6fcb69f..5e2923f 100644 --- a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp +++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp @@ -82,7 +82,8 @@ with_test_prefix "check htm support" { return } - clean_restart $binfile + clean_restart + gdb_load $binfile # Displaced-stepping a tbegin. causes problems, # so we make the breakpoint temporary. @@ -131,7 +132,7 @@ if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { return } -clean_restart $binfile +clean_restart $testfile gdb_breakpoint [gdb_get_line_number "first marker"] temporary diff --git a/gdb/testsuite/gdb.arch/powerpc-power10.exp b/gdb/testsuite/gdb.arch/powerpc-power10.exp index 1bb7174..124baaf 100644 --- a/gdb/testsuite/gdb.arch/powerpc-power10.exp +++ b/gdb/testsuite/gdb.arch/powerpc-power10.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.exp b/gdb/testsuite/gdb.arch/powerpc-power7.exp index f33405d..8885a91 100644 --- a/gdb/testsuite/gdb.arch/powerpc-power7.exp +++ b/gdb/testsuite/gdb.arch/powerpc-power7.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-power8.exp b/gdb/testsuite/gdb.arch/powerpc-power8.exp index ab69b0f..f740ae8 100644 --- a/gdb/testsuite/gdb.arch/powerpc-power8.exp +++ b/gdb/testsuite/gdb.arch/powerpc-power8.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-power9.exp b/gdb/testsuite/gdb.arch/powerpc-power9.exp index b1bfa9d..8dcf536 100644 --- a/gdb/testsuite/gdb.arch/powerpc-power9.exp +++ b/gdb/testsuite/gdb.arch/powerpc-power9.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp index ef6bb9d..1b4c608 100644 --- a/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp +++ b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp @@ -66,7 +66,7 @@ proc ppr_dscr_available {} { } with_test_prefix "check PPR/DSCR access" { - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return @@ -86,7 +86,7 @@ with_test_prefix "check PPR/DSCR access" { } # Now do the actual test -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp index 3c79039..156a70e 100644 --- a/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp +++ b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp @@ -26,7 +26,7 @@ if {[gdb_compile \ } -clean_restart ${binfile} +clean_restart $testfile if ![runto bar] { untested "could not run to bar" diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-prologue.exp index 4e697c1..44877a1 100644 --- a/gdb/testsuite/gdb.arch/powerpc-prologue.exp +++ b/gdb/testsuite/gdb.arch/powerpc-prologue.exp @@ -31,7 +31,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] ! } -clean_restart $binfile +clean_restart $testfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/powerpc-tar.exp b/gdb/testsuite/gdb.arch/powerpc-tar.exp index b44d554..a060ec8 100644 --- a/gdb/testsuite/gdb.arch/powerpc-tar.exp +++ b/gdb/testsuite/gdb.arch/powerpc-tar.exp @@ -68,7 +68,7 @@ proc tar_available {} { # Do one pass to check if TAR is usable, system # software can prevent it from being used. with_test_prefix "check TAR access" { - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return @@ -84,7 +84,7 @@ with_test_prefix "check TAR access" { } # Now do the actual test -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return diff --git a/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp index 9e9162e..4537646 100644 --- a/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp +++ b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp @@ -30,7 +30,7 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable {debug}] } # Check if our test binary can actually run on this processor. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_run_cmd @@ -44,7 +44,7 @@ gdb_test_multiple "" "wait for exit" { } # Run the actual test. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_breakpoint [gdb_get_line_number "marker"] diff --git a/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp b/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp index be1f93a..db568c6 100644 --- a/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp +++ b/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp @@ -34,7 +34,7 @@ if {[build_executable "compile" $binfile $gen_src] == -1} { return -1 } -clean_restart $binfile +clean_restart $testfile if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.arch/powerpc-vsx.exp b/gdb/testsuite/gdb.arch/powerpc-vsx.exp index a6832e6..73a0fdc 100644 --- a/gdb/testsuite/gdb.arch/powerpc-vsx.exp +++ b/gdb/testsuite/gdb.arch/powerpc-vsx.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-vsx2.exp b/gdb/testsuite/gdb.arch/powerpc-vsx2.exp index d5cb18e..dfee7a3 100644 --- a/gdb/testsuite/gdb.arch/powerpc-vsx2.exp +++ b/gdb/testsuite/gdb.arch/powerpc-vsx2.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/powerpc-vsx3.exp b/gdb/testsuite/gdb.arch/powerpc-vsx3.exp index bd54eaf..fd725f9 100644 --- a/gdb/testsuite/gdb.arch/powerpc-vsx3.exp +++ b/gdb/testsuite/gdb.arch/powerpc-vsx3.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] return -1 } -clean_restart ${objfile} +clean_restart +gdb_load $objfile # Disassemble the function. set func "" diff --git a/gdb/testsuite/gdb.arch/ppc-dfp.exp b/gdb/testsuite/gdb.arch/ppc-dfp.exp index d7a8312..20145ae 100644 --- a/gdb/testsuite/gdb.arch/ppc-dfp.exp +++ b/gdb/testsuite/gdb.arch/ppc-dfp.exp @@ -31,7 +31,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {quie return -1 } -clean_restart $binfile +clean_restart $::testfile gdb_breakpoint [gdb_get_line_number "Set DFP rounding mode."] diff --git a/gdb/testsuite/gdb.arch/ppc-fp.exp b/gdb/testsuite/gdb.arch/ppc-fp.exp index 4733296..c8342bb 100644 --- a/gdb/testsuite/gdb.arch/ppc-fp.exp +++ b/gdb/testsuite/gdb.arch/ppc-fp.exp @@ -31,7 +31,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {quie return -1 } -clean_restart $binfile +clean_restart $::testfile gdb_breakpoint [gdb_get_line_number "Invalid operation."] gdb_breakpoint [gdb_get_line_number "Division by zero."] diff --git a/gdb/testsuite/gdb.arch/ppc-longdouble.exp b/gdb/testsuite/gdb.arch/ppc-longdouble.exp index f3603f1..739e36f 100644 --- a/gdb/testsuite/gdb.arch/ppc-longdouble.exp +++ b/gdb/testsuite/gdb.arch/ppc-longdouble.exp @@ -28,7 +28,7 @@ proc do_test { name {opts {}} } { return } - clean_restart ${binfile}.${name} + clean_restart ${::testfile}.${name} if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.arch/pr25124.exp b/gdb/testsuite/gdb.arch/pr25124.exp index 4c43716..4e7c114 100644 --- a/gdb/testsuite/gdb.arch/pr25124.exp +++ b/gdb/testsuite/gdb.arch/pr25124.exp @@ -25,7 +25,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug return -1 } -clean_restart $binfile +clean_restart $testfile # Check if the disassemble ouput is correct. gdb_test "x /i main+8" \ diff --git a/gdb/testsuite/gdb.arch/sparc-sysstep.exp b/gdb/testsuite/gdb.arch/sparc-sysstep.exp index 40de862..4dfc514 100644 --- a/gdb/testsuite/gdb.arch/sparc-sysstep.exp +++ b/gdb/testsuite/gdb.arch/sparc-sysstep.exp @@ -28,7 +28,7 @@ set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} set opts {} -if {[prepare_for_testing "failed to prepare" ${binfile} $srcfile {additional_flags=-g}]} { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {additional_flags=-g}]} { return -1 } diff --git a/gdb/testsuite/gdb.arch/thumb-prologue.exp b/gdb/testsuite/gdb.arch/thumb-prologue.exp index 112c111..2ee82fb 100644 --- a/gdb/testsuite/gdb.arch/thumb-prologue.exp +++ b/gdb/testsuite/gdb.arch/thumb-prologue.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {"add } -clean_restart $binfile +clean_restart $testfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.arch/thumb2-it.exp b/gdb/testsuite/gdb.arch/thumb2-it.exp index 49031e1..e6ef06d 100644 --- a/gdb/testsuite/gdb.arch/thumb2-it.exp +++ b/gdb/testsuite/gdb.arch/thumb2-it.exp @@ -24,7 +24,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug return -1 } -clean_restart $binfile +clean_restart $testfile if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.arch/vsx-regs.exp b/gdb/testsuite/gdb.arch/vsx-regs.exp index 645207f..df74ef3 100644 --- a/gdb/testsuite/gdb.arch/vsx-regs.exp +++ b/gdb/testsuite/gdb.arch/vsx-regs.exp @@ -184,7 +184,8 @@ if {!$core_supported} { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"] if { $core_loaded == -1 } { diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp index e3655b1..eb96c19 100644 --- a/gdb/testsuite/gdb.asm/asm-source.exp +++ b/gdb/testsuite/gdb.asm/asm-source.exp @@ -1,5 +1,5 @@ # Copyright 1998-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 @@ -184,7 +184,7 @@ if {[istarget "*-*-openbsd*"]} { # built with different defaults. So no matter what we do, we lose. We may as # well get out of this test sooner rather than later. set dest [target_info name] -if [board_info $dest exists multilib_flags] { +if {[board_info $dest exists multilib_flags]} { set multilib_flags [board_info $dest multilib_flags] if { "${multilib_flags}" != "" } { untested "failed to compile" @@ -269,16 +269,16 @@ if { [istarget "m6811-*-*"] || [istarget "m6812-*-*"] } { } # Collect some line numbers. -set line_enter [expr [gdb_get_line_number "main enter" "asmsrc1.s"] + 1] -set line_main [expr [gdb_get_line_number "main start" "asmsrc1.s"] + 1] -set line_call_foo2 [expr [gdb_get_line_number "call foo2" "asmsrc1.s"] + 1] -set line_search_comment [expr [gdb_get_line_number "search" "asmsrc1.s"] + 1] -set line_foo3 [expr [gdb_get_line_number "foo3 start" "asmsrc1.s"] + 1] -set line_main_exit [expr [gdb_get_line_number "main exit" "asmsrc1.s"] + 1] -set line_foo2 [expr [gdb_get_line_number "foo2 start" "asmsrc2.s"] + 1] -set line_call_foo3 [expr [gdb_get_line_number "call foo3" "asmsrc2.s"] + 1] -set line_call_foo3_again [expr $line_call_foo3 + 1] -set line_foo2_leave [expr [gdb_get_line_number "foo2 leave" "asmsrc2.s"] + 1] +set line_enter [expr {[gdb_get_line_number "main enter" "asmsrc1.s"] + 1}] +set line_main [expr {[gdb_get_line_number "main start" "asmsrc1.s"] + 1}] +set line_call_foo2 [expr {[gdb_get_line_number "call foo2" "asmsrc1.s"] + 1}] +set line_search_comment [expr {[gdb_get_line_number "search" "asmsrc1.s"] + 1}] +set line_foo3 [expr {[gdb_get_line_number "foo3 start" "asmsrc1.s"] + 1}] +set line_main_exit [expr {[gdb_get_line_number "main exit" "asmsrc1.s"] + 1}] +set line_foo2 [expr {[gdb_get_line_number "foo2 start" "asmsrc2.s"] + 1}] +set line_call_foo3 [expr {[gdb_get_line_number "call foo3" "asmsrc2.s"] + 1}] +set line_call_foo3_again [expr {$line_call_foo3 + 1}] +set line_foo2_leave [expr {[gdb_get_line_number "foo2 leave" "asmsrc2.s"] + 1}] gdb_start gdb_reinitialize_dir $srcdir/$subdir @@ -346,7 +346,7 @@ gdb_test "f" ".*asmsrc2\[.\]s:$line_foo2.*" "f in foo2" # `next' one insn (or macro) to set up our stackframe (for the following bt). gdb_test "n" "$line_call_foo3\[ \]*.*foo3" "n in foo2" -# See if a simple `bt' prints the right source files and +# See if a simple `bt' prints the right source files and # doesn't fall off the stack. gdb_test "bt 10" \ @@ -405,7 +405,7 @@ gdb_test_multiple "info sources" "info sources" { set seen_asmsrc_2 1 exp_continue } - -re ", " { + -re ", " { exp_continue } -re "$gdb_prompt $" { @@ -416,7 +416,7 @@ gdb_test_multiple "info sources" "info sources" { } } } - + # Try 'info line' gdb_test "info line" \ diff --git a/gdb/testsuite/gdb.base/a2-run.exp b/gdb/testsuite/gdb.base/a2-run.exp index 4e95e56..966e12a 100644 --- a/gdb/testsuite/gdb.base/a2-run.exp +++ b/gdb/testsuite/gdb.base/a2-run.exp @@ -18,6 +18,8 @@ # Can't do this test without stdio support. require {!gdb_skip_stdio_test "a2run.exp"} +set have_startup_shell [have_startup_shell] + # # test running programs # @@ -166,9 +168,8 @@ gdb_run_cmd setup_xfail "arm-*-coff" gdb_test_stdio "" "720" "" "run \"$testfile\" again after setting args" -# GOAL: Test that shell is being used with "run". For remote debugging -# targets, there is no guarantee that a "shell" (whatever that is) is used. -if {![is_remote target]} { +# GOAL: Test that shell is being used with "run". +if { $have_startup_shell == 1 } { gdb_test_stdio "run `echo 8`" \ "40320" "" "run \"$testfile\" with shell" } diff --git a/gdb/testsuite/gdb.base/access-mem-running.exp b/gdb/testsuite/gdb.base/access-mem-running.exp index ecff427..280e89b 100644 --- a/gdb/testsuite/gdb.base/access-mem-running.exp +++ b/gdb/testsuite/gdb.base/access-mem-running.exp @@ -32,7 +32,8 @@ proc test { non_stop } { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop $non_stop\"" - clean_restart ${binfile} + clean_restart + gdb_load $binfile } if ![runto_main] { diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 06dbec2..744d825 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -533,7 +533,8 @@ proc thread_test {} { if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}] == "" } { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.base/annotate-symlink.exp b/gdb/testsuite/gdb.base/annotate-symlink.exp index f7f6f18..a5d431e 100644 --- a/gdb/testsuite/gdb.base/annotate-symlink.exp +++ b/gdb/testsuite/gdb.base/annotate-symlink.exp @@ -20,7 +20,7 @@ standard_testfile realname-expand.c realname-expand-real.c require {!is_remote host} set srcdirabs [file join [pwd] $srcdir] -set srcfilelink [standard_output_file realname-expand-link.c] +set srcfilelink [build_standard_output_file realname-expand-link.c] remote_exec build "ln -sf ${srcdirabs}/${subdir}/${srcfile2} $srcfilelink" diff --git a/gdb/testsuite/gdb.base/args.exp b/gdb/testsuite/gdb.base/args.exp index 33952e4..3930059 100644 --- a/gdb/testsuite/gdb.base/args.exp +++ b/gdb/testsuite/gdb.base/args.exp @@ -21,6 +21,7 @@ require {!target_info exists noargs} # This test requires starting new inferior processes, skip it if the target # board is a stub. require !use_gdb_stub +require {expr [have_startup_shell] != -1} standard_testfile @@ -29,74 +30,187 @@ if {[build_executable $testfile.exp $testfile $srcfile] == -1} { return -1 } -# NAME is the name to use for the tests and ARGLIST is the list of -# arguments that are passed to GDB when it is started. +# Assuming a running GDB. Check the status of the single inferior +# argument feature. When this feature is on GDB passes inferior +# arguments as a single combined string. When this feature is off GDB +# will split the inferior arguments into multiple separate strings. # -# The optional RE_LIST is the list of patterns to check the arguments -# against, these patterns should match ARGLIST. If the arguments are -# expected to show up unmodified in the test output then RE_LIST can -# be dropped, and this proc will reuse ARGLIST. - -proc args_test { name arglist {re_list {}} } { - - # If RE_LIST is not supplied then we can reuse ARGLIST, this - # implies that the arguments will appear unmodified in the test - # output. - if {[llength $re_list] == 0} { - set re_list $arglist +# Return true when arguments are being split, or false when a single +# combined string is being sent. + +proc is_argument_splitting_on {} { + set arg_splitting true + + gdb_test_multiple "show remote single-inferior-argument-feature-packet" "" { + -re -wrap "Support for the 'single-inferior-argument-feature' packet on the current remote target is \"(on|off)\"\\.(.*)" { + set value $expect_out(1,string) + pass $gdb_test_name + if { $value eq "on" } { + set arg_splitting false + } + } + -re -wrap "Support for the 'single-inferior-argument-feature' packet on the current remote target is \"auto\", currently (enabled|disabled)\\.(.*)" { + set value $expect_out(1,string) + pass $gdb_test_name + if { $value eq "enabled" } { + set arg_splitting false + } + } } - foreach_with_prefix startup_with_shell { on off } { - save_vars { ::GDBFLAGS } { - set ::GDBFLAGS "$::GDBFLAGS --args $::binfile $arglist" - - clean_restart $::binfile - - gdb_test_no_output "set startup-with-shell ${startup_with_shell}" \ - "set startup-with-shell for $name" + return $arg_splitting +} - runto_main - gdb_breakpoint [gdb_get_line_number "set breakpoint here"] - gdb_continue_to_breakpoint "breakpoint for $name" +# NAME is the name to use for the tests and ARGLIST is the list of +# arguments that are passed to GDB when it is started. +# +# The optional RE_ESC_LIST is the list of patterns to check the +# inferior arguments against when GDB is started using --args. If +# RE_ESC_LIST is not given then ARGLIST is reused, this implies that +# the inferior arguments appear unchanged in the test output. +# +# The optional RE_NO_ESC_LIST is the list of patterns to check the +# inferior arguments against when GDB is started using +# --no-escape-args. If RE_NO_ESC_LIST is not given then RE_ESC_LIST +# is reused, this implies that there's no difference between the test +# output when the arguments are escaped or not. + +proc args_test { name arglist {re_esc_list {}} {re_no_esc_list {}} } { + + # If either of the two regexp lists are not specificed then we can + # use an earlier argument value instead. + # + # For the first regexp list, if this is missing then we use the + # argument list, this assumes that the arguments will appear + # unmodified in the output. + if {[llength $re_esc_list] == 0} { + set re_esc_list $arglist + } - set expected_len [expr 1 + [llength $re_list]] - gdb_test "print argc" "\\\$$::decimal = $expected_len" "argc for $name" + # If the second regexp list is missing then we reuse the first + # regexp list. This assumes there's no difference between escaped + # and unescaped arguments in the output. + if {[llength $re_no_esc_list] == 0} { + set re_no_esc_list $re_esc_list + } - set i 1 - foreach arg $re_list { - gdb_test "print argv\[$i\]" "\\\$$::decimal = $::hex \"$arg\"" \ - "argv\[$i\] for $name" - set i [expr $i + 1] + foreach_with_prefix startup_with_shell { on off } { + foreach_with_prefix arg_flag { args no-escape-args } { + save_vars { ::GDBFLAGS } { + set ::GDBFLAGS "$::GDBFLAGS --${arg_flag} $::binfile $arglist" + + clean_restart $::testfile + + gdb_test_no_output \ + "set startup-with-shell ${startup_with_shell}" \ + "set startup-with-shell for $name" + + runto_main + gdb_breakpoint [gdb_get_line_number "set breakpoint here"] + gdb_continue_to_breakpoint "breakpoint for $name" + + if { $arg_flag eq "args" || $startup_with_shell eq "off" } { + set re_list $re_esc_list + } else { + set re_list $re_no_esc_list + } + + set expected_len [expr 1 + [llength $re_list]] + gdb_test "print argc" \ + "\\\$$::decimal = $expected_len" "argc for $name" + + set i 1 + foreach arg $re_list { + if { $arg eq "\n" } { + set arg {\\n} + } elseif { $arg eq "\"" } { + set arg {\\\"} + } + + # If we are starting with a shell, we're not escaping + # special shell characters in arguments passed to GDB, + # we're using a remote target, and the arguments contain + # a shell variable (indicated with a '$'), then this + # test will currently fail if we are splitting the + # arguments. + if { $startup_with_shell eq "on" + && $arg_flag eq "no-escape-args" + && [gdb_protocol_is_remote] + && [string first "\$" $arglist] != -1 + && [is_argument_splitting_on] } { + setup_xfail "*-*-*" gdb/28392 + } + + gdb_test "print argv\[$i\]" \ + "\\\$$::decimal = $::hex \"$arg\"" \ + "argv\[$i\] for $name" + set i [expr $i + 1] + } } } } } -# Test that the --args are processed correctly. +# Run all the tests. +proc run_all_tests {} { + # Test that the --args are processed correctly. + + args_test basic {{1} {3}} -args_test basic {{1} {3}} + # Test that the --args are processed correctly even if one of them is + # empty. -# Test that the --args are processed correctly even if one of them is -# empty. + args_test "one empty" {{1} {} {3}} -args_test "one empty" {{1} {} {3}} + # Try with 2 empty args. -# Try with 2 empty args. + args_test "two empty" {{1} {} {} 3} -args_test "two empty" {{1} {} {} 3} + # Try with arguments containing literal single quotes. -# Try with arguments containing literal single quotes. + args_test "one empty with single quotes" {{1} {''} {3}} -args_test "one empty with single quotes" {{1} {''} {3}} + args_test "two empty with single quotes" {{1} {''} {''} {3}} -args_test "two empty with single quotes" {{1} {''} {''} {3}} + # Try with arguments containing literal newlines. -# Try with arguments containing literal newlines. + args_test "one newline" {{1} "\n" {3}} {1 \\\\n 3} -args_test "one newline" {{1} "\n" {3}} {1 \\\\n 3} + args_test "two newlines" {{1} "\n" "\n" {3}} {1 \\\\n \\\\n 3} -args_test "two newlines" {{1} "\n" "\n" {3}} {1 \\\\n \\\\n 3} + args_test "lone single quote" {{1} \' {3}} -args_test "lone single quote" {{1} \' {3}} + args_test "lone double quote" {{1} \" {3}} {1 \\\\\" 3} -args_test "lone double quote" {{1} \" {3}} {1 \\\\\" 3} + save_vars { ::env(TEST) } { + set ::env(TEST) "ABCD" + args_test "shell variable" {{$TEST}} {\\$TEST} {{ABCD}} + } + + # At one point we had a bug where, if the last inferior argument, + # appearing after --args, looked like an option GDB might be able + # to process, e.g. started with a dash, then GDB would try to + # process it. This would leave GDB in a broken state, and so GDB + # would fail to start. A example of a failing GDB command line: + # $ gdb --args /bin/ls --all + foreach_with_prefix flag { args no-escape-args } { + args_test "with trailing GDB flag" [list "--${flag}"] + } + args_test "with trailing GDB option and value" [list "--ex" "start"] + args_test "with trailing double dash option" [list "--foo"] + args_test "with trailing single dash option" [list "-foo"] +} + +run_all_tests + +# For extended-remote targets, disable the packet which passes +# inferior arguments as a single string. This changes how the vRun +# (extended-remote only) packet works. +if {[target_info gdb_protocol] == "extended-remote"} { + with_test_prefix "single-inferior-arg disabled" { + save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"set remote single-inferior-argument-feature-packet off\"" + run_all_tests + } + } +} diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp index 4fc221f..757ce92 100644 --- a/gdb/testsuite/gdb.base/arrayidx.exp +++ b/gdb/testsuite/gdb.base/arrayidx.exp @@ -24,7 +24,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/assign.exp b/gdb/testsuite/gdb.base/assign.exp index a69655d..aaee796 100644 --- a/gdb/testsuite/gdb.base/assign.exp +++ b/gdb/testsuite/gdb.base/assign.exp @@ -33,7 +33,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # diff --git a/gdb/testsuite/gdb.base/attach-deleted-exec.exp b/gdb/testsuite/gdb.base/attach-deleted-exec.exp index 82a7bb4..45fac0d 100644 --- a/gdb/testsuite/gdb.base/attach-deleted-exec.exp +++ b/gdb/testsuite/gdb.base/attach-deleted-exec.exp @@ -67,5 +67,49 @@ if { [regexp $re_nfs $filename] } { gdb_assert { [string equal $filename /proc/${testpid}/exe] } $test } +# Restart GDB. +clean_restart + +# Setup an empty sysroot. GDB will fail to find the executable within +# the sysroot. Additionally, the presence of a sysroot should prevent +# GDB from trying to load the executable from /proc/PID/exe. +set sysroot [standard_output_file "sysroot"] +gdb_test_no_output "set sysroot $sysroot" \ + "setup sysroot" + +# Attach to the inferior. GDB should complain about failing to find +# the executable. It is the name of the executable that GDB doesn't +# find that we're interesting in here. For native targets GDB should +# be looking for BINFILE, not /proc/PID/exe. +# +# For extended-remote targets things are unfortunately harder. Native +# GDB looks for BINFILE because it understands that GDB will be +# looking in the sysroot. But remote GDB doesn't know if GDB is using +# a sysroot or not. As such, gdbserver will return /proc/PID/exe if +# it knows that the file has been deleted locally. This isn't great +# if GDB then plans to look in a sysroot, but equally, if the remote +# file has been deleted, then the name GDB will return, will have had +# " (deleted" appended, so we're unlikely to get a hit in the sysroot +# either way. +if { [target_info gdb_protocol] == "extended-remote" } { + set filename_re "/proc/$testpid/exe" +} else { + set filename_re "\[^\r\n\]+/${testfile} \\(deleted\\)" +} + +verbose -log "APB: warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\." + +gdb_test "attach $testpid" \ + [multi_line \ + "Attaching to process $decimal" \ + "warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\." \ + ".*"] \ + "attach to inferior" + +# Check GDB hasn't managed to load an executable. +gdb_test "info inferior" \ + "\\*\[^)\]+\\)\\s*" \ + "confirm no executable is loaded." + # Cleanup. kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.base/attach-fail-twice.exp b/gdb/testsuite/gdb.base/attach-fail-twice.exp index 529002d..5e5d73f 100644 --- a/gdb/testsuite/gdb.base/attach-fail-twice.exp +++ b/gdb/testsuite/gdb.base/attach-fail-twice.exp @@ -77,7 +77,8 @@ proc test_good_attach {test} { } proc_with_prefix test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile # GDB used to have a bug on Windows where failing to attach once # made a subsequent "attach" or "run" hang. So it's important for diff --git a/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp b/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp index 2ce092d..c43a11c 100644 --- a/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp +++ b/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp @@ -36,7 +36,8 @@ proc do_test {} { # Attach to the parent, run it to a known point, extract the # child's PID, and detach. with_test_prefix "parent" { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test "attach $parent_pid" \ "Attaching to program.*, process $parent_pid.*" \ @@ -56,7 +57,8 @@ proc do_test {} { # Start over, and attach to the child this time. with_test_prefix "child" { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "attach $child_pid" \ "Attaching to program.*, process $child_pid.*" \ diff --git a/gdb/testsuite/gdb.base/attach-twice.exp b/gdb/testsuite/gdb.base/attach-twice.exp index 3d74298..63205e2 100644 --- a/gdb/testsuite/gdb.base/attach-twice.exp +++ b/gdb/testsuite/gdb.base/attach-twice.exp @@ -45,6 +45,6 @@ gdb_test_multiple "attach $testpid" $test { } if {$parentpid != 0} { - eval exec kill -9 $parentpid + exec kill -9 $parentpid } kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.base/attach-wait-input.exp b/gdb/testsuite/gdb.base/attach-wait-input.exp index 84c9bab..47e3d25 100644 --- a/gdb/testsuite/gdb.base/attach-wait-input.exp +++ b/gdb/testsuite/gdb.base/attach-wait-input.exp @@ -43,7 +43,8 @@ proc start_program {binfile} { global gdb_prompt global decimal - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto setup_done]} { return 0 diff --git a/gdb/testsuite/gdb.base/attach.c b/gdb/testsuite/gdb.base/attach.c index b3c5498..5133dd0 100644 --- a/gdb/testsuite/gdb.base/attach.c +++ b/gdb/testsuite/gdb.base/attach.c @@ -5,7 +5,7 @@ exit unless/until gdb sets the variable to non-zero.) */ #include <stdio.h> -#include <unistd.h> +#include "gdb_watchdog.h" int bidule = 0; volatile int should_exit = 0; @@ -14,7 +14,7 @@ int main () { int local_i = 0; - alarm (60); + gdb_watchdog (60); while (! should_exit) { diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp index 0d1550a..d0a29f2 100644 --- a/gdb/testsuite/gdb.base/attach.exp +++ b/gdb/testsuite/gdb.base/attach.exp @@ -56,7 +56,8 @@ proc_with_prefix do_attach_failure_tests {} { global escapedbinfile global srcfile - clean_restart $binfile + clean_restart + gdb_load $binfile # Figure out a regular expression that will match the sysroot, # noting that the default sysroot is "target:", and also noting @@ -215,7 +216,8 @@ proc_with_prefix do_attach_tests {} { global timeout global decimal - clean_restart $binfile + clean_restart + gdb_load $binfile # Figure out a regular expression that will match the sysroot, # noting that the default sysroot is "target:", and also noting @@ -519,7 +521,8 @@ proc_with_prefix do_attach_exec_mismatch_handling_tests {} { global binfile2 global binfile3 - clean_restart $binfile + clean_restart + gdb_load $binfile # Start two programs that can be attached to. # The first program contains a 'int bidule' variable, the second a 'float bidule'. diff --git a/gdb/testsuite/gdb.base/auxv.exp b/gdb/testsuite/gdb.base/auxv.exp index 090d9ba..38efa45 100644 --- a/gdb/testsuite/gdb.base/auxv.exp +++ b/gdb/testsuite/gdb.base/auxv.exp @@ -41,7 +41,8 @@ set core_works [expr [isnative] && ! [is_remote target]] # Run GDB on the test program up to where it will dump core. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.base/backtrace-through-cu-nodebug.exp b/gdb/testsuite/gdb.base/backtrace-through-cu-nodebug.exp index 53bf642..652e8c1 100644 --- a/gdb/testsuite/gdb.base/backtrace-through-cu-nodebug.exp +++ b/gdb/testsuite/gdb.base/backtrace-through-cu-nodebug.exp @@ -31,7 +31,7 @@ proc prepare_test {has_cfi} { "${objcallerfile}" \ object [list {additional_flags=-fomit-frame-pointer \ -funwind-tables -fasynchronous-unwind-tables}]] != "" } { - untested "couldn't compile with cfi" + untested "couldn't compile" return false } } else { @@ -41,7 +41,7 @@ proc prepare_test {has_cfi} { object [list {additional_flags=-fomit-frame-pointer \ -fno-unwind-tables \ -fno-asynchronous-unwind-tables}]] != "" } { - untested "couldn't compile without cfi" + untested "couldn't compile" return false } } @@ -52,17 +52,15 @@ proc prepare_test {has_cfi} { return false } - clean_restart "$binfile-${extension}" + clean_restart + gdb_load $binfile-$extension - with_test_prefix "${extension}" { - - if ![runto callback] then { - fail "has_cfi=$has_cfi: Can't run to callback" - return false - } - gdb_test_no_output "maint frame-unwinder disable ARCH" - return true + if { ![runto callback] } { + fail "has_cfi=$has_cfi: Can't run to callback" + return false } + gdb_test_no_output "maint frame-unwinder disable ARCH" + return true } if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" \ @@ -72,15 +70,45 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" \ return } -if { [prepare_test false] } { - gdb_test "bt" \ +proc_with_prefix no-cfi {} { + if { ![prepare_test false] } { + return + } + + set re_msg \ + [string_list_to_regexp \ + "Required frame unwinder may have been disabled," \ + " see 'maint info frame-unwinders'"] + set hs {[^\r\n]} + set re_bt_line "#0\\s+[string_to_regexp {callback ()}] $hs+" + set re_bt_no_filters \ [multi_line \ - "\[^\r\n\]+Required frame unwinder may have been disabled, \[^\r\n\]+" \ - "#0\\s+callback \\(\\) \[^\r\n\]+"] \ - "verify unwind fail without CFI" + $re_bt_line \ + $re_msg] + gdb_test "bt -no-filters" \ + $re_bt_no_filters \ + "verify no-filters unwind fail" + + # Flush frame cache to retrigger the message. + gdb_test "maint flush register-cache" \ + [string_to_regexp "Register cache flushed."] + + # This output may occur when we run into the message while applying the + # frame filters. + set re_bt \ + [multi_line \ + $hs+$re_msg \ + $re_bt_line] + gdb_test "bt" \ + "($re_bt|$re_bt_no_filters)" \ + "verify unwind fail" } -if { [prepare_test true] } { +proc_with_prefix cfi {} { + if { ![prepare_test true] } { + return + } + if { [istarget "arm*-*-*"] } { setup_kfail backtrace/31950 *-*-* } @@ -89,6 +117,12 @@ if { [prepare_test true] } { # #1 0x00000000004004e9 in caller () # #2 0x00000000004004cd in main () at ... gdb_test "bt" \ - "#0 +callback $text\r\n#1 $text in caller $text\r\n#2 $text in main $text" \ - "Verify unwinding works based only on CFI information" + [multi_line \ + "#0 +callback $text" \ + "#1 $text in caller $text" \ + "#2 $text in main $text"] \ + "Verify unwinding works" } + +no-cfi +cfi diff --git a/gdb/testsuite/gdb.base/backtrace.exp b/gdb/testsuite/gdb.base/backtrace.exp index 35784b4..3020666 100644 --- a/gdb/testsuite/gdb.base/backtrace.exp +++ b/gdb/testsuite/gdb.base/backtrace.exp @@ -17,11 +17,7 @@ standard_testfile -set flags {} -lappend flags debug -lappend_include_file flags $srcdir/lib/attributes.h - -if { [prepare_for_testing "failed to prepare" $testfile $srcfile $flags] } { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { return -1 } diff --git a/gdb/testsuite/gdb.base/basic-edit-cmd.exp b/gdb/testsuite/gdb.base/basic-edit-cmd.exp index 8a23c9b..7ad8ab9 100644 --- a/gdb/testsuite/gdb.base/basic-edit-cmd.exp +++ b/gdb/testsuite/gdb.base/basic-edit-cmd.exp @@ -68,7 +68,8 @@ save_vars { env(EDITOR) } { "try edit when no symbol file is loaded" # Now start with a test binary. - clean_restart $binfile + clean_restart + gdb_load $binfile with_test_prefix "before starting inferior" { diff --git a/gdb/testsuite/gdb.base/bfp-test.exp b/gdb/testsuite/gdb.base/bfp-test.exp index 7781fe1..53d274f 100644 --- a/gdb/testsuite/gdb.base/bfp-test.exp +++ b/gdb/testsuite/gdb.base/bfp-test.exp @@ -23,7 +23,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/bg-exec-sigint-bp-cond.exp b/gdb/testsuite/gdb.base/bg-exec-sigint-bp-cond.exp index 18e20e0..2e2a8e6 100644 --- a/gdb/testsuite/gdb.base/bg-exec-sigint-bp-cond.exp +++ b/gdb/testsuite/gdb.base/bg-exec-sigint-bp-cond.exp @@ -34,7 +34,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug]} { # AFTER_KILL_COND is appended to the breakpoint condition, after "kill # -SIGINT $gdb_pid". proc test { {after_kill_cond ""} } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.exp b/gdb/testsuite/gdb.base/bg-execution-repeat.exp index b1496ee..e7bdf49 100644 --- a/gdb/testsuite/gdb.base/bg-execution-repeat.exp +++ b/gdb/testsuite/gdb.base/bg-execution-repeat.exp @@ -33,7 +33,8 @@ proc test {continue_cmd} { global binfile global linenum - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return @@ -67,6 +68,17 @@ proc test {continue_cmd} { # enable the "set var" command with an interrupt / continue& pair. gdb_test -no-prompt-anchor "interrupt" + set test "interrupt received" + set re [string_to_regexp "Program received signal SIGINT, Interrupt."] + gdb_expect { + -re $re { + pass $test + } + timeout { + fail "$test (timeout)" + } + } + # Allow the breakpoint to trigger. gdb_test -no-prompt-anchor "set var do_wait=0" diff --git a/gdb/testsuite/gdb.base/bigcore.exp b/gdb/testsuite/gdb.base/bigcore.exp index 7727e48..f917eb8 100644 --- a/gdb/testsuite/gdb.base/bigcore.exp +++ b/gdb/testsuite/gdb.base/bigcore.exp @@ -117,7 +117,8 @@ proc test {dumper} { # Run GDB on the bigcore program up-to where it will dump core. - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.base/bitfields2.exp b/gdb/testsuite/gdb.base/bitfields2.exp index a99660a..3e981dd 100644 --- a/gdb/testsuite/gdb.base/bitfields2.exp +++ b/gdb/testsuite/gdb.base/bitfields2.exp @@ -233,7 +233,8 @@ proc bitfield_set {} { } } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" runto_main diff --git a/gdb/testsuite/gdb.base/bp-cmds-continue-ctrl-c.exp b/gdb/testsuite/gdb.base/bp-cmds-continue-ctrl-c.exp index 4fc8f06..648992c 100644 --- a/gdb/testsuite/gdb.base/bp-cmds-continue-ctrl-c.exp +++ b/gdb/testsuite/gdb.base/bp-cmds-continue-ctrl-c.exp @@ -118,7 +118,8 @@ proc do_test {} { # "attach". with_test_prefix "run" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return -1 @@ -129,7 +130,8 @@ with_test_prefix "run" { with_test_prefix "attach" { if {[can_spawn_for_attach]} { - clean_restart $binfile + clean_restart + gdb_load $binfile set test_spawn_id [spawn_wait_for_attach $binfile] set testpid [spawn_id_get_pid $test_spawn_id] diff --git a/gdb/testsuite/gdb.base/bp-cond-failure.exp b/gdb/testsuite/gdb.base/bp-cond-failure.exp index d645454..f33092b 100644 --- a/gdb/testsuite/gdb.base/bp-cond-failure.exp +++ b/gdb/testsuite/gdb.base/bp-cond-failure.exp @@ -26,7 +26,7 @@ standard_testfile -if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \ +if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ {debug c++}] == -1 } { return } @@ -45,7 +45,8 @@ if { [is_address_zero_readable] } { } proc run_test { cond_eval access_type bpexpr nloc } { - clean_restart ${::binfile} + clean_restart + gdb_load $::binfile if { ![runto_main] } { return -1 @@ -75,7 +76,7 @@ proc run_test { cond_eval access_type bpexpr nloc } { "Error in testing condition for breakpoint ${bp_num}.2:" \ "Cannot access memory at address 0x0" \ "" \ - "Breakpoint ${bp_num}.2, foo \\(c=49 ...\\) at \[^\r\n\]+:\[0-9\]+" \ + "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}.2, foo \\(c=49 ...\\) at \[^\r\n\]+:\[0-9\]+" \ "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"] } else { gdb_test "continue" \ @@ -84,7 +85,7 @@ proc run_test { cond_eval access_type bpexpr nloc } { "Error in testing condition for breakpoint ${bp_num}:" \ "Cannot access memory at address 0x0" \ "" \ - "Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \ + "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \ "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"] } } diff --git a/gdb/testsuite/gdb.base/bp-disabled-by-cond.exp b/gdb/testsuite/gdb.base/bp-disabled-by-cond.exp index f0bdd16..371b9e7 100644 --- a/gdb/testsuite/gdb.base/bp-disabled-by-cond.exp +++ b/gdb/testsuite/gdb.base/bp-disabled-by-cond.exp @@ -52,7 +52,8 @@ set exit_bp_line [gdb_get_line_number "BP before exit" $srcfile] # Restart the inferior, which should unload the shared library, GDB # should mark the b/p as disabled due to its condition again. proc run_test { hit_cond } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/bp-permanent.c b/gdb/testsuite/gdb.base/bp-permanent.c index d586acc..72e5e8a 100644 --- a/gdb/testsuite/gdb.base/bp-permanent.c +++ b/gdb/testsuite/gdb.base/bp-permanent.c @@ -101,7 +101,7 @@ test_signal_no_handler (void) } static void -test_signal_nested_handler () +test_signal_nested_handler (int sig) { test (); } diff --git a/gdb/testsuite/gdb.base/bp-permanent.exp b/gdb/testsuite/gdb.base/bp-permanent.exp index 62ce3f6..3ae5efe 100644 --- a/gdb/testsuite/gdb.base/bp-permanent.exp +++ b/gdb/testsuite/gdb.base/bp-permanent.exp @@ -42,7 +42,8 @@ proc test {always_inserted sw_watchpoint} { global gdb_prompt global srcfile binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return -1 @@ -134,7 +135,7 @@ proc test {always_inserted sw_watchpoint} { unsupported "failed to stop at permanent breakpoint" return } - -re "Program received signal SIGTRAP.*$gdb_prompt $" { + -re "received signal SIGTRAP.*$gdb_prompt $" { pass $test } } @@ -174,7 +175,7 @@ proc test {always_inserted sw_watchpoint} { # disabled, it should act as if we hadn't created it in the first # place. IOW, we should get a random signal, and, the breakpoint's # command should not run. - gdb_test "continue" "Program received signal SIGTRAP.*" \ + gdb_test "continue" "received signal SIGTRAP.*" \ "disabled permanent breakpoint doesn't explain stop" gdb_test "info breakpoints" \ diff --git a/gdb/testsuite/gdb.base/break-dbg.cc b/gdb/testsuite/gdb.base/break-dbg.cc new file mode 100644 index 0000000..642ded0 --- /dev/null +++ b/gdb/testsuite/gdb.base/break-dbg.cc @@ -0,0 +1,31 @@ +/* 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/>. */ + +volatile int global_var = 0; + +int +foo () +{ + return global_var; +} + +int +main () +{ + int res = foo (); + return res; +} diff --git a/gdb/testsuite/gdb.base/break-dbg.exp b/gdb/testsuite/gdb.base/break-dbg.exp new file mode 100644 index 0000000..a7c7d92 --- /dev/null +++ b/gdb/testsuite/gdb.base/break-dbg.exp @@ -0,0 +1,80 @@ +# 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/>. */ + +# Some basic testing of 'set debug breakpoint on'. At one point a bug +# meant that some breakpoints would immediately trigger a segfault if +# GDB tried to run with breakpoint debugging turned on. +# +# Test is compiled as C++ only so 'catch catch/throw/rethrow' have a +# something to do. The original bug would trigger for any 'catch' +# style breakpoint, so C++ isn't really a hard requirement. + +standard_testfile .cc + +require allow_cplus_tests + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug c++}] } { + return +} + +if {![runto_main]} { + return +} + +gdb_test "catch catch" "^Catchpoint $decimal \\(catch\\)" +gdb_test "catch throw" "^Catchpoint $decimal \\(throw\\)" +gdb_test "catch rethrow" "^Catchpoint $decimal \\(rethrow\\)" + +gdb_test "catch exec" "^Catchpoint $decimal \\(exec\\)" +gdb_test "catch fork" "^Catchpoint $decimal \\(fork\\)" +gdb_test "catch vfork" "^Catchpoint $decimal \\(vfork\\)" + +gdb_test "catch load" "^Catchpoint $decimal \\(load\\)" +gdb_test "catch unload" "^Catchpoint $decimal \\(unload\\)" + +gdb_test "catch signal" "^Catchpoint $decimal \\(standard signals\\)" + +set re_warning_xml_disabled \ + [string_to_regexp \ + [join \ + [list \ + "warning: Can not parse XML syscalls information;" \ + "XML support was disabled at compile time."]]] +gdb_test "catch syscall" \ + [multi_line \ + "^($re_warning_xml_disabled" \ + ")?Catchpoint $decimal [string_to_regexp {(any syscall)}]"] + +gdb_test "watch -l global_var" "\[Ww]atchpoint $decimal: -location global_var" + +gdb_test_no_output "set debug breakpoint on" + +set saw_bp_debug_line false +gdb_test_multiple "step" "" { + -re "^step\r\n" { + exp_continue + } + -re "^\\\[breakpoint\\\] \[^\r\n\]+\r\n" { + set saw_bp_debug_line true + exp_continue + } + -re "^$gdb_prompt $" { + gdb_assert { $saw_bp_debug_line } $gdb_test_name + } + -re "^\[^\r\n\]*\r\n" { + exp_continue + } +} diff --git a/gdb/testsuite/gdb.base/break-fun-addr.exp b/gdb/testsuite/gdb.base/break-fun-addr.exp index 9f5325a..ba6e32e 100644 --- a/gdb/testsuite/gdb.base/break-fun-addr.exp +++ b/gdb/testsuite/gdb.base/break-fun-addr.exp @@ -44,7 +44,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {d # on the first instruction of function "main" ("*main"), then # run to that breakpoint. -clean_restart ${binfile1} +clean_restart +gdb_load $binfile1 with_test_prefix "${testfile1}" { diff --git a/gdb/testsuite/gdb.base/break-idempotent.exp b/gdb/testsuite/gdb.base/break-idempotent.exp index ed23b64..3b32c89 100644 --- a/gdb/testsuite/gdb.base/break-idempotent.exp +++ b/gdb/testsuite/gdb.base/break-idempotent.exp @@ -161,7 +161,7 @@ foreach_with_prefix pie { "nopie" "pie" } { set binfile [standard_output_file $testfile-$pie] - if {[prepare_for_testing "failed to prepare" $binfile $srcfile $opts]} { + if {[prepare_for_testing "failed to prepare" $testfile-$pie $srcfile $opts]} { continue } diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp index 649cc86..038c3ea 100644 --- a/gdb/testsuite/gdb.base/break-interp.exp +++ b/gdb/testsuite/gdb.base/break-interp.exp @@ -78,7 +78,8 @@ gdb_test_multiple $test $test { } set interp_system [section_get [standard_output_file $binfile_test] .interp] -clean_restart $interp_system +clean_restart +gdb_load $interp_system set dl_main_found 0 gdb_test_multiple "info addr dl_main" "" { -re -wrap "Symbol \"dl_main\" is a function at address $hex\\." { @@ -218,6 +219,7 @@ proc test_core {file displacement} { set corefile [core_find $file {} "segv"] if {$corefile == ""} { + untested "unable to create or find corefile" return } diff --git a/gdb/testsuite/gdb.base/break1.c b/gdb/testsuite/gdb.base/break1.c index 110341c..26c4663 100644 --- a/gdb/testsuite/gdb.base/break1.c +++ b/gdb/testsuite/gdb.base/break1.c @@ -23,7 +23,13 @@ struct some_struct { int a_field; int b_field; - union { int z_field; }; + union + { + struct + { + int z_field; + }; + }; }; struct some_struct values[50]; diff --git a/gdb/testsuite/gdb.base/bt-on-fatal-signal.exp b/gdb/testsuite/gdb.base/bt-on-fatal-signal.exp index 06402dc..63428a1 100644 --- a/gdb/testsuite/gdb.base/bt-on-fatal-signal.exp +++ b/gdb/testsuite/gdb.base/bt-on-fatal-signal.exp @@ -61,7 +61,8 @@ foreach test_data {{SEGV "Segmentation fault"} \ # Restart GDB. save_vars { GDB } { set GDB [gdb_no_core] - clean_restart $binfile + clean_restart + gdb_load $binfile } # Capture the pid of GDB. diff --git a/gdb/testsuite/gdb.base/bt-selected-frame.exp b/gdb/testsuite/gdb.base/bt-selected-frame.exp index 68f5ed4..bbe2a5a 100644 --- a/gdb/testsuite/gdb.base/bt-selected-frame.exp +++ b/gdb/testsuite/gdb.base/bt-selected-frame.exp @@ -24,7 +24,8 @@ if { [build_executable "failed to prepare" $testfile $srcfile debug] } { proc check_selected_frame_after_bt { bt_cmd stack_pattern } { global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile with_test_prefix $bt_cmd { diff --git a/gdb/testsuite/gdb.base/call-rt-st.exp b/gdb/testsuite/gdb.base/call-rt-st.exp index 244eba8..511e209 100644 --- a/gdb/testsuite/gdb.base/call-rt-st.exp +++ b/gdb/testsuite/gdb.base/call-rt-st.exp @@ -39,7 +39,8 @@ set allow_float_test [allow_float_test] # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.base/call-sc.exp b/gdb/testsuite/gdb.base/call-sc.exp index 4d0fccc..f67670d 100644 --- a/gdb/testsuite/gdb.base/call-sc.exp +++ b/gdb/testsuite/gdb.base/call-sc.exp @@ -46,7 +46,7 @@ proc start_scalars_test { type } { set testfile "call-sc-${type}" set binfile [standard_output_file ${testfile}] - if { [prepare_for_testing "failed to prepare" $binfile $srcfile $flags] } { + if { [prepare_for_testing "failed to prepare" $testfile $srcfile $flags] } { return -1 } diff --git a/gdb/testsuite/gdb.base/call-signal-resume.exp b/gdb/testsuite/gdb.base/call-signal-resume.exp index 10a2928..a74b8af 100644 --- a/gdb/testsuite/gdb.base/call-signal-resume.exp +++ b/gdb/testsuite/gdb.base/call-signal-resume.exp @@ -47,7 +47,8 @@ proc get_dummy_frame_number { } { # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if { ![runto_main] } { return 0 diff --git a/gdb/testsuite/gdb.base/callexit.exp b/gdb/testsuite/gdb.base/callexit.exp index c250c67..e0ce899 100644 --- a/gdb/testsuite/gdb.base/callexit.exp +++ b/gdb/testsuite/gdb.base/callexit.exp @@ -27,7 +27,8 @@ require {!target_info exists gdb,cannot_call_functions} # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if { ![runto_main] } { return 0 diff --git a/gdb/testsuite/gdb.base/catch-fork-kill.exp b/gdb/testsuite/gdb.base/catch-fork-kill.exp index 0fd853b..224a8df 100644 --- a/gdb/testsuite/gdb.base/catch-fork-kill.exp +++ b/gdb/testsuite/gdb.base/catch-fork-kill.exp @@ -32,6 +32,8 @@ standard_testfile +require allow_fork_tests + # Build two programs -- one for fork, and another for vfork. set testfile_fork "${testfile}-fork" set testfile_vfork "${testfile}-vfork" diff --git a/gdb/testsuite/gdb.base/catch-fork-static.exp b/gdb/testsuite/gdb.base/catch-fork-static.exp index b171a6d..9d50d5d 100644 --- a/gdb/testsuite/gdb.base/catch-fork-static.exp +++ b/gdb/testsuite/gdb.base/catch-fork-static.exp @@ -21,9 +21,7 @@ # ld.so probes before reaching main, and ptrace flags were set then. But a # static executable would just keep running and never catch the fork. -# Until "catch fork" is implemented on other targets... -# -require {is_any_target "*-*-linux*" "*-*-openbsd*"} +require allow_fork_tests # Reusing foll-fork.c since it's a simple forking program. standard_testfile foll-fork.c diff --git a/gdb/testsuite/gdb.base/catch-signal-fork.exp b/gdb/testsuite/gdb.base/catch-signal-fork.exp index dea0cc4..2a33ee1 100644 --- a/gdb/testsuite/gdb.base/catch-signal-fork.exp +++ b/gdb/testsuite/gdb.base/catch-signal-fork.exp @@ -14,6 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. require {!target_info exists gdb,nosignals} +require allow_fork_tests standard_testfile diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp index f3ddef5..9c5839c 100644 --- a/gdb/testsuite/gdb.base/catch-syscall.exp +++ b/gdb/testsuite/gdb.base/catch-syscall.exp @@ -630,7 +630,8 @@ proc test_catch_syscall_multi_arch {} { test_catch_syscall_multi_arch_1 $arch1 $arch2 $syscall1_name \ $syscall2_name $syscall_number - clean_restart $binfile + clean_restart + gdb_load $binfile } proc do_syscall_tests_without_xml {} { @@ -801,18 +802,21 @@ fill_all_syscalls_numbers # Execute the tests, using XML support gdb_exit if { [allow_xml_test] } { - clean_restart $binfile + clean_restart + gdb_load $binfile do_syscall_tests # Now, we have to see if GDB displays a warning when we # don't set the data-directory but try to use catch syscall # anyway. For that, we must restart GDB first. - clean_restart $binfile + clean_restart + gdb_load $binfile test_catch_syscall_fail_nodatadir } # Restart gdb -clean_restart $binfile +clean_restart +gdb_load $binfile # Execute the tests, without XML support. In this case, GDB will # only display syscall numbers, and not syscall names. diff --git a/gdb/testsuite/gdb.base/checkpoint.exp b/gdb/testsuite/gdb.base/checkpoint.exp index 89b36f5..55eba5d 100644 --- a/gdb/testsuite/gdb.base/checkpoint.exp +++ b/gdb/testsuite/gdb.base/checkpoint.exp @@ -290,7 +290,8 @@ gdb_test "restart 10" "has no checkpoints" "no more checkpoint 10" # Now let's try setting a large number of checkpoints (>600) # -clean_restart $binfile +clean_restart +gdb_load $binfile runto_main gdb_breakpoint $break1_loc @@ -356,7 +357,8 @@ gdb_test "kill" "" "kill all one with many checkpoints" \ # with_test_prefix "delete checkpoint 0" { - clean_restart $binfile + clean_restart + gdb_load $binfile runto_main gdb_test "checkpoint" "Checkpoint 1: fork returned pid $decimal\\." diff --git a/gdb/testsuite/gdb.base/chng-syms.exp b/gdb/testsuite/gdb.base/chng-syms.exp index a561689..dbc523d 100644 --- a/gdb/testsuite/gdb.base/chng-syms.exp +++ b/gdb/testsuite/gdb.base/chng-syms.exp @@ -36,7 +36,8 @@ proc expect_to_stop_here { ident } { gdb_test "" "Breakpoint \[0-9\]*, stop_here .*" "running to stop_here $ident" } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test "break stop_here if (var1 == 42)" \ "Breakpoint.*at.* file .*$srcfile, line.*" \ diff --git a/gdb/testsuite/gdb.base/clear_non_user_bp.exp b/gdb/testsuite/gdb.base/clear_non_user_bp.exp index f078b97..c016d07 100644 --- a/gdb/testsuite/gdb.base/clear_non_user_bp.exp +++ b/gdb/testsuite/gdb.base/clear_non_user_bp.exp @@ -47,7 +47,8 @@ if { [gdb_compile "${srcdir}/${subdir}/main.c" "${binfile}" executable {debug}] } # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/cli-suppress-notification.exp b/gdb/testsuite/gdb.base/cli-suppress-notification.exp index 19f9c55..6880d98 100644 --- a/gdb/testsuite/gdb.base/cli-suppress-notification.exp +++ b/gdb/testsuite/gdb.base/cli-suppress-notification.exp @@ -17,7 +17,7 @@ standard_testfile -if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile}]} { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { return } diff --git a/gdb/testsuite/gdb.base/code-expr.exp b/gdb/testsuite/gdb.base/code-expr.exp index 4288617..8af2ee6 100644 --- a/gdb/testsuite/gdb.base/code-expr.exp +++ b/gdb/testsuite/gdb.base/code-expr.exp @@ -29,7 +29,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" diff --git a/gdb/testsuite/gdb.base/color-prompt.exp b/gdb/testsuite/gdb.base/color-prompt.exp new file mode 100644 index 0000000..c037185 --- /dev/null +++ b/gdb/testsuite/gdb.base/color-prompt.exp @@ -0,0 +1,29 @@ +# 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/>. + +# Check using a prompt with color in CLI. + +# Using tuiterm requires setting TERM on host. +require {!is_remote host} + +# We use a tuiterm, which allows us to determine cursor position. +tuiterm_env +Term::clean_restart 8 80 + +# We start with an empty screen, to generate a visible prompt. +Term::gen_prompt + +set tui 0 +source $srcdir/$subdir/../gdb.tui/color-prompt.exp.tcl diff --git a/gdb/testsuite/gdb.base/command-line-input.exp b/gdb/testsuite/gdb.base/command-line-input.exp index af228dc..9760f1a 100644 --- a/gdb/testsuite/gdb.base/command-line-input.exp +++ b/gdb/testsuite/gdb.base/command-line-input.exp @@ -18,19 +18,59 @@ # Test issuing a command split in multiple lines with continuation # characters. -gdb_exit -gdb_start +clean_restart -set test "print 1\\\\n + 2" -gdb_test_multiple "print 1\\\n + 2" $test { - -re "^print 1\\\\\r\n \\+ 2\r\n\\\$$decimal = 3\r\n$gdb_prompt $" { - pass $test +set bs "\\" +set re_bs [string_to_regexp $bs] +set re_dollar [string_to_regexp $] + +set re \ + [multi_line \ + ^[string_to_regexp "print 1$bs"] \ + [string_to_regexp " + 2"] \ + "$re_dollar$decimal = 3" \ + "$gdb_prompt $"] +gdb_test_multiple "print 1$bs\n + 2" "print 1$bs${bs}n + 2" { + -re $re { + pass $gdb_test_name + } +} + +set re \ + [multi_line \ + ^[string_to_regexp "print 1$bs"] \ + "2" \ + "$re_dollar$decimal = 12" \ + "$gdb_prompt $"] +gdb_test_multiple "print 1$bs\n2" "print 1$bs${bs}n2" { + -re $re { + pass $gdb_test_name } } -set test "print 1\\\\n2" -gdb_test_multiple "print 1\\\n2" $test { - -re "^print 1\\\\\r\n2\r\n\\\$$decimal = 12\r\n$gdb_prompt $" { - pass $test +with_test_prefix "cancel multiline" { + send_gdb "print$bs\n 1" + gdb_test_multiple "" "setup" { + -re "print$re_bs\r\n 1" { + pass $gdb_test_name + } + } + + send_gdb "\003" + gdb_test_multiple "" "cancel" { + -re -wrap "" { + pass $gdb_test_name + } + } + + # Regression test for PR cli/33063. + gdb_test_multiple "print 2" "command after cancel" { + -re -wrap " = 2" { + pass $gdb_test_name + } + -re -wrap "" { + # Avoid undefined command error. + fail $gdb_test_name + } } } diff --git a/gdb/testsuite/gdb.base/cond-expr.exp b/gdb/testsuite/gdb.base/cond-expr.exp index e60fd16..2080937 100644 --- a/gdb/testsuite/gdb.base/cond-expr.exp +++ b/gdb/testsuite/gdb.base/cond-expr.exp @@ -39,7 +39,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/condbreak-bad.exp b/gdb/testsuite/gdb.base/condbreak-bad.exp index 7aff409..19c16dc 100644 --- a/gdb/testsuite/gdb.base/condbreak-bad.exp +++ b/gdb/testsuite/gdb.base/condbreak-bad.exp @@ -17,7 +17,7 @@ standard_testfile -if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile}]} { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { return } diff --git a/gdb/testsuite/gdb.base/condbreak-multi-context.exp b/gdb/testsuite/gdb.base/condbreak-multi-context.exp index dce162b..b4ea0f1 100644 --- a/gdb/testsuite/gdb.base/condbreak-multi-context.exp +++ b/gdb/testsuite/gdb.base/condbreak-multi-context.exp @@ -53,7 +53,8 @@ proc find_location_contexts { } { global loc_name loc_index fill global decimal hex gdb_prompt binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile if {![runto_main]} { return @@ -130,7 +131,8 @@ proc check_bp_locations {bpnum states cond {msg ""}} { proc_with_prefix scenario_1 { start_before } { global warning decimal fill bkptno_num_re binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile if { $start_before } { if {![runto_main temporary]} { @@ -242,7 +244,8 @@ proc setup_bps { bpnum1_name bpnum2_name } { proc_with_prefix scenario_2 { start_before } { global binfile bkptno_num_re - clean_restart ${binfile} + clean_restart + gdb_load $binfile if { $start_before } { if {![runto_main temporary]} { @@ -290,7 +293,8 @@ proc_with_prefix scenario_2 { start_before } { proc_with_prefix scenario_3 { start_before } { global binfile bkptno_num_re loc_index warning - clean_restart ${binfile} + clean_restart + gdb_load $binfile if { $start_before } { if {![runto_main temporary]} { @@ -367,7 +371,8 @@ proc_with_prefix scenario_3 { start_before } { proc_with_prefix scenario_4 { start_before } { global binfile bkptno_num_re loc_index warning - clean_restart ${binfile} + clean_restart + gdb_load $binfile if { $start_before } { if {![runto_main temporary]} { diff --git a/gdb/testsuite/gdb.base/consecutive.exp b/gdb/testsuite/gdb.base/consecutive.exp index e73b3c3..fa58a8f 100644 --- a/gdb/testsuite/gdb.base/consecutive.exp +++ b/gdb/testsuite/gdb.base/consecutive.exp @@ -54,7 +54,7 @@ gdb_test "break \*$bp_addr" "Breakpoint $decimal at $bp_addr: file .*" \ gdb_test_multiple "step" "stopped at bp, 2nd instr" { -re -wrap "Breakpoint $decimal, ($hex) in foo.*" { set stop_addr $expect_out(1,string) - if {[eval expr "$bp_addr == $stop_addr"]} { + if {$bp_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" @@ -65,7 +65,7 @@ gdb_test_multiple "step" "stopped at bp, 2nd instr" { set stop_addr_is_stmt [hex_in_list $stop_addr $is_stmt] if {!$stop_addr_is_stmt} { fail "stopped at bp, 2nd instr (missing hex prefix)" - } elseif {[eval expr "$bp_addr == $stop_addr"]} { + } elseif {$bp_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" diff --git a/gdb/testsuite/gdb.base/constvars.exp b/gdb/testsuite/gdb.base/constvars.exp index 8f55945..dcc8d1b 100644 --- a/gdb/testsuite/gdb.base/constvars.exp +++ b/gdb/testsuite/gdb.base/constvars.exp @@ -34,7 +34,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # diff --git a/gdb/testsuite/gdb.base/continue-after-aborted-step-over.exp b/gdb/testsuite/gdb.base/continue-after-aborted-step-over.exp index 4764d72..8ba1f61 100644 --- a/gdb/testsuite/gdb.base/continue-after-aborted-step-over.exp +++ b/gdb/testsuite/gdb.base/continue-after-aborted-step-over.exp @@ -45,7 +45,8 @@ proc do_test {displaced breakpoint_always_inserted} { global gdb_prompt decimal global srcfile binfile - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test_no_output "set displaced-stepping $displaced" gdb_test_no_output "set breakpoint always-inserted $breakpoint_always_inserted" diff --git a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp index 7594cc2..eb5b489 100644 --- a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp +++ b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp @@ -28,7 +28,7 @@ if { ![istarget *-*-linux*] } { untested "$testfile.exp" return -1 } -require is_x86_64_m64_target +require is_x86_64_m64_target gcore_cmd_available if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug build-id}] } { return -1 diff --git a/gdb/testsuite/gdb.base/corefile-exec-context.exp b/gdb/testsuite/gdb.base/corefile-exec-context.exp index 7c9647c..23fd964 100644 --- a/gdb/testsuite/gdb.base/corefile-exec-context.exp +++ b/gdb/testsuite/gdb.base/corefile-exec-context.exp @@ -51,7 +51,8 @@ remote_exec build "mv $corefile $corefile_1" # Load the core file and confirm that the full executable name is # seen. -clean_restart $binfile +clean_restart +gdb_load $binfile set saw_generated_line false gdb_test_multiple "core-file $corefile_1" "load core file no args" { -re "^Core was generated by `[string_to_regexp $binfile]'\\.\r\n" { @@ -80,7 +81,8 @@ remote_exec build "mv $corefile $corefile_2" # Load the core file and confirm that the full executable name and # argument list are seen. -clean_restart $binfile +clean_restart +gdb_load $binfile set saw_generated_line false gdb_test_multiple "core-file $corefile_2" "load core file with args" { -re "^Core was generated by `[string_to_regexp $binfile] $args'\\.\r\n" { @@ -155,7 +157,8 @@ remote_exec build "mv $corefile $corefile_3" # Restart, load the core file, and check the environment variable # shows up. -clean_restart $binfile +clean_restart +gdb_load $binfile # Check for environment variable VAR_NAME in the environment, its # value should be VAR_VALUE. diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c b/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c new file mode 100644 index 0000000..58fdec6 --- /dev/null +++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c @@ -0,0 +1,522 @@ +/* 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/>. */ + +/* This file contains a library that can be preloaded into GDB on Linux + using the LD_PRELOAD technique. + + The library intercepts calls to OPEN, CLOSE, READ, and PREAD in order to + fake the inode number of a shared memory mapping. + + When GDB creates a core file (e.g. with the 'gcore' command), then + shared memory mappings should be included in the generated core file. + + The 'id' for the shared memory mapping shares the inode slot in the + /proc/PID/smaps file, which is what GDB consults to decide which + mappings should be included in the core file. + + It is possible for a shared memory mapping to have an 'id' of zero. + + At one point there was a bug in GDB where mappings with an inode of zero + would not be included in the generated core file. This meant that most + shared memory mappings would be included in the generated core file, + but, if a shared memory mapping happened to get an 'id' of zero, then, + because this would appear as a zero inode in the smaps file, this shared + memory mapping would be excluded from the generated core file. + + This preload library spots when GDB opens a /proc/PID/smaps file and + immediately copies the contents of this file into an internal buffer. + The buffer is then scanned looking for a shared memory mapping, and, if + a shared memory mapping is found, its 'id' (in the inode position) is + changed to zero. + + Calls to read/pread are intercepted, and attempts to read from the smaps + file are then served from the modified buffer contents. + + The close calls are monitored and, when the smaps file is closed, the + internal buffer is released. + + This works with GDB (currently) because the requirements for access to + the smaps file are pretty simple. GDB opens the file and grabs the + entire contents with a single pread call and a large buffer. There's no + seeking within the file or anything like that. + + The intention is that this library is preloaded into a GDB session which + is then used to start an inferior and generate a core file. GDB will + then see the zero inode for the shared memory mapping and should, if the + bug is correctly fixed, still add the shared memory mapping to the + generated core file. */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <errno.h> +#include <ctype.h> +#include <string.h> +#include <stdbool.h> +#include <assert.h> + +/* Logging. */ + +static void +log_msg (const char *fmt, ...) +{ +#ifdef LOGGING + va_list ap; + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); +#endif /* LOGGING */ +} + +/* Error handling, message and exit. */ + +static void +error (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + + exit (EXIT_FAILURE); +} + +/* The type of the open() function. */ +typedef int (*open_func_type)(const char *pathname, int flags, ...); + +/* The type of the close() function. */ +typedef int (*close_func_type)(int fd); + +/* The type of the read() function. */ +typedef ssize_t (*read_func_type)(int fd, void *buf, size_t count); + +/* The type of the pread() function. */ +typedef ssize_t (*pread_func_type) (int fd, void *buf, size_t count, off_t offset); + +/* Structure that holds information about a /proc/PID/smaps file that has + been opened. */ +struct interesting_file +{ + /* The file descriptor for the opened file. */ + int fd; + + /* The read offset within the file. Set to zero when the file is + opened. Any 'read' calls will update this offset. */ + size_t offset; + + /* The size of the contents within the buffer. This is not the total + buffer size (which might be larger). Attempts to read beyond SIZE + indicate an attempt to read beyond the end of the file. */ + size_t size; + + /* The (possibly modified) contents of the file. */ + char *content; +}; + +/* We only track a single interesting file. Currently, for the use case + we imagine, GDB will only ever open one /proc/PID/smaps file at once. */ +struct interesting_file the_file = { -1, 0, 0, NULL }; + +/* Update the contents of the global THE_FILE buffer. It is assumed that + the file contents have already been loaded into THE_FILE's content + buffer. + + Look for any lines that represent a shared memory mapping and modify + the inode field (which holds the shared memory id) to be zero. */ +static void +update_file_content_buffer (void) +{ + assert (the_file.content != NULL); + + char *start = the_file.content; + do + { + /* Every line, even the last one, ends with a newline. */ + char *end = strchrnul (start, '\n'); + assert (end != NULL); + assert (*end != '\0'); + + /* Attribute lines start with an uppercase letter. The lines we want + to modify should start with a lower case hex character, + i.e. [0-9a-f]. Also, every line that we want to consider should + be long enough, but just in case, check the longest possible + filename that we care about. */ + if (isxdigit (*start) && (isdigit (*start) || islower (*start)) + && (end - start) > 23) + { + /* There are two possible filenames that we look for: + /SYSV%08x + /SYSV%08x (deleted) + The END pointer is pointing to the first character after the + filename. + + Setup OFFSET to be the offset from END to the start of the + filename. As we check the filename we set OFFSET to 0 if the + filename doesn't match one of the expected patterns. */ + size_t offset; + if (strncmp ((end - 13), "/SYSV", 5) == 0) + offset = 13; + else if (strncmp ((end - 23), "/SYSV", 5) == 0) + { + if (strncmp ((end - 10), " (deleted)", 10) == 0) + offset = 23; + else + offset = 0; + } + else + offset = 0; + + for (int i = 0; i < 8 && offset != 0; ++i) + { + if (!isdigit (*(end - offset + 5 + i))) + offset = 0; + } + + /* If OFFSET is non-zero then the filename on this line looks + like a shared memory mapping, and OFFSET is the offset from + END to the first character of the filename. */ + if (offset != 0) + { + log_msg ("[LD_PRELOAD] shared memory entry: %.*s\n", + offset, (end - offset)); + + /* Set PTR to the first character before the filename. This + should be a white space character. */ + char *ptr = end - offset - 1; + assert (isspace (*ptr)); + + /* Walk backwards until we find the inode field. */ + while (isspace (*ptr)) + --ptr; + + /* Now replace every character in the inode field, except the + first one, with a space character. */ + while (!isspace (*(ptr - 1))) + { + assert (isdigit (*ptr)); + *ptr = ' '; + --ptr; + } + + /* Replace the first character with '0'. */ + assert (isdigit (*ptr)); + *ptr = '0'; + + /* This print is checked for from GDB. */ + printf ("[LD_PRELOAD] updated a shared memory mapping\n"); + } + } + + /* Update START to point to the next line. The last line of the + file will be empty. */ + assert (*end == '\n'); + start = end; + while (*start == '\n') + ++start; + } + while (*start != '\0'); +} + +/* Return true if PATHNAME has for form "/proc/PID/smaps" (without the + quotes). Otherwise, return false. */ + +static bool +is_smaps_file (const char *pathname) +{ + if (strncmp (pathname, "/proc/", 6) == 0) + { + int idx = 6; + while (isdigit (pathname[idx])) + idx++; + if (idx > 6 && strcmp (&pathname[idx], "/smaps") == 0) + return true; + } + + return false; +} + +/* Return true if PATHNAME should be considered interesting. PATHNAME is + interesting if it has the form /proc/PID/smaps, and there is no + interesting file already opened. */ + +static bool +is_interesting_pathname (const char *pathname) +{ + return the_file.fd == -1 && is_smaps_file (pathname); +} + +/* Read the contents of an interesting file from FD (and open file + descriptor) into the global THE_FILE variable, making the file FD the + current interesting file. There should be no already open interesting + file when this function is called. + + The contents of the file FD are read into a memory buffer and updated so + that any shared memory mappings listed within FD (which will be an smaps + file) will have the id zero. */ + +static void +read_interesting_file_contents (int fd) +{ +#define BLOCK_SIZE 1024 + /* Slurp contents into a local buffer. */ + size_t buffer_size = 1024; + size_t offset = 0; + + assert (the_file.size == 0); + assert (the_file.content == NULL); + assert (the_file.fd == -1); + assert (the_file.offset == 0); + + do + { + the_file.content = (char *) realloc (the_file.content, buffer_size); + if (the_file.content == NULL) + error ("[LD_PRELOAD] Failed allocating memory: %s\n", strerror (errno)); + + ssize_t bytes_read = read (fd, the_file.content + offset, BLOCK_SIZE); + if (bytes_read == -1) + error ("[LD_PRELOAD] Failed reading file: %s\n", strerror (errno)); + + the_file.size += bytes_read; + + if (bytes_read < BLOCK_SIZE) + break; + + offset += BLOCK_SIZE; + buffer_size += BLOCK_SIZE; + } + while (true); + + /* Add a null terminator. This makes the update easier. We know + there will be space because we only break out of the loop above + when the last read returns less than BLOCK_SIZE bytes. This means + we allocated an extra BLOCK_SIZE bytes, but didn't fill them all. + This means there must be at least 1 byte available for the null. */ + the_file.content[the_file.size] = '\0'; + + /* Reset the seek pointer. */ + if (lseek (fd, 0, SEEK_SET) == (off_t) -1) + error ("[LD_PRELOAD] Failed to lseek in file: %s\n", strerror (errno)); + + /* Record the file descriptor, this is used in read, pread, and close + in order to spot when we need to intercept the call. */ + the_file.fd = fd; + + update_file_content_buffer (); +#undef BLOCK_SIZE +} + +/* Intercept calls to 'open'. If this is an attempt to open a + /proc/PID/smaps file then intercept it, load the file contents into a + buffer and update the file contents. For all other open requests, just + forward to the real open function. */ +int +open (const char *pathname, int flags, ...) +{ + /* Pointer to the real open function. */ + static open_func_type real_open = NULL; + + /* Mode is only used if the O_CREAT flag is set in FLAGS. */ + mode_t mode = 0; + + /* Set true if this is a /proc/PID/smaps file. */ + bool is_interesting = is_interesting_pathname (pathname); + + /* Check if O_CREAT is in flags. If it is, get the mode. */ + if (flags & O_CREAT) + { + va_list args; + va_start (args, flags); + mode = va_arg (args, mode_t); + va_end (args); + } + + /* Debug. */ + if (is_interesting) + log_msg ("[LD_PRELOAD] Opening file: %s\n", pathname); + + /* Make sure we have a pointer to the real open() function. */ + if (real_open == NULL) + { + /* Get the address of the real open() function. */ + real_open = (open_func_type) dlsym (RTLD_NEXT, "open"); + if (real_open == NULL) + error ("[LD_PRELOAD] dlsym() error for 'open': %s\n", dlerror ()); + } + + /* Call the original open() function with the provided arguments. */ + int res = -1; + if (flags & O_CREAT) + res = real_open (pathname, flags, mode); + else + res = real_open (pathname, flags); + + if (res != -1 && is_interesting) + read_interesting_file_contents (res); + + return res; +} + +/* Like above, but for open64. */ + +int +open64 (const char *pathname, int flags, ...) +{ + /* Pointer to the real open64 function. */ + static open_func_type real_open64 = NULL; + + /* Mode is only used if the O_CREAT flag is set in FLAGS. */ + mode_t mode = 0; + + /* Set true if this is a /proc/PID/smaps file. */ + bool is_interesting = is_interesting_pathname (pathname); + + /* Check if O_CREAT is in flags. If it is, get the mode. */ + if (flags & O_CREAT) + { + va_list args; + va_start (args, flags); + mode = va_arg (args, mode_t); + va_end (args); + } + + /* Debug. */ + if (is_interesting) + log_msg ("[LD_PRELOAD] Opening file: %s\n", pathname); + + /* Make sure we have a pointer to the real open64() function. */ + if (real_open64 == NULL) + { + /* Get the address of the real open64() function. */ + real_open64 = (open_func_type) dlsym (RTLD_NEXT, "open64"); + if (real_open64 == NULL) + error ("[LD_PRELOAD] dlsym() error for 'open64': %s\n", dlerror ()); + } + + /* Call the original open64() function with the provided arguments. */ + int res = -1; + if (flags & O_CREAT) + res = real_open64 (pathname, flags, mode); + else + res = real_open64 (pathname, flags); + + if (res != -1 && is_interesting) + read_interesting_file_contents (res); + + return res; +} + +/* Intercept the 'close' function. If this is a previously opened + interesting file then clean up. Otherwise, forward to the normal close + function. */ +int +close (int fd) +{ + static close_func_type real_close = NULL; + + if (fd == the_file.fd) + { + the_file.fd = -1; + free (the_file.content); + the_file.content = NULL; + the_file.offset = 0; + the_file.size = 0; + log_msg ("[LD_PRELOAD] Closing file.\n"); + } + + /* Make sure we have a pointer to the real open() function. */ + if (real_close == NULL) + { + /* Get the address of the real open() function. */ + real_close = (close_func_type) dlsym (RTLD_NEXT, "close"); + if (real_close == NULL) + error ("[LD_PRELOAD] dlsym() error for 'close': %s\n", dlerror ()); + } + + return real_close (fd); +} + +/* Intercept 'pread' calls. If this is a pread from a previously opened + interesting file, then read from the in memory buffer. Otherwise, + forward to the real pread function. */ +ssize_t +pread (int fd, void *buf, size_t count, off_t offset) +{ + static pread_func_type real_pread = NULL; + + if (fd == the_file.fd) + { + size_t max; + + if (offset > the_file.size) + max = 0; + else + max = the_file.size - offset; + if (count > max) + count = max; + + memcpy (buf, the_file.content + offset, count); + log_msg ("[LD_PRELOAD] Read from file.\n"); + return count; + } + + if (real_pread == NULL) + { + /* Get the address of the real read() function. */ + real_pread = (pread_func_type) dlsym (RTLD_NEXT, "pread"); + if (real_pread == NULL) + error ("[LD_PRELOAD] dlsym() error for 'pread': %s\n", dlerror ()); + } + + return real_pread (fd, buf, count, offset); +} + +/* Intercept 'read' calls. If this is a read from a previously opened + interesting file, then read from the in memory buffer. Otherwise, + forward to the real read function. */ +ssize_t +read (int fd, void *buf, size_t count) +{ + static read_func_type real_read = NULL; + + if (fd == the_file.fd) + { + ssize_t bytes_read = pread (fd, buf, count, the_file.offset); + if (bytes_read > 0) + the_file.offset += bytes_read; + return bytes_read; + } + + if (real_read == NULL) + { + /* Get the address of the real read() function. */ + real_read = (read_func_type) dlsym (RTLD_NEXT, "read"); + if (real_read == NULL) + error ("[LD_PRELOAD] dlsym() error for 'read': %s\n", dlerror ()); + } + + return real_read (fd, buf, count); +} diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c new file mode 100644 index 0000000..92d2edf --- /dev/null +++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c @@ -0,0 +1,63 @@ +/* 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/>. */ + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#include <time.h> + +void +breakpt (void) +{ + /* Nothing. */ +} + +int +main (void) +{ + /* Create a shared memory mapping. */ + int sid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | IPC_EXCL | 0777); + if (sid == -1) + { + perror ("shmget"); + exit (1); + } + + /* Attach the shared memory mapping. */ + void *addr = shmat (sid, NULL, SHM_RND); + if (addr == (void *) -1L) + { + perror ("shmat"); + exit (1); + } + + breakpt (); + + /* Mark the shared memory mapping as deleted -- once the last user + has finished with it. */ + if (shmctl (sid, IPC_RMID, NULL) != 0) + { + perror ("shmctl"); + exit (1); + } + + return 0; +} diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp new file mode 100644 index 0000000..94ab454 --- /dev/null +++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp @@ -0,0 +1,230 @@ +# 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/>. + +# This test script tries to check GDB's ability to create a core file +# (e.g. with 'gcore' command) when there's a shared memory mapping +# with the id zero. +# +# Testing this case is hard. Older kernels don't even seem to give +# out the shared memory id zero. And on new kernels you still cannot +# guarantee to grab the zero id for testing; the id might be in use by +# some other process, or the kernel might just not give out that id +# for some other reason. +# +# To figure out which mappings to include in the core file, GDB reads +# the /proc/PID/smaps file. There is a field in this file which for +# file backed mappings, holds the inode of the file. But for shared +# memory mappings this field holds the shared memory id. The problem +# was that GDB would ignore any entry in /proc/PID/smaps with an inode +# entry of zero, which would catch the shared memory mapping with a +# zero id. +# +# There was an attempt to write a test which spammed out requests for +# shared memory mappings and tried to find the one with id zero, but +# this was still really unreliable. +# +# This test takes a different approach. We compile a library which we +# preload into the GDB process. This library intercepts calls to +# open, close, read, and pread, and watches for an attempt to open the +# /proc/PID/smaps file. +# +# When we see that file being opened, we copy the file contents into a +# memory buffer and modify the buffer so that the inode field for any +# shared memory mappings is set to zero. We then intercept calls to +# read and pread and return results from that in memory buffer. +# +# The test executable itself create a shared memory mapping (which +# might have any id). +# +# GDB, with the pre-load library in place, start the inferior and then +# uses the 'gcore' command to dump a core file. When GDB opens the +# smaps file and reads from it, the preload library ensures that GDB +# sees an inode of zero. +# + +# This test only works on Linux +require isnative +require {!is_remote host} +require {!is_remote target} +require {istarget *-linux*} +require gcore_cmd_available + +standard_testfile .c -lib.c + +set libfile ${testfile}-lib +set libobj [standard_output_file ${libfile}.so] + +# Compile the preload library. We only get away with this as we +# limit this test to running when ISNATIVE is true. +if { [build_executable "build preload lib" $libobj $srcfile2 \ + {debug shlib libs=-ldl}] == -1 } { + return +} + +# Now compile the inferior executable. +if {[build_executable "build executable" $testfile $srcfile] == -1} { + return +} + +# Spawn GDB with LIBOBJ preloaded using LD_PRELOAD. +save_vars { env(LD_PRELOAD) env(ASAN_OPTIONS) } { + if { ![info exists env(LD_PRELOAD) ] + || $env(LD_PRELOAD) == "" } { + set env(LD_PRELOAD) "$libobj" + } else { + append env(LD_PRELOAD) ":$libobj" + } + + # Prevent address sanitizer error: + # ASan runtime does not come first in initial library list; you should + # either link runtime to your application or manually preload it with + # LD_PRELOAD. + append_environment_default ASAN_OPTIONS verify_asan_link_order 0 + + clean_restart + gdb_load $binfile + + # Start GDB with the modified environment, this means that, when + # using remote targets, gdbserver will also use the preload + # library. + if {![runto_main]} { + return + } +} + +gdb_breakpoint breakpt +gdb_continue_to_breakpoint "run to breakpt" + +# Check the /proc/PID/smaps file itself. The call to 'cat' should +# inherit the preload library, so should see the modified file +# contents. Check that the shared memory mapping line has an id of +# zero. This confirms that the preload library is working. If the +# preload library breaks then we'll start seeing non-zero shared +# memory ids, which always worked, so we'd never know that this test +# is broken! +# +# This check ensures the test is working as expected. +set shmem_line_count 0 +set fixup_line_count 0 +set inf_pid [get_inferior_pid] +gdb_test_multiple "shell cat /proc/${inf_pid}/smaps" "check smaps" { + -re "^\\\[LD_PRELOAD\\\] updated a shared memory mapping\r\n" { + incr fixup_line_count + exp_continue + } + -re "^\[^\r\n\]+($decimal)\\s+/SYSV\[0-9\]{8}(?: \\(deleted\\))?\r\n" { + set id $expect_out(1,string) + if { $id == 0 } { + incr shmem_line_count + } + exp_continue + } + -re "^$gdb_prompt $" { + with_test_prefix $gdb_test_name { + gdb_assert { $shmem_line_count == 1 } \ + "single shared memory mapping found" + gdb_assert { $fixup_line_count == 1 } \ + "single fixup line found" + } + } + -re "^\[^\r\n\]+\r\n" { + exp_continue + } +} + +# Now generate a core file. This will use the preload library to read +# the smaps file. The code below is copied from 'proc gdb_gcore_cmd', +# but we don't use that as we also look for a message that is printed +# by the LD_PRELOAD library. This is an extra level of check that the +# preload library is triggering when needed. +set corefile [standard_output_file ${testfile}.core] +set saw_ld_preload_msg false +set saw_saved_msg false +with_timeout_factor 3 { + gdb_test_multiple "gcore $corefile" "save core file" { + -re "^\\\[LD_PRELOAD\\\] updated a shared memory mapping\r\n" { + # GDB actually reads the smaps file multiple times when + # creating a core file, so we'll see multiple of these + # fixup lines. + set saw_ld_preload_msg true + exp_continue + } + -re "^Saved corefile \[^\r\n\]+\r\n" { + set saw_saved_msg true + exp_continue + } + -re "^$gdb_prompt $" { + with_test_prefix $gdb_test_name { + gdb_assert { $saw_saved_msg } \ + "saw 'Saved corefile' message" + + # If we're using a remote target then the message from + # the preload library will go to gdbservers stdout, + # not GDB's, so don't check for it. + if { [gdb_protocol_is_native] } { + gdb_assert { $saw_ld_preload_msg } \ + "saw LD_PRELOAD message from library" + } + } + } + -re "^\[^\r\n\]*\r\n" { + exp_continue + } + } +} + +# Restart GDB. This time we are _not_ using the preload library. We +# no longer need it as we are only analysing the core file now. +clean_restart +gdb_load $binfile + +# Load the core file. +gdb_test "core-file $corefile" \ + "Program terminated with signal SIGTRAP, Trace/breakpoint trap\\..*" \ + "load core file" + +# Look through the mappings. We _should_ see the shared memory +# mapping. We _should_not_ see any of the special '[blah]' style +# mappings, e.g. [vdso], [vstack], [vsyscalls], etc. +set saw_special_mapping false +set saw_shmem_mapping false +gdb_test_multiple "info proc mappings" "" { + -re "\r\nStart Addr\[^\r\n\]+File\\s*\r\n" { + exp_continue + } + + -re "^$hex\\s+$hex\\s+$hex\\s+$hex\\s+\\\[\\S+\\\]\\s*\r\n" { + set saw_special_mapping true + exp_continue + } + + -re "^$hex\\s+$hex\\s+$hex\\s+$hex\\s+/SYSV\[0-9\]+ \\(deleted\\)\\s*\r\n" { + set saw_shmem_mapping true + exp_continue + } + + -re "^$hex\\s+$hex\\s+$hex\\s+$hex\[^\r\n\]*\r\n" { + exp_continue + } + + -re "^$gdb_prompt $" { + with_test_prefix $gdb_test_name { + gdb_assert { $saw_shmem_mapping } \ + "check shared memory mapping exists" + gdb_assert { !$saw_special_mapping } \ + "check no special mappings added" + } + } +} diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index da1fdf3..c34dfb5 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -31,6 +31,7 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { # mmapped data in core file" test. set corefile [core_find $binfile {}] if {$corefile == ""} { + untested "unable to create or find corefile" return 0 } @@ -96,7 +97,8 @@ foreach_with_prefix coreopt {--core= -core= "-c "} { # Now restart normally. -clean_restart $binfile +clean_restart +gdb_load $binfile # Test basic corefile recognition via core-file command. @@ -200,7 +202,8 @@ set coremmap_data_backup_filename \ remote_exec host "mv ${coremmap_data_filename} \ ${coremmap_data_backup_filename}" -clean_restart $binfile +clean_restart +gdb_load $binfile # Load the core file and check we get a warning about the # coremmap.data file being missing. @@ -229,7 +232,8 @@ remote_exec host "mv ${coremmap_data_backup_filename} \ # Test that we can unload the core with the "detach" command. proc_with_prefix corefile_detach {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_test "core-file $::corefile" "Core was generated by .*" "load core" gdb_test "detach" "No core file now\\." "detach core" @@ -251,7 +255,8 @@ proc corefile_test_run {} { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again" set re "Local core dump file:" diff --git a/gdb/testsuite/gdb.base/corefile2.exp b/gdb/testsuite/gdb.base/corefile2.exp index 392705b..3975460 100644 --- a/gdb/testsuite/gdb.base/corefile2.exp +++ b/gdb/testsuite/gdb.base/corefile2.exp @@ -40,6 +40,7 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { set corefile [core_find $binfile {}] if {$corefile == ""} { + untested "unable to create or find corefile" return 0 } @@ -170,7 +171,8 @@ with_test_prefix "renamed binfile" { # Restart and run to the abort call. -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return @@ -194,7 +196,8 @@ if {!$core_supported} { gdb_test_no_output "maint print core-file-backed-mappings" \ "maint print core-file-backed-mapping with no core file" -clean_restart $binfile +clean_restart +gdb_load $binfile set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"] if { $core_loaded == -1 } { diff --git a/gdb/testsuite/gdb.base/corefile3.exp b/gdb/testsuite/gdb.base/corefile3.exp index 57b2300..4528509 100644 --- a/gdb/testsuite/gdb.base/corefile3.exp +++ b/gdb/testsuite/gdb.base/corefile3.exp @@ -34,6 +34,7 @@ if {[build_executable $testfile.exp $testfile $srcfile] == -1} { set corefile [core_find $binfile {}] if {$corefile == ""} { + untested "unable to create or find corefile" return } @@ -46,7 +47,8 @@ set backup_filename \ [standard_output_file coredir.[getpid]/coremmap.data.backup] remote_exec host "mv ${data_filename} ${backup_filename}" -clean_restart $binfile +clean_restart +gdb_load $binfile # Load the core file. The 'coremap.data' file cannot be found by GDB, # but all the mappings for that file are r/w and should be present in diff --git a/gdb/testsuite/gdb.base/ctf-ptype.exp b/gdb/testsuite/gdb.base/ctf-ptype.exp index 3f9023f..6d55cb2 100644 --- a/gdb/testsuite/gdb.base/ctf-ptype.exp +++ b/gdb/testsuite/gdb.base/ctf-ptype.exp @@ -234,11 +234,10 @@ proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } # Turn the arguments, which are literal strings, into # regular expressions by quoting any special characters they contain. foreach var { prototyped plain overprototyped } { - eval "set val \$$var" - regsub -all "\[\]\[*()\]" $val "\\\\&" val + set val [string_to_regexp [set $var]] regsub -all "short int" $val "short( int)?" val regsub -all "long int" $val "long( int)?" val - eval "set $var \$val" + set $var $val } gdb_test_multiple "ptype $id" "ptype $id" { diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp index 3e527db..e2f8c35 100644 --- a/gdb/testsuite/gdb.base/cvexpr.exp +++ b/gdb/testsuite/gdb.base/cvexpr.exp @@ -517,7 +517,7 @@ foreach testspec $specs { # These tests don't rely on the debug format. with_test_prefix nodebug { - if { [prepare_for_testing "failed to prepare" $binfile $srcfile {nodebug}] } { + if { [prepare_for_testing "failed to prepare" $testfile $srcfile {nodebug}] } { return 0 } diff --git a/gdb/testsuite/gdb.base/default-args.exp b/gdb/testsuite/gdb.base/default-args.exp index efc4205..ae417ed 100644 --- a/gdb/testsuite/gdb.base/default-args.exp +++ b/gdb/testsuite/gdb.base/default-args.exp @@ -25,7 +25,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug]} { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # Basic/core tests using user-visible commands. with_test_prefix "basics" { diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index d4d6b20..b5e64c2 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -253,10 +253,39 @@ gdb_test "h" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-d gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-defined aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." #test handle gdb_test "handle" "Argument required .signal to handle.*" -#test info "i" abbreviation -gdb_test "i" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation" + +proc test_info_command { command message } { + set saw_info_header 0 + set saw_help_info 0 + set saw_command_abbrev 0 + gdb_test_multiple $command $message -lbl { + -re "\r\nList of \"info\" subcommands:" { + verbose "Info header displayed" + set saw_info_header 1 + exp_continue + } + -re "Type \"help info\" followed by subcommand name for full documentation\\." { + verbose "Help info displayed" + set saw_help_info 1 + exp_continue + } + -re "\r\nCommand name abbreviations are allowed if unambiguous\\." { + verbose "Command name abbreviations displayed" + set saw_command_abbrev 1 + exp_continue + } + -re -wrap "" { + gdb_assert { $saw_info_header && $saw_help_info + && $saw_command_abbrev } $gdb_test_name + } + } +} + +#test info "i" abbreviation +test_info_command "i" "info \"i\" abbreviation" #test info -gdb_test "info" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." +test_info_command "info" "info" + #test ignore gdb_test "ignore" "Argument required .a breakpoint number.*" #test info address @@ -379,38 +408,52 @@ gdb_test "info registers" "The program has no registers now." gdb_test "info s" "No stack." "info stack \"s\" abbreviation" #test info stack gdb_test "info stack" "No stack." -#test info set -# Test improved to check three parts: -# 1) confirm -# 2) prompt -# 3) write -# And only succeed if all three are matched. -# This should fix an old problem on native solaris 2.8, -# where this test fails due to this line: + +#test "info set" and "show" commands +# The test needs to match the "prompt: ..." part to fix an old problem on native +# Solaris 2.8, where this test fails due to this line: # prompt: Gdb's prompt is "(gdb) ".^M -set set_confirm_seen 0 -set set_prompt_seen 0 -gdb_test_multiple "info set" "info set" { - -re "confirm: Whether to confirm potentially dangerous operations is o\[a-z\]*.(\[^\r\n\]*\[\r\n\])+history filename: The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+listsize: Number of source lines gdb will list by default is 10" { - verbose "Confirm dislayed" - set set_confirm_seen 1 - exp_continue - } - -re "Gdb's prompt is \"$gdb_prompt \"" { - verbose "GDB prompt displayed" - set set_prompt_seen 1 - exp_continue - } - -re "Writing into executable.*$gdb_prompt $" { - verbose "write displayed" - if { $set_prompt_seen && $set_confirm_seen } { - pass "info set" - } else { - verbose "prompt $set_prompt_seen confirm $set_confirm_seen" - fail "info set (incomplete output)" +proc test_info_set_show { command } { + set set_confirm_seen 0 + set set_history_filename_seen 0 + set set_listsize_seen 0 + set set_prompt_seen 0 + set set_write_seen 0 + gdb_test_multiple $command $command -lbl { + -re "\r\nconfirm: Whether to confirm potentially dangerous operations is o\[a-z\]+\\." { + verbose "Confirm displayed" + set set_confirm_seen 1 + exp_continue + } + -re "\r\nhistory filename: The filename in which to record the command history is \[^\r\n\]+\\." { + verbose "History filename displayed" + set set_history_filename_seen 1 + exp_continue + } + -re "\r\nlistsize: Number of source lines gdb will list by default is 10\\." { + verbose "Listsize displayed" + set set_listsize_seen 1 + exp_continue + } + -re "\r\nprompt: Gdb's prompt is \"$::gdb_prompt \"" { + verbose "GDB prompt displayed" + set set_prompt_seen 1 + exp_continue + } + -re "write: Writing into executable and core files is o\[a-z\]+\\." { + verbose "Write displayed" + set set_write_seen 1 + exp_continue + } + -re -wrap "" { + gdb_assert { $set_confirm_seen && $set_history_filename_seen + && $set_listsize_seen && $set_prompt_seen + && $set_write_seen } $gdb_test_name } } } +test_info_set_show "info set" + gdb_test "info symbol" "Argument required .address.." #test info source gdb_test "info source" "No current source file..*" @@ -591,12 +634,41 @@ gdb_test "set history" "List of \"set history\" subcommands:(\[^\r\n\]*\[\r\n\]) gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, asm, c, c.., d, fortran, go, minimal, modula-2, objective-c, opencl, pascal, rust." #test set listsize gdb_test "set listsize" "Argument required .integer to set it to.*" + +proc test_set_print { command message } { + set saw_info_header 0 + set saw_help_info 0 + set saw_command_abbrev 0 + gdb_test_multiple $command $message -lbl { + -re "\r\nList of \"set print\" subcommands:" { + verbose "Info header displayed" + set saw_info_header 1 + exp_continue + } + -re "Type \"help set print\" followed by subcommand name for full documentation\\." { + verbose "Help info displayed" + set saw_help_info 1 + exp_continue + } + -re "\r\nCommand name abbreviations are allowed if unambiguous\\." { + verbose "Command name abbreviations displayed" + set saw_command_abbrev 1 + exp_continue + } + -re -wrap "" { + gdb_assert { $saw_info_header && $saw_help_info + && $saw_command_abbrev } $gdb_test_name + } + } +} + #test set print "p" abbreviation -gdb_test "set p" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation" +test_set_print "set p" "set print \"p\" abbreviation" #test set print "pr" abbreviation -gdb_test "set pr" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation" +test_set_print "set pr" "set print \"pr\" abbreviation" #test set print -gdb_test "set print" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." +test_set_print "set print" "set print" + #test set print address gdb_test_no_output "set print address" "set print address" #test set print array @@ -687,7 +759,6 @@ set show_conv_list \ {$_probe_arg10 = <error: No frame selected>} \ {$_probe_arg11 = <error: No frame selected>} \ {$_cimag = <internal function _cimag>} \ - {$_colorsupport = "monochrome"} \ {$_creal = <internal function _creal>} \ {$_isvoid = <internal function _isvoid>} \ {$_shell = <internal function _shell>} \ @@ -695,10 +766,10 @@ set show_conv_list \ {$_gdb_maint_setting = <internal function _gdb_maint_setting>} \ {$_gdb_setting_str = <internal function _gdb_setting_str>} \ {$_gdb_setting = <internal function _gdb_setting>} \ - {$_gdb_major = 17} \ - {$_gdb_minor = 1} \ {$_shell_exitsignal = void} \ {$_shell_exitcode = 0} \ + {$_linker_namespace_count = 0} \ + {$_linker_namespace = <error: No registers.>}\ } if [allow_python_tests] { append show_conv_list \ @@ -714,10 +785,52 @@ if [allow_python_tests] { {$_any_caller_matches = <internal function _any_caller_matches>} \ } } -gdb_test_list_exact "show convenience" "show convenience" \ - "\[^\r\n\]+\[\r\n\]+" \ - "\[^\r\n\]+" \ - $show_conv_list + +set lines [gdb_get_lines_no_pass "show convenience"] +set matches 0 +set all_found 1 +foreach s $show_conv_list { + if {  $lines] } { + verbose -log "didn't match: '$s'" + set all_found 0 + break + } + incr matches +} + +set re_var [string_to_regexp {$_colorsupport}] +if { [is_remote host] } { + set re_val {[^\r\n]+} +} else { + set re_val [string_to_regexp {"monochrome"}] +} +if { [regexp "$re_var = $re_val" $lines] } { + incr matches +} else { + set all_found 0 +} + +set re_vars \ + [list \ + [string_to_regexp {$_gdb_major}] \ + [string_to_regexp {$_gdb_minor}]] +foreach re_var $re_vars { + if { [regexp "$re_var = $decimal" $lines] } { + incr matches + } else { + set all_found 0 + } +} + +if { [regexp [string_to_regexp {$_tlb = void}] $lines] } { + incr matches +} else { + # Convenience variable _tlb is added only if support for windows targets + # is enabled. Don't complain if it's missing. +} + +gdb_assert { $all_found && $matches == [count_newlines $lines] } \ + "show convenience" #test show directories gdb_test "show directories" "Source directories searched: .cdir\[:;\].cwd" @@ -739,12 +852,47 @@ gdb_test "show history" "history expansion: *History expansion on command input gdb_test "show language" "The current source language is \"auto; currently c\"." #test show listsize gdb_test "show listsize" "Number of source lines gdb will list by default is 10." + +proc test_show_print { command } { + set saw_print_address 0 + set saw_print_frame_args 0 + set saw_print_symbol 0 + set saw_print_vtbl 0 + gdb_test_multiple $command $command -lbl { + -re "\r\nprint address: Printing of addresses is o\[a-z\]+\\." { + verbose "Print address displayed" + set saw_print_address 1 + exp_continue + } + -re "\r\nprint frame-arguments: Printing of non-scalar frame arguments is \[^\r\n\]+\\." { + verbose "Print frame-arguments displayed" + set saw_print_frame_args 1 + exp_continue + } + -re "\r\nprint symbol: Printing of symbols when printing pointers is o\[a-z\]+\\." { + verbose "Print symbol displayed" + set saw_print_symbol 1 + exp_continue + } + -re "\r\nprint vtbl: Printing of C\\+\\+ virtual function tables is o\[a-z\]+\\." { + verbose "Print vtbl displayed" + set saw_print_vtbl 1 + exp_continue + } + -re -wrap "" { + gdb_assert { $saw_print_address && $saw_print_frame_args + && $saw_print_symbol && $saw_print_vtbl } $gdb_test_name + } + } +} + #test show print "p" abbreviation -gdb_test "show p" ".*" +test_show_print "show p" #test show print "pr" abbreviation -gdb_test "show pr" ".*" +test_show_print "show pr" #test show print -gdb_test "show print" ".*" +test_show_print "show print" + #test show paths gdb_test "show paths" "Executable and object file path:.*" #test show print address @@ -790,30 +938,10 @@ gdb_test "show width" "Number of characters gdb thinks are in a line is.*" #test show write # This is only supported on targets which use exec.o. gdb_test "show write" "Writing into executable and core files is o.*" + #test show -set show_confirm_seen 0 -set show_prompt_seen 0 -gdb_test_multiple "show" "show" { - -re "confirm: *Whether to confirm potentially dangerous operations is on.(\[^\r\n\]*\[\r\n\])+history filename: *The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+history save: *Saving of the history record on exit is on.(\[^\r\n\]*\[\r\n\])+history size: *The size of the command history is(\[^\r\n\]*\[\r\n\])+listsize: *Number of source lines gdb will list by default is 10(\[^\r\n]*\[\r\n\])+print elements: *Limit on string chars or array elements to print is 200." { - verbose "Confirm displayed" - set show_confirm_seen 1 - exp_continue - } - -re "Gdb's prompt is \"$gdb_prompt \"" { - verbose "GDB prompt displayed" - set show_prompt_seen 1 - exp_continue - } - -re "Writing into executable.*$gdb_prompt $" { - verbose "write displayed" - if { $show_prompt_seen && $show_confirm_seen } { - pass "show" - } else { - verbose "prompt $show_prompt_seen confirm $show_confirm_seen" - fail "show (incomplete output)" - } - } -} +test_info_set_show "show" + #history saving should stay disabled gdb_test_no_output "set history save off" "set history save off" #test stepi "si" abbreviation diff --git a/gdb/testsuite/gdb.base/detach-sysroot-target.exp b/gdb/testsuite/gdb.base/detach-sysroot-target.exp index 4248c86..c7466c0 100644 --- a/gdb/testsuite/gdb.base/detach-sysroot-target.exp +++ b/gdb/testsuite/gdb.base/detach-sysroot-target.exp @@ -22,7 +22,7 @@ standard_testfile -if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile}]} { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { return } diff --git a/gdb/testsuite/gdb.base/detach-while-running.exp b/gdb/testsuite/gdb.base/detach-while-running.exp index 60943f3..34c2adc 100644 --- a/gdb/testsuite/gdb.base/detach-while-running.exp +++ b/gdb/testsuite/gdb.base/detach-while-running.exp @@ -45,7 +45,8 @@ proc test {} { if {$is_remote} { append ::GDBFLAGS " -ex \"maint set target-non-stop on\"" } - clean_restart ${binfile} + clean_restart + gdb_load $binfile } set test_spawn_id [spawn_wait_for_attach $binfile] diff --git a/gdb/testsuite/gdb.base/detach.exp b/gdb/testsuite/gdb.base/detach.exp index f9f67a8..c8d4350 100644 --- a/gdb/testsuite/gdb.base/detach.exp +++ b/gdb/testsuite/gdb.base/detach.exp @@ -42,7 +42,8 @@ proc do_detach_tests {} { gdb_test "detach" "Detaching from program: .*$escapedbinfile, .*" "detach, $pass" } -clean_restart $binfile +clean_restart +gdb_load $binfile global pass set pass "one" diff --git a/gdb/testsuite/gdb.base/dfp-test.exp b/gdb/testsuite/gdb.base/dfp-test.exp index 2a6c377..11f75da 100644 --- a/gdb/testsuite/gdb.base/dfp-test.exp +++ b/gdb/testsuite/gdb.base/dfp-test.exp @@ -28,7 +28,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {quie return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/display.exp b/gdb/testsuite/gdb.base/display.exp index 7aed6d5..2fb6e07 100644 --- a/gdb/testsuite/gdb.base/display.exp +++ b/gdb/testsuite/gdb.base/display.exp @@ -52,7 +52,8 @@ if !$use_gdb_stub { gdb_test "kill" ".*" "kill again" gdb_test "detach" ".*" "detach again" - clean_restart $binfile + clean_restart + gdb_load $binfile } # Ok, on to real life diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c index 3bcd819..c7c038a 100644 --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c @@ -41,6 +41,12 @@ main (void) handle[2] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL); assert (handle[2] != NULL); + for (dl = 2; dl >= 0; dl--) + { + fun = dlsym (handle[dl], "inc"); + fun (dl); + } + dlclose (handle[0]); /* TAG: first dlclose */ dlclose (handle[1]); /* TAG: second dlclose */ dlclose (handle[2]); /* TAG: third dlclose */ diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp index 3ddc07e..f3bdfb0 100644 --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp @@ -38,16 +38,80 @@ if { [build_executable "failed to build" $testfile $srcfile \ 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+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library(?=\r\n)" { + -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]+${lib_regexp}(?=\r\n)" { if {$ns == -1} { set ns $expect_out(1,string) } @@ -62,7 +126,8 @@ proc get_first_so_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 + clean_restart + gdb_load $::binfile if { ![runto_main] } { return @@ -78,9 +143,11 @@ proc test_info_shared {} { # 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.*" \ + "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" @@ -105,4 +172,149 @@ proc test_info_shared {} { "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 + gdb_load $::binfile + + 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 + gdb_load $::binfile + 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 + gdb_load $::binfile + + # 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 diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp index da17002..c4eb7cd 100644 --- a/gdb/testsuite/gdb.base/dlmopen.exp +++ b/gdb/testsuite/gdb.base/dlmopen.exp @@ -95,9 +95,19 @@ if { $dyln_name eq "" } { return } +# If the dynamic linker path contains a symlink, some instances show the real +# path instead of the original path. Accept both. +lassign [remote_exec target realpath "$dyln_name"] realpath_ret dyln_realpath_name + +if { $realpath_ret == 0 } { + set dyln_realpath_name [string trim $dyln_realpath_name] +} else { + set dyln_realpath_name "not-a-valid-path" +} + # Return true if FILENAME is the dynamic linker. Otherwise return false. proc is_dyln { filename } { - return [expr {$filename eq $::dyln_name}] + return [expr {$filename eq $::dyln_name || $filename eq $::dyln_realpath_name}] } # Check that 'info shared' show NUM occurrences of DSO. @@ -106,7 +116,7 @@ proc check_dso_count { dso num } { set count 0 gdb_test_multiple "info shared" "info shared" { - -re "$hex $hex \(\[\[$::decimal\]\]\\s+\)\?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 @@ -173,7 +183,8 @@ proc test_dlmopen {} { # Setup for calling 'test_dlmopen', this is the version of the test # that doesn't use 'attach'. proc test_dlmopen_no_attach {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if { ![runto_main] } { return @@ -198,7 +209,8 @@ proc test_dlmopen_with_attach {} { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile # Start the test program. set test_spawn_id [spawn_wait_for_attach $::binfile] @@ -233,7 +245,7 @@ proc get_dyld_info {} { set dyld_count 0 set dyld_start_addr "" gdb_test_multiple "info sharedlibrary" "" { - -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" { + -re "From\\s+To\\s+\(Linker NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" { exp_continue } -re "^($::hex)\\s+$::hex\\s+\(\#$::decimal\\s+\)?\[^/\]+(/\[^\r\n\]+)\r\n" { @@ -288,7 +300,8 @@ proc_with_prefix test_solib_unmap_events { } { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile if { ![runto_main] } { return @@ -358,15 +371,19 @@ proc_with_prefix test_solib_unmap_events { } { # dynamic linker as pending when some instances of the library were # unloaded, despite there really only being one copy of the dynamic # linker actually loaded into the inferior's address space. - gdb_test_multiple "info breakpoints $bpnum" "check b/p status" { - -re -wrap "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+\\*$::hex\\s*\r\n\\s+stop only if \\(0\\)" { - fail $gdb_test_name - } - - -re -wrap "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+$::hex\\s*\[^\r\n\]+\r\n\\s+stop only if \\(0\\)" { - pass $gdb_test_name - } - } + set hs {[^\r\n]} + set re_pass \ + [multi_line \ + "" \ + [join \ + [list \ + "$bpnum" "breakpoint" "keep" "y" "$::hex$hs+"] \ + {\s+}] \ + [string cat \ + {\s+} \ + [string_to_regexp "stop only if (0)"] \ + ([string_to_regexp " (target evals)"])?]] + gdb_test "info breakpoints $bpnum" $re_pass "check b/p status" # With all the dlclose calls now complete, we should be back to a # single copy of the dynamic linker. @@ -379,7 +396,8 @@ proc_with_prefix test_solib_unmap_events { } { # Check that we can 'next' over the dlclose calls without GDB giving any # warnings or errors. proc_with_prefix test_next_over_dlclose {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if { ![runto_main] } { return diff --git a/gdb/testsuite/gdb.base/dprintf-bp-same-addr.exp b/gdb/testsuite/gdb.base/dprintf-bp-same-addr.exp index 649784b..11a8310 100644 --- a/gdb/testsuite/gdb.base/dprintf-bp-same-addr.exp +++ b/gdb/testsuite/gdb.base/dprintf-bp-same-addr.exp @@ -28,7 +28,8 @@ proc test { style } { global gdb_prompt binfile dp_location with_test_prefix "$style" { - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.base/dprintf-detach.exp b/gdb/testsuite/gdb.base/dprintf-detach.exp index dc3384b..431037c 100644 --- a/gdb/testsuite/gdb.base/dprintf-detach.exp +++ b/gdb/testsuite/gdb.base/dprintf-detach.exp @@ -37,7 +37,8 @@ proc dprintf_detach_test { breakpoint_always_inserted dprintf_style disconnected with_test_prefix "$test_prefix" { # Start with a clean gdb - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test_no_output "set breakpoint always-inserted ${breakpoint_always_inserted}" gdb_test_no_output "set dprintf-style ${dprintf_style}" @@ -68,7 +69,8 @@ proc dprintf_detach_test { breakpoint_always_inserted dprintf_style disconnected gdb_exit # Check that the process still exists by attaching a new gdb to it. - clean_restart ${binfile} + clean_restart + gdb_load $binfile set test "re-attach to inferior" set is_gdbserver [target_is_gdbserver] diff --git a/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp b/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp index 06be468..65de2d5 100644 --- a/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp +++ b/gdb/testsuite/gdb.base/dprintf-execution-x-script.exp @@ -93,7 +93,8 @@ do_test "" $test # Restart GDB and 'source' the script; this will (still) run the program # due to the 'run' command in the script. -clean_restart $binfile +clean_restart +gdb_load $binfile do_test "source $x_file" "load and run script using source command" # This should leave us at the gdb prompt; Run program again using diff --git a/gdb/testsuite/gdb.base/dprintf-pending.exp b/gdb/testsuite/gdb.base/dprintf-pending.exp index 9242a84..f28e969 100644 --- a/gdb/testsuite/gdb.base/dprintf-pending.exp +++ b/gdb/testsuite/gdb.base/dprintf-pending.exp @@ -60,7 +60,8 @@ with_test_prefix "without symbols" { gdb_test "" ".*x=3.*x=4.*x=3.*" "run to resolved dprintf" } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib $lib_sl # diff --git a/gdb/testsuite/gdb.base/dprintf.exp b/gdb/testsuite/gdb.base/dprintf.exp index 0135b86..262ccc1 100644 --- a/gdb/testsuite/gdb.base/dprintf.exp +++ b/gdb/testsuite/gdb.base/dprintf.exp @@ -74,7 +74,8 @@ proc restart {} { global binfile global bp_location1 dp_location1 - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.base/dso2dso.exp b/gdb/testsuite/gdb.base/dso2dso.exp index 24d4203..3b00f6d 100644 --- a/gdb/testsuite/gdb.base/dso2dso.exp +++ b/gdb/testsuite/gdb.base/dso2dso.exp @@ -54,7 +54,8 @@ if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable \ return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $binfile_libdso2 gdb_load_shlib $binfile_libdso1 diff --git a/gdb/testsuite/gdb.base/dtrace-probe.exp b/gdb/testsuite/gdb.base/dtrace-probe.exp index 32a72cc..5d4b9df 100644 --- a/gdb/testsuite/gdb.base/dtrace-probe.exp +++ b/gdb/testsuite/gdb.base/dtrace-probe.exp @@ -27,7 +27,8 @@ proc dtrace_test {} { return -1 } - clean_restart ${binfile} + clean_restart + gdb_load $binfile if ![runto_main] { return -1 @@ -63,8 +64,8 @@ proc dtrace_test {} { # Since test:progress-counter is disabled we can run to the second # instance of the test:two-locations probe. - runto "-probe-dtrace test:two-locations"] - runto "-probe-dtrace test:two-locations"] + runto "-probe-dtrace test:two-locations" + runto "-probe-dtrace test:two-locations" # Go back to the breakpoint on main() and enable the # test:progress-counter probe. Set a breakpoint on it and see diff --git a/gdb/testsuite/gdb.base/dump.c b/gdb/testsuite/gdb.base/dump.c index bdcafbf..14b66b1 100644 --- a/gdb/testsuite/gdb.base/dump.c +++ b/gdb/testsuite/gdb.base/dump.c @@ -35,7 +35,7 @@ main() for (i = 0; i < ARRSIZE; i++) intarray[i] = i+1; - intstruct.a = 12 * 1; + intstruct.a = (12 * 1) << 16; intstruct.b = 12 * 2; intstruct.c = 12 * 3; intstruct.d = 12 * 4; diff --git a/gdb/testsuite/gdb.base/dump.exp b/gdb/testsuite/gdb.base/dump.exp index a55e5b0..64d897b 100644 --- a/gdb/testsuite/gdb.base/dump.exp +++ b/gdb/testsuite/gdb.base/dump.exp @@ -46,7 +46,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${op return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_test "dump mem /dev/null 0x10 0x20" "Cannot access memory at address 0x10" \ "inaccessible memory is reported" @@ -107,14 +108,7 @@ set endian [get_endianness] # Now generate some dump files. proc make_dump_file { command msg } { - global gdb_prompt - - gdb_test_multiple "${command}" "$msg" { - -re ".*\[Ee\]rror.*$gdb_prompt $" { fail $msg } - -re ".*\[Ww\]arning.*$gdb_prompt $" { fail $msg } - -re ".*\[Uu\]ndefined .*$gdb_prompt $" { fail $msg } - -re ".*$gdb_prompt $" { pass $msg } - } + gdb_test_no_output "${command}" "$msg" } make_dump_file "dump val [set intarr1.bin] intarray" \ diff --git a/gdb/testsuite/gdb.base/duplicate-bp.exp b/gdb/testsuite/gdb.base/duplicate-bp.exp index b1003f2..da5834b 100644 --- a/gdb/testsuite/gdb.base/duplicate-bp.exp +++ b/gdb/testsuite/gdb.base/duplicate-bp.exp @@ -24,7 +24,8 @@ proc test_setup { count } { global srcfile global binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/eh_return.exp b/gdb/testsuite/gdb.base/eh_return.exp index 5a4f524..703f9e9 100644 --- a/gdb/testsuite/gdb.base/eh_return.exp +++ b/gdb/testsuite/gdb.base/eh_return.exp @@ -71,7 +71,8 @@ if { $address == -1 } { return 0 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_assert [gdb_breakpoint "*$address" no-message] "set breakpoint on address" diff --git a/gdb/testsuite/gdb.base/ending-run.exp b/gdb/testsuite/gdb.base/ending-run.exp index 022ac28..0b5eadf 100644 --- a/gdb/testsuite/gdb.base/ending-run.exp +++ b/gdb/testsuite/gdb.base/ending-run.exp @@ -224,7 +224,7 @@ set program_in_exit 0 if {!$use_gdb_stub && (! [target_info exists use_cygmon] || ! [target_info use_cygmon])} { global program_exited - if {[eval expr $program_exited == 0]} { + if {$program_exited == 0} { gdb_test_multiple "n" "step to end of run" { -re "$inferior_exited_re normally.*$gdb_prompt $" { # If we actually have debug info for the start function, diff --git a/gdb/testsuite/gdb.base/errno.exp b/gdb/testsuite/gdb.base/errno.exp index ff18214..ea1ff70 100644 --- a/gdb/testsuite/gdb.base/errno.exp +++ b/gdb/testsuite/gdb.base/errno.exp @@ -45,7 +45,8 @@ standard_testfile proc do_tests {{do_xfail_cast 0} {do_xfail 0} {do_xfail_core_test 0}} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if ![runto_main] { return } @@ -176,7 +177,8 @@ proc do_tests {{do_xfail_cast 0} {do_xfail 0} {do_xfail_core_test 0}} { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile set core_loaded [gdb_core_cmd $corefile "load corefile"] if { $core_loaded == -1 } { diff --git a/gdb/testsuite/gdb.base/eval-skip.exp b/gdb/testsuite/gdb.base/eval-skip.exp index 82c5fe0..b4c856e 100644 --- a/gdb/testsuite/gdb.base/eval-skip.exp +++ b/gdb/testsuite/gdb.base/eval-skip.exp @@ -39,7 +39,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/exe-lock.exp b/gdb/testsuite/gdb.base/exe-lock.exp index 40a470f..2e375b4 100644 --- a/gdb/testsuite/gdb.base/exe-lock.exp +++ b/gdb/testsuite/gdb.base/exe-lock.exp @@ -27,7 +27,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Sanity-check: Verify that the executable exists. This is just to # make sure that, when we verify later that the file does not exist, diff --git a/gdb/testsuite/gdb.base/exec-invalid-sysroot.exp b/gdb/testsuite/gdb.base/exec-invalid-sysroot.exp index 7ab446e..99f5e7d 100644 --- a/gdb/testsuite/gdb.base/exec-invalid-sysroot.exp +++ b/gdb/testsuite/gdb.base/exec-invalid-sysroot.exp @@ -69,5 +69,6 @@ proc do_exec_sysroot_test {} { } # Start with a fresh gdb -clean_restart $binfile +clean_restart +gdb_load $binfile do_exec_sysroot_test diff --git a/gdb/testsuite/gdb.base/execl-update-breakpoints.exp b/gdb/testsuite/gdb.base/execl-update-breakpoints.exp index 27bd042..cd49df1 100644 --- a/gdb/testsuite/gdb.base/execl-update-breakpoints.exp +++ b/gdb/testsuite/gdb.base/execl-update-breakpoints.exp @@ -41,7 +41,8 @@ if { [gdb_compile $objfile $exec1 executable {debug text_segment=0x1000000}] != # First check whether the address of "main" in exec1 is readable in # exec2. If it is, then skip the test as unsupported. -clean_restart ${exec1} +clean_restart +gdb_load $exec1 if {![runto_main]} { return -1 } @@ -55,7 +56,8 @@ gdb_test_multiple "p/x &main" $test { } } -clean_restart ${exec2} +clean_restart +gdb_load $exec2 if {![runto_main]} { return -1 } @@ -84,7 +86,8 @@ proc test { always_inserted } { global exec1 global gdb_prompt - clean_restart ${exec1} + clean_restart + gdb_load $exec1 gdb_test_no_output "set breakpoint always-inserted $always_inserted" diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp index eb2d0e4..ee0c198 100644 --- a/gdb/testsuite/gdb.base/exprs.exp +++ b/gdb/testsuite/gdb.base/exprs.exp @@ -26,7 +26,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # # set it up at a breakpoint so we can play with the variable values @@ -284,3 +285,24 @@ gdb_test "print v_short + " \ # Test for a syntax error in the middle of an expression. gdb_test "print v_short =}{= 3" \ "A syntax error in expression, near `\\}\\{= 3'\\." + +set hs {[^\r\n]} +set re_debug [string cat $hs* {[Ss]hift} $hs*] + +gdb_test_no_output "set debug parse 1" +set saw_start 0 +set saw_val 0 +gdb_test_multiple "print 23" "print with debugging" -lbl { + -re "\r\n${re_debug}(?=\r\n)" { + set saw_start 1 + exp_continue + } + -re "\r\n.$decimal = 23(?=\r\n)" { + set saw_val 1 + exp_continue + } + + -re -wrap "" { + gdb_assert {$saw_start && $saw_val} $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.base/fileio.c b/gdb/testsuite/gdb.base/fileio.c index 0f20151..4ba5ab0 100644 --- a/gdb/testsuite/gdb.base/fileio.c +++ b/gdb/testsuite/gdb.base/fileio.c @@ -73,6 +73,10 @@ static const char *strerrno (int err); #define STRING "Hello World" +#define STRINGIFY(s) STRINGIFY_(s) +#define STRINGIFY_(s) #s +#define OUTDIR STRINGIFY (OUTDIR_) + static void stop (void) {} /* A NULL string. We pass this to stat below instead of a NULL diff --git a/gdb/testsuite/gdb.base/fileio.exp b/gdb/testsuite/gdb.base/fileio.exp index 6996d6d..a6b4c23 100644 --- a/gdb/testsuite/gdb.base/fileio.exp +++ b/gdb/testsuite/gdb.base/fileio.exp @@ -27,7 +27,7 @@ if {[is_remote host]} { if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ executable \ - [list debug "additional_flags=-DOUTDIR=\"$outdir/\""]] != "" } { + [list debug additional_flags=[quote_for_host -DOUTDIR_=$outdir/]]] != "" } { untested "failed to compile" return -1 } @@ -41,7 +41,8 @@ system "rm -rf [standard_output_file *.fileio.test]" set oldtimeout $timeout set timeout [expr "$timeout + 60"] -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.base/filename-completion.exp b/gdb/testsuite/gdb.base/filename-completion.exp index cb3fc90..c10941c 100644 --- a/gdb/testsuite/gdb.base/filename-completion.exp +++ b/gdb/testsuite/gdb.base/filename-completion.exp @@ -385,7 +385,7 @@ proc run_quoting_and_escaping_tests { root } { remove-symbol-file \ "target core" "target exec" "target tfile" \ "maint print c-tdesc" "save gdb-index" - "save gdb-index -dwarf-5" } + "save gdb-index -dwarf-5" "shell ls"} if { [allow_compile_tests] } { lappend all_cmds "compile file" } @@ -408,6 +408,31 @@ proc run_quoting_and_escaping_tests { root } { run_quoting_and_escaping_tests_1 $root $cmd } } + + # Some additional testing of shell command. Test 'shell' and '!' + # when there are multiple filenames on the command line. This + # focuses on completion of the final filename. There is also some + # testing of the shell command above, this tests completion within + # the line. + foreach_with_prefix shell_cmd { "shell " "!" "pipe print 1 | " } { + foreach suffix { "aaa/aa bb" "bb2/dir 1/unique file" } { + set dir $root/$suffix + + regsub -all " " "$dir" "\\ " dir_with_backslash + + with_test_prefix "suffix='$suffix'" { + with_test_prefix "with_backslash" { + run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls $dir_with_backslash" + } + with_test_prefix "with double quotes" { + run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls \"$dir\"" + } + with_test_prefix "with single quotes" { + run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls '$dir'" + } + } + } + } } # Helper for run_unquoted_tests. ROOT is the root directory as setup diff --git a/gdb/testsuite/gdb.base/find.exp b/gdb/testsuite/gdb.base/find.exp index ae68686..3b2dfb0 100644 --- a/gdb/testsuite/gdb.base/find.exp +++ b/gdb/testsuite/gdb.base/find.exp @@ -22,7 +22,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test "break $srcfile:stop_here" \ "Breakpoint.*at.* file .*$srcfile, line.*" \ diff --git a/gdb/testsuite/gdb.base/fixsection.exp b/gdb/testsuite/gdb.base/fixsection.exp index 9a5c996..3056851 100644 --- a/gdb/testsuite/gdb.base/fixsection.exp +++ b/gdb/testsuite/gdb.base/fixsection.exp @@ -32,7 +32,8 @@ if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib ${lib_sl} if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/float128.exp b/gdb/testsuite/gdb.base/float128.exp index 95b83af..b8d3a6c 100644 --- a/gdb/testsuite/gdb.base/float128.exp +++ b/gdb/testsuite/gdb.base/float128.exp @@ -30,7 +30,8 @@ if { [do_compile] != "" && [do_compile {-mfloat128}] != "" } { return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/floatn.exp b/gdb/testsuite/gdb.base/floatn.exp index 7138d04..1b39ed8 100644 --- a/gdb/testsuite/gdb.base/floatn.exp +++ b/gdb/testsuite/gdb.base/floatn.exp @@ -30,7 +30,8 @@ if { [do_compile] != "" && [do_compile {-mfloat128}] != "" } { return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/foll-exec-c++.exp b/gdb/testsuite/gdb.base/foll-exec-c++.exp new file mode 100644 index 0000000..d96310b --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-exec-c++.exp @@ -0,0 +1,24 @@ +# 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/>. + +# This file is part of the gdb testsuite + +# See foll-exec.exp.tcl for test details. This file runs the test +# using the C++ compiler. + +require allow_cplus_tests +set lang c++ + +source $srcdir/$subdir/foll-exec.exp.tcl diff --git a/gdb/testsuite/gdb.base/foll-exec-c.exp b/gdb/testsuite/gdb.base/foll-exec-c.exp new file mode 100644 index 0000000..67f62cc --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-exec-c.exp @@ -0,0 +1,23 @@ +# 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/>. + +# This file is part of the gdb testsuite + +# See foll-exec.exp.tcl for test details. This file runs the test +# using the C compiler. + +set lang c + +source $srcdir/$subdir/foll-exec.exp.tcl diff --git a/gdb/testsuite/gdb.base/foll-exec.c b/gdb/testsuite/gdb.base/foll-exec.c index a1c9b70..291f803 100644 --- a/gdb/testsuite/gdb.base/foll-exec.c +++ b/gdb/testsuite/gdb.base/foll-exec.c @@ -19,25 +19,38 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> - +#include <libgen.h> +#include <assert.h> #include <limits.h> int global_i = 100; +#ifndef EXECD_PROG +#define EXECD_PROG "execd-prog" +#endif + int main (int argc, char ** argv) { int local_j = global_i + 1; int local_k = local_j + 1; char prog[PATH_MAX]; - int len; + size_t len = PATH_MAX - 1; + + printf ("foll-exec is about to execlp(%s)...\n", EXECD_PROG); + + prog [len] = '\0'; + + strncpy (prog, dirname (argv[0]), len); + len -= strlen (prog); + assert (len > 0); - printf ("foll-exec is about to execlp(execd-prog)...\n"); + strncat (prog, "/", len); + len -= 1; + assert (len > 0); - strcpy (prog, argv[0]); - len = strlen (prog); - /* Replace "foll-exec" with "execd-prog". */ - memcpy (prog + len - 9, "execd-prog", 10); - prog[len + 1] = 0; + strncat (prog, EXECD_PROG, len); + len -= strlen (EXECD_PROG); + assert (len > 0); /* In the following function call, maximum line length exceed the limit 80. This is intentional and required for clang compiler such that complete @@ -45,7 +58,7 @@ int main (int argc, char ** argv) multi-line. */ execlp (prog, /* tbreak-execlp */ prog, "execlp arg1 from foll-exec", (char *) 0); - printf ("foll-exec is about to execl(execd-prog)...\n"); + printf ("foll-exec is about to execl(%s)...\n", EXECD_PROG); /* In the following function call, maximum line length exceed the limit 80. This is intentional and required for clang compiler such that complete @@ -61,7 +74,7 @@ int main (int argc, char ** argv) argv[0] = prog; - printf ("foll-exec is about to execv(execd-prog)...\n"); + printf ("foll-exec is about to execv(%s)...\n", EXECD_PROG); execv (prog, argv); /* tbreak-execv */ } diff --git a/gdb/testsuite/gdb.base/foll-exec.exp b/gdb/testsuite/gdb.base/foll-exec.exp.tcl index ad4c3516..64bcea8 100644 --- a/gdb/testsuite/gdb.base/foll-exec.exp +++ b/gdb/testsuite/gdb.base/foll-exec.exp.tcl @@ -22,33 +22,56 @@ require {istarget "*-linux*"} standard_testfile foll-exec.c -set testfile2 "execd-prog" -set srcfile2 ${testfile2}.c -set binfile2 [standard_output_file ${testfile2}] +# Compile a program that performs an exec as EXECER_LANG, and a +# program that will be exec'd as EXECEE_LANG. Either language can be +# 'c' or 'c++'. Then run various test associated with 'catch exec' +# using the compiled programs. +proc do_exec_tests { execer_lang execee_lang } { + global srcfile testfile + global gdb_prompt -set compile_options debug + # First compile the program to be exec'd, the execee. + set execee_base_filename "execd-prog" + set srcfile2 ${execee_base_filename}.c + set execee_testfile "execd-prog-${execee_lang}" + set execee_testfile_re [string_to_regexp $execee_testfile] + set execee_binfile [standard_output_file $execee_testfile] -# build the first test case -if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } { - untested "failed to compile" - return -1 -} + set execee_flags debug + if { $execee_lang == "c++" } { + lappend execee_flags "c++" + } -if { [is_remote target] } { - gdb_remote_download target $binfile2 -} + if { [build_executable "failed to build $execee_testfile" $execee_testfile \ + $srcfile2 $execee_flags] == -1 } { + return + } -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } { - untested "failed to compile" - return -1 -} + if { [is_remote target] } { + gdb_remote_download target $execee_binfile + } -proc do_exec_tests {} { - global binfile srcfile srcfile2 testfile testfile2 - global gdb_prompt + + # Now compile the program to do the exec, the execer. + set execer_testfile "$testfile-${execee_lang}" + set execer_binfile [standard_output_file $execer_testfile] + + set execer_flags debug + if { $execer_lang == "c++" } { + lappend execer_flags "c++" + } + lappend execer_flags "additional_flags=-DEXECD_PROG=\"${execee_testfile}\"" + + if { [build_executable "failed to build $execer_testfile" $execer_testfile \ + $srcfile $execer_flags] == -1 } { + return + } + + # Now we can start running the tests. + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. - # if {![runto_main]} { return } @@ -71,7 +94,8 @@ proc do_exec_tests {} { return } - clean_restart $binfile + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. # @@ -120,7 +144,7 @@ proc do_exec_tests {} { set execd_line [gdb_get_line_number "after-exec" $srcfile2] send_gdb "next\n" gdb_expect { - -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ + -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ {pass "step through execlp call"} -re "$gdb_prompt $" {fail "step through execlp call"} timeout {fail "(timeout) step through execlp call"} @@ -160,7 +184,8 @@ proc do_exec_tests {} { # Explicitly kill this program, or a subsequent rerun actually runs # the exec'd program, not the original program... - clean_restart $binfile + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. # @@ -193,7 +218,7 @@ proc do_exec_tests {} { send_gdb "continue\n" gdb_expect { - -re ".*xecuting new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*$gdb_prompt $"\ + -re ".*xecuting new program:.*${execee_testfile_re}.*Catchpoint .*(exec\'d .*${execee_testfile_re}).*$gdb_prompt $"\ {pass "hit catch exec"} -re "$gdb_prompt $" {fail "hit catch exec"} timeout {fail "(timeout) hit catch exec"} @@ -210,7 +235,7 @@ proc do_exec_tests {} { # set msg "info shows catchpoint exec pathname" gdb_test_multiple "info breakpoints" $msg { - -re ".*catchpoint.*keep y.*exec, program \".*${testfile2}\".*$gdb_prompt $" { + -re ".*catchpoint.*keep y.*exec, program \".*${execee_testfile_re}\".*$gdb_prompt $" { pass $msg } } @@ -228,7 +253,8 @@ proc do_exec_tests {} { # Explicitly kill this program, or a subsequent rerun actually runs # the exec'd program, not the original program... - clean_restart $binfile + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. # @@ -269,7 +295,7 @@ proc do_exec_tests {} { # send_gdb "next 2\n" gdb_expect { - -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ + -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ {pass "step through execl call"} -re "$gdb_prompt $" {fail "step through execl call"} timeout {fail "(timeout) step through execl call"} @@ -295,7 +321,8 @@ proc do_exec_tests {} { # Explicitly kill this program, or a subsequent rerun actually runs # the exec'd program, not the original program... - clean_restart $binfile + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. # @@ -330,7 +357,7 @@ proc do_exec_tests {} { } send_gdb "next\n" gdb_expect { - -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ + -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ {pass "step through execv call"} -re "$gdb_prompt $" {fail "step through execv call"} timeout {fail "(timeout) step through execv call"} @@ -356,7 +383,8 @@ proc do_exec_tests {} { # Explicitly kill this program, or a subsequent rerun actually runs # the exec'd program, not the original program... - clean_restart $binfile + clean_restart + gdb_load $execer_binfile # Start the program running, and stop at main. # @@ -370,13 +398,13 @@ proc do_exec_tests {} { # send_gdb "continue\n" gdb_expect { - -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ + -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\ {pass "continue through exec"} -re "$gdb_prompt $" {fail "continue through exec"} timeout {fail "(timeout) continue through exec"} } } -clean_restart $binfile - -do_exec_tests +foreach_with_prefix execee_lang { c c++ } { + do_exec_tests $lang $execee_lang +} diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.c b/gdb/testsuite/gdb.base/foll-fork-syscall.c new file mode 100644 index 0000000..ef695f5 --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-fork-syscall.c @@ -0,0 +1,35 @@ +/* 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/>. */ + +#include <unistd.h> +#include <stdio.h> + +int +main (int argc, char **argv) +{ + int pid, x = 0; + + pid = fork (); + if (pid == 0) /* set breakpoint here */ + printf ("I am the child\n"); + else + printf ("I am the parent\n"); + + chdir ("."); + ++x; /* set exit breakpoint here */ + return 0; +} diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.exp b/gdb/testsuite/gdb.base/foll-fork-syscall.exp new file mode 100644 index 0000000..21ef334 --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-fork-syscall.exp @@ -0,0 +1,143 @@ +# 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 catching syscalls with all permutations of follow-fork parent/child +# and detach-on-fork on/off. + +# Test relies on checking follow-fork output. Do not run if gdb debug is +# enabled because it will be redirected to the log. +require !gdb_debug_enabled +require {is_any_target "i?86-*-*" "x86_64-*-*"} +require allow_fork_tests + +standard_testfile + +if {[build_executable "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +proc setup_gdb {} { + global testfile + + clean_restart $testfile + + if {![runto_main]} { + return false + } + + # Set a breakpoint after the fork is "complete." + if {![gdb_breakpoint [gdb_get_line_number "set breakpoint here"]]} { + return false + } + + # Set exit breakpoint (to prevent inferior from exiting). + if {![gdb_breakpoint [gdb_get_line_number "set exit breakpoint here"]]} { + return false + } + return true +} + +# Check that fork catchpoints are supported, as an indicator for whether +# fork-following is supported. Return 1 if they are, else 0. + +proc_with_prefix check_fork_catchpoints {} { + global gdb_prompt + + if { ![setup_gdb] } { + return false + } + + # Verify that the system supports "catch fork". + gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint" + set has_fork_catchpoints false + gdb_test_multiple "continue" "continue to first fork catchpoint" { + -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" { + unsupported "continue to first fork catchpoint" + } + -re ".*Catchpoint.*$gdb_prompt $" { + set has_fork_catchpoints true + pass "continue to first fork catchpoint" + } + } + + return $has_fork_catchpoints +} + +proc_with_prefix test_catch_syscall {follow-fork-mode detach-on-fork} { + # Start with shiny new gdb instance. + if {![setup_gdb]} { + return + } + + # The "Detaching..." and "Attaching..." messages may be hidden by + # default. + gdb_test_no_output "set verbose" + + # Setup modes to test. + gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" + gdb_test_no_output "set detach-on-fork ${detach-on-fork}" + + gdb_test "catch fork" "Catchpoint . \\(fork\\)" + gdb_test "catch syscall chdir" "Catchpoint . \\(syscall 'chdir'.*\\)" + + # Which inferior we're expecting to follow. Assuming the parent + # will be inferior #1, and the child will be inferior #2. + if {${follow-fork-mode} == "parent"} { + set following_inf 1 + } else { + set followin_inf 2 + } + # Next stop should be the fork catchpoint. + set expected_re "" + append expected_re "Catchpoint . \\(forked process.*" + gdb_test "continue" $expected_re "continue to fork catchpoint" + + # Next stop should be the breakpoint after the fork. + set expected_re ".*" + if {${follow-fork-mode} == "child" || ${detach-on-fork} == "off"} { + append expected_re "\\\[New inferior.*" + } + if {${detach-on-fork} == "on"} { + append expected_re "\\\[Detaching after fork from " + if {${follow-fork-mode} == "parent"} { + append expected_re "child" + } else { + append expected_re "parent" + } + append expected_re " process.*" + } + append expected_re "Breakpoint .*set breakpoint here.*" + gdb_test "continue" $expected_re "continue to breakpoint after fork" + + # Next stop should be the syscall catchpoint. + set expected_re ".*Catchpoint . \\(call to syscall chdir\\).*" + gdb_test continue $expected_re "continue to chdir syscall" +} + +# Check for follow-fork support. +if {![check_fork_catchpoints]} { + untested "follow-fork not supported" + return +} + +# Test all permutations. +foreach_with_prefix follow-fork-mode {"parent" "child"} { + + # Do not run tests when not detaching from the parent. + # See breakpoints/13457 for discussion. + foreach_with_prefix detach-on-fork {"on"} { + test_catch_syscall ${follow-fork-mode} ${detach-on-fork} + } +} diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp index 94755c6..12db516 100644 --- a/gdb/testsuite/gdb.base/foll-fork.exp +++ b/gdb/testsuite/gdb.base/foll-fork.exp @@ -17,6 +17,8 @@ # enabled as it will be redirected to the log. require !gdb_debug_enabled +require allow_fork_tests + standard_testfile if {[build_executable "failed to prepare" $testfile $srcfile debug]} { diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index 266df46..6ca7711 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -18,12 +18,7 @@ # either execs or exits --- since those events take somewhat different # code paths in GDB, both variants are exercised. -# Until "set follow-fork-mode" and "catch vfork" are implemented on -# other targets... -# -if {![istarget "*-linux*"]} { - continue -} +require allow_fork_tests standard_testfile .c -exit.c vforked-prog.c diff --git a/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp b/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp index 311d7ba..cb49ef6 100644 --- a/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp +++ b/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp @@ -23,6 +23,7 @@ # in the source of the shlib, and "list" should display the source where # the program stopped. +require allow_fork_tests require allow_shlib_tests standard_testfile .c -shlib.c @@ -40,7 +41,8 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile} $opts] } { } proc do_test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_locate_shlib $::shlib_path gdb_test_no_output "set follow-fork-mode child" gdb_test_no_output "set detach-on-fork off" diff --git a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp index 26ed2f9..c24a9bc 100644 --- a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp +++ b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp @@ -19,6 +19,8 @@ # inferior-events [on,off]', 'set follow-fork-mode [child,parent]' and # 'set detach-on-fork [on,off]' are the correct ones. +require allow_fork_tests + # This test relies on "run", so it cannot run on target remote stubs. require !use_gdb_stub @@ -71,7 +73,8 @@ set i 0 foreach_with_prefix print_inferior_events { "on" "off" } { foreach_with_prefix follow_fork_mode { "child" "parent" } { foreach_with_prefix detach_on_fork { "on" "off" } { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test_no_output "set print inferior-events $print_inferior_events" gdb_test_no_output "set follow-fork-mode $follow_fork_mode" gdb_test_no_output "set detach-on-fork $detach_on_fork" diff --git a/gdb/testsuite/gdb.base/fork-running-state.exp b/gdb/testsuite/gdb.base/fork-running-state.exp index 4b810a6..c446800 100644 --- a/gdb/testsuite/gdb.base/fork-running-state.exp +++ b/gdb/testsuite/gdb.base/fork-running-state.exp @@ -17,6 +17,8 @@ # in non-stop). GDB used to miss updating the parent/child running # states after a fork. +require allow_fork_tests + standard_testfile # The test proper. diff --git a/gdb/testsuite/gdb.base/frame-args.exp b/gdb/testsuite/gdb.base/frame-args.exp index 31e4d15..0daa3aa 100644 --- a/gdb/testsuite/gdb.base/frame-args.exp +++ b/gdb/testsuite/gdb.base/frame-args.exp @@ -19,7 +19,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto break_me]} { return diff --git a/gdb/testsuite/gdb.base/frame-info-consistent.exp b/gdb/testsuite/gdb.base/frame-info-consistent.exp index 67bcd18..b594047 100644 --- a/gdb/testsuite/gdb.base/frame-info-consistent.exp +++ b/gdb/testsuite/gdb.base/frame-info-consistent.exp @@ -97,7 +97,8 @@ proc compare_frames {frames} { proc test {enable} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_test_no_output "maint frame-unwinder $enable DEBUGINFO" diff --git a/gdb/testsuite/gdb.base/frame-view.exp b/gdb/testsuite/gdb.base/frame-view.exp index fa00c35..34ac668 100644 --- a/gdb/testsuite/gdb.base/frame-view.exp +++ b/gdb/testsuite/gdb.base/frame-view.exp @@ -28,7 +28,8 @@ if { [build_executable "failed to prepare" \ # "select-frame view". proc test_select_frame_view { with_pretty_printer } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if { $with_pretty_printer } { require allow_python_tests diff --git a/gdb/testsuite/gdb.base/fullname.exp b/gdb/testsuite/gdb.base/fullname.exp index 430d0c4..ec90179 100644 --- a/gdb/testsuite/gdb.base/fullname.exp +++ b/gdb/testsuite/gdb.base/fullname.exp @@ -45,7 +45,8 @@ set line [gdb_get_line_number "set breakpoint 1 here"] # Initialize GDB after getting the line number, to make sure # symbols aren't loaded. -clean_restart $binfile +clean_restart +gdb_load $binfile set msg "set breakpoint by full path before loading symbols - built absolute" if { [gdb_breakpoint [standard_output_file tmp-${srcfile}]:${line} {no-message}] != 0 } { @@ -65,12 +66,13 @@ if { [gdb_breakpoint [standard_output_file tmp-${srcfile}]:${line} {no-message}] } # Build the test executable using a relative path. -if { [gdb_compile [relative_filename [pwd] [standard_output_file tmp-${srcfile}]] \ +if { [gdb_compile [relative_filename [pwd] [build_standard_output_file tmp-${srcfile}]] \ "${binfile}" executable {debug}] != "" } { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile set msg "set breakpoint by full path before loading symbols - built relative" if { [gdb_breakpoint [standard_output_file tmp-${srcfile}]:${line} {no-message}] != 0 } { @@ -99,7 +101,8 @@ with_cwd [standard_output_file {}] { } } -clean_restart $binfile +clean_restart +gdb_load $binfile set msg "set breakpoint by full path before loading symbols - built other" if { [gdb_breakpoint [standard_output_file tmp-${srcfile}]:${line} {no-message}] != 0 } { diff --git a/gdb/testsuite/gdb.base/gcore-buffer-overflow.exp b/gdb/testsuite/gdb.base/gcore-buffer-overflow.exp index 0fb79c7..5a6bfe6 100644 --- a/gdb/testsuite/gdb.base/gcore-buffer-overflow.exp +++ b/gdb/testsuite/gdb.base/gcore-buffer-overflow.exp @@ -29,7 +29,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set args ${pattern}" \ "set buffer exceeding arguments" diff --git a/gdb/testsuite/gdb.base/gcore-memory-usage.exp b/gdb/testsuite/gdb.base/gcore-memory-usage.exp index bd041f2..14b03a0 100644 --- a/gdb/testsuite/gdb.base/gcore-memory-usage.exp +++ b/gdb/testsuite/gdb.base/gcore-memory-usage.exp @@ -47,8 +47,10 @@ proc get_mem_usage {pid prefix} { # This proc restarts GDB, runs the inferior with the desired # amount of memory, then checks how much memory is necessary # to run the gcore command. It will return -1 if the gcore -# command fails, 0 otherwise. -proc run_test {megs} { +# command fails, otherwise the amount of memory used by GDB +# to generate that gcore. MAX_MEM is the maximum amount of +# memory GDB is allowed to use, in megabytes. +proc run_test {megs max_mem} { with_test_prefix "$megs Mb" { clean_restart $::testfile @@ -74,23 +76,24 @@ proc run_test {megs} { set diff_k [expr $mem_after - $mem_before] set diff [expr $diff_k/1024] verbose -log "The gcore command used $diff Mb ($diff_k Kb)" - # The original plan was to compare to a multiple of MEGS - # but since the requirements don't seem to go up as the - # inferior allocated more memory, we instead just hardcode - # 2 megs, since sometimes 1 is used. - gdb_assert {$diff < 2} "gdb did not use too much memory" + gdb_assert {$diff <= $max_mem} "gdb did not use too much memory" gdb_test_no_output "set spin=0" "Allow program to exit" } - return 0 + return $diff } # If we couldn't create the first corefile, there's no point -# in running the second part of the test. -if {[run_test 4] != 0} { +# in running the second part of the test. The maximum amount +# of memory allowed is the same as the memory used by the +# inferior. +set mem_limit [run_test 4 4] +if {$mem_limit < 0} { return } # Surprisingly enough, the larger inferior doesn't seem to use # any extra memory, it usually uses less memory. Which is good, # it means our memory requirements aren't growing with the inferior. -run_test 64 +# This test ensures that it remains true that a larger inferior will +# not grow the memory requirements. +run_test 64 $mem_limit diff --git a/gdb/testsuite/gdb.base/gcore-relro-pie.exp b/gdb/testsuite/gdb.base/gcore-relro-pie.exp index 361fdb6..641caf1 100644 --- a/gdb/testsuite/gdb.base/gcore-relro-pie.exp +++ b/gdb/testsuite/gdb.base/gcore-relro-pie.exp @@ -38,7 +38,8 @@ if [run_on_host "strip" "$strip_program" "-g -o ${stripped_binfile} $binfile"] { set perm [file attributes ${binfile} -permissions] file attributes ${stripped_binfile} -permissions $perm -clean_restart ${stripped_binfile} +clean_restart +gdb_load $stripped_binfile # The binary is stripped of debug info, but not minsyms. if ![runto break_here] { @@ -51,7 +52,8 @@ if {![gdb_gcore_cmd $gcorefile "save a corefile"]} { # Now restart gdb with the unstripped binary and load the corefile. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test "core ${gcorefile}" \ "Core was generated by .*" "re-load generated corefile" diff --git a/gdb/testsuite/gdb.base/gcore-relro.exp b/gdb/testsuite/gdb.base/gcore-relro.exp index 0090c37..2bbd064 100644 --- a/gdb/testsuite/gdb.base/gcore-relro.exp +++ b/gdb/testsuite/gdb.base/gcore-relro.exp @@ -34,7 +34,8 @@ set objfile [standard_output_file ${testfile}.o] } with_test_prefix "first session" { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_load_shlib ${binfile_lib} if ![runto lib] { @@ -49,7 +50,8 @@ with_test_prefix "first session" { # Now restart gdb and load the corefile. with_test_prefix "second session" { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_load_shlib ${binfile_lib} gdb_test "core ${gcorefile}" "Core was generated by .*" \ diff --git a/gdb/testsuite/gdb.base/gcore-tls-pie.exp b/gdb/testsuite/gdb.base/gcore-tls-pie.exp index c508b78..a8f7366 100644 --- a/gdb/testsuite/gdb.base/gcore-tls-pie.exp +++ b/gdb/testsuite/gdb.base/gcore-tls-pie.exp @@ -42,7 +42,8 @@ if [run_on_host "strip" "$strip_program" "-g -o ${stripped_binfile} $binfile"] { set perm [file attributes ${binfile} -permissions] file attributes ${stripped_binfile} -permissions $perm -clean_restart ${stripped_binfile} +clean_restart +gdb_load $stripped_binfile # The binary is stripped of debug info, but not minsyms. if ![runto break_here] { @@ -55,7 +56,8 @@ if {![gdb_gcore_cmd $gcorefile "save a corefile"]} { # Now restart gdb with the unstripped binary and load the corefile. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test "core ${gcorefile}" \ "Core was generated by .*" "re-load generated corefile" diff --git a/gdb/testsuite/gdb.base/gcore.exp b/gdb/testsuite/gdb.base/gcore.exp index 5251e3f..c8a4c11 100644 --- a/gdb/testsuite/gdb.base/gcore.exp +++ b/gdb/testsuite/gdb.base/gcore.exp @@ -16,6 +16,7 @@ # This file was written by Michael Snyder (msnyder@redhat.com) # This is a test for the gdb command "generate-core-file". +require gcore_cmd_available standard_testfile @@ -57,7 +58,8 @@ if {!$core_supported} { } # Now restart gdb and load the corefile. -clean_restart $binfile +clean_restart +gdb_load $binfile set core_loaded [gdb_core_cmd "$corefile" "re-load generated corefile"] if { $core_loaded == -1 } { diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp index 3e79702..fd9f06e 100644 --- a/gdb/testsuite/gdb.base/gcorebg.exp +++ b/gdb/testsuite/gdb.base/gcorebg.exp @@ -46,10 +46,10 @@ proc test_body { detached } { global binfile global GCORE global corefile - global GDB_DATA_DIRECTORY + global GDB GDB_DATA_DIRECTORY # We can't use gdb_test_multiple here because GDB is not started. - set gcore_cmd $GCORE + set gcore_cmd "$GCORE -g $GDB" if {$GDB_DATA_DIRECTORY ne ""} { set gcore_cmd "$gcore_cmd -d '$GDB_DATA_DIRECTORY'" } diff --git a/gdb/testsuite/gdb.base/gdb-index-err.exp b/gdb/testsuite/gdb.base/gdb-index-err.exp index 973248a..b353836 100644 --- a/gdb/testsuite/gdb.base/gdb-index-err.exp +++ b/gdb/testsuite/gdb.base/gdb-index-err.exp @@ -90,13 +90,15 @@ foreach_with_prefix flag { "" "-dwarf-5" } { } # Add the index section to the executable. - clean_restart ${binfile}.${extension} + clean_restart + gdb_load $binfile.$extension gdb_assert {[ensure_gdb_index ${binfile}.${extension} ${flag}] == 1} \ "add index to executable" # Reload the executable (which now has an index), and try to # generate and index from it. This will fail. - clean_restart ${binfile}.${extension} + clean_restart + gdb_load $binfile.$extension gdb_test "save gdb-index ${flag} $already_indexed_dir" \ "Error while writing index for `[string_to_regexp $binfile.$extension]': Cannot use an index to create the index" \ "try to generate an index from a binary with an index" diff --git a/gdb/testsuite/gdb.base/gdb1250.exp b/gdb/testsuite/gdb.base/gdb1250.exp index 4e83c8c..2cabbf0 100644 --- a/gdb/testsuite/gdb.base/gdb1250.exp +++ b/gdb/testsuite/gdb.base/gdb1250.exp @@ -29,7 +29,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto abort {allow-pending}]} { return diff --git a/gdb/testsuite/gdb.base/gdb1555.exp b/gdb/testsuite/gdb.base/gdb1555.exp index 648abd7..ab12a28 100644 --- a/gdb/testsuite/gdb.base/gdb1555.exp +++ b/gdb/testsuite/gdb.base/gdb1555.exp @@ -34,7 +34,8 @@ if { [gdb_compile_shlib $libsrc $libobj {debug}] != "" return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib $libobj if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/gdbindex-stabs.exp b/gdb/testsuite/gdb.base/gdbindex-stabs.exp index 506ad11..9becaa1 100644 --- a/gdb/testsuite/gdb.base/gdbindex-stabs.exp +++ b/gdb/testsuite/gdb.base/gdbindex-stabs.exp @@ -28,7 +28,8 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile_stabs}" ${objfile_stabs} object return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # FAIL was: No line number known for stabs_function. gdb_test "list stabs_function" " marker-here .*" diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp index 48aae6b..11a4a23 100644 --- a/gdb/testsuite/gdb.base/gdbinit-history.exp +++ b/gdb/testsuite/gdb.base/gdbinit-history.exp @@ -141,7 +141,7 @@ proc check_history { hist } { if { [llength $hist_lines] == 1 } { set pattern [lindex $hist_lines 0] } else { - set pattern [eval multi_line $hist_lines] + set pattern [multi_line {*}$hist_lines] } # Check the history. diff --git a/gdb/testsuite/gdb.base/global-var-nested-by-dso.exp b/gdb/testsuite/gdb.base/global-var-nested-by-dso.exp index 92d6c62..480396a 100644 --- a/gdb/testsuite/gdb.base/global-var-nested-by-dso.exp +++ b/gdb/testsuite/gdb.base/global-var-nested-by-dso.exp @@ -42,7 +42,8 @@ if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable \ return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $binfile_lib1 gdb_load_shlib $binfile_lib2 diff --git a/gdb/testsuite/gdb.base/gnu-ifunc.exp b/gdb/testsuite/gdb.base/gnu-ifunc.exp index c7afbe5..f134a0f 100644 --- a/gdb/testsuite/gdb.base/gnu-ifunc.exp +++ b/gdb/testsuite/gdb.base/gnu-ifunc.exp @@ -96,7 +96,8 @@ proc_with_prefix set-break {resolver_attr resolver_debug final_debug} { set suffix [make_binsuffix $resolver_attr $resolver_debug $final_debug] set lib_so [standard_output_file ${libfile}-$suffix.so] - clean_restart $binfile-$suffix + clean_restart + gdb_load $binfile-$suffix gdb_load_shlib ${lib_so} if {![runto_main]} { @@ -185,6 +186,11 @@ proc_with_prefix set-break {resolver_attr resolver_debug final_debug} { # other two locations. gdb_test "info breakpoints" "$location\r\n.*$location\r\n$location" } + + # At one point a bug existed such that GDB would trigger an assert + # while restarting the inferior with ifunc breakpoints set. + gdb_run_cmd + gdb_test "" "Breakpoint $::decimal,.*final \\(\[^\r\n\]*\\).*" "restart, run until breakpoint" } # Misc GNU ifunc tests. For the description of RESOLVER_ATTR, @@ -218,7 +224,8 @@ proc misc_tests {resolver_attr resolver_debug final_debug} { # Start with a fresh gdb. - clean_restart $binfile-$suffix + clean_restart + gdb_load $binfile-$suffix gdb_load_shlib ${lib_so} if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp index ac0bff3..62c2003 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.exp +++ b/gdb/testsuite/gdb.base/gnu_vector.exp @@ -40,7 +40,8 @@ if { [do_compile {-mcpu=native}] != "" return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if { ![runto_main] } { return -1 diff --git a/gdb/testsuite/gdb.base/hashline1.exp b/gdb/testsuite/gdb.base/hashline1.exp index 9af144b..8e815ae 100644 --- a/gdb/testsuite/gdb.base/hashline1.exp +++ b/gdb/testsuite/gdb.base/hashline1.exp @@ -37,7 +37,8 @@ if { [gdb_compile $compile_name "${binfile}" executable {debug}] != "" } { return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile set bp_location [gdb_get_line_number "set breakpoint here" $new_srcfile] diff --git a/gdb/testsuite/gdb.base/hashline2.exp b/gdb/testsuite/gdb.base/hashline2.exp index 740f511..f12b4d1 100644 --- a/gdb/testsuite/gdb.base/hashline2.exp +++ b/gdb/testsuite/gdb.base/hashline2.exp @@ -34,7 +34,8 @@ if { [gdb_compile $new_srcfile "${binfile}" executable {debug}] != "" } { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile set bp_location [gdb_get_line_number "set breakpoint here" ${new_srcfile}] diff --git a/gdb/testsuite/gdb.base/hashline3.exp b/gdb/testsuite/gdb.base/hashline3.exp index 2575c28..508f7c9 100644 --- a/gdb/testsuite/gdb.base/hashline3.exp +++ b/gdb/testsuite/gdb.base/hashline3.exp @@ -35,7 +35,8 @@ if { [gdb_compile $new_srcfile "${binfile}" executable {debug}] != "" } { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile set bp_location [gdb_get_line_number "set breakpoint here" $new_srcfile] diff --git a/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp b/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp index 8598345..9355ce0 100644 --- a/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp +++ b/gdb/testsuite/gdb.base/hbreak-in-shr-unsupported.exp @@ -34,7 +34,8 @@ if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib_src} ${lib_so} $lib_opts] != " return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $lib_so if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/hook-stop.exp b/gdb/testsuite/gdb.base/hook-stop.exp index a7b6ccd..1c774ce 100644 --- a/gdb/testsuite/gdb.base/hook-stop.exp +++ b/gdb/testsuite/gdb.base/hook-stop.exp @@ -37,7 +37,8 @@ proc define_hook_stop {commands} { proc setup {commands} { global srcfile binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return -code return diff --git a/gdb/testsuite/gdb.base/huge.exp b/gdb/testsuite/gdb.base/huge.exp index f75b620..cb12964 100644 --- a/gdb/testsuite/gdb.base/huge.exp +++ b/gdb/testsuite/gdb.base/huge.exp @@ -42,7 +42,8 @@ for { set size $max } { $size >= $min } { set size [expr $size / 2] } { require {expr $compilation_succeeded} # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile save_vars { timeout } { set timeout 30 diff --git a/gdb/testsuite/gdb.base/infcall-exec.exp b/gdb/testsuite/gdb.base/infcall-exec.exp index 33cc5b6..b819284 100644 --- a/gdb/testsuite/gdb.base/infcall-exec.exp +++ b/gdb/testsuite/gdb.base/infcall-exec.exp @@ -36,7 +36,8 @@ if { [is_remote target] } { set binfile2 [gdb_remote_download target $binfile2] } -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.base/infcall-failure-2.exp b/gdb/testsuite/gdb.base/infcall-failure-2.exp new file mode 100644 index 0000000..2a7d784 --- /dev/null +++ b/gdb/testsuite/gdb.base/infcall-failure-2.exp @@ -0,0 +1,37 @@ +# 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/>. + +standard_testfile infcall-failure.c + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] == -1 } { + return +} + +if { ![runto_main] } { + return +} + +if { ![gdb_breakpoint "*0x1" message] } { + return +} + +gdb_test "p foo ()" \ + [multi_line \ + [string_to_regexp "Command aborted."] \ + ".*" ] + +# Check that gdb is still responsive. Regression test for PR gdb/33068. +gdb_test "p 1 + 1" \ + " = 2" diff --git a/gdb/testsuite/gdb.base/infcall-failure.exp b/gdb/testsuite/gdb.base/infcall-failure.exp index 66bccd1..594cb2b 100644 --- a/gdb/testsuite/gdb.base/infcall-failure.exp +++ b/gdb/testsuite/gdb.base/infcall-failure.exp @@ -39,7 +39,8 @@ proc start_gdb_and_runto_main { target_async target_non_stop } { append ::GDBFLAGS \ " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart + gdb_load $::binfile } if { ![runto_main] } { @@ -131,7 +132,13 @@ proc_with_prefix run_cond_hits_segfault_test { async_p non_stop_p } { [multi_line \ "Continuing\\." \ "" \ - "Program received signal SIGSEGV, Segmentation fault\\." \ + [string cat \ + [string_to_regexp \ + "Program received signal SIGSEGV, Segmentation fault."] \ + "("] \ + [string cat \ + [string_to_regexp "Address not mapped to object."] \ + ")?"] \ "${::hex} in func_segfault \\(\\) at \[^\r\n\]+:${::segv_line}" \ "${::decimal}\\s+\[^\r\n\]+Segfault here\[^\r\n\]+" \ "Error in testing condition for breakpoint ${bp_1_num}:" \ @@ -161,7 +168,13 @@ proc_with_prefix run_call_hits_segfault_test { async_p non_stop_p } { gdb_test "call func_segfault ()" \ [multi_line \ "" \ - "Program received signal SIGSEGV, Segmentation fault\\." \ + [string cat \ + [string_to_regexp \ + "Program received signal SIGSEGV, Segmentation fault."] \ + "("] \ + [string cat \ + [string_to_regexp "Address not mapped to object."] \ + ")?"] \ "${::hex} in func_segfault \\(\\) at \[^\r\n\]+:${::segv_line}" \ "${::decimal}\\s+\[^\r\n\]+Segfault here\[^\r\n\]+" \ "The program being debugged was signaled while in a function called from GDB\\." \ diff --git a/gdb/testsuite/gdb.base/infcall-nested-structs.exp.tcl b/gdb/testsuite/gdb.base/infcall-nested-structs.exp.tcl index 3a11d7f..6c95934 100644 --- a/gdb/testsuite/gdb.base/infcall-nested-structs.exp.tcl +++ b/gdb/testsuite/gdb.base/infcall-nested-structs.exp.tcl @@ -81,7 +81,8 @@ proc start_nested_structs_test { lang types } { } # Start with a fresh gdb. - clean_restart ${binfile} + clean_restart + gdb_load $binfile # Make certain that the output is consistent gdb_test_no_output "set print sevenbit-strings" @@ -91,7 +92,7 @@ proc start_nested_structs_test { lang types } { gdb_test_no_output "set print elements 300" # Advance to main - if { ![runto_main] } then { + if { ![runto_main] } { return 0 } diff --git a/gdb/testsuite/gdb.base/infcall-timeout.exp b/gdb/testsuite/gdb.base/infcall-timeout.exp index aa7dbc3..621a7b9 100644 --- a/gdb/testsuite/gdb.base/infcall-timeout.exp +++ b/gdb/testsuite/gdb.base/infcall-timeout.exp @@ -41,7 +41,8 @@ proc run_test { target_async target_non_stop non_stop unwind } { append ::GDBFLAGS \ " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart + gdb_load $::binfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/inferior-args.exp b/gdb/testsuite/gdb.base/inferior-args.exp index 9406c78..6b92c08 100644 --- a/gdb/testsuite/gdb.base/inferior-args.exp +++ b/gdb/testsuite/gdb.base/inferior-args.exp @@ -17,6 +17,7 @@ # This does not work on boards that don't support inferior arguments. require {!target_info exists noargs} +require {expr [have_startup_shell] != -1} standard_testfile .c @@ -42,7 +43,8 @@ proc do_test { method startup_with_shell inferior_args expected_results \ stub_suitable } { global binfile hex - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test_no_output "set startup-with-shell $startup_with_shell" @@ -168,8 +170,7 @@ lappend test_desc_list [list "test one" \ # the rest of this mess in order to avoid TCL escaping the quote for # me. It's super important that what we send to GDB is '"' not '\"'. set item [list "test two" false] -set cmd [format "lappend item \{ '%c' '\\%c' \}" 34 34] -eval $cmd +lappend item [format { '%c' '\%c' } 34 34] set bs "\\\\" lappend item [list "$hex \"$bs\"\"" "$hex \"$bs$bs$bs\"\""] lappend test_desc_list $item @@ -211,14 +212,31 @@ lappend test_desc_list [list "test four" \ [list "$hex \"'\"" \ "$hex \"\\\\\"\""]] -foreach desc $test_desc_list { - lassign $desc name stub_suitable args re_list - with_test_prefix $name { - foreach_with_prefix set_method { "start" "starti" "run" "set args" } { - foreach_with_prefix startup_with_shell { on off } { - do_test $set_method $startup_with_shell $args $re_list \ - $stub_suitable +# Run all tests in the global TEST_DESC_LIST. +proc run_all_tests {} { + foreach desc $::test_desc_list { + lassign $desc name stub_suitable args re_list + with_test_prefix $name { + foreach_with_prefix set_method { "start" "starti" "run" "set args" } { + foreach_with_prefix startup_with_shell { on off } { + do_test $set_method $startup_with_shell $args $re_list \ + $stub_suitable + } } } } } + +run_all_tests + +# For extended-remote targets, disable the packet which passes +# inferior arguments as a single string. This changes how the vRun +# (extended-remote only) packet works. +if {[target_info gdb_protocol] == "extended-remote"} { + with_test_prefix "single-inferior-arg disabled" { + save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"set remote single-inferior-argument-feature-packet off\"" + run_all_tests + } + } +} diff --git a/gdb/testsuite/gdb.base/inferior-died.exp b/gdb/testsuite/gdb.base/inferior-died.exp index 3992561..9ba3a4c 100644 --- a/gdb/testsuite/gdb.base/inferior-died.exp +++ b/gdb/testsuite/gdb.base/inferior-died.exp @@ -13,10 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# Until "set follow-fork-mode" and "catch fork" are implemented on -# other targets... -# -require {istarget "*-*-linux*"} +require allow_fork_tests require support_displaced_stepping @@ -28,7 +25,8 @@ if { [build_executable "failed to build" ${testfile} ${testfile}.c] } { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - clean_restart ${binfile} + clean_restart + gdb_load $binfile } gdb_test_no_output "set detach-on-fork off" diff --git a/gdb/testsuite/gdb.base/info-proc.exp b/gdb/testsuite/gdb.base/info-proc.exp index 8dff6a5..adc8894 100644 --- a/gdb/testsuite/gdb.base/info-proc.exp +++ b/gdb/testsuite/gdb.base/info-proc.exp @@ -63,7 +63,8 @@ if {[istarget "*-*-linux*"]} { } set gcorefile [standard_output_file $testfile.gcore] if {[gdb_gcore_cmd $gcorefile "save a core file"]} { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "core $gcorefile" "Core was generated by.*" \ "core [file tail $gcorefile]" diff --git a/gdb/testsuite/gdb.base/info-program.exp b/gdb/testsuite/gdb.base/info-program.exp index 5a47e1e..da24880 100644 --- a/gdb/testsuite/gdb.base/info-program.exp +++ b/gdb/testsuite/gdb.base/info-program.exp @@ -35,7 +35,8 @@ standard_testfile proc do_test { threads non-stop } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart $::binfile-$threads + clean_restart + gdb_load $::binfile-$threads } gdb_test "info program" \ diff --git a/gdb/testsuite/gdb.base/info-shared.exp b/gdb/testsuite/gdb.base/info-shared.exp index 6f1b2d6..e81b28e 100644 --- a/gdb/testsuite/gdb.base/info-shared.exp +++ b/gdb/testsuite/gdb.base/info-shared.exp @@ -79,6 +79,9 @@ proc check_info_shared { test expect1 expect2 } { } } +# Check that "info shared" before running doesn't crash. +check_info_shared "info sharedlibrary before running" 0 0 + # Start the inferior, and check neither of the libraries are loaded at # the start. if ![runto_main] { diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl index f75bb36..c05837b 100644 --- a/gdb/testsuite/gdb.base/info-types.exp.tcl +++ b/gdb/testsuite/gdb.base/info-types.exp.tcl @@ -33,7 +33,7 @@ proc run_test { lang } { return -1 } - if ![runto_main] then { + if { ![runto_main] } { return 0 } diff --git a/gdb/testsuite/gdb.base/info_sources_2.exp b/gdb/testsuite/gdb.base/info_sources_2.exp index c469049..09e9972 100644 --- a/gdb/testsuite/gdb.base/info_sources_2.exp +++ b/gdb/testsuite/gdb.base/info_sources_2.exp @@ -35,7 +35,8 @@ if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable \ return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile set solib_name [gdb_load_shlib $solib_name] @@ -72,13 +73,18 @@ proc run_info_sources { extra_args args } { set objfile_name "" set source_files {} set files {} + # Note below we sanitize paths so we can compare against the + # host_file_normalize'd paths later. Note we sanitize, but + # don't normalize here, as the latter would turn a relative + # path into an absolute path, and this testcase wants to make + # sure that GDB prints the absolute path. gdb_test_multiple $cmd "" { -re "${command_regex}\r\n" { exp_continue } -re "^(\[^\r\n\]+):\r\n" { - set objfile_name $expect_out(1,string) + set objfile_name [host_file_sanitize $expect_out(1,string)] if { $is_remote_target } { set objfile_name [file tail $objfile_name] } @@ -101,7 +107,7 @@ proc run_info_sources { extra_args args } { } -re "^(\[^,\r\n\]+), " { - set f $expect_out(1,string) + set f [host_file_sanitize $expect_out(1,string)] lappend files $f exp_continue } @@ -111,7 +117,7 @@ proc run_info_sources { extra_args args } { return } - set f $expect_out(1,string) + set f [host_file_sanitize $expect_out(1,string)] lappend files $f set info_sources($objfile_name) $files set $objfile_name "" @@ -133,7 +139,7 @@ proc run_info_sources { extra_args args } { } # Figure out the path for SOURCEFILE that we're looking for. - set sourcepath [file normalize ${srcdir}/${subdir}/${sourcefile}] + set sourcepath [host_file_normalize ${srcdir}/${subdir}/${sourcefile}] if { $is_remote_target } { set objfile [file tail $objfile] @@ -156,32 +162,34 @@ proc run_info_sources { extra_args args } { # The actual tests. +set host_binfile [host_file_normalize $binfile$EXEEXT] + run_info_sources "" \ - ${binfile} ${srcfile} \ - ${binfile} ${testfile}-header.h \ + ${host_binfile} ${srcfile} \ + ${host_binfile} ${testfile}-header.h \ ${solib_name} ${srcfile2} \ ${solib_name} ${testfile}-header.h run_info_sources "-basename info_sources_2" \ - ${binfile} ${srcfile} \ - ${binfile} ${testfile}-header.h \ + ${host_binfile} ${srcfile} \ + ${host_binfile} ${testfile}-header.h \ ${solib_name} ${srcfile2} \ ${solib_name} ${testfile}-header.h run_info_sources "-basename \\.c" \ - ${binfile} ${srcfile} \ - ${binfile} !${testfile}-header.h \ + ${host_binfile} ${srcfile} \ + ${host_binfile} !${testfile}-header.h \ ${solib_name} ${srcfile2} \ ${solib_name} !${testfile}-header.h run_info_sources "-basename -- -test\\.c" \ - ${binfile} ${srcfile} \ - ${binfile} !${testfile}-header.h \ + ${host_binfile} ${srcfile} \ + ${host_binfile} !${testfile}-header.h \ ${solib_name} !${srcfile2} \ ${solib_name} !${testfile}-header.h run_info_sources "-basename -- -lib\\.c" \ - ${binfile} !${srcfile} \ - ${binfile} !${testfile}-header.h \ + ${host_binfile} !${srcfile} \ + ${host_binfile} !${testfile}-header.h \ ${solib_name} ${srcfile2} \ ${solib_name} !${testfile}-header.h diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py index bc4a673..4ab7257 100644 --- a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py +++ b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py @@ -65,6 +65,10 @@ class TestUnwinder(Unwinder): for reg in pending_frame.architecture().registers("general"): val = pending_frame.read_register(reg) + # Having unavailable registers leads to a fall back to the standard + # unwinders. Don't add unavailable registers to avoid this. + if str(val) == "<unavailable>": + continue unwinder.add_saved_register(reg, val) return unwinder diff --git a/gdb/testsuite/gdb.base/internal-string-values.exp b/gdb/testsuite/gdb.base/internal-string-values.exp index aa68bc9..c1afa18 100644 --- a/gdb/testsuite/gdb.base/internal-string-values.exp +++ b/gdb/testsuite/gdb.base/internal-string-values.exp @@ -250,7 +250,8 @@ proc_with_prefix test_internal_var { } { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { fail "could not run to main" diff --git a/gdb/testsuite/gdb.base/interrupt-daemon-attach.exp b/gdb/testsuite/gdb.base/interrupt-daemon-attach.exp index 3c46f5d..a42fc12 100644 --- a/gdb/testsuite/gdb.base/interrupt-daemon-attach.exp +++ b/gdb/testsuite/gdb.base/interrupt-daemon-attach.exp @@ -36,7 +36,8 @@ proc do_test {} { # Attach to the parent, run it to a known point, extract the # child's PID, and detach. with_test_prefix "parent" { - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test "attach $parent_pid" \ "Attaching to program.*, process $parent_pid.*" \ @@ -60,7 +61,8 @@ proc do_test {} { with_test_prefix "child" { global gdb_prompt - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "attach $child_pid" \ "Attaching to program.*, process $child_pid.*" \ diff --git a/gdb/testsuite/gdb.base/interrupt-daemon.exp b/gdb/testsuite/gdb.base/interrupt-daemon.exp index 161f854..b909437 100644 --- a/gdb/testsuite/gdb.base/interrupt-daemon.exp +++ b/gdb/testsuite/gdb.base/interrupt-daemon.exp @@ -16,6 +16,8 @@ # Make sure that we can interrupt an inferior that forks and moves to # its own session. +require allow_fork_tests + standard_testfile if {[build_executable "failed to build" $testfile $srcfile {debug}]} { @@ -28,7 +30,8 @@ proc do_test {} { global binfile global gdb_prompt - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "set follow-fork-mode child" ".*" diff --git a/gdb/testsuite/gdb.base/jit-bfd-name.exp b/gdb/testsuite/gdb.base/jit-bfd-name.exp index 9e4daa1..756a38b 100644 --- a/gdb/testsuite/gdb.base/jit-bfd-name.exp +++ b/gdb/testsuite/gdb.base/jit-bfd-name.exp @@ -46,7 +46,8 @@ if { [compile_jit_main ${main_srcfile} ${main_binfile} {}] != 0 } { return } -clean_restart $::main_binfile +clean_restart +gdb_load $::main_binfile if { ![runto_main] } { return } @@ -67,11 +68,13 @@ gdb_breakpoint [gdb_get_line_number "break here 1" $::main_srcfile] gdb_continue_to_breakpoint "break here 1" # Confirm that the two expected functions are available. +set re_f1 [string_to_regexp "int jit_function_0001(void)"] +set re_f2 [string_to_regexp "int jit_function_0002(void)"] gdb_test "info function ^jit_function" \ [multi_line \ "File \[^\r\n\]+jit-elf-solib.c:" \ - "${decimal}:\\s+int jit_function_0001\\(\\);" \ - "${decimal}:\\s+int jit_function_0002\\(\\);"] + "${decimal}:\\s+$re_f1;" \ + "${decimal}:\\s+$re_f2;"] # Capture the addresses of each JIT symfile. set symfile_addrs {} diff --git a/gdb/testsuite/gdb.base/jit-elf-fork.exp b/gdb/testsuite/gdb.base/jit-elf-fork.exp index 81d3350..92e7dc6 100644 --- a/gdb/testsuite/gdb.base/jit-elf-fork.exp +++ b/gdb/testsuite/gdb.base/jit-elf-fork.exp @@ -15,6 +15,7 @@ # Test fork handling of an inferior that has JIT-ed objfiles. +require allow_fork_tests require allow_shlib_tests load_lib jit-elf-helpers.exp @@ -53,7 +54,8 @@ if { [compile_jit_main ${main_srcfile} ${main_binfile} {}] != 0 } { # that the callers can continue execution until there. proc do_setup { detach-on-fork follow-fork-mode } { - clean_restart ${::main_binfile} + clean_restart + gdb_load $::main_binfile gdb_test_no_output "set detach-on-fork ${detach-on-fork}" gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" diff --git a/gdb/testsuite/gdb.base/jit-elf-so.exp b/gdb/testsuite/gdb.base/jit-elf-so.exp index c227748..8f16bdb 100644 --- a/gdb/testsuite/gdb.base/jit-elf-so.exp +++ b/gdb/testsuite/gdb.base/jit-elf-so.exp @@ -73,7 +73,8 @@ proc one_jit_test {solib_binfiles_target match_str} { global main_loader_binfile main_loader_srcfile global main_solib_binfile main_solib_binfile_target main_solib_srcfile - clean_restart $main_loader_binfile + clean_restart + gdb_load $main_loader_binfile gdb_locate_shlib $main_solib_binfile # This is just to help debugging when things fail diff --git a/gdb/testsuite/gdb.base/jit-elf-solib.c b/gdb/testsuite/gdb.base/jit-elf-solib.c index 690d7a0..c6fcb89 100644 --- a/gdb/testsuite/gdb.base/jit-elf-solib.c +++ b/gdb/testsuite/gdb.base/jit-elf-solib.c @@ -22,4 +22,4 @@ #error "Must define the FUNCTION_NAME macro to set a jited function name" #endif -int FUNCTION_NAME() { return 42; } +int FUNCTION_NAME(void) { return 42; } diff --git a/gdb/testsuite/gdb.base/jit-elf.exp b/gdb/testsuite/gdb.base/jit-elf.exp index a519565..2dc67a5 100644 --- a/gdb/testsuite/gdb.base/jit-elf.exp +++ b/gdb/testsuite/gdb.base/jit-elf.exp @@ -48,7 +48,8 @@ proc clean_reattach {} { gdb_test_no_output "set var wait_for_gdb = 1" gdb_test "detach" "Detaching from .*" - clean_restart ${main_binfile} + clean_restart + gdb_load $main_binfile if { ![gdb_attach $testpid \ -pattern "main.*at .*$::main_basename.c:.*"] } { @@ -84,7 +85,8 @@ proc one_jit_test {jit_solibs_target match_str reattach} { global test_verbose global main_binfile main_srcfile - clean_restart ${main_binfile} + clean_restart + gdb_load $main_binfile # This is just to help debugging when things fail if {$test_verbose > 0} { diff --git a/gdb/testsuite/gdb.base/jit-reader-exec.exp b/gdb/testsuite/gdb.base/jit-reader-exec.exp index ef6148b..e70f104 100644 --- a/gdb/testsuite/gdb.base/jit-reader-exec.exp +++ b/gdb/testsuite/gdb.base/jit-reader-exec.exp @@ -43,7 +43,8 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/jit-reader-simple.exp b/gdb/testsuite/gdb.base/jit-reader-simple.exp index 77705eb..f577dba 100644 --- a/gdb/testsuite/gdb.base/jit-reader-simple.exp +++ b/gdb/testsuite/gdb.base/jit-reader-simple.exp @@ -103,9 +103,11 @@ proc jit_test_reread {standalone change_addr} { with_test_prefix "initial run" { if {$standalone} { - clean_restart $binfile + clean_restart + gdb_load $binfile } else { - clean_restart $binfile_dl + clean_restart + gdb_load $binfile_dl } runto_main @@ -175,7 +177,8 @@ foreach standalone {1 0} { # see JIT breakpoints defined for both. with_test_prefix "two JITers" { - clean_restart $binfile_dl2 + clean_restart + gdb_load $binfile_dl2 if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.base/jit-reader.exp b/gdb/testsuite/gdb.base/jit-reader.exp index 4462ab4..cd844ca 100644 --- a/gdb/testsuite/gdb.base/jit-reader.exp +++ b/gdb/testsuite/gdb.base/jit-reader.exp @@ -102,7 +102,8 @@ proc jit_reader_test {} { set any "\[^\r\n\]*" - clean_restart $jit_host_bin + clean_restart + gdb_load $jit_host_bin gdb_load_shlib $jit_reader_bin if {$test_verbose > 0} { diff --git a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp index ef4bb88..57ec330 100644 --- a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp +++ b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp @@ -19,6 +19,7 @@ # commands. require can_spawn_for_attach +require allow_multi_inferior_tests standard_testfile set executable $testfile diff --git a/gdb/testsuite/gdb.base/kill-during-detach.exp b/gdb/testsuite/gdb.base/kill-during-detach.exp index e164234..290606a 100644 --- a/gdb/testsuite/gdb.base/kill-during-detach.exp +++ b/gdb/testsuite/gdb.base/kill-during-detach.exp @@ -76,7 +76,8 @@ set checkpoint_line [gdb_get_line_number "Checkpoint here"] proc run_test { exit_p checkpoint_p } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"set non-stop on\"" - clean_restart $::binfile + clean_restart + gdb_load $::binfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/killed-outside.exp b/gdb/testsuite/gdb.base/killed-outside.exp index 919584d..2b367e4 100644 --- a/gdb/testsuite/gdb.base/killed-outside.exp +++ b/gdb/testsuite/gdb.base/killed-outside.exp @@ -46,7 +46,8 @@ proc test {cmds_after_kill} { global gdb_prompt global decimal - clean_restart ${binfile} + clean_restart + gdb_load $binfile if ![runto done] { return diff --git a/gdb/testsuite/gdb.base/langs.exp b/gdb/testsuite/gdb.base/langs.exp index b84b7d6..aa8d8e0 100644 --- a/gdb/testsuite/gdb.base/langs.exp +++ b/gdb/testsuite/gdb.base/langs.exp @@ -93,7 +93,8 @@ if {[runto csub]} { gdb_continue_to_end "first session" } -clean_restart $binfile +clean_restart +gdb_load $binfile # Try exercising the "minimal" language a bit... diff --git a/gdb/testsuite/gdb.base/large-frame.exp b/gdb/testsuite/gdb.base/large-frame.exp index 0418b5b..f0d7af6 100644 --- a/gdb/testsuite/gdb.base/large-frame.exp +++ b/gdb/testsuite/gdb.base/large-frame.exp @@ -28,12 +28,12 @@ if { [is_remote host] } { # the test. proc run_test { opt_level } { - global srcfile srcfile2 binfile hex + global srcfile srcfile2 hex standard_testfile large-frame-1.c large-frame-2.c if {[prepare_for_testing_full "failed to prepare" \ - [list ${binfile}-${opt_level} debug \ + [list $::testfile-$opt_level debug \ $srcfile [list debug] \ $srcfile2 [list nodebug optimize=-$opt_level]]]} { return diff --git a/gdb/testsuite/gdb.base/libsegfault.exp b/gdb/testsuite/gdb.base/libsegfault.exp index eab12ff..a3883e1 100644 --- a/gdb/testsuite/gdb.base/libsegfault.exp +++ b/gdb/testsuite/gdb.base/libsegfault.exp @@ -24,6 +24,15 @@ # the local machine. require {!is_remote host} +# On Cygwin, the testcase would somehow end up trying to preload +# libSegFault.so into the Expect process, which would fail and crash +# it. Since libSegFault.so is a glibc feature that doesn't exist on +# Cygwin, just skip testing there. +require {!expr {[isbuild "*-*-cygwin*"] && [ishost "*-*-cygwin*"]}} +# Same when testing MinGW with MSYS2, as MSYS2 is really a Cygwin +# fork. +require {!expr {[isbuild "*-*-mingw*"] && [ishost "*-*-mingw*"]}} + # Spawn GDB with LIB preloaded with LD_PRELOAD. CMDLINE_OPTS are # command line options passed to GDB. diff --git a/gdb/testsuite/gdb.base/lineinc.exp b/gdb/testsuite/gdb.base/lineinc.exp index cfd2ba7..2382fa5 100644 --- a/gdb/testsuite/gdb.base/lineinc.exp +++ b/gdb/testsuite/gdb.base/lineinc.exp @@ -86,7 +86,8 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" ${binfile} executable \ return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Any command that causes GDB to read the debugging info for the # lineinc.c compilation unit will do here. diff --git a/gdb/testsuite/gdb.base/list-missing-source.exp b/gdb/testsuite/gdb.base/list-missing-source.exp index 7807206..196a1f2 100644 --- a/gdb/testsuite/gdb.base/list-missing-source.exp +++ b/gdb/testsuite/gdb.base/list-missing-source.exp @@ -43,7 +43,8 @@ if { [gdb_compile "${srcfile}" "${binfile}" \ remote_file host delete $srcfile # Now start GDB, run to main and try to list the source. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/list.exp b/gdb/testsuite/gdb.base/list.exp index d005ceb..bdbb52b 100644 --- a/gdb/testsuite/gdb.base/list.exp +++ b/gdb/testsuite/gdb.base/list.exp @@ -385,7 +385,8 @@ proc test_only_end {} { proc test_list_invalid_args {} { global binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test "list -INVALID" \ "invalid explicit location argument, \"-INVALID\"" \ "first use of \"list -INVALID\"" @@ -393,7 +394,8 @@ proc test_list_invalid_args {} { "invalid explicit location argument, \"-INVALID\"" \ "second use of \"list -INVALID\"" - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test "list +INVALID" "Function \"\\+INVALID\" not defined." \ "first use of \"list +INVALID\"" gdb_test "list +INVALID" "Function \"\\+INVALID\" not defined." \ @@ -499,7 +501,8 @@ proc test_list {command listsize1 listsize2 linerange1 linerange2} { with_test_prefix "$command after stop: $listsize1, $listsize2" { global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.base/logical.exp b/gdb/testsuite/gdb.base/logical.exp index 31007e8..b00d6d5 100644 --- a/gdb/testsuite/gdb.base/logical.exp +++ b/gdb/testsuite/gdb.base/logical.exp @@ -32,7 +32,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # diff --git a/gdb/testsuite/gdb.base/long_long.exp b/gdb/testsuite/gdb.base/long_long.exp index 38ba03e..4fbb757 100644 --- a/gdb/testsuite/gdb.base/long_long.exp +++ b/gdb/testsuite/gdb.base/long_long.exp @@ -30,7 +30,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [con # use this to debug: #log_user 1 -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto known_types]} { return diff --git a/gdb/testsuite/gdb.base/longjmp.exp b/gdb/testsuite/gdb.base/longjmp.exp index caf0d5c..99552e6 100644 --- a/gdb/testsuite/gdb.base/longjmp.exp +++ b/gdb/testsuite/gdb.base/longjmp.exp @@ -26,7 +26,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } proc do_test { with_probes } { - clean_restart ${::binfile} + clean_restart + gdb_load $::binfile if { !$with_probes } { gdb_test "maint ignore-probes libc ^longjmp$" diff --git a/gdb/testsuite/gdb.base/macro-source-path.exp b/gdb/testsuite/gdb.base/macro-source-path.exp index 47ad789..9c84227 100644 --- a/gdb/testsuite/gdb.base/macro-source-path.exp +++ b/gdb/testsuite/gdb.base/macro-source-path.exp @@ -33,7 +33,7 @@ require {!is_remote host} # Set the current working directory to $out/cwd, so that we can test compiling # using relative paths. -set out_dir [standard_output_file ""] +set out_dir [build_standard_output_file ""] file mkdir $out_dir/cwd file mkdir $out_dir/other file copy -force $srcdir/$subdir/$srcfile $out_dir/cwd @@ -53,7 +53,8 @@ proc test { src name } { return } - clean_restart $binfile + clean_restart + gdb_load [host_file_normalize $binfile] if { ![runto_main] } { return diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp index 0b5f863..63f1356 100644 --- a/gdb/testsuite/gdb.base/macscp.exp +++ b/gdb/testsuite/gdb.base/macscp.exp @@ -29,7 +29,8 @@ if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \ return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Ask GDB to show the current definition of MACRO, and return a list diff --git a/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp b/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp index 80f2d01..91d0379 100644 --- a/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp +++ b/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp @@ -201,7 +201,8 @@ gdb_test "maint info blocks" [make_blocks_result normal_func \ inline_func_a inline_func_b] \ "maint info blocks using stored \$pc, inferior still running" -clean_restart $binfile +clean_restart +gdb_load $binfile # Use the recorded $pc value to check inline frames when the inferior # is not executing. diff --git a/gdb/testsuite/gdb.base/maint-test-remote-args.exp b/gdb/testsuite/gdb.base/maint-test-remote-args.exp new file mode 100644 index 0000000..6cd3006 --- /dev/null +++ b/gdb/testsuite/gdb.base/maint-test-remote-args.exp @@ -0,0 +1,40 @@ +# Copyright 2024-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 the 'maint test-remote-args' command. +# +# We do minimal testing in here. If you are thinking of adding a new +# test here then you are most likely adding the test in the wrong +# place. Remote argument testing is checked in the following test +# scripts: gdb.base/args.exp, gdb.base/inferior-args.exp, +# gdb.base/startup-with-shell.exp, and gdb.python/py-inferior.exp. +# The test gdb.gdb/unittest.exp also runs 'maint selftest +# remote-args', which are the remote argument self tests. +# +# If you have a new test for an argument that was being passed +# incorrectly, then add the test to one of those scripts. +# +# This file is ONLY for validating that the 'maint test-remote-args' +# command itself is working. + +gdb_start + +gdb_test "maint test-remote-args a b c" \ + [multi_line \ + "Input \\(a b c\\)" \ + " \\(a\\)" \ + " \\(b\\)" \ + " \\(c\\)" \ + "Output \\(a b c\\)"] diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index e006d55..3d49b36 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -52,6 +52,41 @@ if {[prepare_for_testing "failed to prepare" $testfile \ return -1 } +# Check "maint set per-command" warnings. We do this early so that +# the following tests don't need to expect them, as GDB only warns +# once. + +with_test_prefix "warnings" { + # Potential warning given by "maint set per-command time". + set maybe_per_command_warning \ + "(?:warning: per-thread run time information not available on this platform)?" + + # This one should not issue the "per-command time" warning. + with_test_prefix "per-command space" { + gdb_test_no_output "mt set per-command space on" + gdb_test_no_output "mt set per-command space off" + } + + # These might warn. "per-command on" enables all sub commands, so + # might trigger the "per-command time" warning. + foreach cmd {"per-command" "per-command time"} { + with_test_prefix $cmd { + # GDB only warns once, so restart between commands. + clean_restart + gdb_load $binfile + gdb_test "mt set $cmd on" "$maybe_per_command_warning" + gdb_test "mt set $cmd off" "command started" + gdb_test_no_output "mt set $cmd on" \ + "mt set $cmd on, again" + gdb_test "mt set $cmd off" "command started" \ + "mt set $cmd off, again" + } + } + + # We've already warned once above, so the following tests don't + # need to expect the warning. +} + set readnow_p [readnow] # The commands we test here produce many lines of output; disable "press @@ -205,8 +240,8 @@ set re \ "( Number of \"partial\" symbols read: $decimal" \ ")?( Number of psym tables \\(not yet expanded\\): $decimal" \ ")?( Total memory used for psymbol cache: $decimal" \ - ")?( Number of read CUs: $decimal" \ - " Number of unread CUs: $decimal" \ + ")?( Number of read units: $decimal" \ + " Number of unread units: $decimal" \ ")? Total memory used for objfile obstack: $decimal" \ " Total memory used for BFD obstack: $decimal" \ " Total memory used for string cache: $decimal" \ @@ -513,4 +548,9 @@ gdb_test_no_output "maint print symbols" gdb_test_no_output "maint print msymbols" gdb_test_no_output "maint print psymbols" +gdb_test "maint canonicalize int short" "canonical = short" +gdb_test "maint canonicalize fn<ty<int>>" \ + "canonical = fn<ty<int> >" +gdb_test "maint canonical unsigned int" "No change\\." + gdb_exit diff --git a/gdb/testsuite/gdb.base/many-headers.exp b/gdb/testsuite/gdb.base/many-headers.exp index f46b980..5e022da 100644 --- a/gdb/testsuite/gdb.base/many-headers.exp +++ b/gdb/testsuite/gdb.base/many-headers.exp @@ -33,6 +33,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug]} { # Generate core file. set corefile [core_find $binfile] if {$corefile == ""} { + untested "unable to create or find corefile" return 0 } diff --git a/gdb/testsuite/gdb.base/max-depth.exp.tcl b/gdb/testsuite/gdb.base/max-depth.exp.tcl index fcec47b..22bf180 100644 --- a/gdb/testsuite/gdb.base/max-depth.exp.tcl +++ b/gdb/testsuite/gdb.base/max-depth.exp.tcl @@ -30,12 +30,12 @@ proc compile_and_run_tests { lang } { lappend flags "additional_flags=-std=c++11" } - if { [prepare_for_testing "failed to prepare" "${binfile}" "${srcfile}" "${flags}"] } { + if { [prepare_for_testing "failed to prepare" $testfile $srcfile $flags] } { return 0 } # Advance to main. - if { ![runto_main] } then { + if { ![runto_main] } { return 0 } diff --git a/gdb/testsuite/gdb.base/memops-watchpoint.exp b/gdb/testsuite/gdb.base/memops-watchpoint.exp index eba54c1..1a8d6d9 100644 --- a/gdb/testsuite/gdb.base/memops-watchpoint.exp +++ b/gdb/testsuite/gdb.base/memops-watchpoint.exp @@ -44,118 +44,63 @@ gdb_test "watch -location c\[28\]" \ # This is to allow the tests to work if there's a properly named symbol for # the function, even if there's no libc debug info. -set saw_watch_trigger 0 -set saw_function 0 -set is_supported 1 -set message "continue until memset watchpoint hits" -set watch_trigger \ +# ARRAY_RE is the array whose modification is caught by the +# watchpoint. SOURCE_FUNCTION is the function that modifies the +# array, as written in the source of the test program. FUNCTION_RE +# matches the name of the symbol that actually implements +# SOURCE_FUNCTION (e.g., memcpy may be implemented with memmove, so we +# may want to expect both). OLD_VALUE_RE and NEW_VALUE_RE match the +# old/new values when the watchpoint triggers. + +proc continue_to_watchpoint {array_re source_function function_re + old_value_re new_value_re} { + set thread_prefix_re "(?:Thread $::decimal \[^\r\n\]*hit )?" + + set saw_watch_trigger 0 + set saw_function 0 + set is_supported 1 + set watch_trigger_re \ [multi_line \ "Continuing\\." \ "" \ - "(Hardware w|W)atchpoint ${decimal}: -location a\\\[28\\\]" \ + "${thread_prefix_re}(Hardware w|W)atchpoint ${::decimal}: -location ${array_re}\\\[28\\\]" \ "" \ - "Old value = 104 'h'" \ - "New value = 0 '\\\\000'"] -gdb_test_multiple "continue" $message { - -re $watch_trigger { - set saw_watch_trigger 1 - exp_continue - } - -re ".*memset.* \\(\\) at .*:$decimal\r\n" { - set saw_function 1 - exp_continue - } - -re ".*memset.* \\(\\) from .*libc\[^\r\n\]+\r\n" { - set saw_function 1 - exp_continue - } - -re "in \\?\\? \\(\\) from .*libc\[^\r\n\]+\r\n" { - set is_supported 0 - unsupported "symbol for memset not found" - exp_continue - } - -re "$gdb_prompt $" { - if { $is_supported } { - setup_kfail breakpoints/31665 arm*-*-linux* - gdb_assert { $saw_watch_trigger && $saw_function } $message + "Old value = ${old_value_re}" \ + "New value = ${new_value_re}"] + gdb_test_multiple "continue" \ + "continue until $source_function watchpoint hits" { + -re $watch_trigger_re { + set saw_watch_trigger 1 + exp_continue + } + -re "${function_re}.* \\(\\) at \[^\r\n\]+:${::decimal}(?=\r\n)" { + set saw_function 1 + exp_continue + } + -re "${function_re}.* \\(\\) from \[^\r\n\]+(?=\r\n)" { + set saw_function 1 + exp_continue + } + -re "in \\?\\? \\(\\) from \[^\r\n\]+(?=\r\n)" { + set is_supported 0 + unsupported "symbol for ${source_function} not found" + exp_continue + } + -re -wrap "" { + if { $is_supported } { + setup_kfail breakpoints/31665 arm*-*-linux* + gdb_assert { $saw_watch_trigger && $saw_function } \ + $gdb_test_name + } } } } +# Note: Some architectures use memmove for memset. +continue_to_watchpoint "a" "memset" "(memset|memmove)" "104 'h'" "0 '\\\\000'" + # Note: Some architectures use memmove for memcpy. -set saw_watch_trigger 0 -set saw_function 0 -set is_supported 1 -set message "continue until memcpy watchpoint hits" -set watch_trigger \ - [multi_line \ - "Continuing\\." \ - "" \ - "(Hardware w|W)atchpoint ${decimal}: -location b\\\[28\\\]" \ - "" \ - "Old value = 101 'e'" \ - "New value = 114 'r'"] -gdb_test_multiple "continue" $message { - -re $watch_trigger { - set saw_watch_trigger 1 - exp_continue - } - -re ".*(memcpy|memmove).* \\(\\) at .*:$decimal\r\n" { - set saw_function 1 - exp_continue - } - -re ".*(memcpy|memmove).* \\(\\) from .*libc\[^\r\n\]+\r\n" { - set saw_function 1 - exp_continue - } - -re "in \\?\\? \\(\\) from .*libc\[^\r\n\]+\r\n" { - set is_supported 0 - unsupported "symbol for memcpy not found" - exp_continue - } - -re "$gdb_prompt $" { - if { $is_supported } { - setup_kfail breakpoints/31665 arm*-*-linux* - gdb_assert { $saw_watch_trigger && $saw_function } $message - } - } -} +continue_to_watchpoint "b" "memcpy" "(memcpy|memmove)" "101 'e'" "114 'r'" # Note: Some architectures use memcpy for memmove. -set saw_watch_trigger 0 -set saw_function 0 -set is_supported 1 -set message "continue until memmove watchpoint hits" -set watch_trigger \ - [multi_line \ - "Continuing\\." \ - "" \ - "(Hardware w|W)atchpoint ${decimal}: -location c\\\[28\\\]" \ - "" \ - "Old value = 100 'd'" \ - "New value = 114 'r'"] -gdb_test_multiple "continue" $message { - -re $watch_trigger { - set saw_watch_trigger 1 - exp_continue - } - -re ".*(memcpy|memmove).* \\(\\) at .*:$decimal\r\n" { - set saw_function 1 - exp_continue - } - -re ".*(memcpy|memmove).* \\(\\) from .*libc\[^\r\n\]+\r\n" { - set saw_function 1 - exp_continue - } - -re "in \\?\\? \\(\\) from .*libc\[^\r\n\]+\r\n" { - set is_supported 0 - unsupported "symbol for memmove not found" - exp_continue - } - -re "$gdb_prompt $" { - if { $is_supported } { - setup_kfail breakpoints/31665 arm*-*-linux* - gdb_assert { $saw_watch_trigger && $saw_function } $message - } - } -} +continue_to_watchpoint "c" "memmove" "(memcpy|memmove)" "100 'd'" "114 'r'" diff --git a/gdb/testsuite/gdb.base/miscexprs.exp b/gdb/testsuite/gdb.base/miscexprs.exp index 86196fa..f723d75 100644 --- a/gdb/testsuite/gdb.base/miscexprs.exp +++ b/gdb/testsuite/gdb.base/miscexprs.exp @@ -44,7 +44,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [lis return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # diff --git a/gdb/testsuite/gdb.base/msym-bp-shl.exp b/gdb/testsuite/gdb.base/msym-bp-shl.exp index b154ce6..41dc818 100644 --- a/gdb/testsuite/gdb.base/msym-bp-shl.exp +++ b/gdb/testsuite/gdb.base/msym-bp-shl.exp @@ -55,7 +55,8 @@ proc test {debug} { return } - clean_restart $bin + clean_restart + gdb_load $bin gdb_load_shlib $lib # Should find two locations: the static foo in the diff --git a/gdb/testsuite/gdb.base/multi-forks.exp b/gdb/testsuite/gdb.base/multi-forks.exp index 61a240f..5d2d220 100644 --- a/gdb/testsuite/gdb.base/multi-forks.exp +++ b/gdb/testsuite/gdb.base/multi-forks.exp @@ -13,11 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# Until "set follow-fork-mode" and "catch fork" are implemented on -# other targets... -# -require {istarget "*-*-linux*"} - +require allow_fork_tests standard_testfile .c @@ -32,7 +28,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $fla # Start with a fresh gdb -clean_restart ${binfile} +clean_restart +gdb_load $binfile global gdb_prompt @@ -107,7 +104,8 @@ proc continue_to_exit_bp_loc {} { # parent's branch. foreach mode { "child" "parent" } { - clean_restart ${binfile} + clean_restart + gdb_load $binfile runto_main gdb_test_no_output "set follow-fork $mode" @@ -139,7 +137,8 @@ foreach mode { "child" "parent" } { # Start with a fresh gdb -clean_restart ${binfile} +clean_restart +gdb_load $binfile runto_main gdb_breakpoint $exit_bp_loc diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp index 2d0a5a9..b839317 100644 --- a/gdb/testsuite/gdb.base/nodebug.exp +++ b/gdb/testsuite/gdb.base/nodebug.exp @@ -33,7 +33,8 @@ if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != " # Start with a fresh gdb. -clean_restart $binfile +clean_restart +gdb_load $binfile # Run to FUNC and unload symbols from system shared libraries, to # avoid conflicts with the minsyms in the program. E.g., diff --git a/gdb/testsuite/gdb.base/nofield.exp b/gdb/testsuite/gdb.base/nofield.exp index 2e88725..31d0234 100644 --- a/gdb/testsuite/gdb.base/nofield.exp +++ b/gdb/testsuite/gdb.base/nofield.exp @@ -23,7 +23,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu set eol "\r\n" set sp "\[ \t\]*" -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test "ptype struct not_empty" \ "type = struct not_empty {$eol${sp}void \\*e;$eol${sp}void \\*u;$eol}" diff --git a/gdb/testsuite/gdb.base/nostdlib.exp b/gdb/testsuite/gdb.base/nostdlib.exp index ecf09a8..8dcefcf 100644 --- a/gdb/testsuite/gdb.base/nostdlib.exp +++ b/gdb/testsuite/gdb.base/nostdlib.exp @@ -49,7 +49,8 @@ foreach_with_prefix pie { "nopie" "pie" } { return -1 } - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_breakpoint "*marker" diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp index f32d258..8ac9f4e 100644 --- a/gdb/testsuite/gdb.base/options.exp +++ b/gdb/testsuite/gdb.base/options.exp @@ -62,8 +62,7 @@ proc check_completion_result {expected test} { # just checking whether GDB recognizes the option and auto-appends a # space. proc test_completer_recognizes {res input_line} { - set expected_re [string_to_regexp $input_line] - test_gdb_complete_unique $input_line $expected_re + test_gdb_complete_unique $input_line $input_line check_completion_result $res $input_line } @@ -206,7 +205,8 @@ proc_with_prefix test-print {{prefix ""}} { } global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return @@ -318,7 +318,8 @@ proc_with_prefix test-backtrace {} { "backtrace no-filters" global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return @@ -509,12 +510,26 @@ proc_with_prefix test-thread-apply {} { proc_with_prefix test-info-threads {} { test_gdb_complete_multiple "info threads " "" "" { "-gid" + "-running" + "-stopped" "ID" } + test_gdb_complete_multiple "info threads " "-" "" { + "-gid" + "-running" + "-stopped" + } + test_gdb_complete_unique \ - "info threads -" \ + "info threads -g" \ "info threads -gid" + test_gdb_complete_unique \ + "info threads -r" \ + "info threads -running" + test_gdb_complete_unique \ + "info threads -s" \ + "info threads -stopped" # "ID" isn't really something the user can type. test_gdb_complete_none "info threads I" diff --git a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp index a831050..d60a0ea 100644 --- a/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp +++ b/gdb/testsuite/gdb.base/paginate-after-ctrl-c-running.exp @@ -31,7 +31,8 @@ proc test_ctrlc_while_target_running_does_not_paginate {} { set testline [gdb_get_line_number "after sleep"] with_test_prefix "ctrlc target running" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/paginate-bg-execution.exp b/gdb/testsuite/gdb.base/paginate-bg-execution.exp index dfd7823..40f98fc 100644 --- a/gdb/testsuite/gdb.base/paginate-bg-execution.exp +++ b/gdb/testsuite/gdb.base/paginate-bg-execution.exp @@ -30,7 +30,8 @@ proc test_bg_execution_pagination_return {} { global decimal with_test_prefix "paginate" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/paginate-inferior-exit.exp b/gdb/testsuite/gdb.base/paginate-inferior-exit.exp index 76176e2..6cc992b 100644 --- a/gdb/testsuite/gdb.base/paginate-inferior-exit.exp +++ b/gdb/testsuite/gdb.base/paginate-inferior-exit.exp @@ -29,7 +29,8 @@ proc test_paginate_inferior_exited {} { global inferior_exited_re with_test_prefix "paginate" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/patch.exp b/gdb/testsuite/gdb.base/patch.exp index 69e5581..f6abc59 100644 --- a/gdb/testsuite/gdb.base/patch.exp +++ b/gdb/testsuite/gdb.base/patch.exp @@ -34,7 +34,8 @@ with_test_prefix "exec" { gdb_test "p extern_global = 2" " = 2" "modify value" gdb_test "p extern_global" " = 2" "value modified" - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "p extern_global" " = 2" "value modified persisted" } @@ -43,7 +44,8 @@ with_test_prefix "exec" { # Generate a core file. with_test_prefix "gcore" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/pc-not-saved.exp b/gdb/testsuite/gdb.base/pc-not-saved.exp index 16e11bc..e761e93 100644 --- a/gdb/testsuite/gdb.base/pc-not-saved.exp +++ b/gdb/testsuite/gdb.base/pc-not-saved.exp @@ -60,7 +60,8 @@ gdb_assert { ![string equal $pc unknown] } \ "check we read the frame's PC" # Restart and load the Python unwinder script. -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_test_no_output "source ${remote_python_file}" "load python file" # Tell the Python unwinder to use the frame-id we cached above. diff --git a/gdb/testsuite/gdb.base/pie-fork.exp b/gdb/testsuite/gdb.base/pie-fork.exp index 48c01d9..9d232c8 100644 --- a/gdb/testsuite/gdb.base/pie-fork.exp +++ b/gdb/testsuite/gdb.base/pie-fork.exp @@ -16,6 +16,8 @@ # Test that we can follow forks properly when the executable is # position-independent. +require allow_fork_tests + standard_testfile set opts [list debug pie] @@ -27,7 +29,8 @@ if [build_executable "failed to prepare" $testfile $srcfile $opts] { proc setup_test {detach_on_fork {follow_fork_mode "parent"}} { global binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile if ![runto_main] { return diff --git a/gdb/testsuite/gdb.base/pointers.exp b/gdb/testsuite/gdb.base/pointers.exp index ab02181..4d4d58e 100644 --- a/gdb/testsuite/gdb.base/pointers.exp +++ b/gdb/testsuite/gdb.base/pointers.exp @@ -32,7 +32,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # diff --git a/gdb/testsuite/gdb.base/pr11022.exp b/gdb/testsuite/gdb.base/pr11022.exp index e7bfba0..70a7d8b 100644 --- a/gdb/testsuite/gdb.base/pr11022.exp +++ b/gdb/testsuite/gdb.base/pr11022.exp @@ -24,7 +24,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/print-symbol-loading.exp b/gdb/testsuite/gdb.base/print-symbol-loading.exp index 15f2c19..91e818b 100644 --- a/gdb/testsuite/gdb.base/print-symbol-loading.exp +++ b/gdb/testsuite/gdb.base/print-symbol-loading.exp @@ -15,7 +15,7 @@ # Test the "print symbol-loading" option. -require allow_shlib_tests +require allow_shlib_tests gcore_cmd_available standard_testfile print-symbol-loading-main.c set libfile print-symbol-loading-lib @@ -35,7 +35,8 @@ if { [gdb_compile ${objfile} ${binfile} executable $opts] != "" } { return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib ${binfile_lib} if ![runto lib] { @@ -94,7 +95,8 @@ proc test_load_shlib { print_symbol_loading } { global binfile global gdb_prompt with_test_prefix "shlib ${print_symbol_loading}" { - clean_restart ${binfile} + clean_restart + gdb_load $binfile if ![runto_main] { return -1 } diff --git a/gdb/testsuite/gdb.base/prologue.exp b/gdb/testsuite/gdb.base/prologue.exp index 0d3902d..736e779 100644 --- a/gdb/testsuite/gdb.base/prologue.exp +++ b/gdb/testsuite/gdb.base/prologue.exp @@ -23,7 +23,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/ptr-typedef.exp b/gdb/testsuite/gdb.base/ptr-typedef.exp index 53d03cc..8bffb26 100644 --- a/gdb/testsuite/gdb.base/ptr-typedef.exp +++ b/gdb/testsuite/gdb.base/ptr-typedef.exp @@ -22,7 +22,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb # Get things started. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if ![runto marker1] { untested "couldn't run to marker1" diff --git a/gdb/testsuite/gdb.base/ptype.exp b/gdb/testsuite/gdb.base/ptype.exp index 788cdfc..04d2d2b 100644 --- a/gdb/testsuite/gdb.base/ptype.exp +++ b/gdb/testsuite/gdb.base/ptype.exp @@ -528,11 +528,10 @@ proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } # Turn the arguments, which are literal strings, into # regular expressions by quoting any special characters they contain. foreach var { prototyped plain overprototyped } { - eval "set val \$$var" - regsub -all "\[\]\[*()\]" $val "\\\\&" val + set val [string_to_regexp [set $var]] regsub -all "short int" $val "short( int)?" val regsub -all "long int" $val "long( int)?" val - eval "set $var \$val" + set $var $val } gdb_test_multiple "ptype $id" "ptype $id" { @@ -544,10 +543,10 @@ proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } fail "ptype $id (compiler doesn't emit prototyped types)" } -re "type = $overprototyped\[\r\n\]+$gdb_prompt $" { - if { [test_compiler_info "armcc-*"] } { - setup_xfail "*-*-*" - } - fail "ptype $id (compiler doesn't emit unprototyped types)" + # C23 no longer supports non-prototype function declaration, in which + # case the overprototyped regexp is the expected one. Simply pass + # in all cases. + pass "ptype $id (overprototyped)" } } } diff --git a/gdb/testsuite/gdb.base/quit-live.exp b/gdb/testsuite/gdb.base/quit-live.exp index a95c980..46579d4 100644 --- a/gdb/testsuite/gdb.base/quit-live.exp +++ b/gdb/testsuite/gdb.base/quit-live.exp @@ -95,7 +95,8 @@ proc quit_with_live_inferior {appear_how extra_inferior quit_how} { set test_spawn_id "" if {$appear_how != "attach-nofile"} { - clean_restart $binfile + clean_restart + gdb_load $binfile } else { clean_restart } diff --git a/gdb/testsuite/gdb.base/random-signal.exp b/gdb/testsuite/gdb.base/random-signal.exp index bb5b482..16f9467 100644 --- a/gdb/testsuite/gdb.base/random-signal.exp +++ b/gdb/testsuite/gdb.base/random-signal.exp @@ -49,7 +49,8 @@ proc do_test {} { # while gdb is processing the internal software watchtpoint # single-step. With remote debugging, the ctrl-c reaches GDB first. with_test_prefix "run" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return -1 @@ -62,7 +63,8 @@ with_test_prefix "run" { # reaches GDB first. Test that as well. with_test_prefix "attach" { if {[can_spawn_for_attach]} { - clean_restart $binfile + clean_restart + gdb_load $binfile set test_spawn_id [spawn_wait_for_attach $binfile] set testpid [spawn_id_get_pid $test_spawn_id] diff --git a/gdb/testsuite/gdb.base/readline-ask.exp b/gdb/testsuite/gdb.base/readline-ask.exp index 3f98e13..0fdfc76 100644 --- a/gdb/testsuite/gdb.base/readline-ask.exp +++ b/gdb/testsuite/gdb.base/readline-ask.exp @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +require {!is_remote host} + standard_testfile .c set inputrc ${srcdir}/${subdir}/${testfile}.inputrc @@ -25,7 +27,8 @@ setenv TERM dumb # INPUTRC gets reset for the next testfile. setenv INPUTRC $inputrc -clean_restart ${binfile} +clean_restart +gdb_load $binfile if { ![readline_is_used] } { unsupported "completion doesn't work when readline isn't used." diff --git a/gdb/testsuite/gdb.base/readline-commands-eof.exp b/gdb/testsuite/gdb.base/readline-commands-eof.exp index 021e40f..d55dd1d 100644 --- a/gdb/testsuite/gdb.base/readline-commands-eof.exp +++ b/gdb/testsuite/gdb.base/readline-commands-eof.exp @@ -43,7 +43,8 @@ if { ![readline_supports_eof_flag] } { # arrived. If it is then GDB will start displaying extra blank lines # after each line of input. proc run_test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_breakpoint main diff --git a/gdb/testsuite/gdb.base/readline.exp b/gdb/testsuite/gdb.base/readline.exp index 198d686..9b87790 100644 --- a/gdb/testsuite/gdb.base/readline.exp +++ b/gdb/testsuite/gdb.base/readline.exp @@ -21,6 +21,8 @@ # Tests for readline operations. # +require {!is_remote host} + # This function is used to test operate-and-get-next. # NAME is the name of the test. # ARGS is a list of alternating commands and expected results. diff --git a/gdb/testsuite/gdb.base/readnever.exp b/gdb/testsuite/gdb.base/readnever.exp index 6dfd576..891adf5 100644 --- a/gdb/testsuite/gdb.base/readnever.exp +++ b/gdb/testsuite/gdb.base/readnever.exp @@ -26,7 +26,7 @@ if { [build_executable "failed to build" $testfile $srcfile { debug }] == -1 } { save_vars { GDBFLAGS } { append GDBFLAGS " --readnever" - if { [clean_restart ${binfile}] == -1 } { + if { [clean_restart $testfile] == -1 } { return -1 } } diff --git a/gdb/testsuite/gdb.base/relativedebug.exp b/gdb/testsuite/gdb.base/relativedebug.exp index d713771..2465ffd 100644 --- a/gdb/testsuite/gdb.base/relativedebug.exp +++ b/gdb/testsuite/gdb.base/relativedebug.exp @@ -24,7 +24,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb # Get things started. -clean_restart ${binfile} +clean_restart +gdb_load $binfile runto_main diff --git a/gdb/testsuite/gdb.base/remote-exec-file.exp b/gdb/testsuite/gdb.base/remote-exec-file.exp index b735281..baaf039 100644 --- a/gdb/testsuite/gdb.base/remote-exec-file.exp +++ b/gdb/testsuite/gdb.base/remote-exec-file.exp @@ -37,10 +37,13 @@ with_test_prefix "set inf 2" { with_test_prefix "show inf 1" { gdb_test "inferior 1" "Switching to inferior 1.*" - gdb_test "show remote exec-file" "prog1" + gdb_test "show remote exec-file" \ + "The remote exec-file is \"prog1\"\\." + } with_test_prefix "show inf 2" { gdb_test "inferior 2" "Switching to inferior 2.*" - gdb_test "show remote exec-file" "prog2" + gdb_test "show remote exec-file" \ + "The remote exec-file is \"prog2\"\\." } diff --git a/gdb/testsuite/gdb.base/remote.exp b/gdb/testsuite/gdb.base/remote.exp index 9917faf..c1d6a99 100644 --- a/gdb/testsuite/gdb.base/remote.exp +++ b/gdb/testsuite/gdb.base/remote.exp @@ -164,7 +164,8 @@ gdb_load_timed $binfile "limit" 0 # Get the size of random_data table (defaults to 48K). set sizeof_random_data [get_sizeof "random_data" 48*1024] -clean_restart $binfile +clean_restart +gdb_load $binfile # # Part THREE: Check the upload behavior. diff --git a/gdb/testsuite/gdb.base/reread.exp b/gdb/testsuite/gdb.base/reread.exp index 7e7d2c8..6c71f40 100644 --- a/gdb/testsuite/gdb.base/reread.exp +++ b/gdb/testsuite/gdb.base/reread.exp @@ -106,7 +106,8 @@ foreach_with_prefix opts { "" "pie" } { gdb_rename_execfile ${binfile1} ${binfile} # Restart GDB entirely. - clean_restart ${binfile} + clean_restart + gdb_load $binfile # Set a breakpoint on foo and run to it. gdb_test "break foo" \ diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp index 062dc63..852576a 100644 --- a/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp +++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp @@ -75,7 +75,8 @@ proc run_test { mode } { return } - clean_restart $exec_name + clean_restart + gdb_load $exec_name gdb_load_shlib $::libfile if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/restore.exp b/gdb/testsuite/gdb.base/restore.exp index 9724032..5448fb4 100644 --- a/gdb/testsuite/gdb.base/restore.exp +++ b/gdb/testsuite/gdb.base/restore.exp @@ -96,7 +96,8 @@ restore_tests set timeout $prev_timeout # Test PR cli/23785 -clean_restart $binfile +clean_restart +gdb_load $binfile if { ![runto_main] } { return -1 } diff --git a/gdb/testsuite/gdb.base/return2.exp b/gdb/testsuite/gdb.base/return2.exp index b657c11..e90a60b 100644 --- a/gdb/testsuite/gdb.base/return2.exp +++ b/gdb/testsuite/gdb.base/return2.exp @@ -103,7 +103,8 @@ proc return2_tests { } { # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile set timeout 30 return2_tests diff --git a/gdb/testsuite/gdb.base/rtld-step.exp b/gdb/testsuite/gdb.base/rtld-step.exp index 242cd47..d1e240b 100644 --- a/gdb/testsuite/gdb.base/rtld-step.exp +++ b/gdb/testsuite/gdb.base/rtld-step.exp @@ -114,7 +114,8 @@ if { [gdb_compile ${srcfile_main} ${binfile_main} executable $main_flags] != "" return -1 } -clean_restart ${binfile_main} +clean_restart +gdb_load $binfile_main if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/run-attach-while-running.exp b/gdb/testsuite/gdb.base/run-attach-while-running.exp index ae1388d..7b40a5f 100644 --- a/gdb/testsuite/gdb.base/run-attach-while-running.exp +++ b/gdb/testsuite/gdb.base/run-attach-while-running.exp @@ -60,7 +60,8 @@ proc_with_prefix test { non-stop threaded run-or-attach } { set ::GDBFLAGS "$::GDBFLAGS -ex \"maint set target-non-stop on\"" } - clean_restart $::binfile + clean_restart + gdb_load $::binfile } if { ![runto_main] } { diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp index 22913ca..2c75d06 100644 --- a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp +++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp @@ -49,9 +49,15 @@ if {[build_executable "failed to prepare" $testfile $srcfile]} { # - run: use the run command # - attach: start a process outside of GDB and attach it proc do_test { action1 action2 } { + + if {$action1 == "add" && ![allow_multi_inferior_tests]} { + return + } + save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop on\"" - clean_restart $::binfile + clean_restart + gdb_load $::binfile } # Ensure we are at least after the getpid call, should we need it. diff --git a/gdb/testsuite/gdb.base/run-fail-twice.exp b/gdb/testsuite/gdb.base/run-fail-twice.exp index af8c61b..07cbdda 100644 --- a/gdb/testsuite/gdb.base/run-fail-twice.exp +++ b/gdb/testsuite/gdb.base/run-fail-twice.exp @@ -43,7 +43,8 @@ proc test_run {testname} { proc_with_prefix test {} { global gdb_prompt binfile - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test_no_output "set confirm off" diff --git a/gdb/testsuite/gdb.base/savedregs.exp b/gdb/testsuite/gdb.base/savedregs.exp index 2c44566..d71d872 100644 --- a/gdb/testsuite/gdb.base/savedregs.exp +++ b/gdb/testsuite/gdb.base/savedregs.exp @@ -35,7 +35,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } # get things started -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Advance to main if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/sep.exp b/gdb/testsuite/gdb.base/sep.exp index 5a1e077..6abf356 100644 --- a/gdb/testsuite/gdb.base/sep.exp +++ b/gdb/testsuite/gdb.base/sep.exp @@ -26,7 +26,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb set location [gdb_get_line_number "say_hello" "sep-proc.c"] -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Try to display the source code inside a file which is included by # another source file. The purpose of this test is to verify that @@ -45,7 +46,8 @@ gdb_test "list sep-proc.c:$location" \ # Try the same, but this time with a breakpoint. We need to exit # GDB to make sure that we havn't loaded the full symbols yet when # we test the breakpoint insertion. -clean_restart $binfile +clean_restart +gdb_load $binfile set test "breakpoint inside included file" gdb_test_multiple "break sep-proc.c:$location" "$test" { diff --git a/gdb/testsuite/gdb.base/sepsymtab.exp b/gdb/testsuite/gdb.base/sepsymtab.exp index f5e8705..ed7a7a2 100644 --- a/gdb/testsuite/gdb.base/sepsymtab.exp +++ b/gdb/testsuite/gdb.base/sepsymtab.exp @@ -31,7 +31,8 @@ if [gdb_gnu_strip_debug $binfile no-main] { return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile set command "info sym main" set command_regex [string_to_regexp $command] diff --git a/gdb/testsuite/gdb.base/set-cwd.exp b/gdb/testsuite/gdb.base/set-cwd.exp index 72a2632..73a200f 100644 --- a/gdb/testsuite/gdb.base/set-cwd.exp +++ b/gdb/testsuite/gdb.base/set-cwd.exp @@ -184,7 +184,9 @@ proc_with_prefix test_cwd_reset { } { } test_cd_into_dir -clean_restart $binfile +clean_restart +gdb_load $binfile test_tilde_expansion -clean_restart $binfile +clean_restart +gdb_load $binfile test_cwd_reset diff --git a/gdb/testsuite/gdb.base/set-inferior-tty.exp b/gdb/testsuite/gdb.base/set-inferior-tty.exp index 64ec57b..c9b0a96 100644 --- a/gdb/testsuite/gdb.base/set-inferior-tty.exp +++ b/gdb/testsuite/gdb.base/set-inferior-tty.exp @@ -24,7 +24,8 @@ if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == proc test_set_inferior_tty { command } { global binfile - clean_restart ${binfile} + clean_restart + gdb_load $binfile gdb_test_no_output "$command hello" "set inferior-tty to hello" gdb_test "show inferior-tty" \ diff --git a/gdb/testsuite/gdb.base/setshow.exp b/gdb/testsuite/gdb.base/setshow.exp index 79ff913..0e38a9d 100644 --- a/gdb/testsuite/gdb.base/setshow.exp +++ b/gdb/testsuite/gdb.base/setshow.exp @@ -29,7 +29,8 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable {debug}] proc_with_prefix test_setshow_annotate {} { # Start with a fresh gdb - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return @@ -78,7 +79,8 @@ proc_with_prefix test_setshow_annotate {} { } proc_with_prefix test_setshow_args {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/settings.exp b/gdb/testsuite/gdb.base/settings.exp index 5e7cc24..d83023b 100644 --- a/gdb/testsuite/gdb.base/settings.exp +++ b/gdb/testsuite/gdb.base/settings.exp @@ -531,7 +531,8 @@ proc test-string {variant} { global srcfile binfile # Load symbols for the completion test below. - clean_restart $binfile + clean_restart + gdb_load $binfile # Use these variables to make sure we don't call the wrong command # by mistake. diff --git a/gdb/testsuite/gdb.base/share-env-with-gdbserver.exp b/gdb/testsuite/gdb.base/share-env-with-gdbserver.exp index 920f435..aa4b300 100644 --- a/gdb/testsuite/gdb.base/share-env-with-gdbserver.exp +++ b/gdb/testsuite/gdb.base/share-env-with-gdbserver.exp @@ -91,7 +91,8 @@ proc do_prepare_inferior { } { proc do_test { var_value { var_name "" } { var_name_match "" } { var_value_match "" } } { global binfile test_var_name - clean_restart $binfile + clean_restart + gdb_load $binfile if { $var_name == "" } { set var_name $test_var_name @@ -146,7 +147,8 @@ with_test_prefix "strange named var" { proc test_set_unset_vars { } { global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile with_test_prefix "set 3 environment variables" { # Set some environment variables @@ -205,7 +207,8 @@ with_test_prefix "test set/unset of vars" { proc test_unset { } { global hex decimal binfile gdb_prompt - clean_restart $binfile + clean_restart + gdb_load $binfile do_prepare_inferior @@ -234,7 +237,8 @@ proc test_unset { } { } with_test_prefix "set-then-unset" { - clean_restart $binfile + clean_restart + gdb_load $binfile # Test if setting and then unsetting $HOME works. gdb_test_no_output "set environment HOME = test" "set HOME as test" diff --git a/gdb/testsuite/gdb.base/shlib-call.exp b/gdb/testsuite/gdb.base/shlib-call.exp index 6a5f6d8..d3ff1c3 100644 --- a/gdb/testsuite/gdb.base/shlib-call.exp +++ b/gdb/testsuite/gdb.base/shlib-call.exp @@ -59,7 +59,8 @@ if { [gdb_compile_shlib ${lib1src} ${lib1} $lib_opts] != "" # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib $lib1 gdb_load_shlib $lib2 @@ -161,7 +162,8 @@ gdb_test "step" "mainshr1 \\(g=4\\) at.*return 2.g;" \ # Start with a fresh gdb. -clean_restart $binfile +clean_restart +gdb_load $binfile # PR's 16495, 18213 # test that we can re-set breakpoints in shared libraries diff --git a/gdb/testsuite/gdb.base/shlib-unload.exp b/gdb/testsuite/gdb.base/shlib-unload.exp index 9d47416..0e1369e 100644 --- a/gdb/testsuite/gdb.base/shlib-unload.exp +++ b/gdb/testsuite/gdb.base/shlib-unload.exp @@ -69,7 +69,8 @@ proc_with_prefix test_bp_modified_events {} { return } - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return @@ -114,7 +115,8 @@ proc_with_prefix test_bp_modified_events {} { # Check that GDB disables dprintf breakpoints within a shared library # when the shared library is unloaded. proc_with_prefix test_dprintf_after_unload {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return @@ -143,7 +145,8 @@ proc_with_prefix test_dprintf_after_unload {} { # inferior. We should not get an error about re-setting the dprintf # breakpoint. proc_with_prefix test_dprintf_with_rerun {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return @@ -238,7 +241,8 @@ proc_with_prefix test_silent_nosharedlib {} { } foreach_with_prefix type { breakpoint dprintf } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/shreloc.exp b/gdb/testsuite/gdb.base/shreloc.exp index 8ab64a8..2bd79af 100644 --- a/gdb/testsuite/gdb.base/shreloc.exp +++ b/gdb/testsuite/gdb.base/shreloc.exp @@ -65,7 +65,8 @@ if { [gdb_compile_shlib $lib1src $lib1_sl $lib_opts] != ""} { # Start with a fresh gdb. -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $lib1_sl gdb_load_shlib $lib2_sl diff --git a/gdb/testsuite/gdb.base/sigall.exp b/gdb/testsuite/gdb.base/sigall.exp index b23e3c5..461a92b 100644 --- a/gdb/testsuite/gdb.base/sigall.exp +++ b/gdb/testsuite/gdb.base/sigall.exp @@ -41,13 +41,14 @@ proc test_one_sig {nextsig} { setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu" } # On Linux SPARC64 systems SIGLOST==SIGPWR and gdb identifies - # the raised signal as PWR. - if {$thissig == "LOST" && [istarget "sparc64-*-linux*"]} { + # the raised signal as PWR. Same for Cygwin. + if {$thissig == "LOST" + && ([istarget "sparc64-*-linux*"] || [istarget "*-*-cygwin*"])} { set esig "PWR" } gdb_test "continue" \ - "Continuing.*Program received signal SIG$esig.*" \ + "Continuing.* received signal SIG$esig.*" \ "get signal $esig" } @@ -177,7 +178,7 @@ gdb_test "handle SIGTERM stop print" \ "SIGTERM\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*" gdb_test "b handle_TERM" "Breakpoint \[0-9\]+ .*" gdb_test "continue" \ - "Continuing.*Program received signal SIGTERM.*" \ + "Continuing.* received signal SIGTERM.*" \ "get signal TERM" gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM" gdb_continue_to_end "continue to sigall exit" diff --git a/gdb/testsuite/gdb.base/sigaltstack.exp b/gdb/testsuite/gdb.base/sigaltstack.exp index 978ddeb..47013a0 100644 --- a/gdb/testsuite/gdb.base/sigaltstack.exp +++ b/gdb/testsuite/gdb.base/sigaltstack.exp @@ -33,7 +33,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } # get things started -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Pass all the alarms straight through (but verbosely) gdb_test "handle SIGALRM print pass nostop" diff --git a/gdb/testsuite/gdb.base/sigchld.exp b/gdb/testsuite/gdb.base/sigchld.exp index 51d41c3..4011241 100644 --- a/gdb/testsuite/gdb.base/sigchld.exp +++ b/gdb/testsuite/gdb.base/sigchld.exp @@ -24,7 +24,8 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile runto_main diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp index d63febb..52f7140 100644 --- a/gdb/testsuite/gdb.base/siginfo-obj.exp +++ b/gdb/testsuite/gdb.base/siginfo-obj.exp @@ -118,7 +118,8 @@ with_test_prefix "validate modified siginfo fields" { # Test siginfo preservation in core files. if {$gcore_created} { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "core $gcorefile" "Core was generated by.*" \ "core [file tail $gcorefile]" diff --git a/gdb/testsuite/gdb.base/siginfo-thread.exp b/gdb/testsuite/gdb.base/siginfo-thread.exp index bf0d58c..270b4e1 100644 --- a/gdb/testsuite/gdb.base/siginfo-thread.exp +++ b/gdb/testsuite/gdb.base/siginfo-thread.exp @@ -27,7 +27,8 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \ return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # Advance to main if {![runto_main]} { @@ -92,7 +93,8 @@ gdb_test "p \$_siginfo.si_signo == $ssi_signo" " = 0" \ # Test siginfo preservation in core files. if {$gcore_created} { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "core $gcorefile" "Core was generated by.*" \ "core [file tail $gcorefile]" diff --git a/gdb/testsuite/gdb.base/signals-state-child.exp b/gdb/testsuite/gdb.base/signals-state-child.exp index 608951f..00ad7f5 100644 --- a/gdb/testsuite/gdb.base/signals-state-child.exp +++ b/gdb/testsuite/gdb.base/signals-state-child.exp @@ -97,7 +97,8 @@ remote_close target # Now run the program through gdb, and dump its initial signal actions # and mask in "gdb.txt". -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.base/signals.exp b/gdb/testsuite/gdb.base/signals.exp index d311361..5ff1e38 100644 --- a/gdb/testsuite/gdb.base/signals.exp +++ b/gdb/testsuite/gdb.base/signals.exp @@ -58,7 +58,8 @@ proc test_handle_all_print {} { } test_handle_all_print -clean_restart $binfile +clean_restart +gdb_load $binfile if {[runto_main]} { diff --git a/gdb/testsuite/gdb.base/signull.exp b/gdb/testsuite/gdb.base/signull.exp index 478e471..9ad772f 100644 --- a/gdb/testsuite/gdb.base/signull.exp +++ b/gdb/testsuite/gdb.base/signull.exp @@ -37,7 +37,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile # # Run to `main' where we begin our tests. diff --git a/gdb/testsuite/gdb.base/sigrepeat.exp b/gdb/testsuite/gdb.base/sigrepeat.exp index 9afa346..8fa92af 100644 --- a/gdb/testsuite/gdb.base/sigrepeat.exp +++ b/gdb/testsuite/gdb.base/sigrepeat.exp @@ -30,7 +30,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb } # get things started -clean_restart ${binfile} +clean_restart +gdb_load $binfile # Advance to main if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/sigstep.exp b/gdb/testsuite/gdb.base/sigstep.exp index b49105c..2df5dd0 100644 --- a/gdb/testsuite/gdb.base/sigstep.exp +++ b/gdb/testsuite/gdb.base/sigstep.exp @@ -40,7 +40,8 @@ set other_handler_location [gdb_get_line_number "other handler location"] proc restart {} { global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test "display/i \$pc" diff --git a/gdb/testsuite/gdb.base/skip.exp b/gdb/testsuite/gdb.base/skip.exp index 016e5eb..0c84cf9 100644 --- a/gdb/testsuite/gdb.base/skip.exp +++ b/gdb/testsuite/gdb.base/skip.exp @@ -309,7 +309,8 @@ with_test_prefix "step using -fi + -fu" { with_test_prefix "skip delete completion" { global binfile - clean_restart "${binfile}" + clean_restart + gdb_load $binfile if ![runto_main] { return } diff --git a/gdb/testsuite/gdb.base/so-impl-ld.exp b/gdb/testsuite/gdb.base/so-impl-ld.exp index d5c4143..1e309e5 100644 --- a/gdb/testsuite/gdb.base/so-impl-ld.exp +++ b/gdb/testsuite/gdb.base/so-impl-ld.exp @@ -33,7 +33,8 @@ if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != "" # Start with a fresh gdb -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib $lib_sl # This program implicitly loads SOM shared libraries. diff --git a/gdb/testsuite/gdb.base/solib-abort.exp b/gdb/testsuite/gdb.base/solib-abort.exp index 2f6d636..ab162a9 100644 --- a/gdb/testsuite/gdb.base/solib-abort.exp +++ b/gdb/testsuite/gdb.base/solib-abort.exp @@ -38,7 +38,8 @@ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/solib-disc.exp b/gdb/testsuite/gdb.base/solib-disc.exp index ba7dcce..880f632 100644 --- a/gdb/testsuite/gdb.base/solib-disc.exp +++ b/gdb/testsuite/gdb.base/solib-disc.exp @@ -44,7 +44,8 @@ if { [gdb_compile_shlib $libsrc $libobj {debug}] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $libobj if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/solib-search.exp b/gdb/testsuite/gdb.base/solib-search.exp index 2efad18..35b0314 100644 --- a/gdb/testsuite/gdb.base/solib-search.exp +++ b/gdb/testsuite/gdb.base/solib-search.exp @@ -16,7 +16,7 @@ # Test solib-search-path, and in the case of solib-svr4.c whether l_addr_p # is properly reset when the path is changed. -require allow_shlib_tests +require allow_shlib_tests gcore_cmd_available require {!is_remote target} # Build "wrong" and "right" versions of the libraries in separate directories. diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp index f3ca612..4d3494c 100644 --- a/gdb/testsuite/gdb.base/solib-symbol.exp +++ b/gdb/testsuite/gdb.base/solib-symbol.exp @@ -34,7 +34,8 @@ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $binfile_lib # Set a breakpoint in the binary. diff --git a/gdb/testsuite/gdb.base/solib-weak.exp b/gdb/testsuite/gdb.base/solib-weak.exp index 2d75a91..511ef37 100644 --- a/gdb/testsuite/gdb.base/solib-weak.exp +++ b/gdb/testsuite/gdb.base/solib-weak.exp @@ -84,7 +84,8 @@ proc do_test { lib1opts lib2opts lib1first } { } with_test_prefix $testopts { - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_load_shlib $lib1 gdb_load_shlib $lib2 diff --git a/gdb/testsuite/gdb.base/source-dir.exp b/gdb/testsuite/gdb.base/source-dir.exp index b2bf78c..e07a117 100644 --- a/gdb/testsuite/gdb.base/source-dir.exp +++ b/gdb/testsuite/gdb.base/source-dir.exp @@ -62,7 +62,7 @@ proc test_truncated_comp_dir {} { # /some/path/to/gdb/build/testsuite/ # We are going to copy the source file out of the source tree into # a location like this: - # /some/path/to/gdb/build/testsuite/output/gdb.base/soure-dir/ + # /some/path/to/gdb/build/testsuite/output/gdb.base/source-dir/ # # We will then switch to this directory and compile the source # file, however, we will ask GCC to remove this prefix from the @@ -87,11 +87,12 @@ proc test_truncated_comp_dir {} { return } - set working_dir [standard_output_file ""] + set working_dir [build_standard_output_file ""] with_cwd $working_dir { - set strip_dir [file normalize "${working_dir}/../.."] + set strip_dir [build_file_normalize "${working_dir}/../.."] + set h_strip_dir [host_file_normalize $strip_dir] - set new_srcfile [standard_output_file ${srcfile}] + set new_srcfile [build_standard_output_file ${srcfile}] set fd [open "$new_srcfile" w] puts $fd "int main () @@ -100,8 +101,17 @@ proc test_truncated_comp_dir {} { }" close $fd + # We ask GCC to remove both the build and host views of the + # path, because we don't know which one GCC uses. E.g., we're + # testing on MSYS2 with an MSYS2 cross-compiler that targets + # MinGW, then the path GCC uses is a Unix path. If OTOH we're + # testing on MSYS2 with a native Windows compiler, then the + # path GCC uses is a Windows path. set options \ - "debug additional_flags=-fdebug-prefix-map=${strip_dir}=" + [list \ + "debug" \ + "additional_flags=-fdebug-prefix-map=${strip_dir}=" \ + "additional_flags=-fdebug-prefix-map=${h_strip_dir}="] if { [gdb_compile "${srcfile}" "${binfile}" \ executable ${options}] != "" } { untested "failed to compile" @@ -109,7 +119,8 @@ proc test_truncated_comp_dir {} { } } - clean_restart ${binfile} + clean_restart + gdb_load $binfile if { [ishost *-*-mingw*] } { gdb_test_no_output "set directories \$cdir;\$cwd" @@ -133,9 +144,9 @@ proc test_truncated_comp_dir {} { "Does not include preprocessor macro info." ] \ "info source before setting directory search list" - gdb_test "dir $strip_dir" \ + gdb_test "dir $h_strip_dir" \ [search_dir_list [list \ - "$strip_dir" \ + "$h_strip_dir" \ "\\\$cdir" \ "\\\$cwd"]] \ "setup source path search directory" @@ -146,17 +157,23 @@ proc test_truncated_comp_dir {} { "4\[ \t\]+return 0;" \ "5\[ \t\]+\\}" ] - gdb_test "info source" \ - [multi_line \ - "Current source file is ${srcfile}" \ - "Compilation directory is \[^\n\r\]+" \ - "Located in ${new_srcfile}" \ - "Contains 5 lines." \ - "Source language is c." \ - "Producer is \[^\n\r\]+" \ - "\[^\n\r\]+" \ - "\[^\n\r\]+" ] \ - "info source after setting directory search list" + set re [multi_line \ + "Current source file is ${srcfile}" \ + "Compilation directory is \[^\n\r\]+" \ + "Located in (\[^\n\r\]+)" \ + "Contains 5 lines." \ + "Source language is c." \ + "Producer is \[^\n\r\]+" \ + "\[^\n\r\]+" \ + "\[^\n\r\]+"] + set test "info source after setting directory search list" + gdb_test_multiple "info source" $test { + -re -wrap "$re" { + set host_new_srcfile [host_file_normalize $new_srcfile] + set host_location [host_file_sanitize $expect_out(1,string)] + gdb_assert {$host_new_srcfile eq $host_location} $gdb_test_name + } + } } proc test_change_search_directory_with_empty_dirname {} { diff --git a/gdb/testsuite/gdb.base/source-search.c b/gdb/testsuite/gdb.base/source-search.c new file mode 100644 index 0000000..2320c5c --- /dev/null +++ b/gdb/testsuite/gdb.base/source-search.c @@ -0,0 +1,127 @@ +/* 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/>. */ + +int +main (void) +{ + /* Line 21 */ + /* Line 22 */ + /* Line 23 */ + /* Line 24 */ + /* Line 25 */ + /* Line 26 */ + /* Line 27 */ + /* Line 28 */ + /* Line 29 */ + /* Line 30 */ + /* Line 31 */ + /* Line 32 */ + /* Line 33 */ + /* Line 34 */ + /* Line 35 */ + /* Line 36 */ + /* Line 37 */ + /* Line 38 */ + /* Line 39 */ + /* Line 40 */ + /* Line 41 */ + /* Line 42 */ + /* Line 43 */ + /* Line 44 */ + /* Line 45 */ + /* Line 46 */ + /* Line 47 */ + /* Line 48 */ + /* Line 49 */ + /* Line 50 */ + /* Line 51 */ + /* Line 52 */ + /* Line 53 */ + /* Line 54 */ + /* Line 55 */ + /* Line 56 */ + /* Line 57 */ + /* Line 58 */ + /* Line 59 */ + /* Line 60 */ + /* Line 61 */ + /* Line 62 */ + /* Line 63 */ + /* Line 64 */ + /* Line 65 */ + /* Line 66 */ + /* Line 67 */ + /* Line 68 */ + /* Line 69 */ + /* Line 70 */ + /* Line 71 */ + /* Line 72 */ + /* Line 73 */ + /* Line 74 */ + /* Line 75 */ + /* Line 76 */ + /* Line 77 */ + /* Line 78 */ + /* Line 79 */ + /* Line 80 */ + /* Line 81 */ + /* Line 82 */ + /* Line 83 */ + /* Line 84 */ + /* Line 85 */ + /* Line 86 */ + /* Line 87 */ + /* Line 88 */ + /* Line 89 */ + /* Line 90 */ + /* Line 91 */ + /* Line 92 */ + /* Line 93 */ + /* Line 94 */ + /* Line 95 */ + /* Line 96 */ + /* Line 97 */ + /* Line 98 */ + /* Line 99 */ + /* Line 100 */ + /* Line 101 */ + /* Line 102 */ + /* Line 103 */ + /* Line 104 */ + /* Line 105 */ + /* Line 106 */ + /* Line 107 */ + /* Line 108 */ + /* Line 109 */ + /* Line 110 */ + /* Line 111 */ + /* Line 112 */ + /* Line 113 */ + /* Line 114 */ + /* Line 115 */ + /* Line 116 */ + /* Line 117 */ + /* Line 118 */ + /* Line 119 */ + /* Line 120 */ + /* Line 121 */ + /* Line 122 */ + /* Line 123 */ + /* Line 124 */ + /* Line 125 */ + return 0; +} /* Last line. */ diff --git a/gdb/testsuite/gdb.base/source-search.exp b/gdb/testsuite/gdb.base/source-search.exp new file mode 100644 index 0000000..559c500 --- /dev/null +++ b/gdb/testsuite/gdb.base/source-search.exp @@ -0,0 +1,106 @@ +# 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 'forward-search' and 'reverse-search' commands. This test +# relies on some hard-coded line numbers relating to the source file. +# We could switch to using gdb_get_line_number, but it doesn't feel +# like that would add much value; just don't change the source file. + +standard_testfile + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return +} + +gdb_test "forward-search This testcase is part" \ + "1\\s+/\\* This testcase is part of GDB, the GNU debugger\\." \ + "search for first line of the file" + +gdb_test "forward-search This testcase is part" \ + "Expression not found" \ + "repeated search doesn't find the same first line" + +# The 'reverse-search' command starts searching from the line before +# the last line displayed. So in this case, the reverse search starts +# from line 0, i.e. nothing is searched. +gdb_test "reverse-search This testcase is part" \ + "Expression not found" \ + "reverse search doesn't find the first line either" + +# List some source lines, and then perform some forward-searches. The +# searches start from the first line after the last line displayed. +gdb_test "list 20" ".*" \ + "list source code ahead of a forward-search" +gdb_test "forward-search Line 2" \ + "25\\s+/\\* Line 25 \\*/" \ + "first forward-search after a list" +gdb_test "forward-search Line 2" \ + "26\\s+/\\* Line 26 \\*/" \ + "second forward-search after a list" +gdb_test "forward-search Line 2" \ + "27\\s+/\\* Line 27 \\*/" \ + "third forward-search after a list" + +# Now reverse-search from where we got too. +gdb_test "reverse-search Line 2" \ + "26\\s+/\\* Line 26 \\*/" \ + "first reverse-search for 'Line 2'" +gdb_test "reverse-search Line 2" \ + "25\\s+/\\* Line 25 \\*/" \ + "second reverse-search for 'Line 2'" +gdb_test "reverse-search Line 2" \ + "24\\s+/\\* Line 24 \\*/" \ + "third reverse-search for 'Line 2'" + +# List some source lines, and then perform a reverse-search. The +# search starts frm the first line before the last line displayed. +gdb_test "list 20" ".*" \ + "list source code ahead of a reverse-search" +gdb_test "reverse-search Line 2" \ + "23\\s+/\\* Line 23 \\*/" \ + "reverse-search after a list" + +# List the last lines of the file, then reverse search for the last +# line. As reverse-search starts on the line before the last line +# displayed, this will fail to find the last line. +gdb_test "list 127" +gdb_test "reverse-search Last line" \ + "Expression not found" \ + "reverse search for the last line fails" + +# List some lines from the middle of the file. Then try an invalid +# 'list' command. Finally, check searches pick up from the middle of +# the file where the first 'list' successfully completed. +foreach_with_prefix search_direction { forward reverse } { + foreach_with_prefix bad_list { out-of-range backwards } { + gdb_test "list 50" + + if { $bad_list eq "out-of-range" } { + gdb_test "list 1000" \ + "Line number 995 out of range; \[^\r\n\]+ has 127 lines\\." + } else { + gdb_test_no_output "list 60,50" + } + + if { $search_direction eq "forward" } { + set line 55 + } else { + set line 53 + } + + gdb_test "${search_direction}-search Line" \ + "$line\\s+/\\* Line $line \\*/" + } +} diff --git a/gdb/testsuite/gdb.base/stack-checking.exp b/gdb/testsuite/gdb.base/stack-checking.exp index 5e55b43..15fc677 100644 --- a/gdb/testsuite/gdb.base/stack-checking.exp +++ b/gdb/testsuite/gdb.base/stack-checking.exp @@ -21,7 +21,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [con return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/startup-with-shell.exp b/gdb/testsuite/gdb.base/startup-with-shell.exp index 80dfdf3..a6ebb57 100644 --- a/gdb/testsuite/gdb.base/startup-with-shell.exp +++ b/gdb/testsuite/gdb.base/startup-with-shell.exp @@ -22,6 +22,8 @@ require !use_gdb_stub # (via dejagnu) yet. require {!is_remote target} +require {expr [have_startup_shell] != -1} + standard_testfile if { [build_executable "failed to prepare" $testfile $srcfile debug] } { @@ -40,7 +42,8 @@ run_on_host \ proc initial_setup_simple { startup_with_shell run_args } { global hex decimal binfile unique_file - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_test_no_output "set startup-with-shell $startup_with_shell" gdb_test_no_output "set print characters unlimited" @@ -91,73 +94,97 @@ proc run_test_same { args re testname } { run_test $args $re $re $testname } -# The regexp to match a single '\' character. -set bs "\\\\" - -# Are we using 'remote' or 'extended-remote' protocol? -set is_remote_p [gdb_protocol_is_remote] - -## Run the actual tests - -run_test "$unique_file_dir/*.unique-extension" \ - "\"$unique_file\"" \ - "\"$unique_file_dir/\\\*\.unique-extension\"" \ - "arg is glob" \ - $is_remote_p - -run_test_same "$unique_file_dir/\\*.unique-extension" \ - "\"$unique_file_dir/\\\*\.unique-extension\"" \ - "arg is escaped glob" - -save_vars { env(TEST) } { - set env(TEST) "1234" - run_test "\$TEST" \ - "\"1234\"" \ - "\"\\\$TEST\"" \ - "arg is shell variable" \ - $is_remote_p +# Run the actual tests +proc run_all_tests { { is_remote_with_split_args false } } { + # The regexp to match a single '\' character. + set bs "\\\\" + + run_test "$::unique_file_dir/*.unique-extension" \ + "\"$::unique_file\"" \ + "\"$::unique_file_dir/\\\*\.unique-extension\"" \ + "arg is glob" \ + $is_remote_with_split_args + + run_test_same "$::unique_file_dir/\\*.unique-extension" \ + "\"$::unique_file_dir/\\\*\.unique-extension\"" \ + "arg is escaped glob" + + save_vars { ::env(TEST) } { + set ::env(TEST) "1234" + run_test "\$TEST" \ + "\"1234\"" \ + "\"\\\$TEST\"" \ + "arg is shell variable" \ + $is_remote_with_split_args + + run_test_same "\\\$TEST" \ + "\"\\\$TEST\"" \ + "arg is escaped shell variable" + } - run_test_same "\\\$TEST" \ - "\"\\\$TEST\"" \ - "arg is escaped shell variable" + run_test "\$(echo foo)" \ + "\"foo\"" \ + "\"\\\$\\(echo\"" \ + "arg is parameter expansion, command execution" \ + $is_remote_with_split_args + + run_test "\$((2 + 3))" \ + "\"5\"" \ + "\"\\\$\\(\\(2\"" \ + "arg is parameter expansion, expression evaluation" \ + $is_remote_with_split_args + + run_test_same "\"\\a\"" \ + "\"${bs}${bs}a\"" \ + "retain backslash in double quote arg" + + run_test_same "'\\a'" \ + "\"${bs}${bs}a\"" \ + "retain backslash in single quote arg" + + run_test_same "\"\\\$\"" \ + "\"\\\$\"" \ + "'\$' can be escaped in double quote arg" + + run_test_same "'\\\$'" \ + "\"${bs}${bs}\\\$\"" \ + "'\$' is not escaped in single quote arg" + + run_test_same "\"\\`\"" \ + "\"\\`\"" \ + "'`' can be escaped in double quote arg" + + run_test_same "'\\`'" \ + "\"${bs}${bs}`\"" \ + "'`' is not escaped in single quote arg" + + run_test_same "\"\\\"\"" \ + "\"${bs}\"\"" \ + "'\"' can be escaped in double quote arg" + + run_test_same "'\\\"'" \ + "\"${bs}${bs}${bs}\"\"" \ + "'\"' is not escaped in single quote arg" + + run_test_same "\"\\\\\"" \ + "\"${bs}${bs}\"" \ + "'\\' can be escaped in double quote arg" + + run_test_same "'\\\\'" \ + "\"${bs}${bs}${bs}${bs}\"" \ + "'\\' is not escaped in single quote arg" } -run_test_same "\"\\a\"" \ - "\"${bs}${bs}a\"" \ - "retain backslash in double quote arg" - -run_test_same "'\\a'" \ - "\"${bs}${bs}a\"" \ - "retain backslash in single quote arg" - -run_test_same "\"\\\$\"" \ - "\"\\\$\"" \ - "'\$' can be escaped in double quote arg" +run_all_tests -run_test_same "'\\\$'" \ - "\"${bs}${bs}\\\$\"" \ - "'\$' is not escaped in single quote arg" - -run_test_same "\"\\`\"" \ - "\"\\`\"" \ - "'`' can be escaped in double quote arg" - -run_test_same "'\\`'" \ - "\"${bs}${bs}`\"" \ - "'`' is not escaped in single quote arg" - -run_test_same "\"\\\"\"" \ - "\"${bs}\"\"" \ - "'\"' can be escaped in double quote arg" - -run_test_same "'\\\"'" \ - "\"${bs}${bs}${bs}\"\"" \ - "'\"' is not escaped in single quote arg" - -run_test_same "\"\\\\\"" \ - "\"${bs}${bs}\"" \ - "'\\' can be escaped in double quote arg" - -run_test_same "'\\\\'" \ - "\"${bs}${bs}${bs}${bs}\"" \ - "'\\' is not escaped in single quote arg" +# For extended-remote targets, disable the packet which passes +# inferior arguments as a single string. This changes how the vRun +# (extended-remote only) packet works. +if {[target_info gdb_protocol] == "extended-remote"} { + with_test_prefix "single-inferior-arg disabled" { + save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"set remote single-inferior-argument-feature-packet off\"" + run_all_tests true + } + } +} diff --git a/gdb/testsuite/gdb.base/step-over-exit.exp b/gdb/testsuite/gdb.base/step-over-exit.exp index 2370f97..6dfa7bb 100644 --- a/gdb/testsuite/gdb.base/step-over-exit.exp +++ b/gdb/testsuite/gdb.base/step-over-exit.exp @@ -13,11 +13,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -standard_testfile - # Test a thread is doing step-over a syscall instruction which is exit, # and GDBserver should cleanup its state of step-over properly. +# The testcase relies on follow-fork-mode child. +require allow_fork_tests + +standard_testfile + set syscall_insn "" # Define the syscall instruction for each target. diff --git a/gdb/testsuite/gdb.base/step-over-no-symbols.exp b/gdb/testsuite/gdb.base/step-over-no-symbols.exp index 2eb8efe..1a91986 100644 --- a/gdb/testsuite/gdb.base/step-over-no-symbols.exp +++ b/gdb/testsuite/gdb.base/step-over-no-symbols.exp @@ -47,7 +47,8 @@ proc test_step_over { displaced } { global hex global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.base/step-sw-breakpoint-adjust-pc.exp b/gdb/testsuite/gdb.base/step-sw-breakpoint-adjust-pc.exp index 2dc67ea..2dde3bb 100644 --- a/gdb/testsuite/gdb.base/step-sw-breakpoint-adjust-pc.exp +++ b/gdb/testsuite/gdb.base/step-sw-breakpoint-adjust-pc.exp @@ -36,7 +36,8 @@ proc test {non_stop displaced always_inserted} { save_vars { GDBFLAGS } { set GDBFLAGS "$GDBFLAGS -ex \"set non-stop $non_stop\"" - clean_restart $binfile + clean_restart + gdb_load $binfile } gdb_test_no_output "set displaced-stepping $displaced" diff --git a/gdb/testsuite/gdb.base/step-test.exp b/gdb/testsuite/gdb.base/step-test.exp index 28eccf7..39833a3 100644 --- a/gdb/testsuite/gdb.base/step-test.exp +++ b/gdb/testsuite/gdb.base/step-test.exp @@ -24,7 +24,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.base/structs.exp b/gdb/testsuite/gdb.base/structs.exp index 31a45b5..fa7f786 100644 --- a/gdb/testsuite/gdb.base/structs.exp +++ b/gdb/testsuite/gdb.base/structs.exp @@ -56,7 +56,7 @@ proc start_structs_test { types } { } set binfile [standard_output_file ${testfile}] - if { [prepare_for_testing "failed to prepare" $binfile $srcfile $flags] } { + if { [prepare_for_testing "failed to prepare" $testfile $srcfile $flags] } { return -1 } diff --git a/gdb/testsuite/gdb.base/structs2.exp b/gdb/testsuite/gdb.base/structs2.exp index 8ccd50d..f377022 100644 --- a/gdb/testsuite/gdb.base/structs2.exp +++ b/gdb/testsuite/gdb.base/structs2.exp @@ -15,7 +15,7 @@ standard_testfile .c -if { [prepare_for_testing "failed to prepare" $binfile $srcfile {debug}] } { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug}] } { return -1 } diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp index 59c93ee..92b5085 100644 --- a/gdb/testsuite/gdb.base/style.exp +++ b/gdb/testsuite/gdb.base/style.exp @@ -13,6 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +require {!is_remote host} + load_lib gdb-python.exp # Test CLI output styling. @@ -48,7 +50,7 @@ proc clean_restart_and_disable { prefix args } { global currently_disabled_style with_test_prefix "$prefix" { - eval "clean_restart $args" + clean_restart {*}$args if { $currently_disabled_style != "" } { set st $currently_disabled_style @@ -75,7 +77,7 @@ proc run_style_tests { } { # Restart GDB with the correct TERM variable setting, this # means that GDB will enable styling. - clean_restart_and_disable "restart 1" ${binfile} + clean_restart_and_disable "restart 1" $::testfile set readnow [readnow] @@ -323,12 +325,24 @@ proc run_style_tests { } { gdb_test_no_output "set style version background 255" gdb_test_no_output "set style version foreground #FED210" gdb_test "show style version background" \ - "The \033\\\[38;2;254;210;16;48;5;255;22;27m.*\".*version.*\".*style.*\033\\\[m background color is: 255" \ + "The \033\\\[38;2;254;210;16;48;5;255;22;23;24;27m.*\".*version.*\".*style.*\033\\\[m background color is: 255" \ "Version's 256-color background style" gdb_test "show style version foreground" \ - "The \033\\\[38;2;254;210;16;48;5;255;22;27m.*\".*version.*\".*style.*\033\\\[m foreground color is: #FED210" \ + "The \033\\\[38;2;254;210;16;48;5;255;22;23;24;27m.*\".*version.*\".*style.*\033\\\[m foreground color is: #FED210" \ "Version's TrueColor foreground style" } + + gdb_test_no_output "set host-charset UTF-8" + # Chosen since it will print an error. + gdb_test "maint translate-address" \ + "❌️ requires argument.*" \ + "emoji output" + + gdb_test_no_output "set style error-prefix abcd:" \ + "set the error prefix" + gdb_test "maint translate-address" \ + "abcd:requires argument.*" \ + "error prefix" } } @@ -344,7 +358,7 @@ proc test_disable_disassembler_styling { } { # Restart GDB with the correct TERM variable setting, this # means that GDB will enable styling. - clean_restart_and_disable "restart 3" $::binfile + clean_restart_and_disable "restart 3" $::testfile set styled_hex [limited_style $::hex address] set main [limited_style main function] @@ -459,7 +473,7 @@ proc test_disassembler_error_handling { } { # Restart GDB with the correct TERM variable setting, this # means that GDB will enable styling. - clean_restart_and_disable "restart 4" $::binfile + clean_restart_and_disable "restart 4" $::testfile # Disable use of libopcodes for styling. As this function is # only called when Python Pygments module is available, we @@ -739,10 +753,293 @@ proc test_enable_styling_warning { } { } } +# Run an 'apropos' command. Each line of output starts with a +# non-default style (command style). Ensure that pagination triggers +# during the 'apropos' output such that, at the point pagination kicks +# in, a non-default style is in effect. +# +# Then, at the pagination prompt, quit the command. +# +# Next, run a command which switches to a different style, and then +# back to the current style. +# +# At one point, a bug in the pagination code would leave the +# non-default style from the 'apropos' command recorded as the current +# style, such that the second command would switch back to the earlier +# style. +proc test_pagination_cmd_after_quit_styling {} { + with_ansi_styling_terminal { + clean_restart + } + + # We're going to use 'apropos time'. Check that with a height of + # 12 lines, each line starts with a non-default style, and that we + # do see the pagination prompt. This means that there are more + # than 12 lines for this command. + with_test_prefix "validate apropos output" { + gdb_test_no_output "set height 12" + + set saw_pagination_prompt false + gdb_test_multiple "apropos time" "" { + -re "^apropos time\r\n" { + exp_continue + } + -re "^\033\\\[39;49;1;23;24;27m\[^\r\n\]+\r\n" { + exp_continue + } + -re "^$::pagination_prompt$" { + set saw_pagination_prompt true + send_gdb "q\n" + exp_continue + } + -re "^q\r\n" { + exp_continue + } + -re "^Quit\r\n" { + exp_continue + } + -re "^$::gdb_prompt $" { + gdb_assert { $saw_pagination_prompt } $gdb_test_name + } + -re "^\[^\r\n\]+\r\n" { + exp_continue + } + } + } + + # Now reduce the height to 10 and re-run 'apropos time'. Based on + # the previous check, we know that this is going to present the + # pagination prompt when a non-default style is in use. + gdb_test_no_output "set height 10" + + set saw_pagination_prompt false + gdb_test_multiple "apropos time" "" { + -re "$::pagination_prompt" { + set saw_pagination_prompt true + send_gdb "q\n" + exp_continue + } + -re "\r\n$::gdb_prompt $" { + gdb_assert { $saw_pagination_prompt } $gdb_test_name + } + } + + # The help output for this maintenance command switches to a + # different style, and then back to the default. If the + # pagination bug still exists, then this would switch back to the + # non-default style that was in use when pagination kicked in + # above. + gdb_test "maintenance time" \ + "^\"\033\\\[39;49;1;23;24;27mmaintenance time\033\\\[m\" takes a numeric argument\\." +} + +# Helper for test_pagination_prompt_styling. Return false if STR, a +# line that appears immediately before a pagination prompt, matches +# the pattern for needing a style reset at the end, but does not have +# the style reset. +# +# In all other cases, return true. So lines that don't match the +# known pattern for neededing a style reset will always return true, +# as will lines that match the pattern, and do have the style reset. +proc previous_line_is_ok { str } { + + # Create a copy of STR with all the '\033' characters removed. + # Then compare string lengths to get a count of the '\033' + # charactes present in STR. + regsub -all "\033" $str {} stripped + set count [expr [string length $str] - [string length $stripped]] + + # If STR switched styles, then it _must_ switch back again, + # otherwise the pagination prompt will be in the wrong style. + # This means that there _must_ be an even number of '\033' + # characters in STR. If there is not then we switched style, but + # failed to switch back. + if { [expr $count % 2] != 0 } { + return false + } + + # For lines that don't match this pattern, we cannot comment on + # where the style reset should occur, so lets just claim the line + # is fine. + if { ![regexp "\\s+$::hex - $::hex is \[^\r\n\]+ in \033" $str] } { + return true + } + + # This line did match the above pattern, so we know that a style + # reset _must_ occur at the end of the line. If it doesn't then + # this line is not OK. + if { ![regexp "\033\\\[m$" $str] } { + return false + } + + # All tests passed, this line looks OK. + return true +} + +# Test that the pagination prompt is displayed unstyled. This is done +# by looking at the 'info files' output and selecting a width that +# will mean we should get a pagination prompt part way through a +# styled filename. +# +# Then, re-run 'info files' and check that for every pagination +# prompt, the previous line disables styling as expected. +proc test_pagination_prompt_styling {} { + with_ansi_styling_terminal { + clean_restart + gdb_load $::binfile + } + + if {![runto_main]} { + return + } + + # Set height so we actually get a pagination prompt. + gdb_test_no_output "set height 3" + + # Scan the 'info files' output and set DESIRED_WIDTH such that it + # will trigger pagination part-way through a styled filename. + set desired_width 0 + gdb_test_multiple "info files" "find good test width" { + -re "^info files\r\n" { + exp_continue + } + + -re "^$::pagination_prompt$" { + send_gdb "\n" + exp_continue + } + + -re "^$::gdb_prompt $" { + } + + -re "^((\\s+$::hex - $::hex is \[^\r\n\]+ in )\[^\r\n\]+)\r\n" { + if { $desired_width == 0 } { + set full_line $expect_out(1,string) + set inner_line $expect_out(2,string) + set desired_width [expr [string length $inner_line] + ([string length $full_line] - [string length $inner_line]) / 2] + } + exp_continue + } + + -re "^\[^\r\n\]*\r\n" { + exp_continue + } + } + + if { $desired_width < [string length $::pagination_prompt_str] + 2 } { + # Avoid readline wrapping after printing the pagination prompt. + return + } + + # Now setup the screen width. + gdb_test_no_output "set width $desired_width" \ + "set width to desired width" + + # Re-run 'info files'. Check that the content before any + # pagination prompt correctly disables styling. + set saw_bad_line false + set prev_line "" + gdb_test_multiple "info files" "check pagination prompt styling" { + -re "^info files\r\n" { + exp_continue + } + + -re "^$::pagination_prompt$" { + if { ![previous_line_is_ok $prev_line] } { + set saw_bad_line true + } + send_gdb "\n" + exp_continue + } + + -re "^(\[^\r\n\]+)$::pagination_prompt$" { + set prev_line $expect_out(1,string) + if { ![previous_line_is_ok $prev_line] } { + set saw_bad_line true + } + send_gdb "\n" + exp_continue + } + + -re "^$::gdb_prompt $" { + gdb_assert { !$saw_bad_line } $gdb_test_name + } + + -re "^(\[^\r\n\]*)\r\n" { + set prev_line $expect_out(1,string) + exp_continue + } + } +} + +# Test that GDB can correctly restore the current style after a +# pagination prompt. +# +# Set the logging file to a garbage string based on LENGTH (is +# actually 2x LENGTH), then 'show logging file'. Press return at the +# pagination prompt, and check that the reset of the filename is +# styled correctly, and that GDB correctly switches back to the +# default style once the logging file has finished. +proc test_pagination_continue_styling_1 { length } { + with_ansi_styling_terminal { + clean_restart + gdb_load $::binfile + } + + set filename [string repeat "ax" $length] + + gdb_test_no_output "set logging file $filename" + + gdb_test_no_output "set height 3" + gdb_test_no_output "set width 80" + + set saw_bad_styling false + gdb_test_multiple "show logging file" "" { + -re "^show logging file\r\n" { + exp_continue + } + + -re "^The current logfile is \"\033\\\[32;49;22;23;24;27m(?:ax)+\033\\\[m" { + exp_continue + } + + -re "^\r\n\033\\\[32;49;22;23;24;27m(?:ax)+\033\\\[m(?=--)" { + exp_continue + } + + -re "^\r\n\033\\\[32;49;22;23;24;27m(?:ax)+(?=--)" { + set saw_bad_styling true + exp_continue + } + + -re "^\r\n\033\\\[32;49;22;23;24;27m(?:ax)+\033\\\[m\"\\.\r\n" { + exp_continue + } + + -re "^$::gdb_prompt $" { + gdb_assert { !$saw_bad_styling } $gdb_test_name + } + + -re "^$::pagination_prompt$$" { + send_gdb "\n" + exp_continue + } + } +} + +# Wrapper around test_pagination_continue_styling_1, calls that +# function with different lengths. +proc test_pagination_continue_styling { } { + foreach_with_prefix length { 80 160 } { + test_pagination_continue_styling_1 $length + } +} + # Check to see if the Python styling of disassembler output is # expected or not, this styling requires Python support in GDB, and # the Python pygments module to be available. -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {[allow_python_tests] && [gdb_py_module_available "pygments"]} { set python_disassembly_styling true } else { @@ -781,3 +1078,6 @@ test_colorsupport_truecolor test_colorsupport_truecolor_only test_enable_styling_warning +test_pagination_cmd_after_quit_styling +test_pagination_prompt_styling +test_pagination_continue_styling diff --git a/gdb/testsuite/gdb.base/sym-file.exp b/gdb/testsuite/gdb.base/sym-file.exp index 8197c0e..13febda 100644 --- a/gdb/testsuite/gdb.base/sym-file.exp +++ b/gdb/testsuite/gdb.base/sym-file.exp @@ -61,7 +61,8 @@ if {[gdb_compile_shlib $libsrc $lib_so {debug}] != ""} { return } -if {[prepare_for_testing "failed to prepare" $binfile "$srcfile $srcfile2" $exec_opts]} { +if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" \ + $exec_opts] } { return } @@ -70,7 +71,8 @@ gdb_load_shlib ${lib_so} proc do_test { remove_expr } { global lib_basename lib_syms srcfile srcfile3 - clean_restart $::binfile + clean_restart + gdb_load $::binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/symtab-search-order.exp b/gdb/testsuite/gdb.base/symtab-search-order.exp index cf0d507..34b1db0 100644 --- a/gdb/testsuite/gdb.base/symtab-search-order.exp +++ b/gdb/testsuite/gdb.base/symtab-search-order.exp @@ -33,7 +33,8 @@ if { [gdb_compile_shlib $lib1src $lib1 $lib_opts] != "" # Start with a fresh gdb. -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $lib1 if ![runto_main] { diff --git a/gdb/testsuite/gdb.base/testenv.exp b/gdb/testsuite/gdb.base/testenv.exp index beb59d2..59cd33c 100644 --- a/gdb/testsuite/gdb.base/testenv.exp +++ b/gdb/testsuite/gdb.base/testenv.exp @@ -27,7 +27,7 @@ standard_testfile .c # Compile binary # and start with a fresh gdb -if { [prepare_for_testing "failed to prepare" ${binfile} ${srcfile}] } { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { return -1 } @@ -90,7 +90,8 @@ proc find_env {varname} { proc_with_prefix test_set_unset_env {} { global binfile - clean_restart $binfile + clean_restart + gdb_load $binfile # First test with no TEST_GDB_VAR. with_test_prefix "test1" { @@ -151,7 +152,8 @@ proc_with_prefix test_inherit_env_var {} { save_vars {env(TEST_GDB_GLOBAL)} { set env(TEST_GDB_GLOBAL) "Global environment value" - clean_restart $binfile + clean_restart + gdb_load $binfile gdb_breakpoint $bp_line diff --git a/gdb/testsuite/gdb.base/tls-common.exp.tcl b/gdb/testsuite/gdb.base/tls-common.exp.tcl new file mode 100644 index 0000000..fc212a9 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-common.exp.tcl @@ -0,0 +1,50 @@ +# Copyright 2024-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. + +# Require statement, variables and procs used by tls-nothreads.exp, +# tls-multiobj.exp, and tls-dlobj.exp. + +# The tests listed above are known to work for the targets listed on +# the 'require' line, below. +# +# At the moment, only the Linux target is listed, but, ideally, these +# tests should be run on other targets too. E.g, testing on FreeBSD +# shows many failures which should be addressed in some fashion before +# enabling it for that target. + +require {is_any_target "*-*-linux*"} + +# These are the targets which have support for internal TLS lookup: + +set internal_tls_linux_targets {"x86_64-*-linux*" "aarch64-*-linux*" + "riscv*-*-linux*" "powerpc64*-*-linux*" + "s390x*-*-linux*"} + +# The "maint set force-internal-tls-address-lookup" command is only +# available for certain Linux architectures. Don't attempt to force +# use of internal TLS support for architectures which don't support +# it. + +if [is_any_target {*}$internal_tls_linux_targets] { + set internal_tls_iters { false true } +} else { + set internal_tls_iters { false } +} + +# Set up a kfail with message KFAIL_MSG when KFAIL_COND holds, then +# issue gdb_test with command CMD and regular expression RE. + +proc gdb_test_with_kfail {cmd re kfail_cond kfail_msg} { + if [uplevel 1 [list expr $kfail_cond]] { + setup_kfail $kfail_msg *-*-* + } + gdb_test $cmd $re +} diff --git a/gdb/testsuite/gdb.base/tls-dlobj-lib.c b/gdb/testsuite/gdb.base/tls-dlobj-lib.c new file mode 100644 index 0000000..e82a064 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj-lib.c @@ -0,0 +1,87 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +/* This program needs to be compiled with preprocessor symbol set to + a small integer, e.g. "gcc -DN=1 ..." With N defined, the CONCAT2 + and CONCAT3 macros will construct suitable names for the global + variables and functions. */ + +#define CONCAT2(a,b) CONCAT2_(a,b) +#define CONCAT2_(a,b) a ## b + +#define CONCAT3(a,b,c) CONCAT3_(a,b,c) +#define CONCAT3_(a,b,c) a ## b ## c + +/* For N=1, this ends up being... + __thread int tls_lib1_tbss_1; + __thread int tls_lib1_tbss_2; + __thread int tls_lib1_tdata_1 = 196; + __thread int tls_lib1_tdata_2 = 197; */ + +__thread int CONCAT3(tls_lib, N, _tbss_1); +__thread int CONCAT3(tls_lib, N, _tbss_2); +__thread int CONCAT3(tls_lib, N, _tdata_1) = CONCAT2(N, 96); +__thread int CONCAT3(tls_lib, N, _tdata_2) = CONCAT2(N, 97); + +/* Substituting for N, define function: + + int get_tls_libN_var (int which) . */ + +int +CONCAT3(get_tls_lib, N, _var) (int which) +{ + switch (which) + { + case 0: + return -1; + case 1: + return CONCAT3(tls_lib, N, _tbss_1); + case 2: + return CONCAT3(tls_lib, N, _tbss_2); + case 3: + return CONCAT3(tls_lib, N, _tdata_1); + case 4: + return CONCAT3(tls_lib, N, _tdata_2); + } + return -1; +} + +/* Substituting for N, define function: + + void set_tls_libN_var (int which, int val) . */ + +void +CONCAT3(set_tls_lib, N, _var) (int which, int val) +{ + switch (which) + { + case 0: + break; + case 1: + CONCAT3(tls_lib, N, _tbss_1) = val; + break; + case 2: + CONCAT3(tls_lib, N, _tbss_2) = val; + break; + case 3: + CONCAT3(tls_lib, N, _tdata_1) = val; + break; + case 4: + CONCAT3(tls_lib, N, _tdata_2) = val; + break; + } +} diff --git a/gdb/testsuite/gdb.base/tls-dlobj.c b/gdb/testsuite/gdb.base/tls-dlobj.c new file mode 100644 index 0000000..a93f4a7 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj.c @@ -0,0 +1,311 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +#include <dlfcn.h> +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> + +typedef void (*setter_ftype) (int which, int val); + +__thread int tls_main_tbss_1; +__thread int tls_main_tbss_2; +__thread int tls_main_tdata_1 = 96; +__thread int tls_main_tdata_2 = 97; + +extern void set_tls_lib10_var (int which, int val); +extern void set_tls_lib11_var (int which, int val); + +volatile int data; + +static void +set_tls_main_var (int which, int val) +{ + switch (which) + { + case 1: + tls_main_tbss_1 = val; + break; + case 2: + tls_main_tbss_2 = val; + break; + case 3: + tls_main_tdata_1 = val; + break; + case 4: + tls_main_tdata_2 = val; + break; + } +} + +void +use_it (int a) +{ + data = a; +} + +static void * +load_dso (char *dso_name, int n, setter_ftype *setterp) +{ + char buf[80]; + void *sym; + void *handle = dlopen (dso_name, RTLD_NOW | RTLD_GLOBAL); + if (handle == NULL) + { + fprintf (stderr, "dlopen of DSO '%s' failed: %s\n", dso_name, dlerror ()); + exit (1); + } + sprintf (buf, "set_tls_lib%d_var", n); + sym = dlsym (handle, buf); + assert (sym != NULL); + *setterp = sym; + + /* Some libc implementations (for some architectures) refuse to + initialize TLS data structures (specifically, the DTV) without + first calling dlsym on one of the TLS symbols. */ + sprintf (buf, "tls_lib%d_tdata_1", n); + assert (dlsym (handle, buf) != NULL); + + return handle; +} + +int +main (int argc, char **argv) +{ + int i, status; + setter_ftype s0, s1, s2, s3, s4, s10, s11; + void *h1 = load_dso (OBJ1, 1, &s1); + void *h2 = load_dso (OBJ2, 2, &s2); + void *h3 = load_dso (OBJ3, 3, &s3); + void *h4 = load_dso (OBJ4, 4, &s4); + s0 = set_tls_main_var; + s10 = set_tls_lib10_var; + s11 = set_tls_lib11_var; + + use_it (0); /* main-breakpoint-1 */ + + /* Set TLS variables in main program and all libraries. */ + for (i = 1; i <= 4; i++) + s0 (i, 10 + i); + for (i = 1; i <= 4; i++) + s1 (i, 110 + i); + for (i = 1; i <= 4; i++) + s2 (i, 210 + i); + for (i = 1; i <= 4; i++) + s3 (i, 310 + i); + for (i = 1; i <= 4; i++) + s4 (i, 410 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1010 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1110 + i); + + use_it (0); /* main-breakpoint-2 */ + + /* Unload lib2 and lib3. */ + status = dlclose (h2); + assert (status == 0); + status = dlclose (h3); + assert (status == 0); + + /* Set TLS variables in main program and in libraries which are still + loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 20 + i); + for (i = 1; i <= 4; i++) + s1 (i, 120 + i); + for (i = 1; i <= 4; i++) + s4 (i, 420 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1020 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1120 + i); + + use_it (0); /* main-breakpoint-3 */ + + /* Load lib3. */ + h3 = load_dso (OBJ3, 3, &s3); + + /* Set TLS vars again; currently, only lib2 is not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 30 + i); + for (i = 1; i <= 4; i++) + s1 (i, 130 + i); + for (i = 1; i <= 4; i++) + s3 (i, 330 + i); + for (i = 1; i <= 4; i++) + s4 (i, 430 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1030 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1130 + i); + + use_it (0); /* main-breakpoint-4 */ + + /* Unload lib1 and lib4; load lib2. */ + status = dlclose (h1); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + h2 = load_dso (OBJ2, 2, &s2); + + /* Set TLS vars; currently, lib2 and lib3 are loaded, + lib1 and lib4 are not. */ + for (i = 1; i <= 4; i++) + s0 (i, 40 + i); + for (i = 1; i <= 4; i++) + s2 (i, 240 + i); + for (i = 1; i <= 4; i++) + s3 (i, 340 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1040 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1140 + i); + + use_it (0); /* main-breakpoint-5 */ + + /* Load lib4 and lib1. Unload lib2. */ + h4 = load_dso (OBJ4, 4, &s4); + h1 = load_dso (OBJ1, 1, &s1); + status = dlclose (h2); + assert (status == 0); + + /* Set TLS vars; currently, lib1, lib3, and lib4 are loaded; + lib2 is not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 50 + i); + for (i = 1; i <= 4; i++) + s1 (i, 150 + i); + for (i = 1; i <= 4; i++) + s3 (i, 350 + i); + for (i = 1; i <= 4; i++) + s4 (i, 450 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1050 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1150 + i); + + use_it (0); /* main-breakpoint-6 */ + + /* Load lib2, unload lib1, lib3, and lib4; then load lib3 again. */ + h2 = load_dso (OBJ2, 2, &s2); + status = dlclose (h1); + assert (status == 0); + status = dlclose (h3); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + h3 = load_dso (OBJ3, 3, &s3); + + /* Set TLS vars; currently, lib2 and lib3 are loaded; + lib1 and lib4 are not loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 60 + i); + for (i = 1; i <= 4; i++) + s2 (i, 260 + i); + for (i = 1; i <= 4; i++) + s3 (i, 360 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1060 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1160 + i); + + use_it (0); /* main-breakpoint-7 */ + + /* Unload lib3 and lib2, then (re)load lib4, lib3, lib2, and lib1, + in that order. */ + status = dlclose (h3); + assert (status == 0); + status = dlclose (h2); + assert (status == 0); + h4 = load_dso (OBJ4, 4, &s4); + h3 = load_dso (OBJ3, 3, &s3); + h2 = load_dso (OBJ2, 2, &s2); + h1 = load_dso (OBJ1, 1, &s1); + + /* Set TLS vars; currently, lib1, lib2, lib3, and lib4 are all + loaded. */ + for (i = 1; i <= 4; i++) + s0 (i, 70 + i); + for (i = 1; i <= 4; i++) + s1 (i, 170 + i); + for (i = 1; i <= 4; i++) + s2 (i, 270 + i); + for (i = 1; i <= 4; i++) + s3 (i, 370 + i); + for (i = 1; i <= 4; i++) + s4 (i, 470 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1070 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1170 + i); + + use_it (0); /* main-breakpoint-8 */ + + /* Unload lib3, lib1, and lib4. */ + status = dlclose (h3); + assert (status == 0); + status = dlclose (h1); + assert (status == 0); + status = dlclose (h4); + assert (status == 0); + + /* Set TLS vars; currently, lib2 is loaded; lib1, lib3, and lib4 are + not. */ + for (i = 1; i <= 4; i++) + s0 (i, 80 + i); + for (i = 1; i <= 4; i++) + s2 (i, 280 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1080 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1180 + i); + + use_it (0); /* main-breakpoint-9 */ + + /* Load lib3, unload lib2, load lib4. */ + h3 = load_dso (OBJ3, 3, &s3); + status = dlclose (h2); + assert (status == 0); + h4 = load_dso (OBJ4, 4, &s4); + + /* Set TLS vars; currently, lib3 and lib4 are loaded; lib1 and lib2 + are not. */ + for (i = 1; i <= 4; i++) + s0 (i, 90 + i); + for (i = 1; i <= 4; i++) + s3 (i, 390 + i); + for (i = 1; i <= 4; i++) + s4 (i, 490 + i); + for (i = 1; i <= 4; i++) + s10 (i, 1090 + i); + for (i = 1; i <= 4; i++) + s11 (i, 1190 + i); + + use_it (0); /* main-breakpoint-10 */ + + /* Attempt to keep variables in the main program from being optimized + away. */ + use_it (tls_main_tbss_1); + use_it (tls_main_tbss_2); + use_it (tls_main_tdata_1); + use_it (tls_main_tdata_2); + + use_it (100); /* main-breakpoint-last */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-dlobj.exp b/gdb/testsuite/gdb.base/tls-dlobj.exp new file mode 100644 index 0000000..1509ec8 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-dlobj.exp @@ -0,0 +1,380 @@ +# Copyright 2024-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. + +# Test that the GDB-internal TLS link map to module id mapping code +# works correctly when debugging a program which is linked against +# shared objects and which also loads and unloads other shared objects +# in different orders. For targets which have GDB-internal TLS +# support, it'll check both GDB-internal TLS support as well as that +# provided by a helper library such as libthread_db. + +source $srcdir/$subdir/tls-common.exp.tcl + +require allow_shlib_tests + +standard_testfile + +set libsrc "${srcdir}/${subdir}/${testfile}-lib.c" + +# These will be dlopen'd: +set lib1obj [standard_output_file "${testfile}1-lib.so"] +set lib2obj [standard_output_file "${testfile}2-lib.so"] +set lib3obj [standard_output_file "${testfile}3-lib.so"] +set lib4obj [standard_output_file "${testfile}4-lib.so"] + +# These will be dynamically linked with the main program: +set lib10obj [standard_output_file "${testfile}10-lib.so"] +set lib11obj [standard_output_file "${testfile}11-lib.so"] + +# Due to problems with some versions of glibc, we expect some tests to +# fail due to TLS storage not being allocated/initialized. Test +# command CMD using regular expression RE, and use XFAIL instead of +# FAIL when the relevant RE is matched and COND is true when evaluated +# in the upper level. + +proc gdb_test_with_xfail { cmd re cond} { + gdb_test_multiple $cmd $cmd { + -re -wrap $re { + pass $gdb_test_name + } + -re -wrap "The inferior has not yet allocated storage for thread-local variables.*" { + if [ uplevel 1 [list expr $cond]] { + xfail $gdb_test_name + } else { + fail $gdb_test_name + } + } + } +} + +proc do_tests {force_internal_tls} { + clean_restart + gdb_load $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + with_test_prefix "before assignments" { + gdb_test "print tls_main_tbss_1" ".* = 0" + gdb_test "print tls_main_tbss_2" ".* = 0" + gdb_test "print tls_main_tdata_1" ".* = 96" + gdb_test "print tls_main_tdata_2" ".* = 97" + + # For these tests, where we're attempting to access TLS vars + # in a dlopen'd library, but before assignment to any of the + # vars, so it could happen that storage hasn't been allocated + # yet. But it might also work. (When testing against MUSL, + # things just work; GLIBC ends to produce the TLS error.) So + # accept either the right answer or a TLS error message. + + set tlserr "The inferior has not yet allocated storage for thread-local variables.*" + foreach n {1 2 3 4} { + gdb_test "print tls_lib${n}_tbss_1" \ + "0|${tlserr}" + gdb_test "print tls_lib${n}_tbss_2" \ + "0|${tlserr}" + gdb_test "print tls_lib${n}_tdata_1" \ + "96|${tlserr}" + gdb_test "print tls_lib${n}_tdata_2" \ + "97|${tlserr}" + } + foreach n {10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = 0" + gdb_test "print tls_lib${n}_tbss_2" ".* = 0" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}96" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}97" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "at main-breakpoint-2" { + gdb_test "print tls_main_tbss_1" ".* = 11" + gdb_test "print tls_main_tbss_2" ".* = 12" + gdb_test "print tls_main_tdata_1" ".* = 13" + gdb_test "print tls_main_tdata_2" ".* = 14" + + foreach n {1 2 3 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}11" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}12" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}13" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}14" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-3"] + gdb_continue_to_breakpoint "main-breakpoint-3" + + # At this point lib2 and lib3 have been unloaded. Also, TLS vars + # in remaining libraries have been changed. + + with_test_prefix "at main-breakpoint-3" { + gdb_test "print tls_main_tbss_1" ".* = 21" + gdb_test "print tls_main_tbss_2" ".* = 22" + gdb_test "print tls_main_tdata_1" ".* = 23" + gdb_test "print tls_main_tdata_2" ".* = 24" + + foreach n {1 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}21" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}22" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}23" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}24" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-4"] + gdb_continue_to_breakpoint "main-breakpoint-4" + + # lib3 has been loaded again; lib2 is the only one not loaded. + + with_test_prefix "at main-breakpoint-4" { + gdb_test "print tls_main_tbss_1" ".* = 31" + gdb_test "print tls_main_tbss_2" ".* = 32" + gdb_test "print tls_main_tdata_1" ".* = 33" + gdb_test "print tls_main_tdata_2" ".* = 34" + + set cond { $n == 3 } + foreach n {1 3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}31" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}32" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}33" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}34" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-5"] + gdb_continue_to_breakpoint "main-breakpoint-5" + + # lib2 and lib3 are loaded; lib1 and lib4 are not. + + with_test_prefix "at main-breakpoint-5" { + gdb_test "print tls_main_tbss_1" ".* = 41" + gdb_test "print tls_main_tbss_2" ".* = 42" + gdb_test "print tls_main_tdata_1" ".* = 43" + gdb_test "print tls_main_tdata_2" ".* = 44" + + set cond { $n == 2 || $n == 3 } + foreach n {2 3 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}41" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}42" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}43" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}44" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-6"] + gdb_continue_to_breakpoint "main-breakpoint-6" + + # lib1, lib3 and lib4 are loaded; lib2 is not loaded. + + with_test_prefix "at main-breakpoint-6" { + gdb_test "print tls_main_tbss_1" ".* = 51" + gdb_test "print tls_main_tbss_2" ".* = 52" + gdb_test "print tls_main_tdata_1" ".* = 53" + gdb_test "print tls_main_tdata_2" ".* = 54" + + set cond { $n == 1 || $n == 3 || $n == 4} + foreach n {1 3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}51" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}52" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}53" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}54" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-7"] + gdb_continue_to_breakpoint "main-breakpoint-7" + + # lib2 and lib3 are loaded; lib1 and lib4 are not. + + with_test_prefix "at main-breakpoint-7" { + gdb_test "print tls_main_tbss_1" ".* = 61" + gdb_test "print tls_main_tbss_2" ".* = 62" + gdb_test "print tls_main_tdata_1" ".* = 63" + gdb_test "print tls_main_tdata_2" ".* = 64" + + set cond { $n == 2 || $n == 3 } + foreach n {2 3 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}61" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}62" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}63" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}64" $cond + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-8"] + gdb_continue_to_breakpoint "main-breakpoint-8" + + # lib1, lib2, lib3, and lib4 are all loaded. + + with_test_prefix "at main-breakpoint-8" { + gdb_test "print tls_main_tbss_1" ".* = 71" + gdb_test "print tls_main_tbss_2" ".* = 72" + gdb_test "print tls_main_tdata_1" ".* = 73" + gdb_test "print tls_main_tdata_2" ".* = 74" + + foreach n {1 2 3 4 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}71" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}72" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}73" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}74" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-9"] + gdb_continue_to_breakpoint "main-breakpoint-9" + + # lib2 is loaded; lib1, lib3, and lib4 are not. + + with_test_prefix "at main-breakpoint-9" { + gdb_test "print tls_main_tbss_1" ".* = 81" + gdb_test "print tls_main_tbss_2" ".* = 82" + gdb_test "print tls_main_tdata_1" ".* = 83" + gdb_test "print tls_main_tdata_2" ".* = 84" + + foreach n {2 10 11} { + gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}81" + gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}82" + gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}83" + gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}84" + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-10"] + gdb_continue_to_breakpoint "main-breakpoint-10" + + # lib3 and lib4 are loaded; lib1 and lib2 are not. + + with_test_prefix "at main-breakpoint-10" { + gdb_test "print tls_main_tbss_1" ".* = 91" + gdb_test "print tls_main_tbss_2" ".* = 92" + gdb_test "print tls_main_tdata_1" ".* = 93" + gdb_test "print tls_main_tdata_2" ".* = 94" + + set cond { $n == 3 || $n == 4 } + foreach n {3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond + } + } + + # gdb_interact + + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart + gdb_load $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + gdb_test "print tls_main_tbss_1" ".* = 91" + gdb_test "print tls_main_tbss_2" ".* = 92" + gdb_test "print tls_main_tdata_1" ".* = 93" + gdb_test "print tls_main_tdata_2" ".* = 94" + + set cond { $n == 3 || $n == 4 } + foreach n {3 4 10 11} { + gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond + gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond + gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond + } + } +} + +# Build shared objects for dlopen: +if { [gdb_compile_shlib $libsrc $lib1obj [list debug additional_flags=-DN=1]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib2obj [list debug additional_flags=-DN=2]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib3obj [list debug additional_flags=-DN=3]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib4obj [list debug additional_flags=-DN=4]] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Build shared objects to link against main program: +if { [gdb_compile_shlib $libsrc $lib10obj [list debug additional_flags=-DN=10]] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $libsrc $lib11obj [list debug additional_flags=-DN=11]] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Use gdb_compile_pthreads to build and link the main program for +# testing. It's also possible to run the tests using plain old +# gdb_compile, but this adds complexity with setting up additional +# KFAILs. (When run using GLIBC versions earlier than 2.34, a program +# that's not dynamically linked against libpthread will lack a working +# libthread_db, and, therefore, won't be able to access thread local +# storage without GDB-internal TLS support. Additional complications +# arise from when testing on x86_64 with -m32, which tends to work +# okay on GLIBC 2.34 and newer, but not older versions. It gets messy +# to properly sort out all of these cases.) +# +# This test was originally written to do it both ways, i.e. with both +# both gdb_compile and gdb_compile_pthreads, but the point of this +# test is to check that the link map address to TLS module id mapping +# code works correctly in programs which use lots of dlopen and +# dlclose calls in various orders - and that can be done using just +# gdb_compile_pthreads. + +if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib_load \ + shlib=${lib10obj} \ + shlib=${lib11obj} \ + additional_flags=-DOBJ1=\"${lib1obj}\" \ + additional_flags=-DOBJ2=\"${lib2obj}\" \ + additional_flags=-DOBJ3=\"${lib3obj}\" \ + additional_flags=-DOBJ4=\"${lib4obj}\" \ + ]] != "" } { + untested "failed to compile" +} else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj.c b/gdb/testsuite/gdb.base/tls-multiobj.c new file mode 100644 index 0000000..dd4aadb --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj.c @@ -0,0 +1,89 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +__thread int tls_main_tbss_1; +__thread int tls_main_tbss_2; +__thread int tls_main_tdata_1 = 96; +__thread int tls_main_tdata_2 = 97; + +extern __thread int tls_lib1_tbss_1; +extern __thread int tls_lib1_tbss_2; +extern __thread int tls_lib1_tdata_1; +extern __thread int tls_lib1_tdata_2; + +extern __thread int tls_lib2_tbss_1; +extern __thread int tls_lib2_tbss_2; +extern __thread int tls_lib2_tdata_1; +extern __thread int tls_lib2_tdata_2; + +extern __thread int tls_lib3_tbss_1; +extern __thread int tls_lib3_tbss_2; +extern __thread int tls_lib3_tdata_1; +extern __thread int tls_lib3_tdata_2; + +extern void lib1_func (); +extern void lib2_func (); +extern void lib3_func (); + +volatile int data; + +void +use_it (int a) +{ + data = a; +} + +int +main (int argc, char **argv) +{ + use_it (-1); + + tls_main_tbss_1 = 51; /* main-breakpoint-1 */ + tls_main_tbss_2 = 52; + tls_main_tdata_1 = 53; + tls_main_tdata_2 = 54; + + tls_lib1_tbss_1 = 151; + tls_lib1_tbss_2 = 152; + tls_lib1_tdata_1 = 153; + tls_lib1_tdata_2 = 154; + + tls_lib2_tbss_1 = 251; + tls_lib2_tbss_2 = 252; + tls_lib2_tdata_1 = 253; + tls_lib2_tdata_2 = 254; + + tls_lib3_tbss_1 = 351; + tls_lib3_tbss_2 = 352; + tls_lib3_tdata_1 = 353; + tls_lib3_tdata_2 = 354; + + lib1_func (); + lib2_func (); + lib3_func (); + + /* Attempt to keep variables in the main program from being optimized + away. */ + use_it (tls_main_tbss_1); + use_it (tls_main_tbss_2); + use_it (tls_main_tdata_1); + use_it (tls_main_tdata_2); + + use_it (100); /* main-breakpoint-2 */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj.exp b/gdb/testsuite/gdb.base/tls-multiobj.exp new file mode 100644 index 0000000..eb3721e --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj.exp @@ -0,0 +1,232 @@ +# Copyright 2024-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. + +# Using different compilation/linking scenarios, attempt to access +# thread-local variables in a non-threaded program using multiple +# shared objects. + +source $srcdir/$subdir/tls-common.exp.tcl + +standard_testfile + +set lib1src "${srcdir}/${subdir}/${testfile}1.c" +set lib2src "${srcdir}/${subdir}/${testfile}2.c" +set lib3src "${srcdir}/${subdir}/${testfile}3.c" + +set lib1obj [standard_output_file "${testfile}1-lib.so"] +set lib2obj [standard_output_file "${testfile}2-lib.so"] +set lib3obj [standard_output_file "${testfile}3-lib.so"] + +proc do_tests {force_internal_tls {do_kfail_tls_access 0}} { + clean_restart + gdb_load $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + if { $do_kfail_tls_access && [istarget "*-*-linux*"] } { + # Turn off do_kfail_tls_access when libthread_db is loaded. + # This can happen for the default case when testing x86_64 + # w/ -m32 using glibc versions 2.34 or newer. + gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" { + -re -wrap "libthread_db integrity checks passed." { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "No libthread_db loaded" { + pass $gdb_test_name + } + } + # Also turn off do_kfail_tls_access when connected to a + # gdbserver and we observe that accessing a TLS variable + # works. + if [target_is_gdbserver] { + gdb_test_multiple "print tls_main_tbss_1" \ + "Check TLS accessibility when connected to a gdbserver" { + -re -wrap "= 0" { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "Remote target failed to process qGetTLSAddr request" { + pass $gdb_test_name + } + } + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + set t $do_kfail_tls_access + set m "tls not available" + with_test_prefix "before assignments" { + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 96" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 97" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 196" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 197" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 296" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 297" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 396" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 397" $t $m + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "after assignments" { + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m + } + + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart + gdb_load $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m + gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m + gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m + gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m + + gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m + gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m + gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m + + gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m + gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m + gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m + + gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m + gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m + gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m + } +} + +if { [gdb_compile_shlib $lib1src $lib1obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $lib2src $lib2obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} +if { [gdb_compile_shlib $lib3src $lib3obj {debug}] != "" } { + untested "failed to compile shared object" + return -1 +} + +# Certain linux target architectures implement support for internal +# TLS lookup which is used when thread stratum support (via +# libthread_db) is missing or when the linux-only GDB maintenance +# setting 'force-internal-tls-address-lookup' is 'on'. Thus for some +# of the testing scenarios, such as statically linked executables, +# this internal support will be used. Set 'do_kfail_tls_access' to 1 +# for those architectures which don't implement internal tls support. +if {[istarget *-*-linux*] + && ![is_any_target {*}$internal_tls_linux_targets]} { + set do_kfail_tls_access 1 +} elseif {[istarget *-*-linux*] && [is_x86_like_target]} { + # This covers the case of x86_64 with -m32: + set do_kfail_tls_access 1 +} else { + set do_kfail_tls_access 0 +} + +set binprefix $binfile + +with_test_prefix "default" { + set binfile $binprefix-default + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib=${lib1obj} \ + shlib=${lib2obj} \ + shlib=${lib3obj}]] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + # Depending on glibc version, it might not be appropriate + # for do_kfail_tls_access to be set here. That will be + # handled in 'do_tests', disabling it if necessary. + # + # Specifically, glibc versions 2.34 and later have the + # thread library (and libthread_db availability) in + # programs not linked against libpthread.so + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "pthreads" { + set binfile $binprefix-pthreads + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ + [list debug shlib=${lib1obj} \ + shlib=${lib2obj} \ + shlib=${lib3obj}]] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } + } +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj1.c b/gdb/testsuite/gdb.base/tls-multiobj1.c new file mode 100644 index 0000000..6207173 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj1.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +__thread int tls_lib1_tbss_1; +__thread int tls_lib1_tbss_2; +__thread int tls_lib1_tdata_1 = 196; +__thread int tls_lib1_tdata_2 = 197; + +void +lib1_func () +{ +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj2.c b/gdb/testsuite/gdb.base/tls-multiobj2.c new file mode 100644 index 0000000..9ff8b67 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj2.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +__thread int tls_lib2_tbss_1; +__thread int tls_lib2_tbss_2; +__thread int tls_lib2_tdata_1 = 296; +__thread int tls_lib2_tdata_2 = 297; + +void +lib2_func () +{ +} diff --git a/gdb/testsuite/gdb.base/tls-multiobj3.c b/gdb/testsuite/gdb.base/tls-multiobj3.c new file mode 100644 index 0000000..3594eba0 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj3.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +__thread int tls_lib3_tbss_1; +__thread int tls_lib3_tbss_2; +__thread int tls_lib3_tdata_1 = 396; +__thread int tls_lib3_tdata_2 = 397; + +void +lib3_func () +{ +} diff --git a/gdb/testsuite/gdb.base/tls-nothreads.c b/gdb/testsuite/gdb.base/tls-nothreads.c new file mode 100644 index 0000000..cac20f8 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-nothreads.c @@ -0,0 +1,57 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-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/>. */ + +__thread int tls_tbss_1; +__thread int tls_tbss_2; +__thread int tls_tbss_3; + +__thread int tls_tdata_1 = 21; +__thread int tls_tdata_2 = 22; +__thread int tls_tdata_3 = 23; + +volatile int data; + +void +use_it (int a) +{ + data = a; +} + +int +main (int argc, char **argv) +{ + use_it (-1); + + tls_tbss_1 = 24; /* main-breakpoint-1 */ + tls_tbss_2 = 25; + tls_tbss_3 = 26; + + tls_tdata_1 = 42; + tls_tdata_2 = 43; + tls_tdata_3 = 44; + + use_it (tls_tbss_1); + use_it (tls_tbss_2); + use_it (tls_tbss_3); + use_it (tls_tdata_1); + use_it (tls_tdata_2); + use_it (tls_tdata_3); + + use_it (100); /* main-breakpoint-2 */ + + return 0; +} diff --git a/gdb/testsuite/gdb.base/tls-nothreads.exp b/gdb/testsuite/gdb.base/tls-nothreads.exp new file mode 100644 index 0000000..c7b1476 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-nothreads.exp @@ -0,0 +1,251 @@ +# Copyright 2024-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. + +# Using different compilation/linking scenarios, attempt to access +# thread-local variables in a non-threaded program. Also test that +# GDB internal TLS lookup works correctly. + +source $srcdir/$subdir/tls-common.exp.tcl + +standard_testfile + +proc do_tests {force_internal_tls {do_kfail_tls_access 0}} { + clean_restart + gdb_load $::binfile + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + if { $do_kfail_tls_access && [istarget "*-*-linux*"] } { + # Turn off do_kfail_tls_access when libthread_db is loaded. + # This can happen for the default case when testing x86_64 + # w/ -m32 using glibc versions 2.34 or newer. + gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" { + -re -wrap "libthread_db integrity checks passed." { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "No libthread_db loaded" { + pass $gdb_test_name + } + } + # Also turn off do_kfail_tls_access when connected to a + # gdbserver and we observe that accessing a TLS variable + # works. + if [target_is_gdbserver] { + gdb_test_multiple "print tls_tbss_1" "Check TLS accessibility when connected to a gdbserver" { + -re -wrap "= 0" { + set do_kfail_tls_access 0 + pass $gdb_test_name + } + -re -wrap "Remote target failed to process qGetTLSAddr request" { + pass $gdb_test_name + } + } + } + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"] + gdb_continue_to_breakpoint "main-breakpoint-1" + + set t $do_kfail_tls_access + set m "tls not available" + with_test_prefix "before assignments" { + gdb_test_with_kfail "print tls_tbss_1" ".* = 0" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 0" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 0" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 21" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 22" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 23" $t $m + } + + gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"] + gdb_continue_to_breakpoint "main-breakpoint-2" + + with_test_prefix "after assignments" { + gdb_test_with_kfail "print tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 44" $t $m + } + + # Make a core file now, but save testing using it until the end + # in case core files are not supported. + set corefile ${::binfile}.core + set core_supported 0 + if { ![is_remote host] } { + set core_supported [gdb_gcore_cmd $corefile "save corefile"] + } + + # Now continue to end and see what happens when attempting to + # access a TLS variable when the program is no longer running. + gdb_continue_to_end + with_test_prefix "after exit" { + gdb_test "print tls_tbss_1" \ + "Cannot (?:read|find address of TLS symbol) `tls_tbss_1' without registers" + } + + with_test_prefix "stripped" { + set binfile_stripped "${::binfile}.stripped" + set objcopy [gdb_find_objcopy] + set cmd "$objcopy --strip-debug ${::binfile} $binfile_stripped" + if ![catch "exec $cmd" cmd_output] { + clean_restart + gdb_load $binfile_stripped + if ![runto_main] { + return + } + + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + # While there are no debug (e.g. DWARF) symbols, there + # are minimal symbols, so we should be able to place a + # breakpoint in use_it and continue to it. Continuing + # twice should put us past the assignments, at which point + # we can see if the TLS variables are still accessible. + gdb_test "break use_it" "Breakpoint 2 at $::hex" + gdb_test "continue" "Breakpoint 2, $::hex in use_it.*" + gdb_test "continue" "Breakpoint 2, $::hex in use_it.*" "continue 2" + + # Note that a cast has been added in order to avoid the + # "...has unknown type; cast it to its declared type" + # problem. + gdb_test_with_kfail "print (int) tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print (int) tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print (int) tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print (int) tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print (int) tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print (int) tls_tdata_3" ".* = 44" $t $m + + # Get rid of the "use_it" breakpoint + gdb_test_no_output "del 2" + + # Continue to program exit + gdb_continue_to_end + + # TLS variables should not be accessible after program exit + # (This case initially caused GDB to crash during development + # of GDB-internal TLS lookup support.) + with_test_prefix "after exit" { + gdb_test "print (int) tls_tbss_1" \ + "Cannot find address of TLS symbol `tls_tbss_1' without registers" + } + } + } + + # Finish test early if no core file was made. + if !$core_supported { + return + } + + clean_restart + gdb_load $::binfile + + set core_loaded [gdb_core_cmd $corefile "load corefile"] + if { $core_loaded == -1 } { + return + } + + with_test_prefix "core file" { + if $force_internal_tls { + gdb_test_no_output "maint set force-internal-tls-address-lookup on" + } + + gdb_test_with_kfail "print tls_tbss_1" ".* = 24" $t $m + gdb_test_with_kfail "print tls_tbss_2" ".* = 25" $t $m + gdb_test_with_kfail "print tls_tbss_3" ".* = 26" $t $m + + gdb_test_with_kfail "print tls_tdata_1" ".* = 42" $t $m + gdb_test_with_kfail "print tls_tdata_2" ".* = 43" $t $m + gdb_test_with_kfail "print tls_tdata_3" ".* = 44" $t $m + } +} + +# Certain linux target architectures implement support for internal +# TLS lookup which is used when thread stratum support (via +# libthread_db) is missing or when the linux-only GDB maintenance +# setting 'force-internal-tls-address-lookup' is 'on'. Thus for some +# of the testing scenarios, such as statically linked executables, +# this internal support will be used. Set 'do_kfail_tls_access' to 1 +# for those architectures which don't implement internal TLS support. +if {[istarget *-*-linux*] + && ![is_any_target {*}$internal_tls_linux_targets]} { + set do_kfail_tls_access 1 +} elseif {[istarget *-*-linux*] && [is_x86_like_target]} { + # This covers the case of x86_64 with -m32: + set do_kfail_tls_access 1 +} else { + set do_kfail_tls_access 0 +} + +set binprefix $binfile + +with_test_prefix "default" { + set binfile $binprefix-default + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + # Depending on glibc version, it might not be appropriate + # for do_kfail_tls_access to be set here. That will be + # handled in 'do_tests', disabling it if necessary. + # + # Specifically, glibc versions 2.34 and later have the + # thread library (and libthread_db availability) in + # programs not linked against libpthread.so + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "static" { + set binfile $binprefix-static + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} + +with_test_prefix "pthreads" { + set binfile $binprefix-pthreads + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls + } + } +} + +with_test_prefix "pthreads-static" { + set binfile $binprefix-pthreads-static + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } { + untested "failed to compile" + } else { + foreach_with_prefix force_internal_tls $internal_tls_iters { + do_tests $force_internal_tls $do_kfail_tls_access + } + } +} diff --git a/gdb/testsuite/gdb.base/twice.exp b/gdb/testsuite/gdb.base/twice.exp index 6f49c46..995cd4d 100644 --- a/gdb/testsuite/gdb.base/twice.exp +++ b/gdb/testsuite/gdb.base/twice.exp @@ -32,7 +32,8 @@ if { [gdb_compile $local_srcfile "${binfile}" executable $options] != "" } { # Start with a fresh gdb. -clean_restart $binfile +clean_restart +gdb_load $binfile if {[runto_main]} { # Test that GDB can still detect whether we have line numbers diff --git a/gdb/testsuite/gdb.base/type-opaque.exp b/gdb/testsuite/gdb.base/type-opaque.exp index da060b9..f5d8582 100644 --- a/gdb/testsuite/gdb.base/type-opaque.exp +++ b/gdb/testsuite/gdb.base/type-opaque.exp @@ -32,7 +32,8 @@ if { [gdb_compile_shlib $libsrc $libobj {debug}] != "" return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_load_shlib ${libobj} if {![runto_main]} { diff --git a/gdb/testsuite/gdb.base/unload.exp b/gdb/testsuite/gdb.base/unload.exp index 0761f27..b2d848d 100644 --- a/gdb/testsuite/gdb.base/unload.exp +++ b/gdb/testsuite/gdb.base/unload.exp @@ -50,7 +50,8 @@ if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $lib_sl gdb_load_shlib $lib_sl2 diff --git a/gdb/testsuite/gdb.base/until-trailing-insns.exp b/gdb/testsuite/gdb.base/until-trailing-insns.exp index a3701f2..cc28adc 100644 --- a/gdb/testsuite/gdb.base/until-trailing-insns.exp +++ b/gdb/testsuite/gdb.base/until-trailing-insns.exp @@ -100,16 +100,16 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name until-trailing-isns.c} - {stmt_list $L DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_language @DW_LANG_C + DW_AT_name until-trailing-isns.c + DW_AT_stmt_list $L DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc $main_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len DW_FORM_data4 } } } diff --git a/gdb/testsuite/gdb.base/user-namespace-attach.c b/gdb/testsuite/gdb.base/user-namespace-attach.c new file mode 100644 index 0000000..684ce1c --- /dev/null +++ b/gdb/testsuite/gdb.base/user-namespace-attach.c @@ -0,0 +1,35 @@ +/* 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/>. */ + +#include <sys/types.h> +#include <unistd.h> +#include <stdio.h> + +volatile int spin_p = 1; + +int +main () +{ + alarm (60); + + printf ("pid = %lld\n", ((long long) getpid ())); + + while (spin_p) + sleep (1); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/user-namespace-attach.exp b/gdb/testsuite/gdb.base/user-namespace-attach.exp new file mode 100644 index 0000000..741093c --- /dev/null +++ b/gdb/testsuite/gdb.base/user-namespace-attach.exp @@ -0,0 +1,148 @@ +# 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/>. + +# Check that GDB can attach to a process started using 'unshare'. The +# inferior is started in a separate mnt namespace. + +require can_spawn_for_attach + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile] == -1} { + return +} + +# This test relies (at least in some parts) on the sysroot being +# 'target:'. Grab the current sysroot now so we can skip those tests +# if the board file has changed the sysroot. +set sysroot "" +set test "show sysroot" +gdb_test_multiple $test $test { + -re -wrap "The current system root is \"(.*)\"\\." { + set sysroot $expect_out(1,string) + } +} + +# Start a process using 'unshare FLAGS', then attach to the process +# from GDB. Check that the attach worked as expected. +proc run_test { flags } { + + # If FLAGS contains '--mount' then a separate mnt namespace will + # be created, in which case the executable will have been read + # from the 'target:'. Otherwise, the executable will have been + # read from the local filesystem, and there will be no prefix. + # + # Of course, this only applies if the sysroot is 'target:', some + # boards change this, so skip these tests on those boards. + if { [lsearch -exact [split $flags " "] "--mount"] != -1 } { + if { $::sysroot ne "target:" } { + return + } + + set prefix "target:" + } else { + set prefix "" + } + + set unshare_cmd "unshare $flags" + + # Run '/bin/true' using UNSHARE_CMD. If the flags in UNSHARE_CMD + # aren't supported then this will fail, this means we shouldn't + # spawn the command with our test executable and try attaching. + # + # This will also fail if /bin/true isn't present, or doesn't work + # as we expect. But this should be fine for many targets. + set res [remote_exec target "$unshare_cmd /bin/true"] + if { [lindex $res 0] != 0 } { + unsupported "unshare flags not supported" + return + } + + set inferior_spawn_id \ + [spawn_wait_for_attach [list "$unshare_cmd $::binfile"]] + if { $inferior_spawn_id == -1 } { + unsupported "failed to spawn for attach" + return + } + + set inferior_pid [spawn_id_get_pid $inferior_spawn_id] + + clean_restart + + set saw_bad_warning false + gdb_test_multiple "attach $inferior_pid" "attach to inferior" { + -re "^attach $::decimal\r\n" { + exp_continue + } + + -re "^warning: \[^\r\n\]+: could not open as an executable file: \[^\r\n\]+\r\n" { + set saw_bad_warning true + exp_continue + } + + -re "^warning: \[^\r\n\]+: can't open to read symbols: \[^\r\n\]+\r\n" { + set saw_bad_warning true + exp_continue + } + + -re "^warning: Could not load vsyscall page because no executable was specified\r\n" { + # This warning is a secondary consequence of the above bad + # warnings, so don't count this as a bad warnings, ignore + # it instead. + exp_continue + } + + -re "^warning:\\s+$::decimal\\s*\[^\r\n\]+: No such file or directory\r\n" { + # This unrelated warning is seen when GDB stops in libc, + # and the source code for libc is not available. + exp_continue + } + + -re "^warning: \[^\r\n\]+\r\n" { + # If we ignore "other" warnings then, should the above + # warnings strings change we'll start ignoring the bad + # warnings, and the test will appear to pass. + # + # If you are seeing a warning here that really has nothing + # to do with the test failing, then the correct solution + # is to add a new regexp to specifically match _that_ + # warning, and ignore it. + set saw_bad_warning true + exp_continue + } + + -re "^$::gdb_prompt $" { + gdb_assert { !$saw_bad_warning } $gdb_test_name + } + + -re "^\[^\r\n\]*\r\n" { + exp_continue + } + } + + # Ensure GDB could access the executable. + set binfile_re [string_to_regexp $::binfile] + gdb_test "info inferiors" \ + "\r\n\\*\\s+$::decimal\\s+\[^\r\n\]+\\s+${prefix}${binfile_re}\\s*" +} + +set test_flags [list \ + "--mount --map-root-user" \ + "--user" \ + "--user --map-root-user"] + +foreach_with_prefix flags $test_flags { + run_test $flags +} diff --git a/gdb/testsuite/gdb.base/varargs.exp b/gdb/testsuite/gdb.base/varargs.exp index a34a578..534971c 100644 --- a/gdb/testsuite/gdb.base/varargs.exp +++ b/gdb/testsuite/gdb.base/varargs.exp @@ -49,7 +49,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart +gdb_load $binfile gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.base/vfork-follow-parent.exp b/gdb/testsuite/gdb.base/vfork-follow-parent.exp index fca2993..8cb785d 100644 --- a/gdb/testsuite/gdb.base/vfork-follow-parent.exp +++ b/gdb/testsuite/gdb.base/vfork-follow-parent.exp @@ -19,6 +19,8 @@ # schedule-multiple on" or "set detach-on-fork on". Test these two resolution # methods. +require allow_fork_tests + standard_testfile .c vforked-prog.c set binfile ${testfile}-exit diff --git a/gdb/testsuite/gdb.base/watch-before-fork.exp b/gdb/testsuite/gdb.base/watch-before-fork.exp index 074cfbd..509561e 100644 --- a/gdb/testsuite/gdb.base/watch-before-fork.exp +++ b/gdb/testsuite/gdb.base/watch-before-fork.exp @@ -20,6 +20,8 @@ # This test uses "awatch". require allow_hw_watchpoint_access_tests +require allow_fork_tests + standard_testfile if {[build_executable "failed to prepare" $testfile $srcfile debug]} { diff --git a/gdb/testsuite/gdb.base/watch-vfork.exp b/gdb/testsuite/gdb.base/watch-vfork.exp index 1bc61bc..503727d 100644 --- a/gdb/testsuite/gdb.base/watch-vfork.exp +++ b/gdb/testsuite/gdb.base/watch-vfork.exp @@ -17,6 +17,8 @@ standard_testfile .c +require allow_fork_tests + if { [build_executable ${testfile}.exp ${testfile} $srcfile {debug}] } { untested "failed to compile" return -1 diff --git a/gdb/testsuite/gdb.base/watch_thread_num.exp b/gdb/testsuite/gdb.base/watch_thread_num.exp index 4a5c1c2..e1b54c0 100644 --- a/gdb/testsuite/gdb.base/watch_thread_num.exp +++ b/gdb/testsuite/gdb.base/watch_thread_num.exp @@ -31,7 +31,8 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart +gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp b/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp index b3892f3..afdb82e 100644 --- a/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp +++ b/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp @@ -26,29 +26,19 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { return -1 } -if ![runto_main] { - return -1 -} +set test_spawn_id [spawn_wait_for_attach $binfile] +set testpid [spawn_id_get_pid $test_spawn_id] -# Run to the point where mypid in the test program has been -# populated. -gdb_breakpoint [gdb_get_line_number "pidacquired"] -gdb_continue_to_breakpoint "pidacquired" - -# Get the PID of the test process. -set testpid [get_integer_valueof "mypid" 0] +gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach once" gdb_test "detach" "Detaching from program: .*, process $testpid\r\n\\\[Inferior $decimal \\(process $testpid\\) detached\\\]" -if {$testpid == ""} { - return -1 -} - # A clean restart is needed to force the hardware watchpoint setup # logic to run post attach rather than post inferior launch. -clean_restart $binfile +clean_restart +gdb_load $binfile -gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach" +gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach twice" # Ensure the test program is in the top frame so the required # variables are in scope. @@ -62,3 +52,5 @@ gdb_test "watch watched_variable" \ gdb_test "continue" \ "continue.*Continuing.*\.Hardware watchpoint $decimal: watched_variable.*Old value = 0.*New value = 4.*watched_variable\\);" + +kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.base/watchpoint-running.exp b/gdb/testsuite/gdb.base/watchpoint-running.exp index 1a5f9c3..04c4c52 100644 --- a/gdb/testsuite/gdb.base/watchpoint-running.exp +++ b/gdb/testsuite/gdb.base/watchpoint-running.exp @@ -43,7 +43,8 @@ proc test {stop_mode hw} { # default. append ::GDBFLAGS " -ex \"maint set target-non-stop on\"" } - clean_restart $::binfile + clean_restart + gdb_load $::binfile } gdb_test_no_output "set can-use-hw-watchpoints $hw" diff --git a/gdb/testsuite/gdb.base/watchpoint-solib.exp b/gdb/testsuite/gdb.base/watchpoint-solib.exp index 28b8d08..7f58a83 100644 --- a/gdb/testsuite/gdb.base/watchpoint-solib.exp +++ b/gdb/testsuite/gdb.base/watchpoint-solib.exp @@ -49,7 +49,8 @@ if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != "" return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_load_shlib $lib_sl runto_main diff --git a/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp index 2bedcaa..163ec3b 100644 --- a/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp +++ b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp @@ -129,7 +129,8 @@ proc test {always_inserted} { with_test_prefix "always-inserted $always_inserted" { - clean_restart $binfile + clean_restart + gdb_load $binfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.c b/gdb/testsuite/gdb.base/watchpoint-unaligned.c index d3c1349..ca2fa45 100644 --- a/gdb/testsuite/gdb.base/watchpoint-unaligned.c +++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.c @@ -18,6 +18,8 @@ #include <stdint.h> #include <assert.h> +static volatile int volatile_dummy; + static int again; static volatile struct @@ -53,6 +55,40 @@ write_size8twice (void) data.u.size8twice[offset] = first; data.u.size8twice[offset + 1] = second; #endif + + /* Setting a breakpoint on an instruction after an instruction triggering a + watchpoint makes it ambiguous which one will be reported. + Insert a dummy instruction in between to make sure the watchpoint gets + reported. */ + volatile_dummy = 1; + + return; /* write_size8twice_return */ +} + +static void +read_size8twice (void) +{ + static uint64_t volatile first; + static uint64_t volatile second; + +#ifdef __aarch64__ + volatile void *p = &data.u.size8twice[offset]; + asm volatile ("ldp %0, %1, [%2]" + : "=r" (first), "=r" (second) /* output */ + : "r" (p) /* input */ + : /* clobber */); +#else + first = data.u.size8twice[offset]; + second = data.u.size8twice[offset + 1]; +#endif + + /* Setting a breakpoint on an instruction after an instruction triggering a + watchpoint makes it ambiguous which one will be reported. + Insert a dummy instruction inbetween to make sure the watchpoint gets + reported. */ + volatile_dummy = 1; + + return; /* read_size8twice_return */ } int @@ -63,6 +99,7 @@ main (void) assert (sizeof (data) == 8 + 3 * 8); write_size8twice (); + read_size8twice (); while (size) { diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp index 9220402..85b1eb7 100644 --- a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp +++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp @@ -151,6 +151,63 @@ foreach_with_prefix wpcount {4 7} { gdb_assert $got_hit $test } +proc size8twice { function cmd offset index } { + clean_restart $::testfile + + if { ![runto $function] } { + return -1 + } + + # Set offset in the inferior. + gdb_test_no_output "set var offset = $offset" + + # Set a breakpoint. + set bp_src_string "${function}_return" + set bp_loc [gdb_get_line_number $bp_src_string] + gdb_breakpoint $bp_loc \ + "Breakpoint $::decimal at $::hex" "$bp_src_string" + + # Set a hardware watchpoint. + set watch_index [expr $offset + $index] + set test "$cmd data.u.size8twice\[$watch_index\]" + set wpnum 0 + gdb_test_multiple $test "" { + -re -wrap "Hardware (read )?watchpoint ($::decimal): .*" { + set wpnum $expect_out(2,string) + pass $gdb_test_name + } + -re -wrap "Watchpoint ($::decimal): .*" { + if {[istarget "arm*-*-*"]} { + untested $gdb_test_name + } else { + fail $gdb_test_name + } + } + } + + if { ! $wpnum } { + # No hardware watchpoint, we're done. + return 0 + } + + # Try to trigger the hardware watchpoint. + set got_hit 0 + gdb_test_multiple "continue" "" { + -re -wrap "\r\nCould not insert hardware watchpoint .*" { + } + -re -wrap "Hardware (read )?watchpoint $wpnum:.*(New value|Value) = .*" { + set got_hit 1 + send_gdb "continue\n" + exp_continue + } + -re -wrap " $bp_src_string .*" { + } + } + gdb_assert { $got_hit } + + return $got_hit +} + # We've got an array with 3 8-byte elements. Do a store of 16 bytes, # to: # - elements 0 and 1 (offset == 0), and @@ -158,49 +215,21 @@ foreach_with_prefix wpcount {4 7} { # For each case, check setting a watchpoint at: # - the first written element (index == 0), and # - the second element (index == 1). -foreach_with_prefix offset { 0 1 } { - foreach_with_prefix index { 0 1 } { - - clean_restart $binfile - - if ![runto_main] { - return -1 - } - - gdb_test_no_output "set var offset = $offset" - gdb_breakpoint [gdb_get_line_number "final_return"] \ - "Breakpoint $decimal at $hex" "final_return" - set watch_index [expr $offset + $index] - set test "watch data.u.size8twice\[$watch_index\]" - set wpnum 0 - gdb_test_multiple $test $test { - -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { - set wpnum $expect_out(1,string) - pass $gdb_test_name - } - -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { - if {[istarget "arm*-*-*"]} { - untested $gdb_test_name - } else { - fail $gdb_test_name - } +foreach_with_prefix fun { write_size8twice read_size8twice } { + if { $fun == "write_size8twice" } { + set cmd "watch" + } else { + set cmd "rwatch" + } + foreach_with_prefix offset { 0 1 } { + foreach_with_prefix index { 0 1 } { + set res [size8twice $fun $cmd $offset $index] + if { $res != 1 } { + break } } - if {$wpnum} { - set test "continue" - set got_hit 0 - gdb_test_multiple $test $test { - -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { - } - -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" { - set got_hit 1 - send_gdb "continue\n" - exp_continue - } - -re " final_return .*\r\n$gdb_prompt $" { - } - } - gdb_assert $got_hit "size8twice write" + if { $res != 1 } { + break } } } diff --git a/gdb/testsuite/gdb.base/watchpoints.exp b/gdb/testsuite/gdb.base/watchpoints.exp index 37baa5e..d8e4d63 100644 --- a/gdb/testsuite/gdb.base/watchpoints.exp +++ b/gdb/testsuite/gdb.base/watchpoints.exp @@ -53,7 +53,8 @@ with_test_prefix "before inferior start" { # This will turn hardware watchpoints back on and delete the watchpoint # we just created. - clean_restart ${binfile} + clean_restart + gdb_load $binfile # Disable hardware watchpoints if necessary. if {!$allow_hw_watchpoint_tests_p} { diff --git a/gdb/testsuite/gdb.base/wchar.exp b/gdb/testsuite/gdb.base/wchar.exp index 70f738c..f0e4777 100644 --- a/gdb/testsuite/gdb.base/wchar.exp +++ b/gdb/testsuite/gdb.base/wchar.exp @@ -72,3 +72,7 @@ gdb_test "print repeat_p" "= $hex L\"A$cent$cent\"\.\.\." \ # From PR cli/14977, but here because it requires wchar_t. gdb_test "printf \"%ls\\n\", 0" "\\(null\\)" + +# From PR exp/33124 - a bug when converting escapes. +set wbs {L'\\'} +gdb_test "print $wbs" " = $decimal [string_to_regexp $wbs]" diff --git a/gdb/testsuite/gdb.base/with-mf.exp b/gdb/testsuite/gdb.base/with-mf.exp index 564d5d7..3ac5e1d 100644 --- a/gdb/testsuite/gdb.base/with-mf.exp +++ b/gdb/testsuite/gdb.base/with-mf.exp @@ -29,7 +29,8 @@ if { [ensure_gdb_index $binfile] == -1 } { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile gdb_test "with language ada -- print g_s" \ " = \\(a => 1, b => 2, c => 3\\)" diff --git a/gdb/testsuite/gdb.base/with.exp b/gdb/testsuite/gdb.base/with.exp index a9b4a6c..d766e5d 100644 --- a/gdb/testsuite/gdb.base/with.exp +++ b/gdb/testsuite/gdb.base/with.exp @@ -25,7 +25,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug]} { return -1 } -clean_restart $binfile +clean_restart +gdb_load $binfile # Test "maint with". VALUES is a list of values. A nested "with" is # performed with each combination of pair of values from this list. @@ -178,7 +179,8 @@ with_test_prefix "user-defined" { # Check repeating. with_test_prefix "repeat" { - clean_restart $binfile + clean_restart + gdb_load $binfile # "with" with no command reinvokes the previous command. gdb_test "with language ada" \ @@ -209,7 +211,8 @@ with_test_prefix "repeat" { # Basic run control. with_test_prefix "run control" { - clean_restart $binfile + clean_restart + gdb_load $binfile if ![runto_main] { return diff --git a/gdb/testsuite/gdb.btrace/buffer-size.exp b/gdb/testsuite/gdb.btrace/buffer-size.exp index 3a54baa..16958ae 100644 --- a/gdb/testsuite/gdb.btrace/buffer-size.exp +++ b/gdb/testsuite/gdb.btrace/buffer-size.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/data.exp b/gdb/testsuite/gdb.btrace/data.exp index d42d017..4245157 100644 --- a/gdb/testsuite/gdb.btrace/data.exp +++ b/gdb/testsuite/gdb.btrace/data.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/delta.exp b/gdb/testsuite/gdb.btrace/delta.exp index 0807c58..64e965d 100644 --- a/gdb/testsuite/gdb.btrace/delta.exp +++ b/gdb/testsuite/gdb.btrace/delta.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/dlopen.exp b/gdb/testsuite/gdb.btrace/dlopen.exp index 092f4b0..1383bd9 100644 --- a/gdb/testsuite/gdb.btrace/dlopen.exp +++ b/gdb/testsuite/gdb.btrace/dlopen.exp @@ -33,7 +33,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/enable-new-thread.exp b/gdb/testsuite/gdb.btrace/enable-new-thread.exp index ee7c023..ab73d45 100644 --- a/gdb/testsuite/gdb.btrace/enable-new-thread.exp +++ b/gdb/testsuite/gdb.btrace/enable-new-thread.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/enable-running.exp b/gdb/testsuite/gdb.btrace/enable-running.exp index 1daa005..92ae566 100644 --- a/gdb/testsuite/gdb.btrace/enable-running.exp +++ b/gdb/testsuite/gdb.btrace/enable-running.exp @@ -29,7 +29,7 @@ save_vars { GDBFLAGS } { clean_restart $testfile } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/enable.exp b/gdb/testsuite/gdb.btrace/enable.exp index ad62733..cc48cc2 100644 --- a/gdb/testsuite/gdb.btrace/enable.exp +++ b/gdb/testsuite/gdb.btrace/enable.exp @@ -35,11 +35,11 @@ gdb_test "record instruction-history" "No recording is currently active\\..*" "r gdb_test "info record" "No recording is currently active\\." "info record without target" standard_testfile -if [prepare_for_testing "failed to prepare" $testfile {} {debug}] { +if {[prepare_for_testing "failed to prepare" $testfile {} {debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -78,20 +78,20 @@ gdb_exit load_lib gdbserver-support.exp require allow_gdbserver_tests clean_restart $testfile -if ![runto_main] { +if {![runto_main]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } # make sure record-btrace can be enabled after re-run clean_restart $testfile -if ![runto_main] { +if {![runto_main]} { return -1 } gdb_test_no_output "record btrace" "enable after restart" -if ![runto_main] { +if {![runto_main]} { return -1 } gdb_test_no_output "record btrace" "enable after re-run" diff --git a/gdb/testsuite/gdb.btrace/exception.exp b/gdb/testsuite/gdb.btrace/exception.exp index 67e9fbd..61a4bd9 100755 --- a/gdb/testsuite/gdb.btrace/exception.exp +++ b/gdb/testsuite/gdb.btrace/exception.exp @@ -22,12 +22,12 @@ require allow_btrace_tests # We expect a specific function call history. This gets messed up with # PIE on 32-bit. standard_testfile exception.cc -if [prepare_for_testing "failed to prepare" $testfile $srcfile \ - {nopie c++ debug}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ + {nopie c++ debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/function_call_history.exp b/gdb/testsuite/gdb.btrace/function_call_history.exp index e233936..325099a 100644 --- a/gdb/testsuite/gdb.btrace/function_call_history.exp +++ b/gdb/testsuite/gdb.btrace/function_call_history.exp @@ -22,11 +22,11 @@ require allow_btrace_tests # We expect a specific function call history. This gets messed up with # PIE on 32-bit. standard_testfile -if [prepare_for_testing "failed to prepare" $testfile {} {nopie debug}] { +if {[prepare_for_testing "failed to prepare" $testfile {} {nopie debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -226,7 +226,7 @@ gdb_test "record function-call-history /c 21, +11" [multi_line \ ] "indented" # make sure we can handle incomplete trace with respect to indentation -if ![runto_main] { +if {![runto_main]} { return -1 } # navigate to the fib in line 24 above diff --git a/gdb/testsuite/gdb.btrace/gcore.exp b/gdb/testsuite/gdb.btrace/gcore.exp index b9e96d4..6d7ba5c 100644 --- a/gdb/testsuite/gdb.btrace/gcore.exp +++ b/gdb/testsuite/gdb.btrace/gcore.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/instruction_history.exp b/gdb/testsuite/gdb.btrace/instruction_history.exp index 4e20194..fb68b33 100644 --- a/gdb/testsuite/gdb.btrace/instruction_history.exp +++ b/gdb/testsuite/gdb.btrace/instruction_history.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile .c .S -if [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}] { +if {[prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/multi-inferior.exp b/gdb/testsuite/gdb.btrace/multi-inferior.exp index ed2acb2..fc75233 100644 --- a/gdb/testsuite/gdb.btrace/multi-inferior.exp +++ b/gdb/testsuite/gdb.btrace/multi-inferior.exp @@ -24,17 +24,19 @@ require allow_btrace_tests +require allow_multi_inferior_tests + require !use_gdb_stub standard_testfile -if [prepare_for_testing "failed to prepare" $testfile {} {debug}] { +if {[prepare_for_testing "failed to prepare" $testfile {} {debug}]} { return -1 } set host_binfile [gdb_remote_download host $binfile] with_test_prefix "inferior 1" { - if ![runto_main] { + if {![runto_main]} { return -1 } } @@ -44,7 +46,7 @@ with_test_prefix "inferior 2" { "add second inferior" gdb_test "inferior 2" "Switching to inferior 2.*" - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -63,7 +65,7 @@ with_test_prefix "inferior 3" { "add third inferior" gdb_test "inferior 3" "Switching to inferior 3.*" - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/multi-thread-step.exp b/gdb/testsuite/gdb.btrace/multi-thread-step.exp index 9f4c6c0..7a769b5 100644 --- a/gdb/testsuite/gdb.btrace/multi-thread-step.exp +++ b/gdb/testsuite/gdb.btrace/multi-thread-step.exp @@ -26,7 +26,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debu } clean_restart $testfile -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/nohist.exp b/gdb/testsuite/gdb.btrace/nohist.exp index f573ed3..220a380 100644 --- a/gdb/testsuite/gdb.btrace/nohist.exp +++ b/gdb/testsuite/gdb.btrace/nohist.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/non-stop.exp b/gdb/testsuite/gdb.btrace/non-stop.exp index 856985c..bc5ebdb 100644 --- a/gdb/testsuite/gdb.btrace/non-stop.exp +++ b/gdb/testsuite/gdb.btrace/non-stop.exp @@ -28,7 +28,7 @@ save_vars { GDBFLAGS } { clean_restart $testfile } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/ptwrite.exp b/gdb/testsuite/gdb.btrace/ptwrite.exp index 0c2bb7c..5207488 100644 --- a/gdb/testsuite/gdb.btrace/ptwrite.exp +++ b/gdb/testsuite/gdb.btrace/ptwrite.exp @@ -21,7 +21,7 @@ require allow_btrace_ptw_tests allow_python_tests set opts {} -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.btrace/ptwrite.exp COMPILE=1" standard_testfile ptwrite.c lappend opts debug additional_flags=-mptwrite @@ -36,7 +36,7 @@ if [info exists COMPILE] { return -1 } -if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $opts]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/reconnect.exp b/gdb/testsuite/gdb.btrace/reconnect.exp index 15a0bca..44a9121 100644 --- a/gdb/testsuite/gdb.btrace/reconnect.exp +++ b/gdb/testsuite/gdb.btrace/reconnect.exp @@ -23,7 +23,7 @@ require allow_btrace_tests require allow_gdbserver_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/record_goto-step.exp b/gdb/testsuite/gdb.btrace/record_goto-step.exp index 10307a7..d881cf7 100644 --- a/gdb/testsuite/gdb.btrace/record_goto-step.exp +++ b/gdb/testsuite/gdb.btrace/record_goto-step.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/record_goto.exp b/gdb/testsuite/gdb.btrace/record_goto.exp index b1b3c09..f7dbe10 100644 --- a/gdb/testsuite/gdb.btrace/record_goto.exp +++ b/gdb/testsuite/gdb.btrace/record_goto.exp @@ -28,7 +28,7 @@ require allow_btrace_tests # Luckily, they are similar enough that a single test script can handle # both. set opts {} -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.btrace/record_goto.exp COMPILE=1" standard_testfile record_goto.c lappend opts debug @@ -43,11 +43,11 @@ if [info exists COMPILE] { return -1 } -if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $opts]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/rn-dl-bind.exp b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp index 6592b74c..22ce8e5 100644 --- a/gdb/testsuite/gdb.btrace/rn-dl-bind.exp +++ b/gdb/testsuite/gdb.btrace/rn-dl-bind.exp @@ -24,12 +24,12 @@ require allow_btrace_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile \ - {debug ldflags=-Wl,-z,lazy}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ + {debug ldflags=-Wl,-z,lazy}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/segv.exp b/gdb/testsuite/gdb.btrace/segv.exp index 628c155..509bcf1 100644 --- a/gdb/testsuite/gdb.btrace/segv.exp +++ b/gdb/testsuite/gdb.btrace/segv.exp @@ -20,10 +20,10 @@ require allow_btrace_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/step.exp b/gdb/testsuite/gdb.btrace/step.exp index 7852d65..e96714a 100644 --- a/gdb/testsuite/gdb.btrace/step.exp +++ b/gdb/testsuite/gdb.btrace/step.exp @@ -20,11 +20,11 @@ require allow_btrace_tests standard_testfile record_goto.c -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/stepi.exp b/gdb/testsuite/gdb.btrace/stepi.exp index 3684bef..a37d144 100644 --- a/gdb/testsuite/gdb.btrace/stepi.exp +++ b/gdb/testsuite/gdb.btrace/stepi.exp @@ -26,7 +26,7 @@ require allow_btrace_tests # # Luckily, they are similar enough that a single test script can handle # both. -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.btrace/stepi.exp COMPILE=1" standard_testfile record_goto.c lappend opts debug @@ -41,11 +41,11 @@ if [info exists COMPILE] { return -1 } -if [prepare_for_testing "failed to prepare" $testfile $srcfile {}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/tailcall-only.exp b/gdb/testsuite/gdb.btrace/tailcall-only.exp index c4f032a..5010d16 100644 --- a/gdb/testsuite/gdb.btrace/tailcall-only.exp +++ b/gdb/testsuite/gdb.btrace/tailcall-only.exp @@ -30,7 +30,7 @@ require allow_btrace_tests # Luckily, they are similar enough that a single test script can handle # both. set opts {} -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.btrace/tailcall-only.exp COMPILE=1" standard_testfile tailcall-only.c lappend opts debug optimize=-O2 @@ -45,11 +45,11 @@ if [info exists COMPILE] { return -1 } -if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $opts]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/tailcall.exp b/gdb/testsuite/gdb.btrace/tailcall.exp index 50d0a8b..d4d445c 100644 --- a/gdb/testsuite/gdb.btrace/tailcall.exp +++ b/gdb/testsuite/gdb.btrace/tailcall.exp @@ -27,7 +27,7 @@ require allow_btrace_tests # Luckily, they are similar enough that a single test script can handle # both. set opts {} -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.btrace/tailcall.exp COMPILE=1" standard_testfile tailcall.c lappend opts debug optimize=-O2 @@ -42,10 +42,10 @@ if [info exists COMPILE] { return -1 } -if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $opts]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/tsx.exp b/gdb/testsuite/gdb.btrace/tsx.exp index 168319b..6da3fa7 100644 --- a/gdb/testsuite/gdb.btrace/tsx.exp +++ b/gdb/testsuite/gdb.btrace/tsx.exp @@ -18,11 +18,11 @@ require allow_btrace_pt_tests allow_tsx_tests standard_testfile .c x86-tsx.S -if [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}] { +if {[prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" {debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/unknown_functions.exp b/gdb/testsuite/gdb.btrace/unknown_functions.exp index 61aed6f..0696d8b 100644 --- a/gdb/testsuite/gdb.btrace/unknown_functions.exp +++ b/gdb/testsuite/gdb.btrace/unknown_functions.exp @@ -25,12 +25,12 @@ standard_testfile # PIE on 32-bit. # # Also discard local symbols. -if [prepare_for_testing "failed to prepare" $testfile $srcfile \ - {ldflags=-Wl,-x nopie}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ + {ldflags=-Wl,-x nopie}]} { return -1 } -if ![runto test] { +if {![runto test]} { return -1 } diff --git a/gdb/testsuite/gdb.btrace/vdso.exp b/gdb/testsuite/gdb.btrace/vdso.exp index 1e19f99..0484da1 100644 --- a/gdb/testsuite/gdb.btrace/vdso.exp +++ b/gdb/testsuite/gdb.btrace/vdso.exp @@ -23,11 +23,11 @@ require allow_btrace_tests standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-cplus-print.exp b/gdb/testsuite/gdb.compile/compile-cplus-print.exp index d89bf61..e4e2782 100644 --- a/gdb/testsuite/gdb.compile/compile-cplus-print.exp +++ b/gdb/testsuite/gdb.compile/compile-cplus-print.exp @@ -22,7 +22,7 @@ require is_c_compiler_gcc require allow_compile_tests set options {} -if [test_compiler_info gcc*] { +if {[test_compiler_info gcc*]} { lappend options additional_flags=-g3 lappend options additional_flags=-std=gnu++11 lappend options c++ @@ -30,13 +30,14 @@ if [test_compiler_info gcc*] { set srcfilesoptions [list ${srcfile} ${options}] -if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { +if { [build_executable_from_specs $testfile.exp $testfile $options \ + {*}$srcfilesoptions] } { return -1 } clean_restart ${testfile} -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-cplus.exp b/gdb/testsuite/gdb.compile/compile-cplus.exp index a0f5cf0..66ac76f 100644 --- a/gdb/testsuite/gdb.compile/compile-cplus.exp +++ b/gdb/testsuite/gdb.compile/compile-cplus.exp @@ -39,7 +39,9 @@ if { $srcfile3 != "" } { } set srcfile4options "nodebug c++" lappend srcfilesoptions $srcfile4 $srcfile4options -if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { + +if { [build_executable_from_specs $testfile.exp $testfile $options \ + {*}$srcfilesoptions] } { return -1 } @@ -52,7 +54,7 @@ clean_restart ${testfile} gdb_test_no_output "set language c++" \ "Set language to C++" -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.exp b/gdb/testsuite/gdb.compile/compile-ifunc.exp index 068dce5..72c1142 100644 --- a/gdb/testsuite/gdb.compile/compile-ifunc.exp +++ b/gdb/testsuite/gdb.compile/compile-ifunc.exp @@ -24,7 +24,7 @@ standard_testfile require is_c_compiler_gcc set flags "" -if [test_compiler_info gcc*] { +if {[test_compiler_info gcc*]} { set flags additional_flags=-Wno-attribute-alias } diff --git a/gdb/testsuite/gdb.compile/compile-ops.exp b/gdb/testsuite/gdb.compile/compile-ops.exp index 410d5a4..c41c91e 100644 --- a/gdb/testsuite/gdb.compile/compile-ops.exp +++ b/gdb/testsuite/gdb.compile/compile-ops.exp @@ -375,36 +375,36 @@ Dwarf::assemble $asm_file { declare_labels int_label compile_unit { - {name file1.txt} - {language @DW_LANG_C} - {low_pc $func_start addr} - {high_pc $func_end addr} + DW_AT_name file1.txt + DW_AT_language @DW_LANG_C + DW_AT_low_pc $func_start addr + DW_AT_high_pc $func_end addr } { global program int_label: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } subprogram { - {external 1 flag} - {name func} - {low_pc $func_start addr} - {high_pc $func_end addr} + DW_AT_external 1 flag + DW_AT_name func + DW_AT_low_pc $func_start addr + DW_AT_high_pc $func_end addr } { formal_parameter { - {name param} - {variable_parameter 1 flag} - {type :$int_label} - {location $program SPECIAL_expr} + DW_AT_name param + DW_AT_variable_parameter 1 flag + DW_AT_type :$int_label + DW_AT_location $program SPECIAL_expr } formal_parameter { - {name optimized_out} - {variable_parameter 1 flag} - {type :$int_label} + DW_AT_name optimized_out + DW_AT_variable_parameter 1 flag + DW_AT_type :$int_label } } } @@ -416,7 +416,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -if ![runto func] { +if {![runto func]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-print.exp b/gdb/testsuite/gdb.compile/compile-print.exp index 4c90a71..2d3ad2f 100644 --- a/gdb/testsuite/gdb.compile/compile-print.exp +++ b/gdb/testsuite/gdb.compile/compile-print.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" "$testfile"] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-setjmp.exp b/gdb/testsuite/gdb.compile/compile-setjmp.exp index 73f6b8b..048d0a4 100644 --- a/gdb/testsuite/gdb.compile/compile-setjmp.exp +++ b/gdb/testsuite/gdb.compile/compile-setjmp.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" $testfile] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.compile/compile-tls.exp b/gdb/testsuite/gdb.compile/compile-tls.exp index aaa8e03..e7db1da 100644 --- a/gdb/testsuite/gdb.compile/compile-tls.exp +++ b/gdb/testsuite/gdb.compile/compile-tls.exp @@ -26,7 +26,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.compile/compile.exp b/gdb/testsuite/gdb.compile/compile.exp index ff20b2e..66ac182 100644 --- a/gdb/testsuite/gdb.compile/compile.exp +++ b/gdb/testsuite/gdb.compile/compile.exp @@ -32,7 +32,8 @@ if { $srcfile3 != "" } { lappend srcfilesoptions $srcfile3 ${options} } lappend srcfilesoptions $srcfile4 "nodebug" -if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } { +if { [build_executable_from_specs $testfile.exp $testfile $options \ + {*}$srcfilesoptions] } { return -1 } @@ -53,7 +54,7 @@ gdb_test "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \ "The program must be running for the compile command to work.*" \ "test compile file command without running inferior" -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -378,8 +379,9 @@ if { $srcfile3 != "" } { require allow_shlib_tests -set libbin [standard_output_file ${testfile}-shlib.so] -set binfile [standard_output_file ${testfile}-shlib] +set testfile $testfile-shlib +set libbin [standard_output_file $testfile.so] +set binfile [standard_output_file $testfile] if { [gdb_compile_shlib ${srcdir}/${subdir}/${srcfile2} $libbin {debug}] != "" || [gdb_compile ${srcdir}/${subdir}/${srcfile} $binfile executable \ @@ -387,10 +389,10 @@ if { [gdb_compile_shlib ${srcdir}/${subdir}/${srcfile2} $libbin {debug}] != "" return -1 } -clean_restart $binfile +clean_restart $testfile gdb_load_shlib $libbin -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.cp/call-c.exp b/gdb/testsuite/gdb.cp/call-c.exp index f99d171..6d240c8 100644 --- a/gdb/testsuite/gdb.cp/call-c.exp +++ b/gdb/testsuite/gdb.cp/call-c.exp @@ -27,7 +27,7 @@ if {[gdb_compile "$srcdir/$subdir/${srcfile2}" "${objfilec}" object {debug}] != return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main diff --git a/gdb/testsuite/gdb.cp/call-method-register.exp b/gdb/testsuite/gdb.cp/call-method-register.exp index dfd3ce0..b736312 100644 --- a/gdb/testsuite/gdb.cp/call-method-register.exp +++ b/gdb/testsuite/gdb.cp/call-method-register.exp @@ -45,59 +45,59 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $::srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $::srcfile + DW_AT_comp_dir /tmp } { declare_labels int_type_label struct_type_label \ struct_ptr_type_label set ptr_size [get_sizeof "void *" 96] DW_TAG_subprogram { - {name main} - {low_pc $main_start addr} - {high_pc $main_length data8} - {DW_AT_type :$int_type_label} + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_length data8 + DW_AT_type :$int_type_label } int_type_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } struct_type_label: DW_TAG_structure_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_name small} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_name small } { member { - {name xxx} - {type :$int_type_label} - {data_member_location 0 data1} + DW_AT_name xxx + DW_AT_type :$int_type_label + DW_AT_data_member_location 0 data1 } subprogram { - {name yyy} - {type :$int_type_label} + DW_AT_name yyy + DW_AT_type :$int_type_label } { formal_parameter { - {type :$struct_ptr_type_label} - {artificial 1 flag_present} + DW_AT_type :$struct_ptr_type_label + DW_AT_artificial 1 flag_present } } } struct_ptr_type_label: DW_TAG_pointer_type { - {DW_AT_byte_size $ptr_size DW_FORM_data1} - {type :$struct_type_label} + DW_AT_byte_size $ptr_size DW_FORM_data1 + DW_AT_type :$struct_type_label } DW_TAG_variable { - {DW_AT_name global_var} - {DW_AT_type :$struct_type_label} - {DW_AT_location { + DW_AT_name global_var + DW_AT_type :$struct_type_label + DW_AT_location { DW_OP_reg0 - } SPECIAL_expr} - {external 1 flag} + } SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.cp/chained-calls.cc b/gdb/testsuite/gdb.cp/chained-calls.cc index 9d12c98..9358c71 100644 --- a/gdb/testsuite/gdb.cp/chained-calls.cc +++ b/gdb/testsuite/gdb.cp/chained-calls.cc @@ -23,6 +23,8 @@ public: S operator+ (const S &s); + int get (); + int a; }; @@ -41,6 +43,12 @@ S::operator+ (const S &s) return res; } +int +S::get () +{ + return a; +} + S f (int i) { @@ -162,6 +170,8 @@ public: U (type t); type get_type (); + int get (); + int a; char c; type tp[2]; @@ -191,6 +201,12 @@ U::get_type () } int +U::get () +{ + return a; +} + +int main () { int i = g(f(0)); @@ -198,6 +214,7 @@ main () B b = makeb (); C c; + int z = f (42).get (); return i + getb(b, 0); /* Break here */ } diff --git a/gdb/testsuite/gdb.cp/chained-calls.exp b/gdb/testsuite/gdb.cp/chained-calls.exp index 4f0597a..d34162c 100644 --- a/gdb/testsuite/gdb.cp/chained-calls.exp +++ b/gdb/testsuite/gdb.cp/chained-calls.exp @@ -42,3 +42,6 @@ gdb_test "p *c" ".* = {a = 5678}" "*c" gdb_test "p *c + *c" ".* = {a = 11356}" "*c + *c" gdb_test "p q(*c + *c)" ".* = {a = 11356}" "q(*c + *c)" gdb_test "p make_int().get_type ()" ".* = INT" "make_int().get_type ()" +gdb_test "p f(42).get()" " = 42" "f().get()" +gdb_test "ptype f(42).get()" "type = int" "ptype f().get()" +gdb_test "ptype make_int().get()" "type = int" "make_int().get()" diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl index 1ac35af..5c3dfd6 100644 --- a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl +++ b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl @@ -28,17 +28,33 @@ proc test_breakpoint {func} { delete_breakpoints if { ! [gdb_breakpoint test_function] } { fail "set test_function breakpoint for $func" - } elseif { [gdb_test "continue" \ - "Continuing.\r\n\r\nBreakpoint $DEC+,.*test_function.*" \ - "continue to test_function for $func"] != 0 } { - } else { - gdb_breakpoint "$func" - set i [expr {[string last : $func] + 1}] - set efunc [string_to_regexp [string range $func $i end]] - gdb_test "continue" \ - "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \ - "continue to $func" + return + } + + # Accept any input between "Continuing" and the breakpoint hit, as + # on Cygwin, we may see a "New Thread" notification. This is the + # Cygwin runtime spawning its own internal threads. + if { [gdb_test "continue" \ + "Continuing.\r\n.*Breakpoint $DEC+,.*test_function.*" \ + "continue to test_function for $func"] != 0 } { + return } + + # On some systems, the in-charge and not-in-charge dtors of a + # class may end up with the same address, so setting a breakpoint + # at a dtor like base::~base only finds one location. On other + # systems (e.g. Cygwin), the two dtors for the same class may have + # different addresses, so we find two locations for the + # breakpoint. Thus, expect that the breakpoint hit may or may not + # report a location number. + set bp_re "$DEC+(\.$DEC+)?" + + gdb_breakpoint "$func" + set i [expr {[string last : $func] + 1}] + set efunc [string_to_regexp [string range $func $i end]] + gdb_test "continue" \ + "Continuing.\r\n.*Breakpoint $bp_re,.*$efunc.*" \ + "continue to $func" } # Add a function to the list of tested functions diff --git a/gdb/testsuite/gdb.cp/eval-reference-type.cc b/gdb/testsuite/gdb.cp/eval-reference-type.cc new file mode 100644 index 0000000..b177cbf --- /dev/null +++ b/gdb/testsuite/gdb.cp/eval-reference-type.cc @@ -0,0 +1,36 @@ +/* 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/>. */ + +/* Tests that expression evaluation does not return an error if one of + the operands is of reference type. */ + +struct +{ + int &get () + { + return x; + }; + + int x = 1; +} v_struct; + +int +main (void) +{ + v_struct.get () = 2; + return 0; +} diff --git a/gdb/testsuite/gdb.cp/eval-reference-type.exp b/gdb/testsuite/gdb.cp/eval-reference-type.exp new file mode 100644 index 0000000..4c7b3b7 --- /dev/null +++ b/gdb/testsuite/gdb.cp/eval-reference-type.exp @@ -0,0 +1,46 @@ +# 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/>. + +standard_testfile .cc + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return +} + +runto_main + +# Test for reference type. +gdb_test "print v_struct.get () == 1 && v_struct.get () == 2" \ + " = false" +gdb_test "print v_struct.get () == 1 || v_struct.get () == 2" \ + " = true" + +# Test for correct type resolution using 'ptype'. +gdb_test "ptype v_struct.get ()" \ + "type = int &" +gdb_test "ptype v_struct.get () == 1" \ + "type = bool" +gdb_test "ptype v_struct.get () + 1" \ + "type = int" +gdb_test "ptype v_struct.get () && 1" \ + "type = bool" +gdb_test "ptype v_struct.get () || 1" \ + "type = bool" +gdb_test "ptype !v_struct.get ()" \ + "type = bool" +gdb_test "ptype v_struct.get () ? 2 : 3" \ + "type = int" +gdb_test "ptype v_struct.get () | 1" \ + "type = int" diff --git a/gdb/testsuite/gdb.cp/gdb2384.exp b/gdb/testsuite/gdb.cp/gdb2384.exp index 204bdeb..a53ec3a 100644 --- a/gdb/testsuite/gdb.cp/gdb2384.exp +++ b/gdb/testsuite/gdb.cp/gdb2384.exp @@ -35,7 +35,7 @@ if { [gdb_compile_shlib $srcdir/$subdir/$srcfile2 $sofile {debug c++}] != "" return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_load_shlib ${sofile} diff --git a/gdb/testsuite/gdb.cp/incomplete-type-overload.exp b/gdb/testsuite/gdb.cp/incomplete-type-overload.exp index aa51fd9..aa582e0 100644 --- a/gdb/testsuite/gdb.cp/incomplete-type-overload.exp +++ b/gdb/testsuite/gdb.cp/incomplete-type-overload.exp @@ -57,105 +57,109 @@ Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {name $srcfile} - {stmt_list $L DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_stmt_list $L DW_FORM_sec_offset } { declare_labels int_label base_label complete_label incomplete_label declare_labels ptr_base_label ptr_inc_label ptr_comp_label ptr_int_label int_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } base_label: DW_TAG_class_type { - {DW_AT_byte_size $struct_base_size DW_FORM_sdata} - {DW_AT_name "base"} + DW_AT_byte_size $struct_base_size DW_FORM_sdata + DW_AT_name "base" } { DW_TAG_member { - {DW_AT_name "member"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 0 DW_FORM_sdata} + DW_AT_name "member" + DW_AT_type :$int_label + DW_AT_data_member_location 0 DW_FORM_sdata } } complete_label: DW_TAG_class_type { - {DW_AT_byte_size $struct_complete_size DW_FORM_sdata} - {DW_AT_name "complete"} + DW_AT_byte_size $struct_complete_size DW_FORM_sdata + DW_AT_name "complete" } { DW_TAG_inheritance { - {DW_AT_type :$base_label} - {DW_AT_data_member_location 0 DW_FORM_sdata} - {DW_AT_accessibility 1 DW_FORM_data1} + DW_AT_type :$base_label + DW_AT_data_member_location 0 DW_FORM_sdata + DW_AT_accessibility 1 DW_FORM_data1 } } incomplete_label: DW_TAG_class_type { - {DW_AT_name "incomplete"} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_name "incomplete" + DW_AT_declaration 1 DW_FORM_flag_present } ptr_base_label: DW_TAG_pointer_type { - {DW_AT_byte_size $addr_size DW_FORM_udata} - {DW_AT_type :$base_label} + DW_AT_byte_size $addr_size DW_FORM_udata + DW_AT_type :$base_label } ptr_inc_label: DW_TAG_pointer_type { - {DW_AT_byte_size $addr_size DW_FORM_udata} - {DW_AT_type :$incomplete_label} + DW_AT_byte_size $addr_size DW_FORM_udata + DW_AT_type :$incomplete_label } ptr_comp_label: DW_TAG_pointer_type { - {DW_AT_byte_size $addr_size DW_FORM_udata} - {DW_AT_type :$complete_label} + DW_AT_byte_size $addr_size DW_FORM_udata + DW_AT_type :$complete_label } ptr_int_label: DW_TAG_pointer_type { - {DW_AT_byte_size $addr_size DW_FORM_udata} - {DW_AT_type :$int_label} + DW_AT_byte_size $addr_size DW_FORM_udata + DW_AT_type :$int_label } DW_TAG_variable { - {DW_AT_name "comp"} - {DW_AT_type :$complete_label} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "comp"]} SPECIAL_expr} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "comp" + DW_AT_type :$complete_label + DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "comp"]}] \ + SPECIAL_expr + DW_AT_external 1 DW_FORM_flag } DW_TAG_variable { - {DW_AT_name "cp"} - {DW_AT_type :$ptr_comp_label} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "cp"]} SPECIAL_expr} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "cp" + DW_AT_type :$ptr_comp_label + DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "cp"]}] \ + SPECIAL_expr + DW_AT_external 1 DW_FORM_flag } DW_TAG_variable { - {DW_AT_name "inc"} - {DW_AT_type :$ptr_inc_label} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "inc"]} SPECIAL_expr} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "inc" + DW_AT_type :$ptr_inc_label + DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "inc"]}] \ + SPECIAL_expr + DW_AT_external 1 DW_FORM_flag } DW_TAG_variable { - {DW_AT_name "ip"} - {DW_AT_type :$ptr_int_label} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "ip"]} SPECIAL_expr} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "ip" + DW_AT_type :$ptr_int_label + DW_AT_location [subst {DW_OP_addr [gdb_target_symbol "ip"]}] \ + SPECIAL_expr + DW_AT_external 1 DW_FORM_flag } DW_TAG_subprogram { - {MACRO_AT_func {"main"}} - {DW_AT_external 1 flag} + MACRO_AT_func {"main"} + DW_AT_external 1 flag } DW_TAG_subprogram { - {MACRO_AT_func {"foo"}} - {DW_AT_type :$int_label} - {DW_AT_external 1 flag} + MACRO_AT_func {"foo"} + DW_AT_type :$int_label + DW_AT_external 1 flag } { formal_parameter { - {DW_AT_name "b"} - {DW_AT_type :$ptr_base_label} + DW_AT_name "b" + DW_AT_type :$ptr_base_label } } } diff --git a/gdb/testsuite/gdb.cp/infcall-nodebug.exp.tcl b/gdb/testsuite/gdb.cp/infcall-nodebug.exp.tcl index 0a7bc76..764d31d 100644 --- a/gdb/testsuite/gdb.cp/infcall-nodebug.exp.tcl +++ b/gdb/testsuite/gdb.cp/infcall-nodebug.exp.tcl @@ -71,9 +71,9 @@ proc build_and_run_test { lang symbols } { # Startup and run to main. - clean_restart $binfile + clean_restart $::testfile - if ![runto_main] then { + if { ![runto_main] } { return } diff --git a/gdb/testsuite/gdb.cp/method-ref-return.cc b/gdb/testsuite/gdb.cp/method-ref-return.cc new file mode 100644 index 0000000..4169bfe --- /dev/null +++ b/gdb/testsuite/gdb.cp/method-ref-return.cc @@ -0,0 +1,42 @@ +/* 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 that we can access class method/data member via reference. */ + +struct foo +{ + foo () : m_a (42) {} + int get_a () const { return m_a; } + int m_a; +}; + +struct bar +{ + bar () : m_foo () {} + const foo &get_foo () const { return m_foo; } + foo m_foo; +}; + +int +main (int argc, char *argv[]) +{ + bar b; + const foo &ref = b.get_foo (); + int ret = ref.m_a; // breakpoint here + ret += ref.get_a (); + return ret; +}
\ No newline at end of file diff --git a/gdb/testsuite/gdb.cp/method-ref-return.exp b/gdb/testsuite/gdb.cp/method-ref-return.exp new file mode 100644 index 0000000..1ac5ac9 --- /dev/null +++ b/gdb/testsuite/gdb.cp/method-ref-return.exp @@ -0,0 +1,70 @@ +# 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 calling methods and accessing members via reference. + +require allow_cplus_tests + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +# Set a breakpoint after the bar object is created and the reference is obtained. +gdb_breakpoint [gdb_get_line_number "breakpoint here"] +gdb_continue_to_breakpoint "after reference assignment" + +# Test that we can call the method through reference and get the expected result. +gdb_test_multiple "print b.get_foo()" "print method call returning reference" { + -re "\\$\[0-9\]+ = \\(const foo &\\) @$hex: \\{m_a = 42\\}\r\n$gdb_prompt $" { + pass $gdb_test_name + } + -re "Could not validate memory tag: Value can't be converted to integer\\." { + fail "$gdb_test_name" + } +} + +# Test accessing the member through the reference. +gdb_test "print b.get_foo ().m_a" \ + "\\$\[0-9\]+ = 42" \ + "print member access through reference" + +# Test calling method on the referenced object. +gdb_test "print b.get_foo ().get_a()" \ + "\\$\[0-9\]+ = 42" \ + "print method call on referenced object" + +# Test that the stored reference works correctly. +gdb_test_multiple "print ref" "print stored reference" { + -re "\\$\[0-9\]+ = \\(const foo &\\) @$hex: \\{m_a = 42\\}\r\n$gdb_prompt $" { + pass $gdb_test_name + } + -re "Could not validate memory tag: Value can't be converted to integer\\." { + fail "$gdb_test_name" + } +} + +gdb_test "print ref.m_a" \ + "\\$\[0-9\]+ = 42" \ + "print member through stored reference" + +gdb_test "print ref.get_a()" \ + "\\$\[0-9\]+ = 42" \ + "print method call through stored reference"
\ No newline at end of file diff --git a/gdb/testsuite/gdb.cp/nsalias.exp b/gdb/testsuite/gdb.cp/nsalias.exp index a145410..7ad2da8 100644 --- a/gdb/testsuite/gdb.cp/nsalias.exp +++ b/gdb/testsuite/gdb.cp/nsalias.exp @@ -56,111 +56,113 @@ standard_testfile .cc nsalias-dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C_plus_plus}} { + compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { declare_labels int_label outer_label inner_label innermost_label declare_labels im_foo_label i_foo_label o_foo_label declare_labels OuterInner_label oi1_label oi2_label int_label: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } outer_label: DW_TAG_namespace { - {name outer} + DW_AT_name outer } { inner_label: DW_TAG_namespace { - {name inner} + DW_AT_name inner } { innermost_label: DW_TAG_namespace { - {name innermost} + DW_AT_name innermost } { DW_TAG_variable { - {name x} - {type :$int_label} - {const_value 2 DW_FORM_data1} + DW_AT_name x + DW_AT_type :$int_label + DW_AT_const_value 2 DW_FORM_data1 } im_foo_label: DW_TAG_subprogram { - {name foo} - {external 1 flag_present} - {declaration 1 flag_present} + DW_AT_name foo + DW_AT_external 1 flag_present + DW_AT_declaration 1 flag_present } } imported_declaration { - {name Innermost} - {import :$innermost_label} + DW_AT_name Innermost + DW_AT_import :$innermost_label } DW_TAG_variable { - {name x} - {type :$int_label} - {const_value 1 DW_FORM_data1} + DW_AT_name x + DW_AT_type :$int_label + DW_AT_const_value 1 DW_FORM_data1 } i_foo_label: subprogram { - {name foo} - {external 1 flag_present} - {declaration 1 flag_present} + DW_AT_name foo + DW_AT_external 1 flag_present + DW_AT_declaration 1 flag_present } } OuterInner_label: imported_declaration { - {name Inner} - {import :$inner_label} + DW_AT_name Inner + DW_AT_import :$inner_label } DW_TAG_variable { - {name x} - {type :$int_label} - {const_value 0 DW_FORM_data1} + DW_AT_name x + DW_AT_type :$int_label + DW_AT_const_value 0 DW_FORM_data1 } o_foo_label: subprogram { - {name foo} - {external 1 flag_present} - {declaration 1 flag_present} + DW_AT_name foo + DW_AT_external 1 flag_present + DW_AT_declaration 1 flag_present } } imported_declaration { - {name Outer} - {import :$outer_label} + DW_AT_name Outer + DW_AT_import :$outer_label } oi1_label: imported_declaration { - {name oi1} - {import :$OuterInner_label} + DW_AT_name oi1 + DW_AT_import :$OuterInner_label } oi2_label: imported_declaration { - {name oi2} - {import :$oi1_label} + DW_AT_name oi2 + DW_AT_import :$oi1_label } imported_declaration { - {name oi3} - {import :$oi2_label} + DW_AT_name oi3 + DW_AT_import :$oi2_label } subprogram { - {specification :$im_foo_label} - {low_pc 0x4 DW_FORM_addr} - {high_pc 0x7 DW_FORM_addr} + DW_AT_specification :$im_foo_label + DW_AT_low_pc 0x4 DW_FORM_addr + DW_AT_high_pc 0x7 DW_FORM_addr } subprogram { - {specification :$i_foo_label} - {low_pc 0x8 DW_FORM_addr} - {high_pc 0xb DW_FORM_addr} + DW_AT_specification :$i_foo_label + DW_AT_low_pc 0x8 DW_FORM_addr + DW_AT_high_pc 0xb DW_FORM_addr } subprogram { - {specification :$o_foo_label} - {low_pc 0xc DW_FORM_addr} - {high_pc 0xf DW_FORM_addr} + DW_AT_specification :$o_foo_label + DW_AT_low_pc 0xc DW_FORM_addr + DW_AT_high_pc 0xf DW_FORM_addr } } } @@ -253,19 +255,19 @@ set imports { declare_labels n0_label n0_label: DW_TAG_namespace { - {name n0} + DW_AT_name n0 } { DW_TAG_variable { - {name x} - {type :$int_label} - {const_value 3 DW_FORM_data1} + DW_AT_name x + DW_AT_type :$int_label + DW_AT_const_value 3 DW_FORM_data1 } } declare_labels n0_import n0_import: imported_declaration { - {name N0} - {import :$n0_label} + DW_AT_name N0 + DW_AT_import :$n0_label } } @@ -273,8 +275,8 @@ for {set i 1} {$i <= 100} {incr i} { append imports [format " declare_labels n%d_import n%d_import: imported_declaration { - {name N%d} - {import :\$n%d_import} + DW_AT_name N%d + DW_AT_import :\$n%d_import }" $i $i $i [expr {$i - 1}]] } @@ -283,13 +285,15 @@ standard_testfile .cc nsalias-r-dw.S set asm_file [standard_output_file $srcfile2] set the_dwarf [format { cu {} { - compile_unit {{language @DW_LANG_C_plus_plus}} { + compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { declare_labels int_label n0_label int_label: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } %s diff --git a/gdb/testsuite/gdb.cp/pr10728.exp b/gdb/testsuite/gdb.cp/pr10728.exp index 0525ac1..8201e24 100644 --- a/gdb/testsuite/gdb.cp/pr10728.exp +++ b/gdb/testsuite/gdb.cp/pr10728.exp @@ -42,7 +42,7 @@ if { [gdb_compile "${tfx}.o ${tfy}.o" ${binfile} executable {debug c++}] != "" return -1 } -clean_restart $binfile +clean_restart $::testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.cp/print-global-stub.exp b/gdb/testsuite/gdb.cp/print-global-stub.exp index 139e8b1..d847c00 100644 --- a/gdb/testsuite/gdb.cp/print-global-stub.exp +++ b/gdb/testsuite/gdb.cp/print-global-stub.exp @@ -19,14 +19,15 @@ require allow_cplus_tests standard_testfile .cc -set objfile [standard_output_file ${testfile}.o] +set testfile $testfile.o +set binfile [standard_output_file $testfile] -if { [gdb_compile $srcdir/$subdir/$srcfile $objfile object \ +if { [gdb_compile $srcdir/$subdir/$srcfile $binfile object \ {c++ debug}] != "" } { untested "failed to compile" return -1 } -clean_restart $objfile +clean_restart $testfile gdb_test "print s" " = <incomplete type>" diff --git a/gdb/testsuite/gdb.cp/psmang.exp b/gdb/testsuite/gdb.cp/psmang.exp index acc7b3b..67bc9cd9 100644 --- a/gdb/testsuite/gdb.cp/psmang.exp +++ b/gdb/testsuite/gdb.cp/psmang.exp @@ -190,6 +190,6 @@ gdb_test "break s::method1" "Breakpoint .* at .*: file .*psmang1.cc.*" # We have to exit and restart GDB here, to make sure that all the # compilation units are psymtabs again. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test "break s::method2" "Breakpoint .* at .*: file .*psmang2.cc.*" diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp index 97a56ab..4f2cbb5 100644 --- a/gdb/testsuite/gdb.cp/ref-params.exp +++ b/gdb/testsuite/gdb.cp/ref-params.exp @@ -32,7 +32,7 @@ proc gdb_start_again { text } { global binfile global srcfile - clean_restart $binfile + clean_restart $::testfile runto ${srcfile}:[gdb_get_line_number $text] } diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-params.exp b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp index 8a5e66f..267dbc7 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-params.exp +++ b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp @@ -30,7 +30,7 @@ proc gdb_start_again {text prefix} { global srcfile with_test_prefix $prefix { - clean_restart $binfile + clean_restart $::testfile runto ${srcfile}:[gdb_get_line_number $text] } diff --git a/gdb/testsuite/gdb.cp/static-print-quit.exp b/gdb/testsuite/gdb.cp/static-print-quit.exp index 8e0b61d..e4bce7f 100644 --- a/gdb/testsuite/gdb.cp/static-print-quit.exp +++ b/gdb/testsuite/gdb.cp/static-print-quit.exp @@ -27,32 +27,17 @@ clean_restart $testfile.o gdb_test_no_output "set width 80" gdb_test_no_output "set height 2" -set test "print c - <return>" -gdb_test_multiple "print c" $test { - -re "\\$\[0-9\]+ = \{loooooooooooooooooooooooooooooooooooooooooooooong = 0, static field = \{\r\n--Type <RET>" { - pass $test +gdb_test_multiple "print c" "" { + -re "\\$\[0-9\]+ = \{loooooooooooooooooooooooooooooooooooooooooooooong = 0, static field = \{\r\n$pagination_prompt$" { + pass $gdb_test_name } - -re "\r\n--Type <RET>" { + -re "\r\n$pagination_prompt$" { # gdb-7.1 did not crash with this testcase but it had the same bug. untested "bug does not reproduce" return 0 } } -set test "print c - q <return>" -gdb_test_multiple "" $test { - -re " for more, q to quit, " { - pass $test - } -} - -set test "print c - remainder" -gdb_test_multiple "" $test { - -re "c to continue without paging--$" { - pass $test - } -} - gdb_test "q" ".*" # Now the obstack is uninitialized. Exercise it. diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp index 74e4a92..52d0229 100644 --- a/gdb/testsuite/gdb.cp/templates.exp +++ b/gdb/testsuite/gdb.cp/templates.exp @@ -58,9 +58,9 @@ proc test_ptype_of_templates {} { xfail "ptype T5<int> (obsolescent gcc or gdb)" } -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" { - # This also triggers gdb/1113... - kfail "gdb/1111" "ptype T5<int>" - # Add here a PASS case when PR gdb/1111 gets fixed. + # This also triggers gdb/8218... + kfail "gdb/8216" "ptype T5<int>" + # Add here a PASS case when PR gdb/8216 gets fixed. # These are really: # http://sourceware.org/bugzilla/show_bug.cgi?id=8216 # http://sourceware.org/bugzilla/show_bug.cgi?id=8218 @@ -98,9 +98,9 @@ proc test_ptype_of_templates {} { xfail "ptype t5i (obsolescent gcc or gdb) -- without size_t" } -re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" { - # This also triggers gdb/1113... - kfail "gdb/1111" "ptype t5i" - # Add here a PASS case when PR gdb/1111 gets fixed. + # This also triggers gdb/8218... + kfail "gdb/8216" "ptype t5i" + # Add here a PASS case when PR gdb/8216 gets fixed. # These are really: # http://sourceware.org/bugzilla/show_bug.cgi?id=8216 # http://sourceware.org/bugzilla/show_bug.cgi?id=8218 @@ -132,7 +132,7 @@ proc test_template_breakpoints {} { "constructor breakpoint" } -re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. T5 at .*\[\r\n\]*.3. T5 at .*\[\r\n\]*> $" { - setup_kfail "gdb/1062" "*-*-*" + setup_kfail "gdb/8167" "*-*-*" gdb_test "0" \ "nonsense intended to insure that this test fails" \ "constructor breakpoint" @@ -151,7 +151,7 @@ proc test_template_breakpoints {} { } -re "the class `T5<int>' does not have destructor defined\r\nHint: try 'T5<int>::~T5<TAB> or 'T5<int>::~T5<ESC-\\?>\r\n\\(Note leading single quote.\\)\r\n$gdb_prompt $" { - kfail "gdb/1112" "destructor breakpoint" + kfail "gdb/8217" "destructor breakpoint" } } @@ -307,7 +307,7 @@ gdb_test_multiple "ptype/r Foo" "ptype Foo" { } -re "type = class Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Foo" + kfail "gdb/7162" "ptype Foo" } -re "No symbol \"Foo\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -342,28 +342,25 @@ gdb_test_multiple "ptype/r fchar" "ptype fchar" { # ptype Foo<volatile char *> gdb_test_multiple "ptype/r fvpchar" "ptype fvpchar" { - -re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" { - pass "ptype fvpchar" - } - -re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);.*\r\n\\}\r\n$gdb_prompt $" { + -re "type = class Foo<char volatile\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*volatile char \\*t;\r\n\r\n\[ \t\]*volatile char \\* foo\\(int, volatile char \\*\\);.*\r\n\\}\r\n$gdb_prompt $" { pass "ptype fvpchar" } -re "type = (class |)Foo<char volatile ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" { - kfail "gdb/1512" "ptype fvpchar" + kfail "gdb/8617" "ptype fvpchar" } } # print a function from Foo<volatile char *> # This test is sensitive to whitespace matching, so we'll do it twice, -# varying the spacing, because of PR gdb/33. +# varying the spacing, because of PR gdb/7138. gdb_test_multiple "print Foo<volatile char *>::foo" "print Foo<volatile char *>::foo" { -re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" } -re "No symbol \"Foo<volatile char \\*>\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33 and then kfail gdb/931. + # This used to be a kfail gdb/7138 and then kfail gdb/8036. fail "print Foo<volatile char *>::foo" } } @@ -373,7 +370,7 @@ gdb_test_multiple "print Foo<volatile char*>::foo" "print Foo<volatile char*>::f pass "print Foo<volatile char*>::foo" } -re "No symbol \"Foo<volatile char\\*>\" in current context.\r\n$gdb_prompt $" { - # This used to be a kfail gdb/33 and then kfail gdb/931. + # This used to be a kfail gdb/7138 and then kfail gdb/8036. fail "print Foo<volatile char*>::foo" } } @@ -390,7 +387,7 @@ gdb_test_multiple "ptype/r Bar" "ptype Bar" { } -re "ptype Bar\r\ntype = class Bar<int, ?33> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Bar" + kfail "gdb/7162" "ptype Bar" } -re "No symbol \"Bar\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -433,11 +430,11 @@ gdb_test_multiple "ptype/r Baz" "ptype Baz" { } -re "type = class Baz<int, ?'s'> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Baz" + kfail "gdb/7162" "ptype Baz" } -re "type = class Baz<int, ?(\\(char\\))?115> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" { - # GCC 3.x, DWARF-2 output, running into gdb/57 and gdb/1512. - kfail "gdb/57" "ptype Baz" + # GCC 3.x, DWARF-2 output, running into gdb/7162 and gdb/8617. + kfail "gdb/7162" "ptype Baz" } -re "No symbol \"Baz\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -479,11 +476,11 @@ gdb_test_multiple "ptype/r Qux" "ptype Qux" { } -re "type = class Qux<char, ?&string> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Qux" + kfail "gdb/7162" "ptype Qux" } -re "type = class Qux<char, ?&\\(string\\)> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" { - # GCC 3.x, DWARF-2 output; gdb/57 + gdb/1512. - kfail "gdb/57" "ptype Qux" + # GCC 3.x, DWARF-2 output; gdb/7162 + gdb/8617. + kfail "gdb/7162" "ptype Qux" } -re "No symbol \"Qux\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. @@ -507,7 +504,7 @@ gdb_test_multiple "ptype/r quxint" "ptype quxint" { pass "ptype quxint" } -re "type = class Qux<int, ?& ?\\(string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" { - kfail "gdb/1512" "ptype quxint" + kfail "gdb/8617" "ptype quxint" } } @@ -524,7 +521,7 @@ gdb_test_multiple "ptype/r Spec" "ptype Spec" { } -re "type = class Spec<int, ?char> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*int spec\\(char\\);\r\n}\r\n$gdb_prompt $" { # GCC 3.1, DWARF-2 output. - kfail "gdb/57" "ptype Spec" + kfail "gdb/7162" "ptype Spec" } -re "No symbol \"Spec\" in current context.\r\n$gdb_prompt $" { # GCC 2.95.3, stabs+ output. diff --git a/gdb/testsuite/gdb.ctf/cross-tu-cyclic.exp b/gdb/testsuite/gdb.ctf/cross-tu-cyclic.exp index 922729f..2a0e999 100644 --- a/gdb/testsuite/gdb.ctf/cross-tu-cyclic.exp +++ b/gdb/testsuite/gdb.ctf/cross-tu-cyclic.exp @@ -37,6 +37,6 @@ gdb_test_no_output "set always-read-ctf on" gdb_load $binfile # Same thing with struct and union. -gdb_test "ptype struct A" "type = struct A \{\[\r\n\]+\[ \t\]+struct B \\*foo;\[\r\n\]+\}.*" "ptype structure A" -gdb_test "ptype struct B" "type = struct B \{\[\r\n\]+\[ \t\]+struct B \\*next;\[\r\n\]+\}.*" "ptype structure B" +gdb_test "ptype struct A" "type = struct A \{\[\r\n\]+\[ \t\]+long a;\[\r\n\]+\[ \t\]+struct B \\*foo;\[\r\n\]+\}.*" "ptype structure A" +gdb_test "ptype struct B" "type = struct B \{\[\r\n\]+\[ \t\]+int foo;\[\r\n\]+\[ \t\]+struct A \\*bar;\[\r\n\]+\}.*" "ptype structure B" gdb_test "ptype struct C" "type = struct C \{\[\r\n\]+\[ \t\]+struct B \\*foo;\[\r\n\]+\[ \t\]+int b;\[\r\n\]+\}.*" "ptype structure C" diff --git a/gdb/testsuite/gdb.ctf/funcreturn.exp b/gdb/testsuite/gdb.ctf/funcreturn.exp index 4d13531..55ee969 100644 --- a/gdb/testsuite/gdb.ctf/funcreturn.exp +++ b/gdb/testsuite/gdb.ctf/funcreturn.exp @@ -15,7 +15,7 @@ require allow_ctf_tests -if [target_info exists no_long_long] { +if {[target_info exists no_long_long]} { set exec_opts [list debug additional_flags=-DNO_LONG_LONG] } else { set exec_opts [list debug] @@ -91,7 +91,7 @@ gdb_test "print v_unsigned_long_func" \ "$decimal = \{unsigned long|long \\(\\)\} 0x\[0-9a-z\]+ <v_unsigned_long_func>.*" \ "print unsigned long function" -if ![target_info exists no_long_long] { +if {![target_info exists no_long_long]} { gdb_test "print v_long_long_func" \ "$decimal = \{long long \\(\\)\} 0x\[0-9a-z\]+ <v_long_long_func>.*" \ "print long long function" @@ -164,7 +164,7 @@ gdb_test "whatis v_unsigned_long_func" \ "type = (unsigned (int|long|long int)|long unsigned int) \\($void\\)" \ "whatis unsigned long function" -if ![target_info exists no_long_long] { +if {![target_info exists no_long_long]} { gdb_test "whatis v_long_long_func" \ "type = long long(| int) \\($void\\)" \ "whatis long long function" diff --git a/gdb/testsuite/gdb.dap/attach-fail.exp b/gdb/testsuite/gdb.dap/attach-fail.exp new file mode 100644 index 0000000..8992f62 --- /dev/null +++ b/gdb/testsuite/gdb.dap/attach-fail.exp @@ -0,0 +1,32 @@ +# 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 "attach" failure in DAP. + +require can_spawn_for_attach allow_dap_tests + +load_lib dap-support.exp + +# Passing an empty remote name here will guarantee a failure without +# trying to find a real remote. +set id [dap_target_remote {""}] + +dap_check_request_and_response "configurationDone" configurationDone + +set resp [lindex [dap_read_response attach $id] 0] +gdb_assert {[dict get $resp success] == "false"} \ + "attach failed" + +dap_shutdown diff --git a/gdb/testsuite/gdb.dap/attach.exp b/gdb/testsuite/gdb.dap/attach.exp index 37e867c..5e1f634 100644 --- a/gdb/testsuite/gdb.dap/attach.exp +++ b/gdb/testsuite/gdb.dap/attach.exp @@ -33,11 +33,11 @@ set attach_id [dap_attach $testpid $binfile] dap_check_request_and_response "configurationDone" configurationDone +dap_check_response "attach response" attach $attach_id + dap_wait_for_event_and_check "stopped" stopped \ "body reason" attach -dap_check_response "attach response" attach $attach_id - dap_shutdown true kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.dap/bt-nodebug.exp b/gdb/testsuite/gdb.dap/bt-nodebug.exp index 3053f8c..8188a98 100644 --- a/gdb/testsuite/gdb.dap/bt-nodebug.exp +++ b/gdb/testsuite/gdb.dap/bt-nodebug.exp @@ -71,6 +71,7 @@ gdb_assert {[dict exists [lindex $breakpoints 0] instructionReference]} \ # slipped in that caused this to be incorrect, so we test both parts # here; to test whether a string was given, we have to reach into the # TON form. +# tclint-disable-next-line command-args set list_form [namespace eval ton::2list $last_ton] set ref [namespace eval ton::2list { get $list_form body breakpoints 0 instructionReference diff --git a/gdb/testsuite/gdb.dap/catch-exception.exp b/gdb/testsuite/gdb.dap/catch-exception.exp index ced2cc5..0e8c27a 100644 --- a/gdb/testsuite/gdb.dap/catch-exception.exp +++ b/gdb/testsuite/gdb.dap/catch-exception.exp @@ -35,7 +35,7 @@ set obj [dap_check_request_and_response "set exception catchpoints" \ setExceptionBreakpoints \ {o filters [a [s nosuchfilter] [s assert]] \ filterOptions [a [o filterId [s exception] \ - condition [s "Global_Var = 23"]]]}] + condition [s program_error]]]}] set bps [dict get [lindex $obj 0] body breakpoints] # We should get three responses, because we requested three @@ -77,6 +77,20 @@ dap_wait_for_event_and_check "stopped at first raise" stopped \ "body reason" breakpoint \ "body hitBreakpointIds" 2 +set found_line -1 +set line [gdb_get_line_number "EXPECTED" $testdir/prog.adb] +set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \ + {o threadId [i 1]}] \ + 0] +foreach frame [dict get $bt body stackFrames] { + if {[dict exists $frame source path] + && [file tail [dict get $frame source path]] == "prog.adb"} { + set found_line [dict get $frame line] + } +} + +gdb_assert {$found_line == $line} "stopped at correct raise" + dap_check_request_and_response "continue to assert" continue \ {o threadId [i 1]} dap_wait_for_event_and_check "stopped at assert" stopped \ diff --git a/gdb/testsuite/gdb.dap/catch-exception/prog.adb b/gdb/testsuite/gdb.dap/catch-exception/prog.adb index ed60272..7a5a31d 100644 --- a/gdb/testsuite/gdb.dap/catch-exception/prog.adb +++ b/gdb/testsuite/gdb.dap/catch-exception/prog.adb @@ -19,15 +19,14 @@ procedure Prog is begin begin - raise Program_Error; + raise Constraint_Error; exception when others => null; end; begin - Global_Var := 23; - raise Program_Error; + raise Program_Error; -- EXPECTED exception when others => null; diff --git a/gdb/testsuite/gdb.dap/eof.exp b/gdb/testsuite/gdb.dap/eof.exp index 4752347..5c709ed 100644 --- a/gdb/testsuite/gdb.dap/eof.exp +++ b/gdb/testsuite/gdb.dap/eof.exp @@ -30,8 +30,10 @@ if {[dap_initialize] == ""} { return } -catch "close -i $gdb_spawn_id" -catch "wait -i $gdb_spawn_id" +# Expect support is missing ( https://github.com/nmoroze/tclint/issues/118 ). +# tclint-disable-next-line command-args +catch {close -i $gdb_spawn_id} +catch {wait -i $gdb_spawn_id} unset gdb_spawn_id dap_check_log_file diff --git a/gdb/testsuite/gdb.dap/log-message.exp b/gdb/testsuite/gdb.dap/log-message.exp index 421df14..cce367d 100644 --- a/gdb/testsuite/gdb.dap/log-message.exp +++ b/gdb/testsuite/gdb.dap/log-message.exp @@ -40,6 +40,15 @@ set obj [dap_check_request_and_response "set breakpoint" \ [list s $srcfile] $line]] set fn_bpno [dap_get_breakpoint_number $obj] +set eol {\n} +dap_wait_for_event_and_check "set breakpoint output, part 1" output \ + {body category} stdout \ + {body output} "No source file named log-message.c.$eol" + +dap_wait_for_event_and_check "set breakpoint output, part 2" output \ + {body category} stdout \ + {body output} "Breakpoint 1 (-source log-message.c -line $line) pending.$eol" + dap_check_request_and_response "configurationDone" configurationDone dap_check_response "launch response" launch $launch_id diff --git a/gdb/testsuite/gdb.dap/scopes.c b/gdb/testsuite/gdb.dap/scopes.c index d8929f1..2a1d76c 100644 --- a/gdb/testsuite/gdb.dap/scopes.c +++ b/gdb/testsuite/gdb.dap/scopes.c @@ -27,6 +27,8 @@ int main () static int scalar = 23; + void *ptr = (void *) &scalar; + { const char *inner = "inner block"; diff --git a/gdb/testsuite/gdb.dap/scopes.exp b/gdb/testsuite/gdb.dap/scopes.exp index 59d344b..52efa68 100644 --- a/gdb/testsuite/gdb.dap/scopes.exp +++ b/gdb/testsuite/gdb.dap/scopes.exp @@ -70,7 +70,8 @@ lassign $scopes scope reg_scope gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" gdb_assert {[dict get $scope presentationHint] == "locals"} \ "locals presentation hint" -gdb_assert {[dict get $scope namedVariables] == 3} "three vars in scope" +set count [dict get $scope namedVariables] +gdb_assert {$count == 4} "four vars in scope" gdb_assert {[dict get $reg_scope name] == "Registers"} \ "second scope is registers" @@ -89,8 +90,8 @@ set refs1 [lindex [dap_check_request_and_response "fetch variables 0,1" \ set refs2 [lindex [dap_check_request_and_response "fetch variables 2" \ "variables" \ [format {o variablesReference [i %d] \ - start [i 2] count [i 1]} \ - $num]] \ + start [i 2] count [i %d]} \ + $num [expr {$count - 2}]]] \ 0] set vars [concat [dict get $refs1 body variables] \ @@ -115,6 +116,10 @@ foreach var $vars { "scalar" { gdb_assert {[dict get $var value] == 23} "check value of scalar" } + "ptr" { + gdb_assert {[dict get $var memoryReference] != ""} \ + "check memoryReference of ptr" + } default { fail "unknown variable $name" } @@ -128,11 +133,38 @@ set refs [lindex [dap_check_request_and_response "fetch contents of dei" \ set deivals [dict get $refs body variables] gdb_assert {[llength $deivals] == 2} "dei has two members" +# Request more children than exist. See PR dap/33228. +set seq [dap_send_request variables \ + [format {o variablesReference [i %d] count [i 100]} $dei_ref]] +lassign [dap_read_response variables $seq] response ignore +gdb_assert {[dict get $response success] == "false"} \ + "variables with invalid count" + set num [dict get $reg_scope variablesReference] -# The request succeeding is sufficient. -set val [dap_check_request_and_response "fetch first register" \ +lassign [dap_check_request_and_response "fetch all registers" \ "variables" \ - [format {o variablesReference [i %d] count [i 1]} $num]] + [format {o variablesReference [i %d] count [i %d]} $num\ + [dict get $reg_scope namedVariables]]] \ + val events + +# If any register has children, try to fetch those as well. This is a +# regression test for part of PR dap/33228. +foreach var [dict get $val body variables] { + set regvar [dict get $var variablesReference] + if {$regvar > 0} { + # If variablesReference is non-zero, then there must be either + # named or indexed children. + if {[dict exists $var namedVariables]} { + set n [dict get $var namedVariables] + } else { + set n [dict get $var indexedVariables] + } + + dap_check_request_and_response "fetch register children for $regvar" \ + "variables" \ + [format {o variablesReference [i %d] count [i %d]} $regvar $n] + } +} set num [dict get $scope variablesReference] set refs [lindex [dap_check_request_and_response "set variable scalar" \ diff --git a/gdb/testsuite/gdb.dap/threads.c b/gdb/testsuite/gdb.dap/threads.c new file mode 100644 index 0000000..168f044 --- /dev/null +++ b/gdb/testsuite/gdb.dap/threads.c @@ -0,0 +1,67 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2019-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/>. */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pthread.h> + +#define NUM 2 + +static pthread_barrier_t threads_started_barrier; + +static void * +thread_function (void *arg) +{ + pthread_barrier_wait (&threads_started_barrier); + + while (1) + sleep (1); + + pthread_exit (NULL); +} + +static void +all_started (void) +{ +} + +int +main () +{ + pthread_t threads[NUM]; + long i; + + pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1); + + for (i = 1; i <= NUM; i++) + { + int res; + + res = pthread_create (&threads[i - 1], NULL, thread_function, NULL); + } + + pthread_barrier_wait (&threads_started_barrier); + + all_started (); + + printf ("sleeping\n"); + fflush (stdout); + sleep (180); + + exit (EXIT_SUCCESS); +} diff --git a/gdb/testsuite/gdb.dap/threads.exp b/gdb/testsuite/gdb.dap/threads.exp new file mode 100644 index 0000000..c91d107 --- /dev/null +++ b/gdb/testsuite/gdb.dap/threads.exp @@ -0,0 +1,81 @@ +# 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 DAP "threads" request. + +require allow_shlib_tests allow_dap_tests + +load_lib dap-support.exp + +standard_testfile + +set libname $testfile-solib +set srcfile_lib $srcdir/$subdir/$libname.c +set binfile_lib [standard_output_file $libname.so] + +if {[build_executable "failed to prepare" $testfile $srcfile \ + {debug pthreads}] == -1} { + return +} + +if {[dap_initialize] == ""} { + return +} + +set launch_id [dap_launch $testfile] + +set obj [dap_check_request_and_response "set breakpoint on all_started function" \ + setFunctionBreakpoints \ + {o breakpoints [a [o name [s all_started]]]}] +set fn_bpno [dap_get_breakpoint_number $obj] + +dap_check_request_and_response "configurationDone" configurationDone + +dap_check_response "launch response" launch $launch_id + +lassign [dap_wait_for_event_and_check "stopped at function breakpoint" \ + stopped \ + "body reason" breakpoint \ + "body hitBreakpointIds" $fn_bpno] \ + ignore \ + all_events + +# Verify that we saw the correct number of thread events. +set count 0 +foreach event $all_events { + if {[dict get $event type] == "event" + && [dict get $event event] == "thread" + && [dict get $event body reason] == "started"} { + incr count + } +} +gdb_assert {$count == 3} "correct number of thread events" + +dap_check_request_and_response "continue" continue \ + {o threadId [i 1]} + +# Make sure that the inferior has really re-started -- note that there +# is no "continue" event, because the "continue" request suppresses +# those. +dap_wait_for_event_and_check "output from inferior" output \ + {body output} "sleeping\\n" + +lassign [dap_check_request_and_response "threads request" threads] \ + response ignore + +gdb_assert {[llength [dict get $response body threads]] == 3} \ + "correct number of threads" + +dap_shutdown true diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp index 93f8f92..35bb401 100644 --- a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp +++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp @@ -46,7 +46,7 @@ set build_id_debug_file \ [standard_output_file [build_id_debug_filename_get $binfile]] # Get the BINFILE.debug filename. This is the file we should be -# moving to the BUILD_ID_DEBUG_FILE location, but we wont, we're going +# moving to the BUILD_ID_DEBUG_FILE location, but we won't, we're going # to move something else there instead. set debugfile [standard_output_file "${binfile}.debug"] diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp index 78fa252..c85cfb1 100644 --- a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp +++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp @@ -49,7 +49,7 @@ # # This obviously needs fixing, but is a separate problem from the one being # tested here, so this test deliberately checks the mapping using a file that -# is mmaped rather than loaded as a shared library, as such the file is in the +# is mmapped rather than loaded as a shared library, as such the file is in the # core-files list of mapped files, but is not in the shared library list. # # Despite this test living in the gdb.debuginfod/ directory, only the last @@ -69,14 +69,15 @@ standard_testfile -1.c -2.c -3.c # shared library, then use GDB to figure out the offset of the # variable 'library_ptr' within the library. set library_filename [standard_output_file "libfoo.so"] -set binfile2 [standard_output_file "library_loader"] +set testfile2 "library_loader" +set binfile2 [standard_output_file $testfile2] if {[prepare_for_testing_full "build exec which loads the shared library" \ [list $library_filename \ { debug shlib build-id \ additional_flags=-DPOINTER_VALUE=0x12345678 } \ $srcfile2 {}] \ - [list $binfile2 [list debug shlib=$library_filename ] \ + [list $testfile2 [list debug shlib=$library_filename ] \ $srcfile { debug }]] != 0} { return } @@ -160,7 +161,7 @@ if { $ptr_expected_value eq "" } { # Load this executable within GDB and confirm that we can use the # offset we calculated previously to view the value of 'library_ptr'. set opts [list debug additional_flags=-DSHLIB_FILENAME=\"$library_filename\"] -if {[prepare_for_testing "prepare second executable" $binfile \ +if {[prepare_for_testing "prepare second executable" $testfile \ $srcfile3 $opts] != 0} { return } @@ -174,7 +175,7 @@ gdb_continue_to_breakpoint "run to breakpoint" set library_base_address \ [get_hexadecimal_valueof "library_base_address" "unknown"] -set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]] +set ptr_address [format 0x%x [expr {$library_base_address + $ptr_offset}]] set ptr_value [read_ptr_value] gdb_assert { $ptr_value == $ptr_expected_value } \ @@ -260,7 +261,7 @@ proc load_core_file { testname { line_re "" } } { # We expect RES to be 2 (TCL_RETURN) or 1 (TCL_ERROR). If we get # here then somehow the 'catch' above finished without hitting # either of those cases, which is .... weird. - perror "unexepcted return value, code = $res, value = $string" + perror "unexpected return value, code = $res, value = $string" return -1 } } @@ -268,13 +269,13 @@ proc load_core_file { testname { line_re "" } } { # And now restart GDB, load the core-file and check that the library shows as # being mapped in, and that we can still read the library_ptr value from # memory. -clean_restart $binfile +clean_restart $::testfile load_core_file "load core file" set library_base_address [get_hexadecimal_valueof "library_base_address" \ "unknown" "get library_base_address in core-file"] -set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]] +set ptr_address [format 0x%x [expr {$library_base_address + $ptr_offset}]] set ptr_value [read_ptr_value] gdb_assert { $ptr_value == $ptr_expected_value } \ @@ -287,7 +288,7 @@ gdb_assert { $ptr_value == $ptr_expected_value } \ set library_backup_filename [standard_output_file "libfoo.so.backup"] remote_exec build "mv \"$library_filename\" \"$library_backup_filename\"" -clean_restart $binfile +clean_restart $::testfile load_core_file "load corefile with library file missing" \ "warning: Can't open file [string_to_regexp $library_filename] during file-backed mapping note processing" @@ -309,7 +310,7 @@ set build_id_filename \ remote_exec build "mkdir -p [file dirname $build_id_filename]" remote_exec build "ln -sf $library_backup_filename $build_id_filename" -clean_restart $binfile +clean_restart $::testfile gdb_test_no_output "set debug-file-directory $debugdir" \ "set debug-file-directory" @@ -331,7 +332,7 @@ if {[build_executable "build second version of shared library" \ return } -clean_restart $binfile +clean_restart $::testfile load_core_file "load corefile with wrong library in place" \ "warning: File [string_to_regexp $library_filename] doesn't match build-id from core-file during file-backed mapping processing" diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp index 7b36f65..292be70 100644 --- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp +++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp @@ -56,7 +56,7 @@ proc write_just_debugaltlink {filename dwzname buildid} { # Only the DWARF reader checks .gnu_debugaltlink, so make sure # there is a bit of DWARF in here. cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit {DW_AT_language @DW_LANG_C} { } } } @@ -76,17 +76,19 @@ proc write_dwarf_file {filename buildid {value 99}} { build_id $buildid cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { int_label2: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } constant { - {name the_int} - {type :$int_label2} - {const_value $value data1} + DW_AT_name the_int + DW_AT_type :$int_label2 + DW_AT_const_value $value data1 } } } @@ -107,7 +109,7 @@ proc_with_prefix no_url { } { setenv DEBUGINFOD_URLS "" # Test that GDB cannot find source without debuginfod. - clean_restart $binfile + clean_restart $::testfile gdb_test_no_output "set substitute-path $outputdir /dev/null" \ "set substitute-path" gdb_test "list" ".*No such file or directory.*" @@ -126,7 +128,7 @@ proc_with_prefix no_url { } { file rename -force $debuginfo $debugdir # Test that GDB cannot find symbols without debuginfod. - clean_restart $binfile + clean_restart $::testfile gdb_test "file" ".*No symbol file.*" set buildid "01234567890abcdef0123456" @@ -152,12 +154,12 @@ proc_with_prefix no_url { } { # Test that GDB cannot find dwz without debuginfod. clean_restart gdb_test "file ${binfile}_alt.o" \ - ".*could not find '.gnu_debugaltlink'.*" \ + ".*could not find supplementary DWARF file .*" \ "file [file tail ${binfile}_alt.o]" # Generate a core file and test that GDB cannot find the # executable. - clean_restart ${binfile}2 + clean_restart ${::testfile}2 if ![runto_main] { return -1 } diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp index 9f1842c..67d9237 100644 --- a/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp +++ b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp @@ -89,7 +89,7 @@ if {[lindex $status 0] != 0} { } # Build the executable. This links against libfoo.so, which is -# poining at libfoo_1.so. Just to confuse things even more, this +# pointing at libfoo_1.so. Just to confuse things even more, this # executable uses dlopen to load libfoo_2.so. Weird! if { [build_executable "build executable" ${binfile} ${srcfile2} \ [list debug shlib=${library_filename} shlib_load]] == -1 } { @@ -132,7 +132,7 @@ if {$corefile eq ""} { proc load_exec_and_core_file { expect_warning expect_download testname \ {debugdir ""} } { with_test_prefix $testname { - clean_restart $::binfile + clean_restart $::testfile if { $debugdir ne "" } { gdb_test_no_output "set debug-file-directory $debugdir" \ diff --git a/gdb/testsuite/gdb.disasm/am33.exp b/gdb/testsuite/gdb.disasm/am33.exp index b5ae981..7515da1 100644 --- a/gdb/testsuite/gdb.disasm/am33.exp +++ b/gdb/testsuite/gdb.disasm/am33.exp @@ -795,7 +795,7 @@ proc dsp_autoincrement_tests { } { } } -clean_restart $binfile +clean_restart $::testfile call_tests movm_tests diff --git a/gdb/testsuite/gdb.disasm/basics.exp b/gdb/testsuite/gdb.disasm/basics.exp index e54dced..9be9945 100644 --- a/gdb/testsuite/gdb.disasm/basics.exp +++ b/gdb/testsuite/gdb.disasm/basics.exp @@ -22,7 +22,7 @@ if { [prepare_for_testing "failed to prepare" $testfile ${srcfile}] == -1 } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.disasm/hppa.exp b/gdb/testsuite/gdb.disasm/hppa.exp index e330809..10b5cb5 100644 --- a/gdb/testsuite/gdb.disasm/hppa.exp +++ b/gdb/testsuite/gdb.disasm/hppa.exp @@ -23,7 +23,7 @@ set srcfile ${srcdir}/${subdir}/${testfile}.s set binfile ${objdir}/${subdir}/${testfile} set comp_output [gdb_compile "${srcfile}" "${binfile}" executable ""] if { $comp_output != "" } { - if [ regexp "Opcode not defined - DIAG" $comp_output] { + if {[regexp "Opcode not defined - DIAG" $comp_output]} { warning "HP assembler in use--skipping disasm tests" return } else { @@ -686,7 +686,7 @@ proc all_integer_computational_tests { } { } } - set subi_insns [list {subi} {subio} {comiclr} ] + set subi_insns [list {subi} {subio} {comiclr}] foreach i $subi_insns { send_gdb "x/16i $i"; send_gdb "_tests\n" @@ -746,7 +746,7 @@ proc all_integer_computational_tests { } { timeout { fail "(timeout) "shd tests" } } - set extract_insns1 [list {extru} {extrs} {zdep} {dep} ] + set extract_insns1 [list {extru} {extrs} {zdep} {dep}] foreach i $extract_insns1 { send_gdb "x/8i $i"; send_gdb "_tests\n" @@ -766,7 +766,7 @@ proc all_integer_computational_tests { } { } } - set extract_insns2 [list {vextru} {vextrs} {zvdep} {vdep} ] + set extract_insns2 [list {vextru} {vextrs} {zvdep} {vdep}] foreach i $extract_insns2 { send_gdb "x/8i $i"; send_gdb "_tests\n" @@ -786,7 +786,7 @@ proc all_integer_computational_tests { } { } } - set extract_insns3 [list {vdepi} {zvdepi} ] + set extract_insns3 [list {vdepi} {zvdepi}] foreach i $extract_insns3 { send_gdb "x/8i $i"; send_gdb "_tests\n" @@ -806,7 +806,7 @@ proc all_integer_computational_tests { } { } } - set extract_insns4 [list {depi} {zdepi} ] + set extract_insns4 [list {depi} {zdepi}] foreach i $extract_insns4 { send_gdb "x/8i $i"; send_gdb "_tests\n" @@ -1365,7 +1365,7 @@ proc fmemLRbug_tests { } { } } -clean_restart $binfile +clean_restart $::testfile all_integer_memory_tests all_immediate_tests diff --git a/gdb/testsuite/gdb.disasm/mn10300.exp b/gdb/testsuite/gdb.disasm/mn10300.exp index 55ce96c..74e7c7c 100644 --- a/gdb/testsuite/gdb.disasm/mn10300.exp +++ b/gdb/testsuite/gdb.disasm/mn10300.exp @@ -529,7 +529,7 @@ proc sub_tests { } { } } -clean_restart $binfile +clean_restart $::testfile add_tests bcc_tests diff --git a/gdb/testsuite/gdb.disasm/sh3.exp b/gdb/testsuite/gdb.disasm/sh3.exp index 09b27a0..fc591a7 100644 --- a/gdb/testsuite/gdb.disasm/sh3.exp +++ b/gdb/testsuite/gdb.disasm/sh3.exp @@ -100,7 +100,7 @@ proc all_fp_misc_tests { } { } } -clean_restart $binfile +clean_restart $::testfile all_fp_move_and_load_tests all_fp_arithmetic_tests diff --git a/gdb/testsuite/gdb.dlang/circular.exp b/gdb/testsuite/gdb.dlang/circular.exp index e318945..cc79062 100644 --- a/gdb/testsuite/gdb.dlang/circular.exp +++ b/gdb/testsuite/gdb.dlang/circular.exp @@ -27,98 +27,98 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_D} + DW_AT_language @DW_LANG_D } { declare_labels circular1_label circular2_label circular3_label declare_labels circular4_label circular5_label circular1_label: module { - {name circular1} + DW_AT_name circular1 } { imported_module { - {import :$circular2_label} + DW_AT_import :$circular2_label } imported_module { - {import :$circular3_label} + DW_AT_import :$circular3_label } imported_module { - {import :$circular4_label} + DW_AT_import :$circular4_label } imported_module { - {import :$circular5_label} + DW_AT_import :$circular5_label } subprogram { - {external 1 flag_present} - {MACRO_AT_func {found}} + DW_AT_external 1 flag_present + MACRO_AT_func {found} } } circular2_label: module { - {name circular2} + DW_AT_name circular2 } { imported_module { - {import :$circular1_label} + DW_AT_import :$circular1_label } imported_module { - {import :$circular3_label} + DW_AT_import :$circular3_label } imported_module { - {import :$circular4_label} + DW_AT_import :$circular4_label } imported_module { - {import :$circular5_label} + DW_AT_import :$circular5_label } } circular3_label: module { - {name circular3} + DW_AT_name circular3 } { imported_module { - {import :$circular1_label} + DW_AT_import :$circular1_label } imported_module { - {import :$circular2_label} + DW_AT_import :$circular2_label } imported_module { - {import :$circular4_label} + DW_AT_import :$circular4_label } imported_module { - {import :$circular5_label} + DW_AT_import :$circular5_label } } circular4_label: module { - {name circular4} + DW_AT_name circular4 } { imported_module { - {import :$circular1_label} + DW_AT_import :$circular1_label } imported_module { - {import :$circular2_label} + DW_AT_import :$circular2_label } imported_module { - {import :$circular3_label} + DW_AT_import :$circular3_label } imported_module { - {import :$circular5_label} + DW_AT_import :$circular5_label } } circular5_label: module { - {name circular5} + DW_AT_name circular5 } { imported_module { - {import :$circular1_label} + DW_AT_import :$circular1_label } imported_module { - {import :$circular2_label} + DW_AT_import :$circular2_label } imported_module { - {import :$circular3_label} + DW_AT_import :$circular3_label } imported_module { - {import :$circular4_label} + DW_AT_import :$circular4_label } } } diff --git a/gdb/testsuite/gdb.dlang/demangle.exp b/gdb/testsuite/gdb.dlang/demangle.exp index 75c2f79..4181513 100644 --- a/gdb/testsuite/gdb.dlang/demangle.exp +++ b/gdb/testsuite/gdb.dlang/demangle.exp @@ -197,7 +197,7 @@ proc test_d_demangling {} { clean_restart -if [set_lang_d] { +if {[set_lang_d]} { gdb_test_no_output "set width 0" test_d_demangling diff --git a/gdb/testsuite/gdb.dlang/dlang-start-2.exp b/gdb/testsuite/gdb.dlang/dlang-start-2.exp index 403dcfd..b5c0542 100644 --- a/gdb/testsuite/gdb.dlang/dlang-start-2.exp +++ b/gdb/testsuite/gdb.dlang/dlang-start-2.exp @@ -40,24 +40,24 @@ Dwarf::assemble $asm_file { cu { label cu_start } { compile_unit { - {language @DW_LANG_D} + DW_AT_language @DW_LANG_D } { module { - {name dmain} + DW_AT_name dmain } subprogram { - {name "D main" } - {MIPS_linkage_name "_Dmain"} - {low_pc $dmain_start DW_FORM_addr} - {high_pc "$dmain_start + $dmain_length" DW_FORM_addr} - {external 1 flag_present} + DW_AT_name "D main" + DW_AT_MIPS_linkage_name "_Dmain" + DW_AT_low_pc $dmain_start DW_FORM_addr + DW_AT_high_pc "$dmain_start + $dmain_length" DW_FORM_addr + DW_AT_external 1 flag_present } subprogram { - {name "dmain._d_cmain!().main" } - {MIPS_linkage_name "main"} - {low_pc $main_start DW_FORM_addr} - {high_pc "$main_start + $main_length" DW_FORM_addr} - {external 1 flag_present} + DW_AT_name "dmain._d_cmain!().main" + DW_AT_MIPS_linkage_name "main" + DW_AT_low_pc $main_start DW_FORM_addr + DW_AT_high_pc "$main_start + $main_length" DW_FORM_addr + DW_AT_external 1 flag_present } } } diff --git a/gdb/testsuite/gdb.dlang/expression.exp b/gdb/testsuite/gdb.dlang/expression.exp index 0d22cee..6e611ed 100644 --- a/gdb/testsuite/gdb.dlang/expression.exp +++ b/gdb/testsuite/gdb.dlang/expression.exp @@ -129,7 +129,7 @@ proc test_d_expressions {} { clean_restart -if [set_lang_d] { +if {[set_lang_d]} { test_d_integer_literals test_d_float_literals test_d_expressions diff --git a/gdb/testsuite/gdb.dlang/primitive-types.exp b/gdb/testsuite/gdb.dlang/primitive-types.exp index 8e74520..9e6e8fa 100644 --- a/gdb/testsuite/gdb.dlang/primitive-types.exp +++ b/gdb/testsuite/gdb.dlang/primitive-types.exp @@ -51,7 +51,7 @@ proc test_builtin_d_types_accepted {} { clean_restart -if [set_lang_d] { +if {[set_lang_d]} { test_builtin_d_types_accepted } else { warning "D type tests suppressed." diff --git a/gdb/testsuite/gdb.dlang/properties.exp b/gdb/testsuite/gdb.dlang/properties.exp index 0fe18a5..d0266f8 100644 --- a/gdb/testsuite/gdb.dlang/properties.exp +++ b/gdb/testsuite/gdb.dlang/properties.exp @@ -82,7 +82,7 @@ proc test_d_typeof {} { clean_restart -if [set_lang_d] { +if {[set_lang_d]} { test_d_sizeof test_d_typeof } else { diff --git a/gdb/testsuite/gdb.dlang/watch-loc.exp b/gdb/testsuite/gdb.dlang/watch-loc.exp index ec50e91..7cfc539 100644 --- a/gdb/testsuite/gdb.dlang/watch-loc.exp +++ b/gdb/testsuite/gdb.dlang/watch-loc.exp @@ -33,30 +33,30 @@ Dwarf::assemble $asm_file { cu { label cu_start } { compile_unit { - {language @DW_LANG_D} + DW_AT_language @DW_LANG_D } { declare_labels watch_module_label watch_struct_label watch_module_label: module { - {name watch} + DW_AT_name watch } { watch_struct_label: structure_type { - {name tstruct} - {byte_size 1 data1} + DW_AT_name tstruct + DW_AT_byte_size 1 data1 } tag_variable { - {name my_data} - {type :$watch_struct_label} - {location { + DW_AT_name my_data + DW_AT_type :$watch_struct_label + DW_AT_location [subst { addr [gdb_target_symbol my_data] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } subprogram { - {MACRO_AT_func { "_Dmain" }} - {external 1 flag_present} + MACRO_AT_func { "_Dmain" } + DW_AT_external 1 flag_present } } } diff --git a/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp b/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp index 6735207..291bc83 100644 --- a/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp +++ b/gdb/testsuite/gdb.dwarf2/DW_OP_piece_with_DW_OP_GNU_uninit.exp @@ -35,37 +35,37 @@ Dwarf::assemble $asm_file { declare_labels i64_type i32_type i64_type: base_type { - {name "int64_t"} - {encoding @DW_ATE_signed} - {byte_size 8 DW_FORM_sdata} + DW_AT_name "int64_t" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 8 DW_FORM_sdata } i32_type: base_type { - {name "int32_t"} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "int32_t" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } DW_TAG_variable { - {name i64_var} - {type :$i64_type} - {location { + DW_AT_name i64_var + DW_AT_type :$i64_type + DW_AT_location [subst { DW_OP_constu $::c64 DW_OP_stack_value DW_OP_GNU_uninit DW_OP_piece 8 - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {name i32_var} - {type :$i32_type} - {location { + DW_AT_name i32_var + DW_AT_type :$i32_type + DW_AT_location [subst { DW_OP_constu $::c32 DW_OP_stack_value DW_OP_GNU_uninit DW_OP_piece 4 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/ada-array-bound.c b/gdb/testsuite/gdb.dwarf2/ada-array-bound.c new file mode 100644 index 0000000..5a7d397 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/ada-array-bound.c @@ -0,0 +1,29 @@ +/* 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/>. */ + +/* The data used for the structure. */ + +unsigned char our_data[] = { 3, 7, 11, 13 }; + +/* Dummy main function. */ + +int +main() +{ + asm ("main_label: .globl main_label"); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp b/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp new file mode 100644 index 0000000..779ce00 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp @@ -0,0 +1,90 @@ +# 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 handling of an array type whose bound comes from the field of a +# structure. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile .c -debug.S + +# Set up the DWARF for the test. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile + + cu {} { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name $srcfile + } { + declare_labels byte array disc struct + + byte: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name byte + } + + array: DW_TAG_array_type { + DW_AT_name array_type + DW_AT_type :$byte + } { + DW_TAG_subrange_type { + DW_AT_type :$byte + DW_AT_upper_bound :$disc + } + } + + struct: DW_TAG_structure_type { + DW_AT_name discriminated + DW_AT_byte_size 4 DW_FORM_sdata + } { + disc: DW_TAG_member { + DW_AT_name disc + DW_AT_type :$byte + DW_AT_data_member_location 0 DW_FORM_sdata + } + DW_TAG_member { + DW_AT_name nums + DW_AT_type :$array + DW_AT_data_member_location 1 DW_FORM_sdata + } + } + + DW_TAG_variable { + DW_AT_name "value" + DW_AT_type :$struct + DW_AT_external 1 DW_FORM_flag + DW_AT_location \ + [subst {DW_OP_addr [gdb_target_symbol "our_data"]}] \ + SPECIAL_expr + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +gdb_test_no_output "set language ada" +gdb_test "print value" \ + [string_to_regexp " = (disc => 3, nums => (7, 11, 13))"] diff --git a/gdb/testsuite/gdb.dwarf2/ada-cold-name.exp b/gdb/testsuite/gdb.dwarf2/ada-cold-name.exp index c5758c2..3520319 100644 --- a/gdb/testsuite/gdb.dwarf2/ada-cold-name.exp +++ b/gdb/testsuite/gdb.dwarf2/ada-cold-name.exp @@ -30,28 +30,28 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_Ada95 + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels b_l b_l: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name bool} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name bool } DW_TAG_subprogram { - {name pck__xtra__function.cold} - {MACRO_AT_range {first}} - {type :$b_l} + DW_AT_name pck__xtra__function.cold + MACRO_AT_range {first} + DW_AT_type :$b_l } DW_TAG_subprogram { - {name pck__xtra__function} - {MACRO_AT_range {second}} - {type :$b_l} + DW_AT_name pck__xtra__function + MACRO_AT_range {second} + DW_AT_type :$b_l } } } diff --git a/gdb/testsuite/gdb.dwarf2/ada-linkage-name.exp b/gdb/testsuite/gdb.dwarf2/ada-linkage-name.exp index 9f2061c..915f47e 100644 --- a/gdb/testsuite/gdb.dwarf2/ada-linkage-name.exp +++ b/gdb/testsuite/gdb.dwarf2/ada-linkage-name.exp @@ -31,31 +31,31 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_Ada95 + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels b_l b_l: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name bool} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name bool } # Here the name comes first and the linkage name second. DW_TAG_subprogram { - {name system__namefirst} - {linkage_name __gnat_namefirst} - {MACRO_AT_range {first}} - {type :$b_l} + DW_AT_name system__namefirst + DW_AT_linkage_name __gnat_namefirst + MACRO_AT_range {first} + DW_AT_type :$b_l } # Here the linkage name comes first and the name second. DW_TAG_subprogram { - {linkage_name __gnat_namesecond} - {name system__namesecond} - {MACRO_AT_range {second}} - {type :$b_l} + DW_AT_linkage_name __gnat_namesecond + DW_AT_name system__namesecond + MACRO_AT_range {second} + DW_AT_type :$b_l } } } diff --git a/gdb/testsuite/gdb.dwarf2/ada-thick-pointer.exp b/gdb/testsuite/gdb.dwarf2/ada-thick-pointer.exp index 5032252..0efb8cb 100644 --- a/gdb/testsuite/gdb.dwarf2/ada-thick-pointer.exp +++ b/gdb/testsuite/gdb.dwarf2/ada-thick-pointer.exp @@ -31,53 +31,53 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name $srcfile} + DW_AT_language @DW_LANG_Ada95 + DW_AT_name $srcfile } { declare_labels integer array array_pointer bounds_pointer integer: DW_TAG_base_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } array: DW_TAG_array_type { - {DW_AT_name array_type} - {DW_AT_type :$integer} + DW_AT_name array_type + DW_AT_type :$integer } { DW_TAG_subrange_type { - {DW_AT_type :$integer} - {DW_AT_lower_bound 1 DW_FORM_data1} - {DW_AT_upper_bound 7 DW_FORM_data1} + DW_AT_type :$integer + DW_AT_lower_bound 1 DW_FORM_data1 + DW_AT_upper_bound 7 DW_FORM_data1 } } array_pointer: DW_TAG_pointer_type { - {DW_AT_type :$array} - {DW_AT_byte_size 8 DW_FORM_sdata} + DW_AT_type :$array + DW_AT_byte_size 8 DW_FORM_sdata } # This isn't exactly what GNAT emits, but it doesn't # matter. bounds_pointer: DW_TAG_pointer_type { - {DW_AT_type :$integer} - {DW_AT_byte_size 8 DW_FORM_sdata} + DW_AT_type :$integer + DW_AT_byte_size 8 DW_FORM_sdata } DW_TAG_structure_type { - {DW_AT_name thick_pointer_type} - {DW_AT_byte_size 8 DW_FORM_sdata} + DW_AT_name thick_pointer_type + DW_AT_byte_size 8 DW_FORM_sdata } { DW_TAG_member { - {DW_AT_name P_ARRAY} - {DW_AT_type :$array_pointer} - {DW_AT_data_member_location 0 DW_FORM_sdata} + DW_AT_name P_ARRAY + DW_AT_type :$array_pointer + DW_AT_data_member_location 0 DW_FORM_sdata } DW_TAG_member { - {DW_AT_name P_BOUNDS} - {DW_AT_type :$bounds_pointer} - {DW_AT_data_member_location 8 DW_FORM_sdata} + DW_AT_name P_BOUNDS + DW_AT_type :$bounds_pointer + DW_AT_data_member_location 8 DW_FORM_sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/ada-valprint-error.exp b/gdb/testsuite/gdb.dwarf2/ada-valprint-error.exp index e1a76bf..a754426 100644 --- a/gdb/testsuite/gdb.dwarf2/ada-valprint-error.exp +++ b/gdb/testsuite/gdb.dwarf2/ada-valprint-error.exp @@ -35,10 +35,10 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name fd.adb} - {DW_AT_comp_dir /tmp} + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name fd.adb + DW_AT_comp_dir /tmp } { declare_labels array_elt_label integer_label array_label \ typedef_label ref_type_label @@ -48,8 +48,8 @@ Dwarf::assemble $asm_file { # A structure with no size attribute, to mimick structures # in Ada that have a dynamic size... array_elt_label: structure_type { - {name fd__Tints_doubledC} - {artificial 1 DW_FORM_flag_present} + DW_AT_name fd__Tints_doubledC + DW_AT_artificial 1 DW_FORM_flag_present } # ... and a corresponding XVZ variable, supposed to be there @@ -58,44 +58,44 @@ Dwarf::assemble $asm_file { # it has been optimized out (which the compiler can do, # even if it at the expense of debuggability). DW_TAG_variable { - {name fd__Tints_doubledC___XVZ} - {DW_AT_type :$integer_label} - {artificial 1 DW_FORM_flag_present} + DW_AT_name fd__Tints_doubledC___XVZ + DW_AT_type :$integer_label + DW_AT_artificial 1 DW_FORM_flag_present } integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } array_label: DW_TAG_array_type { - {DW_AT_name fd__ints_doubled} - {DW_AT_type :$array_elt_label} + DW_AT_name fd__ints_doubled + DW_AT_type :$array_elt_label } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_upper_bound 2 DW_FORM_data1} + DW_AT_type :$integer_label + DW_AT_upper_bound 2 DW_FORM_data1 } } typedef_label: DW_TAG_typedef { - {DW_AT_name fd__ints_doubled} - {DW_AT_type :$array_label} + DW_AT_name fd__ints_doubled + DW_AT_type :$array_label } ref_type_label: DW_TAG_reference_type { - {DW_AT_byte_size $ptr_size DW_FORM_sdata} - {DW_AT_type :$typedef_label} + DW_AT_byte_size $ptr_size DW_FORM_sdata + DW_AT_type :$typedef_label } DW_TAG_variable { - {name fd__global} - {DW_AT_type :$ref_type_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol fd__global] - } SPECIAL_expr} - {external 1 flag} + DW_AT_name fd__global + DW_AT_type :$ref_type_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol fd__global] + }] SPECIAL_expr + DW_AT_external 1 flag } } diff --git a/gdb/testsuite/gdb.dwarf2/arr-opt-out.exp b/gdb/testsuite/gdb.dwarf2/arr-opt-out.exp index 6bbfef2..d3ccec8 100644 --- a/gdb/testsuite/gdb.dwarf2/arr-opt-out.exp +++ b/gdb/testsuite/gdb.dwarf2/arr-opt-out.exp @@ -29,51 +29,51 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name foo.adb} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_Ada95 + DW_AT_name foo.adb + DW_AT_comp_dir /tmp } { declare_labels integer_label array_label \ low_bound_label high_bound_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } # Note that the bounds don't have a location -- they are # optimized out. This mimics what it is seen sometimes in # the wild with optimized Ada code. low_bound_label: DW_TAG_variable { - {DW_AT_name pck__table___L} - {DW_AT_type :$integer_label} - {DW_AT_declaration 1 flag} + DW_AT_name pck__table___L + DW_AT_type :$integer_label + DW_AT_declaration 1 flag } high_bound_label: DW_TAG_variable { - {DW_AT_name pck__table___U} - {DW_AT_type :$integer_label} - {DW_AT_declaration 1 flag} + DW_AT_name pck__table___U + DW_AT_type :$integer_label + DW_AT_declaration 1 flag } array_label: DW_TAG_array_type { - {DW_AT_name pck__table} - {DW_AT_type :$integer_label} + DW_AT_name pck__table + DW_AT_type :$integer_label } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_lower_bound :$low_bound_label} - {DW_AT_upper_bound :$high_bound_label} + DW_AT_type :$integer_label + DW_AT_lower_bound :$low_bound_label + DW_AT_upper_bound :$high_bound_label } } DW_TAG_variable { - {DW_AT_name the_table} - {DW_AT_type :$array_label} - {DW_AT_location { + DW_AT_name the_table + DW_AT_type :$array_label + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol global_array] - } SPECIAL_expr} - {DW_AT_external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/arr-stride.exp b/gdb/testsuite/gdb.dwarf2/arr-stride.exp index be0fdf3..bad1ffe 100644 --- a/gdb/testsuite/gdb.dwarf2/arr-stride.exp +++ b/gdb/testsuite/gdb.dwarf2/arr-stride.exp @@ -24,86 +24,86 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name foo.adb} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_Ada95 + DW_AT_name foo.adb + DW_AT_comp_dir /tmp } { declare_labels integer_label array_elt_label array_label \ big_array_label struct_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } array_elt_label: DW_TAG_subrange_type { - {DW_AT_lower_bound 0xe0 DW_FORM_data1} - {DW_AT_upper_bound 0x1f DW_FORM_data1} - {DW_AT_name pck__item} - {DW_AT_type :$integer_label} + DW_AT_lower_bound 0xe0 DW_FORM_data1 + DW_AT_upper_bound 0x1f DW_FORM_data1 + DW_AT_name pck__item + DW_AT_type :$integer_label } DW_TAG_typedef { - {DW_AT_name pck__table} - {DW_AT_type :$array_label} + DW_AT_name pck__table + DW_AT_type :$array_label } array_label: DW_TAG_array_type { - {DW_AT_name pck__table} - {DW_AT_bit_stride 6 DW_FORM_data1} - {DW_AT_type :$array_elt_label} + DW_AT_name pck__table + DW_AT_bit_stride 6 DW_FORM_data1 + DW_AT_type :$array_elt_label } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 4 DW_FORM_data1} + DW_AT_type :$integer_label + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 4 DW_FORM_data1 } } DW_TAG_typedef { - {DW_AT_name pck__big_table} - {DW_AT_type :$big_array_label} + DW_AT_name pck__big_table + DW_AT_type :$big_array_label } big_array_label: DW_TAG_array_type { - {DW_AT_name pck__big_table} - {DW_AT_byte_stride 1 DW_FORM_data1} - {DW_AT_type :$array_elt_label} + DW_AT_name pck__big_table + DW_AT_byte_stride 1 DW_FORM_data1 + DW_AT_type :$array_elt_label } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 4 DW_FORM_data1} + DW_AT_type :$integer_label + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 4 DW_FORM_data1 } } struct_label: DW_TAG_structure_type { - {name struct_type} - {byte_size 16 DW_FORM_sdata} + DW_AT_name struct_type + DW_AT_byte_size 16 DW_FORM_sdata } { member { - {name intfield} - {type :$integer_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name intfield + DW_AT_type :$integer_label + DW_AT_data_member_location 0 DW_FORM_sdata } member { - {name arrayfield} - {type :$array_label} - {data_member_location 4 DW_FORM_sdata} + DW_AT_name arrayfield + DW_AT_type :$array_label + DW_AT_data_member_location 4 DW_FORM_sdata } } DW_TAG_variable { - {name the_struct} - {external 1 DW_FORM_flag} - {location { + DW_AT_name the_struct + DW_AT_external 1 DW_FORM_flag + DW_AT_location { DW_OP_const1u 1 DW_OP_stack_value DW_OP_piece 4 DW_OP_piece 12 - } SPECIAL_expr} - {type :$struct_label} + } SPECIAL_expr + DW_AT_type :$struct_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/arr-subrange.exp b/gdb/testsuite/gdb.dwarf2/arr-subrange.exp index 05fe778..24d4600 100644 --- a/gdb/testsuite/gdb.dwarf2/arr-subrange.exp +++ b/gdb/testsuite/gdb.dwarf2/arr-subrange.exp @@ -23,52 +23,52 @@ standard_testfile main.c -dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name foo.adb} - {DW_AT_comp_dir /tmp} - {MACRO_AT_range {main}} - } { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name foo.adb + DW_AT_comp_dir /tmp + MACRO_AT_range {main} + } { declare_labels boolean_label typedef_label array_label enum_label - boolean_label: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_boolean} - {DW_AT_name boolean} - } + boolean_label: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_boolean + DW_AT_name boolean + } - typedef_label: DW_TAG_typedef { - {DW_AT_name pck__table} - {DW_AT_type :$array_label} - } + typedef_label: DW_TAG_typedef { + DW_AT_name pck__table + DW_AT_type :$array_label + } array_label: DW_TAG_array_type { - {DW_AT_name pck__table} - {DW_AT_type :$boolean_label} + DW_AT_name pck__table + DW_AT_type :$boolean_label } { DW_TAG_subrange_type { - {DW_AT_type :$enum_label} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 128 DW_FORM_data1} + DW_AT_type :$enum_label + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 128 DW_FORM_data1 } } enum_label: DW_TAG_enumeration_type { - {DW_AT_name pck__enum_t} - {DW_AT_byte_size 1 DW_FORM_sdata} - } { - DW_TAG_enumerator { - {DW_AT_name pck__enum_000} - {DW_AT_const_value 0 DW_FORM_sdata} - } - DW_TAG_enumerator { - {DW_AT_name pck__enum_001} - {DW_AT_const_value 1 DW_FORM_sdata} - } - DW_TAG_enumerator { - {DW_AT_name pck__enum_128} - {DW_AT_const_value 128 DW_FORM_sdata} - } + DW_AT_name pck__enum_t + DW_AT_byte_size 1 DW_FORM_sdata + } { + DW_TAG_enumerator { + DW_AT_name pck__enum_000 + DW_AT_const_value 0 DW_FORM_sdata + } + DW_TAG_enumerator { + DW_AT_name pck__enum_001 + DW_AT_const_value 1 DW_FORM_sdata + } + DW_TAG_enumerator { + DW_AT_name pck__enum_128 + DW_AT_const_value 128 DW_FORM_sdata + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/assign-variable-value-to-register.exp b/gdb/testsuite/gdb.dwarf2/assign-variable-value-to-register.exp index 64a86ec..1ebd622 100644 --- a/gdb/testsuite/gdb.dwarf2/assign-variable-value-to-register.exp +++ b/gdb/testsuite/gdb.dwarf2/assign-variable-value-to-register.exp @@ -36,29 +36,29 @@ Dwarf::assemble $dwarf_file { declare_labels int_label float_label int_label: DW_TAG_base_type { - { DW_AT_name int } - { DW_AT_byte_size 4 DW_FORM_udata } - { DW_AT_encoding @DW_ATE_signed } + DW_AT_name int + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_encoding @DW_ATE_signed } float_label: DW_TAG_base_type { - { DW_AT_name float } - { DW_AT_byte_size 4 DW_FORM_udata } - { DW_AT_encoding @DW_ATE_float } + DW_AT_name float + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_encoding @DW_ATE_float } DW_TAG_subprogram { - { DW_AT_name main } - { DW_AT_low_pc $main_start DW_FORM_addr } - { DW_AT_high_pc $main_end DW_FORM_addr } - { DW_AT_type :$int_label } + DW_AT_name main + DW_AT_low_pc $main_start DW_FORM_addr + DW_AT_high_pc $main_end DW_FORM_addr + DW_AT_type :$int_label } { DW_TAG_variable { - { DW_AT_name foo } - { DW_AT_type :$float_label } - { DW_AT_location { + DW_AT_name foo + DW_AT_type :$float_label + DW_AT_location [subst { DW_OP_regx $::st0_dwarf_regnum - } SPECIAL_expr } + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/atomic-type.exp b/gdb/testsuite/gdb.dwarf2/atomic-type.exp index 2e6d903..022b63c 100644 --- a/gdb/testsuite/gdb.dwarf2/atomic-type.exp +++ b/gdb/testsuite/gdb.dwarf2/atomic-type.exp @@ -27,54 +27,54 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C11} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_C11 + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels i_l c_l c_c_l ac_c_l pac_c_l vpac_c_l avpac_c_l - i_l: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} - } - - c_l: DW_TAG_base_type { - {DW_AT_byte_size 2 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name char} - } - - c_c_l: DW_TAG_const_type { - {DW_AT_type :$c_l} - } - - ac_c_l: DW_TAG_atomic_type { - {DW_AT_type :$c_c_l} - } - - pac_c_l: DW_TAG_pointer_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_type :$ac_c_l} - } - - vpac_c_l: DW_TAG_volatile_type { - {DW_AT_type :$pac_c_l} - } - - avpac_c_l: DW_TAG_atomic_type { - {DW_AT_type :$vpac_c_l} - } - - DW_TAG_subprogram { - {MACRO_AT_func {f}} - {type :$i_l} - } { - DW_TAG_formal_parameter { - {type :$avpac_c_l} - {name x} - } - } + i_l: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int + } + + c_l: DW_TAG_base_type { + DW_AT_byte_size 2 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name char + } + + c_c_l: DW_TAG_const_type { + DW_AT_type :$c_l + } + + ac_c_l: DW_TAG_atomic_type { + DW_AT_type :$c_c_l + } + + pac_c_l: DW_TAG_pointer_type { + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_type :$ac_c_l + } + + vpac_c_l: DW_TAG_volatile_type { + DW_AT_type :$pac_c_l + } + + avpac_c_l: DW_TAG_atomic_type { + DW_AT_type :$vpac_c_l + } + + DW_TAG_subprogram { + MACRO_AT_func {f} + DW_AT_type :$i_l + } { + DW_TAG_formal_parameter { + DW_AT_type :$avpac_c_l + DW_AT_name x + } + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp index b62f928..0cd26e8 100644 --- a/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp +++ b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp @@ -20,6 +20,7 @@ load_lib dwarf.exp # This test can only be run on targets which support DWARF-2 and use gas. require dwarf2_support +require !readnow standard_testfile main.c -debug.S @@ -32,23 +33,23 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels myint myint: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name myint} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name myint } DW_TAG_namespace { - {DW_AT_name ns} + DW_AT_name ns } { spec: DW_TAG_variable { - {DW_AT_name v} - {DW_AT_type :$myint} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_name v + DW_AT_type :$myint + DW_AT_declaration 1 DW_FORM_flag_present } } } @@ -56,17 +57,17 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { # The new indexer has special code to compute the full # name of an object that uses a specification that appears # later in the DWARF. DW_TAG_variable { - {DW_AT_specification %$spec} - {DW_AT_location { + DW_AT_specification %$spec + DW_AT_location { DW_OP_const1u 23 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } } } @@ -98,6 +99,11 @@ foreach_with_prefix worker_threads $worker_threads_list { gdb_load $binfile + set index [have_index $binfile] + if { ![string eq $index ""] } { + return + } + gdb_test "pipe maint print objfiles | grep ns::v" \ "$ws+qualified:$ws+ns::v" \ "v has parent ns" diff --git a/gdb/testsuite/gdb.dwarf2/bad-regnum.exp b/gdb/testsuite/gdb.dwarf2/bad-regnum.exp index b443f82..eea13af 100644 --- a/gdb/testsuite/gdb.dwarf2/bad-regnum.exp +++ b/gdb/testsuite/gdb.dwarf2/bad-regnum.exp @@ -27,34 +27,34 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_variable { - {DW_AT_name foo1} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name foo1 + DW_AT_type :$integer_label + DW_AT_location { DW_OP_regx 2147483647 - } SPECIAL_expr} - {external 1 flag} + } SPECIAL_expr + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name foo2} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name foo2 + DW_AT_type :$integer_label + DW_AT_location { DW_OP_regx -1 - } SPECIAL_expr} - {external 1 flag} + } SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/bitfield-parent-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/bitfield-parent-optimized-out.exp index d2eb9bf..82eaed7 100644 --- a/gdb/testsuite/gdb.dwarf2/bitfield-parent-optimized-out.exp +++ b/gdb/testsuite/gdb.dwarf2/bitfield-parent-optimized-out.exp @@ -32,37 +32,37 @@ Dwarf::assemble $asm_file { declare_labels struct_label var_label int_label int_label: base_type { - {byte_size 4 sdata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } struct_label: structure_type { - {name S} - {byte_size 8 DW_FORM_sdata} + DW_AT_name S + DW_AT_byte_size 8 DW_FORM_sdata } { member { - {name bitfield} - {type :$int_label} - {bit_size 12 DW_FORM_sdata} - {bit_offset 20 DW_FORM_sdata} + DW_AT_name bitfield + DW_AT_type :$int_label + DW_AT_bit_size 12 DW_FORM_sdata + DW_AT_bit_offset 20 DW_FORM_sdata } member { - {name intfield} - {type :$int_label} - {data_member_location 4 DW_FORM_sdata} + DW_AT_name intfield + DW_AT_type :$int_label + DW_AT_data_member_location 4 DW_FORM_sdata } } subprogram { - {MACRO_AT_func { main }} - {type :$int_label} - {external 1 flag} + MACRO_AT_func { main } + DW_AT_type :$int_label + DW_AT_external 1 flag } { var_label: DW_TAG_variable { - {name var} - {location {} DW_FORM_block1} - {type :$struct_label} + DW_AT_name var + DW_AT_location {} DW_FORM_block1 + DW_AT_type :$struct_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/calling-convention.exp b/gdb/testsuite/gdb.dwarf2/calling-convention.exp index 3cced7d..d3426b9 100644 --- a/gdb/testsuite/gdb.dwarf2/calling-convention.exp +++ b/gdb/testsuite/gdb.dwarf2/calling-convention.exp @@ -42,26 +42,26 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name "calling-convention"} + DW_AT_language @DW_LANG_C + DW_AT_name "calling-convention" } { declare_labels int_label int_label: base_type { - {byte_size [get_sizeof "int" 4] sdata} - {encoding @DW_ATE_signed} - {name "int"} + DW_AT_byte_size [get_sizeof "int" 4] sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } subprogram { - {MACRO_AT_func { foo }} - {type :$int_label} - {calling_convention @DW_CC_nocall} + MACRO_AT_func { foo } + DW_AT_type :$int_label + DW_AT_calling_convention @DW_CC_nocall } subprogram { - {MACRO_AT_func { main }} - {type :$int_label} + MACRO_AT_func { main } + DW_AT_type :$int_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp index b856c5b..d73a3a1 100644 --- a/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp +++ b/gdb/testsuite/gdb.dwarf2/clang-cli-macro.exp @@ -37,22 +37,22 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "clang version 15.0.0"} - {DW_AT_language @DW_LANG_C11} - {DW_AT_name $::srcfile} - {DW_AT_macros $cu_macros DW_FORM_sec_offset} - {DW_AT_stmt_list $L DW_FORM_sec_offset} + DW_AT_producer "clang version 15.0.0" + DW_AT_language @DW_LANG_C11 + DW_AT_name $::srcfile + DW_AT_macros $cu_macros DW_FORM_sec_offset + DW_AT_stmt_list $L DW_FORM_sec_offset } { declare_labels int_type int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$int_type} + MACRO_AT_func {main} + DW_AT_type :$int_type } } } diff --git a/gdb/testsuite/gdb.dwarf2/clztest.exp b/gdb/testsuite/gdb.dwarf2/clztest.exp index 7a74e02..93c2ced 100644 --- a/gdb/testsuite/gdb.dwarf2/clztest.exp +++ b/gdb/testsuite/gdb.dwarf2/clztest.exp @@ -61,7 +61,7 @@ proc scan_gdb_tests {} { continue } - eval $test_cmd + {*}$test_cmd } close $fd } diff --git a/gdb/testsuite/gdb.dwarf2/comp-unit-lang.exp b/gdb/testsuite/gdb.dwarf2/comp-unit-lang.exp index 9b18d9a..f4d9195 100644 --- a/gdb/testsuite/gdb.dwarf2/comp-unit-lang.exp +++ b/gdb/testsuite/gdb.dwarf2/comp-unit-lang.exp @@ -41,13 +41,13 @@ proc do_test {cu_lang gdb_lang} { # both 32- and 64-bit machines. cu { addr_size 4 } { compile_unit { - {name file1.txt} - {language @$cu_lang} - {MACRO_AT_range {func}} + DW_AT_name file1.txt + DW_AT_language @$cu_lang + MACRO_AT_range {func} } { subprogram { - {external 1 flag} - {MACRO_AT_func {func}} + DW_AT_external 1 flag + MACRO_AT_func {func} } { } } diff --git a/gdb/testsuite/gdb.dwarf2/corrupt.exp b/gdb/testsuite/gdb.dwarf2/corrupt.exp index b9f242c..a68b7e3 100644 --- a/gdb/testsuite/gdb.dwarf2/corrupt.exp +++ b/gdb/testsuite/gdb.dwarf2/corrupt.exp @@ -36,31 +36,31 @@ Dwarf::assemble $asm_file { declare_labels int_label int_label: base_type { - {byte_size 4 sdata} - {name "int"} + DW_AT_byte_size 4 sdata + DW_AT_name "int" } enumeration_type { - {name "ENUM"} - {byte_size 4 sdata} + DW_AT_name "ENUM" + DW_AT_byte_size 4 sdata } { enumerator { - {name "A"} - {const_value 0 sdata} + DW_AT_name "A" + DW_AT_const_value 0 sdata } enumerator { - {name "B"} - {const_value 1 sdata} - {sibling 12345678 DW_FORM_ref4} + DW_AT_name "B" + DW_AT_const_value 1 sdata + DW_AT_sibling 12345678 DW_FORM_ref4 } { base_type { - {byte_size 1 sdata} - {name "char"} + DW_AT_byte_size 1 sdata + DW_AT_name "char" } } array_type { - {type :$int_label} - {sibling 12345678 DW_FORM_ref4} + DW_AT_type :$int_label + DW_AT_sibling 12345678 DW_FORM_ref4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/count.exp b/gdb/testsuite/gdb.dwarf2/count.exp index a8b216d..4d2ec31 100644 --- a/gdb/testsuite/gdb.dwarf2/count.exp +++ b/gdb/testsuite/gdb.dwarf2/count.exp @@ -25,100 +25,101 @@ standard_testfile main.c .S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C99}} { + compile_unit { + DW_AT_language @DW_LANG_C99 + } { declare_labels char_label \ array_size_type_label long_unsigned_int_label \ array_label array_label2 static_array_label \ vla_length_label vla_array_label char_label: base_type { - {name char} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name char + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } array_size_type_label: base_type { - {byte_size 8 DW_FORM_sdata} - {encoding @DW_ATE_unsigned} - {name __ARRAY_SIZE_TYPE__} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name __ARRAY_SIZE_TYPE__ } long_unsigned_int_label: base_type { - {byte_size 8 DW_FORM_sdata} - {encoding @DW_ATE_unsigned} - {name "long unsigned int"} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "long unsigned int" } array_label: array_type { - {type :$char_label} + DW_AT_type :$char_label } { subrange_type { - {count {DW_OP_lit5} SPECIAL_expr} - {type :$char_label} + DW_AT_count {DW_OP_lit5} SPECIAL_expr + DW_AT_type :$char_label } } array_label2: array_type { - {type :$char_label} + DW_AT_type :$char_label } { subrange_type { - {count {DW_OP_lit1} SPECIAL_expr} - {type :$char_label} + DW_AT_count {DW_OP_lit1} SPECIAL_expr + DW_AT_type :$char_label } } static_array_label: array_type { - {type :$char_label} + DW_AT_type :$char_label } { subrange_type { - {count 5 DW_FORM_sdata} - {type :$char_label} + DW_AT_count 5 DW_FORM_sdata + DW_AT_type :$char_label } } vla_length_label: DW_TAG_variable { - {location - { - lit6 - stack_value - } SPECIAL_expr} - {name "__vla_array_length"} - {type :$long_unsigned_int_label} - {artificial 1 DW_FORM_flag_present} + DW_AT_location { + lit6 + stack_value + } SPECIAL_expr + DW_AT_name "__vla_array_length" + DW_AT_type :$long_unsigned_int_label + DW_AT_artificial 1 DW_FORM_flag_present } vla_array_label: array_type { - {type :$char_label} + DW_AT_type :$char_label } { subrange_type { - {type :$array_size_type_label} - {count :$vla_length_label} + DW_AT_type :$array_size_type_label + DW_AT_count :$vla_length_label } } DW_TAG_variable { - {name array2} - {type :$array_label2} - {const_value 65 DW_FORM_udata} + DW_AT_name array2 + DW_AT_type :$array_label2 + DW_AT_const_value 65 DW_FORM_udata } DW_TAG_variable { - {name array} - {type :$array_label} - {const_value hello DW_FORM_block1} + DW_AT_name array + DW_AT_type :$array_label + DW_AT_const_value hello DW_FORM_block1 } DW_TAG_variable { - {name static_array} - {type :$static_array_label} - {const_value world DW_FORM_block1} + DW_AT_name static_array + DW_AT_type :$static_array_label + DW_AT_const_value world DW_FORM_block1 } DW_TAG_variable { - {name vla_array} - {type :$vla_array_label} - {const_value saluton DW_FORM_block1} + DW_AT_name vla_array + DW_AT_type :$vla_array_label + DW_AT_const_value saluton DW_FORM_block1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/cpp-linkage-name.exp b/gdb/testsuite/gdb.dwarf2/cpp-linkage-name.exp index 7442399..a21e980 100644 --- a/gdb/testsuite/gdb.dwarf2/cpp-linkage-name.exp +++ b/gdb/testsuite/gdb.dwarf2/cpp-linkage-name.exp @@ -32,49 +32,49 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels a_l b_l a_l: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } # To expose the bug that existed at one point this # structure must have a linkage name, but no name, and the # linkage name is something that doesn't demangle. b_l: DW_TAG_structure_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_linkage_name <anon>} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_linkage_name <anon> } { member { - {name x} - {type :$a_l} - {data_member_location 0 data1} + DW_AT_name x + DW_AT_type :$a_l + DW_AT_data_member_location 0 data1 } member { - {name y} - {type :$a_l} - {data_member_location 0 data1} + DW_AT_name y + DW_AT_type :$a_l + DW_AT_data_member_location 0 data1 } } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$a_l} + MACRO_AT_func {main} + DW_AT_type :$a_l } DW_TAG_variable { - {type :$b_l} - {external 1 flag} - {DW_AT_name global_var} - {DW_AT_location { + DW_AT_type :$b_l + DW_AT_external 1 flag + DW_AT_name global_var + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol global_var] - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/cu-empty-name.exp b/gdb/testsuite/gdb.dwarf2/cu-empty-name.exp index 6bed9e5..6ee55a6 100644 --- a/gdb/testsuite/gdb.dwarf2/cu-empty-name.exp +++ b/gdb/testsuite/gdb.dwarf2/cu-empty-name.exp @@ -27,10 +27,10 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "Tsetsuite"} - {DW_AT_language @DW_LANG_C} - {DW_AT_name ""} - {DW_AT_comp_dir /tmp} + DW_AT_producer "Tsetsuite" + DW_AT_language @DW_LANG_C + DW_AT_name "" + DW_AT_comp_dir /tmp } { } } diff --git a/gdb/testsuite/gdb.dwarf2/cu-no-addrs.exp b/gdb/testsuite/gdb.dwarf2/cu-no-addrs.exp index 7f36878..796f935 100644 --- a/gdb/testsuite/gdb.dwarf2/cu-no-addrs.exp +++ b/gdb/testsuite/gdb.dwarf2/cu-no-addrs.exp @@ -35,13 +35,13 @@ Dwarf::assemble $asm_file { # The PC range here is intentionally empty -- this was the # trigger for the bug. compile_unit { - {language @DW_LANG_C} - {DW_AT_low_pc $main_start DW_FORM_addr} - {DW_AT_high_pc $main_start DW_FORM_addr} + DW_AT_language @DW_LANG_C + DW_AT_low_pc $main_start DW_FORM_addr + DW_AT_high_pc $main_start DW_FORM_addr } { DW_TAG_subprogram { - {DW_AT_name "main"} - {DW_AT_low_pc $main_start DW_FORM_addr} + DW_AT_name "main" + DW_AT_low_pc $main_start DW_FORM_addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/data-loc.exp b/gdb/testsuite/gdb.dwarf2/data-loc.exp index 20500cb..94b9e09 100644 --- a/gdb/testsuite/gdb.dwarf2/data-loc.exp +++ b/gdb/testsuite/gdb.dwarf2/data-loc.exp @@ -34,83 +34,83 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name foo.adb} - {DW_AT_comp_dir /tmp} - } { - declare_labels integer_label array_label array_ptr_label + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name foo.adb + DW_AT_comp_dir /tmp + } { + declare_labels integer_label array_label array_ptr_label set int_size [get_sizeof "int" 4] set voidp_size [get_sizeof "void *" 96] - integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} - } + integer_label: DW_TAG_base_type { + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer + } array_label: DW_TAG_array_type { - {DW_AT_name foo__array_type} - {DW_AT_type :$integer_label} - {DW_AT_data_location { - DW_OP_push_object_address - DW_OP_deref - } SPECIAL_expr} - {external 1 flag} + DW_AT_name foo__array_type + DW_AT_type :$integer_label + DW_AT_data_location { + DW_OP_push_object_address + DW_OP_deref + } SPECIAL_expr + DW_AT_external 1 flag } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_lower_bound { - DW_OP_push_object_address - DW_OP_plus_uconst $voidp_size - DW_OP_deref - DW_OP_deref_size $int_size - } SPECIAL_expr} - {DW_AT_upper_bound { - DW_OP_push_object_address - DW_OP_plus_uconst $voidp_size - DW_OP_deref - DW_OP_plus_uconst $int_size - DW_OP_deref_size $int_size - } SPECIAL_expr} + DW_AT_type :$integer_label + DW_AT_lower_bound [subst { + DW_OP_push_object_address + DW_OP_plus_uconst $voidp_size + DW_OP_deref + DW_OP_deref_size $int_size + }] SPECIAL_expr + DW_AT_upper_bound [subst { + DW_OP_push_object_address + DW_OP_plus_uconst $voidp_size + DW_OP_deref + DW_OP_plus_uconst $int_size + DW_OP_deref_size $int_size + }] SPECIAL_expr } } - array_ptr_label: DW_TAG_typedef { - {DW_AT_name foo__array_type} - {DW_AT_type :$array_label} - } - DW_TAG_variable { - {DW_AT_name foo__three} - {DW_AT_type :$array_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_1] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__three_tdef} - {DW_AT_type :$array_ptr_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_1] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__five} - {DW_AT_type :$array_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_2] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__five_tdef} - {DW_AT_type :$array_ptr_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_2] - } SPECIAL_expr} - {external 1 flag} - } + array_ptr_label: DW_TAG_typedef { + DW_AT_name foo__array_type + DW_AT_type :$array_label + } + DW_TAG_variable { + DW_AT_name foo__three + DW_AT_type :$array_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_1] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__three_tdef + DW_AT_type :$array_ptr_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_1] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__five + DW_AT_type :$array_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_2] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__five_tdef + DW_AT_type :$array_ptr_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_2] + }] SPECIAL_expr + DW_AT_external 1 flag + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/debug-aranges-duplicate-offset-warning.exp b/gdb/testsuite/gdb.dwarf2/debug-aranges-duplicate-offset-warning.exp index ac9c774..9ac9d94 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-aranges-duplicate-offset-warning.exp +++ b/gdb/testsuite/gdb.dwarf2/debug-aranges-duplicate-offset-warning.exp @@ -31,20 +31,20 @@ Dwarf::assemble $asm_file { cu { label cu_label } { compile_unit { - {language @DW_LANG_C} - {name $srcfile} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc $main_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len DW_FORM_data4 } subprogram { - {external 1 flag} - {name frame2} - {low_pc $frame2_start addr} - {high_pc $frame2_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name frame2 + DW_AT_low_pc $frame2_start addr + DW_AT_high_pc $frame2_len DW_FORM_data4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-bad-cu-index.exp b/gdb/testsuite/gdb.dwarf2/debug-names-bad-cu-index.exp index c758db7..016478f 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-names-bad-cu-index.exp +++ b/gdb/testsuite/gdb.dwarf2/debug-names-bad-cu-index.exp @@ -21,7 +21,7 @@ require dwarf2_support standard_testfile _start.c debug-names.S set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] + [get_func_info _start [list debug ldflags=-nostartfiles]] # Create the DWARF. set asm_file [standard_output_file $srcfile2] @@ -35,11 +35,13 @@ Dwarf::assemble { } cu { label cu_label } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} + DW_AT_name _start + DW_AT_low_pc $_start_start DW_FORM_addr + DW_AT_high_pc $_start_end DW_FORM_addr } } } @@ -49,18 +51,18 @@ Dwarf::assemble { declare_labels int_type structure_type { - {name struct_with_int_member} - {byte_size 4 sdata} + DW_AT_name struct_with_int_member + DW_AT_byte_size 4 sdata } { member { - {name member} - {type :$int_type} + DW_AT_name member + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } @@ -74,7 +76,7 @@ Dwarf::assemble { } if {[build_executable ${testfile}.exp $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] == -1} { + [list ldflags=-nostartfiles]] == -1} { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-duplicate-cu.exp b/gdb/testsuite/gdb.dwarf2/debug-names-duplicate-cu.exp index 44d623b..28f2157 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-names-duplicate-cu.exp +++ b/gdb/testsuite/gdb.dwarf2/debug-names-duplicate-cu.exp @@ -21,7 +21,7 @@ require dwarf2_support standard_testfile _start.c debug-names.S set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] + [get_func_info _start [list debug ldflags=-nostartfiles]] # Create the DWARF. set asm_file [standard_output_file $srcfile2] @@ -35,16 +35,18 @@ Dwarf::assemble { } cu { label cu_label } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} + DW_AT_name _start + DW_AT_low_pc $_start_start DW_FORM_addr + DW_AT_high_pc $_start_end DW_FORM_addr } base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } } } @@ -58,7 +60,7 @@ Dwarf::assemble { } if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] { + [list ldflags=-nostartfiles]] { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp b/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp index d7d4fb8..77db144 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp +++ b/gdb/testsuite/gdb.dwarf2/debug-names-missing-cu.exp @@ -18,10 +18,14 @@ load_lib dwarf.exp # This test can only be run on targets which support DWARF-2 and use gas. require dwarf2_support +# This test checks that no CU is initially expanded, which is negated +# by readnow. +require !readnow + standard_testfile _start.c debug-names.S set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] + [get_func_info _start [list debug ldflags=-nostartfiles]] # Create the DWARF. set asm_file [standard_output_file $srcfile2] @@ -35,16 +39,18 @@ Dwarf::assemble { } cu { label cu_label } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} + DW_AT_name _start + DW_AT_low_pc $_start_start DW_FORM_addr + DW_AT_high_pc $_start_end DW_FORM_addr } base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } } } @@ -61,7 +67,7 @@ Dwarf::assemble { } if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] { + [list ldflags=-nostartfiles]] { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-non-ascending-cu.exp b/gdb/testsuite/gdb.dwarf2/debug-names-non-ascending-cu.exp deleted file mode 100644 index d86b5c4..0000000 --- a/gdb/testsuite/gdb.dwarf2/debug-names-non-ascending-cu.exp +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2022-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/>. - -load_lib dwarf.exp - -# This test can only be run on targets which support DWARF-2 and use gas. -require dwarf2_support - -standard_testfile _start.c debug-names.S - -set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] - -# Create the DWARF. -set asm_file [standard_output_file $srcfile2] -Dwarf::assemble { - filename $asm_file - add_dummy_cus 0 -} { - global func_info_vars - foreach var $func_info_vars { - global $var - } - - cu { label cu_label } { - compile_unit {{language @DW_LANG_C}} { - subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} - } - } - } - - cu { label cu_label_2 } { - compile_unit {{language @DW_LANG_C}} { - base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} - } - } - } - - debug_names {} { - cu cu_label_2 - cu cu_label - name _start subprogram cu_label 0xEDDB6232 - name int base_type cu_label 0xB888030 - } -} - -if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] { - return -1 -} - -# Check for warning. -set re \ - [list \ - "warning:" \ - "Section .debug_names has incorrect entry in CU table," \ - "ignoring .debug_names."] -set re [join $re] -gdb_assert {[regexp $re $gdb_file_cmd_msg]} "warning" - -# Verify that .debug_names section is ignored. -set index [have_index $binfile] -gdb_assert { [string equal $index ""] } ".debug_names not used" diff --git a/gdb/testsuite/gdb.dwarf2/debug-names-tu.exp.tcl b/gdb/testsuite/gdb.dwarf2/debug-names-tu.exp.tcl index 60d1d0d..4de96ff 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-names-tu.exp.tcl +++ b/gdb/testsuite/gdb.dwarf2/debug-names-tu.exp.tcl @@ -18,10 +18,14 @@ load_lib dwarf.exp # This test can only be run on targets which support DWARF-2 and use gas. require dwarf2_support +# When using readnow, the index isn't used, which invalidates this +# test. +require !readnow + standard_testfile _start.c debug-names.S set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] + [get_func_info _start [list debug ldflags=-nostartfiles]] # Create the DWARF. set asm_file [standard_output_file $srcfile2] @@ -36,32 +40,36 @@ Dwarf::assemble { } cu { label cu_label version $dwarf_version } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} + DW_AT_name _start + DW_AT_low_pc $_start_start DW_FORM_addr + DW_AT_high_pc $_start_end DW_FORM_addr } } } tu { label tu_label version $dwarf_version } 0x8ece66f4224fddb3 "" { - type_unit {{language @DW_LANG_C}} { + type_unit { + DW_AT_language @DW_LANG_C + } { declare_labels int_type structure_type { - {name struct_with_int_member} - {byte_size 4 sdata} + DW_AT_name struct_with_int_member + DW_AT_byte_size 4 sdata } { member { - {name member} - {type :$int_type} + DW_AT_name member + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } @@ -76,7 +84,7 @@ Dwarf::assemble { } if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] { + [list ldflags=-nostartfiles]] { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/debug-names.exp b/gdb/testsuite/gdb.dwarf2/debug-names.exp index 67a4f49..7f63af2 100644 --- a/gdb/testsuite/gdb.dwarf2/debug-names.exp +++ b/gdb/testsuite/gdb.dwarf2/debug-names.exp @@ -21,7 +21,7 @@ require dwarf2_support standard_testfile _start.c debug-names.S set func_info_vars \ - [get_func_info _start [list debug additional_flags=-nostartfiles]] + [get_func_info _start [list debug ldflags=-nostartfiles]] # Create the DWARF. set asm_file [standard_output_file $srcfile2] @@ -35,16 +35,18 @@ Dwarf::assemble { } cu { label cu_label } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {DW_AT_name _start} - {DW_AT_low_pc $_start_start DW_FORM_addr} - {DW_AT_high_pc $_start_end DW_FORM_addr} + DW_AT_name _start + DW_AT_low_pc $_start_start DW_FORM_addr + DW_AT_high_pc $_start_end DW_FORM_addr } base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } } } @@ -57,7 +59,7 @@ Dwarf::assemble { } if [prepare_for_testing "failed to prepare" $testfile "${asm_file} ${srcfile}" \ - [list additional_flags=-nostartfiles]] { + [list ldflags=-nostartfiles]] { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-ref-addr-with-type-units.exp b/gdb/testsuite/gdb.dwarf2/dw-form-ref-addr-with-type-units.exp new file mode 100644 index 0000000..396fd94 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw-form-ref-addr-with-type-units.exp @@ -0,0 +1,109 @@ +# 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/>. + +# This is a reproducer for PR 29518: +# +# https://sourceware.org/bugzilla/show_bug.cgi?id=29518 +# +# The root cause for the problem was that function +# dwarf2_find_containing_comp_unit was searching the whole "all_units" vector, +# containing both compile units and type units, causing it to sometimes +# erroneously return a type unit. It should have been restricted to searching +# compile units. +# +# To get dwarf2_find_containing_comp_unit to be called and reproduce the +# original bug, we need a value with form DW_FORM_ref_addr pointing to a +# different compile unit. This is produced by `%$int_type` below. + +load_lib dwarf.exp +require dwarf2_support +standard_testfile main.c .S + +set asm_file [standard_output_file $srcfile2] + +Dwarf::assemble $asm_file { + global srcfile + declare_labels int_type + + # The source CU. + cu {version 4} { + compile_unit { + } { + subprogram { + MACRO_AT_func {main} + DW_AT_type %$int_type + } + } + } + + # Create a bunch of empty / dummy CUs, to make the offset of int_type a bit + # higher. + for {set i 1} {$i < 10} {incr i} { + cu {version 4} { + compile_unit {} {} + } + } + + # The target CU. + cu {version 4} { + compile_unit { + } { + int_type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int + } + } + } + + # Create many TUs. + # + # We need enough type units in the "all_units" vector in order to steer the + # binary search in dwarf2_find_containing_comp_unit towards the type units + # region of the array. + for {set i 1} {$i < 20} {incr i} { + tu {version 4} $i the_type_i { + type_unit {} { + declare_labels dummy_int_type + + the_type_i: structure_type { + DW_AT_name s + DW_AT_byte_size 4 sdata + } { + member { + DW_AT_name i + DW_AT_type :$dummy_int_type + } + } + + dummy_int_type: base_type { + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata + } + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +# Without the corresponding fix, we get an internal error: +# +# gdb/dwarf2/read.c:3940: internal-error: load_full_comp_unit: Assertion `! this_cu->is_debug_types' failed. +gdb_test "p main" " = {int \\(void\\)} $hex <main>" diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp b/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp new file mode 100644 index 0000000..cb24b19 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp @@ -0,0 +1,41 @@ +# 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/>. + +# Check that an out-of-bounds DW_FORM_strx attribute triggers a DWARF error. + +# Out of bounds index. +set int_str_idx 1 + +# With readnow, the dwarf error is printed during the file command, so skip +# the test. +require !readnow + +set prepare_for_testing_done 0 +source $srcdir/$subdir/dw-form-strx.exp.tcl +require {expr $prepare_for_testing_done == 1} + +set re_dwarf_error \ + [string_list_to_regexp \ + "DWARF Error: Offset from DW_FORM_GNU_str_index or DW_FORM_strx" \ + " pointing outside of .debug_str_offsets section in CU at offset"\ + " "]$hex +set re_in_module \ + {in module [^\r\n]+} +set re_in_module [string_to_regexp {[}]$re_in_module[string_to_regexp {]}] +set re_no_symbol [string_to_regexp {No symbol "global_var" in current context.}] +gdb_test "ptype global_var" \ + [multi_line \ + "$re_dwarf_error $re_in_module"\ + $re_no_symbol] diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp new file mode 100644 index 0000000..3f739c4 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp @@ -0,0 +1,25 @@ +# 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/>. + +# Check that DW_FORM_strx works. + +# Correct index. +set int_str_idx 0 + +set prepare_for_testing_done 0 +source $srcdir/$subdir/dw-form-strx.exp.tcl +require {expr $prepare_for_testing_done == 1} + +gdb_test "ptype global_var" "type = int" diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl new file mode 100644 index 0000000..0e5cee2 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl @@ -0,0 +1,64 @@ +# 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/>. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile main.c -dw.S + +set asm_file [standard_output_file $srcfile2] + +# Debug info in the main file. +Dwarf::assemble $asm_file { + declare_labels base_offset_cu1 + + debug_str_offsets { base_offset base_offset_cu1 } int + + cu { + version 5 + } { + DW_TAG_compile_unit { + DW_AT_str_offsets_base $base_offset_cu1 sec_offset + } { + declare_labels int4_type + + int4_type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name $::int_str_idx DW_FORM_strx_id + } + + DW_TAG_variable { + DW_AT_name global_var + DW_AT_type :$int4_type + DW_AT_location { + DW_OP_const1u 12 + DW_OP_stack_value + } SPECIAL_expr + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return +} + +# Let includers know prepare_for_testing was done, without having to check +# source return status. +set prepare_for_testing_done 1 diff --git a/gdb/testsuite/gdb.dwarf2/dw2-align.exp b/gdb/testsuite/gdb.dwarf2/dw2-align.exp index 4d43816..dfb11af 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-align.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-align.exp @@ -27,39 +27,39 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels itype ptype - itype: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int_4096} - {DW_AT_alignment 4096 DW_FORM_sdata} - } + itype: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int_4096 + DW_AT_alignment 4096 DW_FORM_sdata + } - ptype: DW_TAG_pointer_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_type :$itype} - {DW_AT_alignment 4096 DW_FORM_sdata} - } + ptype: DW_TAG_pointer_type { + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_type :$itype + DW_AT_alignment 4096 DW_FORM_sdata + } - DW_TAG_typedef { - {DW_AT_name ptr_4096} - {DW_AT_type :$ptype} - } + DW_TAG_typedef { + DW_AT_name ptr_4096 + DW_AT_type :$ptype + } DW_TAG_structure_type { - {DW_AT_name "struct_4096"} - {DW_AT_byte_size 4096 DW_FORM_sdata} - {DW_AT_alignment 4096 DW_FORM_udata} + DW_AT_name "struct_4096" + DW_AT_byte_size 4096 DW_FORM_sdata + DW_AT_alignment 4096 DW_FORM_udata } { member { - {name a} - {type :$itype} - {data_member_location 0 data1} + DW_AT_name a + DW_AT_type :$itype + DW_AT_data_member_location 0 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp index 8d941ba..928edf0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp @@ -25,14 +25,17 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu { label cu_start } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { } } aranges { addr_zero true } cu_start { } } -if { [prepare_for_testing "failed to prepare" $binfile [list $asm_file $srcfile ]] } { +if { [prepare_for_testing "failed to prepare" $testfile \ + [list $asm_file $srcfile ]] } { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-abstract-origin.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-abstract-origin.exp index 9c1f424..0ee06b0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bad-abstract-origin.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-abstract-origin.exp @@ -93,75 +93,75 @@ proc run_test { dwarf_version } { cu { version $dwarf_version } { compile_unit { - {producer "GNU C 14.1.0"} - {language @DW_LANG_C} - {name $::srcfile} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "GNU C 14.1.0" + DW_AT_language @DW_LANG_C + DW_AT_name $::srcfile + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { int_label: base_type { - {name "int"} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } foo_func: subprogram { - {name foo} - {inline @DW_INL_declared_inlined} - {decl_file 1 data1} - {decl_line $::func_a_decl_line data1} + DW_AT_name foo + DW_AT_inline @DW_INL_declared_inlined + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::func_a_decl_line data1 } { foo_block: lexical_block { } { value_label: DW_TAG_variable { - {name value} - {type :$int_label} + DW_AT_name value + DW_AT_type :$int_label } } } subprogram { - {abstract_origin %$foo_func} - {low_pc func_a_0 addr} - {high_pc func_a_6 addr} - {external 1 flag} + DW_AT_abstract_origin %$foo_func + DW_AT_low_pc func_a_0 addr + DW_AT_high_pc func_a_6 addr + DW_AT_external 1 flag } { bad_block: lexical_block { - {abstract_origin %$foo_block} - {ranges $block_ranges DW_FORM_sec_offset} + DW_AT_abstract_origin %$foo_block + DW_AT_ranges $block_ranges DW_FORM_sec_offset } { DW_TAG_variable { - {abstract_origin %$value_label} - {DW_AT_location { + DW_AT_abstract_origin %$value_label + DW_AT_location { DW_OP_const1u 23 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } } } subprogram { - {name baz} - {low_pc func_b_0 addr} - {high_pc func_b_5 addr} - {external 1 flag} + DW_AT_name baz + DW_AT_low_pc func_b_0 addr + DW_AT_high_pc func_b_5 addr + DW_AT_external 1 flag } { inlined_subroutine { - {abstract_origin %$foo_func} - {call_file 1 data1} - {call_line $::call_line data1} - {low_pc func_b_1 addr} - {high_pc func_b_4 addr} + DW_AT_abstract_origin %$foo_func + DW_AT_call_file 1 data1 + DW_AT_call_line $::call_line data1 + DW_AT_low_pc func_b_1 addr + DW_AT_high_pc func_b_4 addr } { lexical_block { - {abstract_origin %$bad_block} - {low_pc func_b_2 addr} - {high_pc func_b_3 addr} + DW_AT_abstract_origin %$bad_block + DW_AT_low_pc func_b_2 addr + DW_AT_high_pc func_b_3 addr } { DW_TAG_variable { - {abstract_origin %$value_label} - {DW_AT_location { + DW_AT_abstract_origin %$value_label + DW_AT_location { DW_OP_const1u 99 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp index fa9d000..a0ae498 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp @@ -54,56 +54,56 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir ${srcdir}/${subdir}} - {stmt_list $L1 DW_FORM_sec_offset} - {ranges ${ranges_label_1} DW_FORM_sec_offset} - {DW_AT_low_pc 0 addr} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir ${srcdir}/${subdir} + DW_AT_stmt_list $L1 DW_FORM_sec_offset + DW_AT_ranges ${ranges_label_1} DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { declare_labels integer_label DW_TAG_subprogram { - {name main} - {low_pc $main_start addr} - {high_pc $main_length data8} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 10 data1} + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_length data8 + DW_AT_type :$integer_label + DW_AT_decl_file 1 data1 + DW_AT_decl_line 10 data1 } integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } } } cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile2} - {DW_AT_comp_dir ${srcdir}/${subdir}} - {stmt_list $L2 DW_FORM_sec_offset} - {ranges ${ranges_label_2} DW_FORM_sec_offset} - {DW_AT_low_pc 0 addr} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile2 + DW_AT_comp_dir ${srcdir}/${subdir} + DW_AT_stmt_list $L2 DW_FORM_sec_offset + DW_AT_ranges ${ranges_label_2} DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { declare_labels integer_label DW_TAG_subprogram { - {name some_func} - {low_pc some_func addr} - {high_pc some_func_end addr} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 2 data1} - {DW_AT_decl_line 5 data1} + DW_AT_name some_func + DW_AT_low_pc some_func addr + DW_AT_high_pc some_func_end addr + DW_AT_type :$integer_label + DW_AT_decl_file 2 data1 + DW_AT_decl_line 5 data1 } integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } } } @@ -170,7 +170,7 @@ if { [build_executable ${testfile}.exp ${testfile} \ proc run_test { goto_main } { global binfile decimal hex - clean_restart ${binfile} + clean_restart ${::testfile} if { $goto_main } { if ![runto_main] { diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-mips-linkage-name.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-mips-linkage-name.exp index f2534cb..ad65842 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bad-mips-linkage-name.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-mips-linkage-name.exp @@ -28,27 +28,26 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - - } { + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels b_l b_l: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name bool} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name bool } - DW_TAG_subprogram { - {MACRO_AT_func {f}} - {type :$b_l} - {DW_AT_MIPS_linkage_name _Z1fv} + DW_TAG_subprogram { + MACRO_AT_func {f} + DW_AT_type :$b_l + DW_AT_MIPS_linkage_name _Z1fv } - DW_TAG_subprogram { - {MACRO_AT_func {g}} - {type :$b_l} - {DW_AT_MIPS_linkage_name 42 DW_FORM_data1} + DW_TAG_subprogram { + MACRO_AT_func {g} + DW_AT_type :$b_l + DW_AT_MIPS_linkage_name 42 DW_FORM_data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-unresolved.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-unresolved.exp index fd2c899..dba8d5e 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bad-unresolved.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-unresolved.exp @@ -30,21 +30,21 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels b_l b_l: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name bool} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name bool } DW_TAG_variable { - {name var} - {type :$b_l} - {external 1 flag} + DW_AT_name var + DW_AT_type :$b_l + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bfloat16.exp b/gdb/testsuite/gdb.dwarf2/dw2-bfloat16.exp index c611ad2..b8f96a1 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bfloat16.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bfloat16.exp @@ -32,35 +32,35 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels bf16_type fp16_type \ bf16_var fp16_var - bf16_type: DW_TAG_base_type { - {DW_AT_name __bf16} - {encoding @DW_ATE_float} - {DW_AT_byte_size 2 DW_FORM_sdata} - } + bf16_type: DW_TAG_base_type { + DW_AT_name __bf16 + DW_AT_encoding @DW_ATE_float + DW_AT_byte_size 2 DW_FORM_sdata + } - fp16_type: DW_TAG_base_type { - {DW_AT_name __fp16} - {encoding @DW_ATE_float} - {DW_AT_byte_size 2 DW_FORM_sdata} - } + fp16_type: DW_TAG_base_type { + DW_AT_name __fp16 + DW_AT_encoding @DW_ATE_float + DW_AT_byte_size 2 DW_FORM_sdata + } bf16_var: DW_TAG_variable { - {DW_AT_name "bf16_1"} - {DW_AT_type :${bf16_type}} - {DW_AT_const_value 0x4049 DW_FORM_sdata} + DW_AT_name "bf16_1" + DW_AT_type :${bf16_type} + DW_AT_const_value 0x4049 DW_FORM_sdata } fp16_var: DW_TAG_variable { - {DW_AT_name "fp16_1"} - {DW_AT_type :${fp16_type}} - {DW_AT_const_value 0x4248 DW_FORM_sdata} + DW_AT_name "fp16_1" + DW_AT_type :${fp16_type} + DW_AT_const_value 0x4248 DW_FORM_sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp index 34746f2..509924a 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp @@ -52,14 +52,14 @@ Dwarf::assemble $asm_file { declare_labels int_type int_type: DW_TAG_base_type { - {DW_AT_byte_size $::int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size $::int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$int_type} + MACRO_AT_func {main} + DW_AT_type :$int_type } # GCC complex float. @@ -67,36 +67,36 @@ Dwarf::assemble $asm_file { declare_labels cf_type cd_type cld_type cf_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex float"} + DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex float" } cd_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex double"} + DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex double" } cld_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex long double"} + DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex long double" } DW_TAG_variable { - {name var_complex_float} - {DW_AT_type :$cf_type} + DW_AT_name var_complex_float + DW_AT_type :$cf_type } DW_TAG_variable { - {name var_complex_double} - {DW_AT_type :$cd_type} + DW_AT_name var_complex_double + DW_AT_type :$cd_type } DW_TAG_variable { - {name var_complex_long_double} - {DW_AT_type :$cld_type} + DW_AT_name var_complex_long_double + DW_AT_type :$cld_type } # GCC complex int. @@ -105,14 +105,14 @@ Dwarf::assemble $asm_file { declare_labels ci_type ci_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::int_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_lo_user} - {DW_AT_name "complex int"} + DW_AT_byte_size [expr 2 * $::int_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_lo_user + DW_AT_name "complex int" } DW_TAG_variable { - {name var_complex_int} - {DW_AT_type :$ci_type} + DW_AT_name var_complex_int + DW_AT_type :$ci_type } # Clang complex float. @@ -122,36 +122,36 @@ Dwarf::assemble $asm_file { declare_labels clang_cf_type clang_cd_type clang_cld_type clang_cf_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex"} + DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex" } DW_TAG_variable { - {name var_complex_clang_float} - {DW_AT_type :$clang_cf_type} + DW_AT_name var_complex_clang_float + DW_AT_type :$clang_cf_type } clang_cd_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex"} + DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex" } DW_TAG_variable { - {name var_complex_clang_double} - {DW_AT_type :$clang_cd_type} + DW_AT_name var_complex_clang_double + DW_AT_type :$clang_cd_type } clang_cld_type: DW_TAG_base_type { - {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_complex_float} - {DW_AT_name "complex"} + DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata + DW_AT_encoding @DW_ATE_complex_float + DW_AT_name "complex" } DW_TAG_variable { - {name var_complex_clang_long_double} - {DW_AT_type :$clang_cld_type} + DW_AT_name var_complex_clang_long_double + DW_AT_type :$clang_cld_type } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-disasm-over-non-stmt.exp b/gdb/testsuite/gdb.dwarf2/dw2-disasm-over-non-stmt.exp index cec1017..ddbab26 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-disasm-over-non-stmt.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-disasm-over-non-stmt.exp @@ -43,15 +43,15 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {producer "gcc" } - {language @DW_LANG_C} - {name ${srcfile3}} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile3} + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-empty-file-name.exp b/gdb/testsuite/gdb.dwarf2/dw2-empty-file-name.exp index 85b6f8b..2a32433 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-empty-file-name.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-empty-file-name.exp @@ -33,13 +33,13 @@ Dwarf::assemble $asm_file { cu { version 5 } { compile_unit { - {language @DW_LANG_C} - {name $srcfile} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-entry-pc.exp b/gdb/testsuite/gdb.dwarf2/dw2-entry-pc.exp index e795040..1a0eeba 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-entry-pc.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-entry-pc.exp @@ -159,20 +159,20 @@ proc_with_prefix use_low_high_bounds_without_entry_pc { dwarf_vesion } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {low_pc $::foo_start addr} - {high_pc $::foo_len $::ptr_type} - {external 1 flag} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_low_pc $::foo_start addr + DW_AT_high_pc $::foo_len $::ptr_type + DW_AT_external 1 flag } } } @@ -202,21 +202,21 @@ proc_with_prefix use_low_high_bounds_with_entry_pc { dwarf_version } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {low_pc $::foo_start addr} - {high_pc $::foo_len $::ptr_type} - {external 1 flag} - {entry_pc foo_middle addr} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_low_pc $::foo_start addr + DW_AT_high_pc $::foo_len $::ptr_type + DW_AT_external 1 flag + DW_AT_entry_pc foo_middle addr } } } @@ -248,21 +248,21 @@ proc_with_prefix use_low_high_bounds_with_entry_offset { dwarf_version } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {low_pc $::foo_start addr} - {high_pc $::foo_len $::ptr_type} - {external 1 flag} - {entry_pc $foo_offset data4} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_low_pc $::foo_start addr + DW_AT_high_pc $::foo_len $::ptr_type + DW_AT_external 1 flag + DW_AT_entry_pc $foo_offset data4 } } } @@ -293,20 +293,20 @@ proc_with_prefix use_ranges_without_entry_pc { dwarf_version } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {external 1 flag} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_external 1 flag + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } } } @@ -357,21 +357,21 @@ proc_with_prefix use_ranges_with_entry_pc { dwarf_version } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {external 1 flag} - {ranges ${ranges_label} DW_FORM_sec_offset} - {entry_pc foo_middle addr} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_external 1 flag + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset + DW_AT_entry_pc foo_middle addr } } } @@ -424,21 +424,21 @@ proc_with_prefix use_ranges_with_entry_offset { dwarf_version } { cu { version $::dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {external 1 flag} - {ranges ${ranges_label} DW_FORM_sec_offset} - {entry_pc $foo_offset data4} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_external 1 flag + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset + DW_AT_entry_pc $foo_offset data4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-entry-points.c b/gdb/testsuite/gdb.dwarf2/dw2-entry-points.c index ccfb150..258ebfa 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-entry-points.c +++ b/gdb/testsuite/gdb.dwarf2/dw2-entry-points.c @@ -33,11 +33,28 @@ bar_helper (void) asm ("foobar_entry_label: .globl foobar_entry_label"); } +__attribute__ ((noinline)) +void +barso_helper (void) +{ + asm ("barso_helper_label: .globl barso_helper_label"); + I++; + J++; + asm ("fooso_entry_label: .globl fooso_entry_label"); + J++; + K++; + asm ("foobarso_entry_label: .globl foobarso_entry_label"); +} + int main (void) { asm ("main_label: .globl main_label"); bar_helper (); + I = 0; + J = 0; + K = 0; + barso_helper (); return 0; } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-entry-points.exp b/gdb/testsuite/gdb.dwarf2/dw2-entry-points.exp index bd22560..97194d5 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-entry-points.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-entry-points.exp @@ -36,6 +36,7 @@ Dwarf::assemble $asm_file { get_func_info main get_func_info bar_helper + get_func_info barso_helper set int_size [get_sizeof "int" 4] @@ -50,69 +51,69 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_Fortran90} - {name dw2-entry-points.f90} - {comp_dir /tmp} + DW_AT_language @DW_LANG_Fortran90 + DW_AT_name dw2-entry-points.f90 + DW_AT_comp_dir /tmp } { int_label: base_type { - {name "int"} - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed } subprogram { - {name prog} - {decl_file 1 data1} - {decl_line $prog_line data1} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} - {external 1 flag} - {main_subprogram 1 flag} + DW_AT_name prog + DW_AT_decl_file 1 data1 + DW_AT_decl_line $prog_line data1 + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr + DW_AT_external 1 flag + DW_AT_main_subprogram 1 flag } subprogram { - {name bar} - {decl_file 1 data1} - {decl_line $bar_line data1} - {external 1 flag} - {low_pc $bar_helper_start addr} - {high_pc "$bar_helper_start + $bar_helper_len" addr} + DW_AT_name bar + DW_AT_decl_file 1 data1 + DW_AT_decl_line $bar_line data1 + DW_AT_external 1 flag + DW_AT_low_pc $bar_helper_start addr + DW_AT_high_pc "$bar_helper_start + $bar_helper_len" addr } { formal_parameter { - {name I} - {type :$int_label} - {location {addr $global_I} SPECIAL_expr} + DW_AT_name I + DW_AT_type :$int_label + DW_AT_location [subst {addr $global_I}] SPECIAL_expr } formal_parameter { - {name J} - {type :$int_label} - {location {addr $global_J} SPECIAL_expr} + DW_AT_name J + DW_AT_type :$int_label + DW_AT_location [subst {addr $global_J}] SPECIAL_expr } entry_point { - {name foo} - {decl_file 1 data1} - {decl_line $foo_line data1} - {low_pc foo_entry_label addr} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $foo_line data1 + DW_AT_low_pc foo_entry_label addr } { formal_parameter { - {name J} - {type :$int_label} - {location {addr $global_J} SPECIAL_expr} + DW_AT_name J + DW_AT_type :$int_label + DW_AT_location [subst {addr $global_J}] SPECIAL_expr } formal_parameter { - {name K} - {type :$int_label} - {location {addr $global_K} SPECIAL_expr} + DW_AT_name K + DW_AT_type :$int_label + DW_AT_location [subst {addr $global_K}] SPECIAL_expr } } entry_point { - {name foobar} - {decl_file 1 data1} - {decl_line $foobar_line data1} - {low_pc foobar_entry_label addr} + DW_AT_name foobar + DW_AT_decl_file 1 data1 + DW_AT_decl_line $foobar_line data1 + DW_AT_low_pc foobar_entry_label addr } { formal_parameter { - {name J} - {type :$int_label} - {location {addr $global_J} SPECIAL_expr} + DW_AT_name J + DW_AT_type :$int_label + DW_AT_location [subst {addr $global_J}] SPECIAL_expr } } } @@ -121,48 +122,48 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_Fortran90} - {name dw2-entry-points-2.f90} - {comp_dir /tmp} + DW_AT_language @DW_LANG_Fortran90 + DW_AT_name dw2-entry-points-2.f90 + DW_AT_comp_dir /tmp } { int2_label: base_type { - {name "int"} - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed } subprogram { - {name barso} - {decl_file 1 data1} - {decl_line $bar_line data1} - {external 1 flag} - {low_pc $bar_helper_start addr} - {high_pc "$bar_helper_start + $bar_helper_len" addr} + DW_AT_name barso + DW_AT_decl_file 1 data1 + DW_AT_decl_line $bar_line data1 + DW_AT_external 1 flag + DW_AT_low_pc $barso_helper_start addr + DW_AT_high_pc "$barso_helper_start + $barso_helper_len" addr } { formal_parameter { - {name I} - {type :$int2_label} - {location {addr $global_I} SPECIAL_expr} + DW_AT_name I + DW_AT_type :$int2_label + DW_AT_location [subst {addr $global_I}] SPECIAL_expr } formal_parameter { - {name J} - {type :$int2_label} - {location {addr $global_J} SPECIAL_expr} + DW_AT_name J + DW_AT_type :$int2_label + DW_AT_location [subst {addr $global_J}] SPECIAL_expr } entry_point { - {name fooso} - {decl_file 1 data1} - {decl_line $foo_line data1} - {low_pc foo_entry_label addr} + DW_AT_name fooso + DW_AT_decl_file 1 data1 + DW_AT_decl_line $foo_line data1 + DW_AT_low_pc fooso_entry_label addr } { formal_parameter { - {name J} - {type :$int2_label} - {location {addr $global_J} SPECIAL_expr} + DW_AT_name J + DW_AT_type :$int2_label + DW_AT_location [subst {addr $global_J}] SPECIAL_expr } formal_parameter { - {name K} - {type :$int2_label} - {location {addr $global_K} SPECIAL_expr} + DW_AT_name K + DW_AT_type :$int2_label + DW_AT_location [subst {addr $global_K}] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-entry-value-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-entry-value-2.exp index 55ecf9c..7dd859c 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-entry-value-2.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-entry-value-2.exp @@ -45,47 +45,47 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name $srcfile} + DW_AT_name $srcfile } { declare_labels integer integer: DW_TAG_base_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_subprogram { - { DW_AT_name main } - { DW_AT_low_pc $main_start DW_FORM_addr } - { DW_AT_high_pc $main_end DW_FORM_addr } + DW_AT_name main + DW_AT_low_pc $main_start DW_FORM_addr + DW_AT_high_pc $main_end DW_FORM_addr } { DW_TAG_variable { - { DW_AT_name argc } - { DW_AT_type :$integer } - { DW_AT_location { + DW_AT_name argc + DW_AT_type :$integer + DW_AT_location [subst { DW_OP_entry_value { DW_OP_regx $::dwarf_regnum } - } SPECIAL_expr } + }] SPECIAL_expr } } DW_TAG_subprogram { - { DW_AT_name bar } - { DW_AT_low_pc $bar_start DW_FORM_addr } - { DW_AT_high_pc $bar_end DW_FORM_addr } + DW_AT_name bar + DW_AT_low_pc $bar_start DW_FORM_addr + DW_AT_high_pc $bar_end DW_FORM_addr } { DW_TAG_variable { - { DW_AT_name foo } - { DW_AT_type :$integer } - { DW_AT_location { + DW_AT_name foo + DW_AT_type :$integer + DW_AT_location [subst { DW_OP_entry_value { DW_OP_bregx $::dwarf_regnum 0 DW_OP_deref_size 4 } DW_OP_stack_value - } SPECIAL_expr } + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-epilogue-begin.exp.tcl b/gdb/testsuite/gdb.dwarf2/dw2-epilogue-begin.exp.tcl index 954a252..7e60b6e 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-epilogue-begin.exp.tcl +++ b/gdb/testsuite/gdb.dwarf2/dw2-epilogue-begin.exp.tcl @@ -56,42 +56,42 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-prologue-end.c} - {stmt_list ${lines_label} DW_FORM_sec_offset} - {producer "clang version 17.0.1"} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-prologue-end.c + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset + DW_AT_producer "clang version 17.0.1" } { declare_labels char_label char_label: base_type { - {name char} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name char + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } subprogram { - {external 1 flag} - {name trivial} - {low_pc $trivial_start addr} - {high_pc "$trivial_start + $trivial_len" addr} + DW_AT_external 1 flag + DW_AT_name trivial + DW_AT_low_pc $trivial_start addr + DW_AT_high_pc "$trivial_start + $trivial_len" addr } subprogram { - {external 1 flag} - {name watch} - {low_pc $watch_start addr} - {high_pc "$watch_start + $watch_len" addr} + DW_AT_external 1 flag + DW_AT_name watch + DW_AT_low_pc $watch_start addr + DW_AT_high_pc "$watch_start + $watch_len" addr } { DW_TAG_variable { - {name local} - {type :$char_label} - {DW_AT_location {DW_OP_reg0} SPECIAL_expr} + DW_AT_name local + DW_AT_type :$char_label + DW_AT_location {DW_OP_reg0} SPECIAL_expr } } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-error.exp index f1c8617..0701ec6 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-error.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-error.exp @@ -37,7 +37,7 @@ set host_binfile [gdb_remote_download host $binfile] # First test that reading symbols fails. gdb_test "file $host_binfile" \ - {Reading symbols.*DWARF Error: wrong version in compilation unit header \(is 153, should be 2, 3, 4 or 5\).*} \ + {Reading symbols.*DWARF Error: wrong version in unit header \(is 153, should be 2, 3, 4 or 5\).*} \ "file $testfile" # We can't use proc readnow, because the PR makes it return 0. diff --git a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp index a8ade90..7666089 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp @@ -23,91 +23,91 @@ standard_testfile dw2-fixed-point.c dw2-fixed-point-dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name pck.ads} - {DW_AT_comp_dir /tmp} - } { - declare_labels fp1_base_type fp2_base_type fp3_small \ - fp3_base_type fp1_range_type - - fp1_base_type: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed_fixed} - {DW_AT_name pck__fp1_type} - {DW_AT_binary_scale -4 DW_FORM_sdata} - } - - DW_TAG_variable { - {DW_AT_name pck__fp1_var} - {DW_AT_type :$fp1_base_type} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol pck__fp1_var] - } SPECIAL_expr} - {external 1 flag} - } - - DW_TAG_variable { - {DW_AT_name pck__fp1_var2} - {DW_AT_type :$fp1_base_type} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol pck__fp1_var2] - } SPECIAL_expr} - {external 1 flag} - } - - fp2_base_type: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed_fixed} - {DW_AT_name pck__fp2_type} - {DW_AT_decimal_scale -2 DW_FORM_sdata} - } - - DW_TAG_variable { - {DW_AT_name pck__fp2_var} - {DW_AT_type :$fp2_base_type} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol pck__fp2_var] - } SPECIAL_expr} - {external 1 flag} - } - - fp3_small: DW_TAG_constant { - {DW_AT_GNU_numerator 1 DW_FORM_data1} - {DW_AT_GNU_denominator 30 DW_FORM_sdata} - } - - fp3_base_type: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed_fixed} - {DW_AT_name pck__fp3_type} - {DW_AT_small :$fp3_small} - } - - DW_TAG_variable { - {DW_AT_name pck__fp3_var} - {DW_AT_type :$fp3_base_type} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol pck__fp3_var] - } SPECIAL_expr} - {external 1 flag} - } - - fp1_range_type: DW_TAG_subrange_type { - {DW_AT_lower_bound 0xf0 DW_FORM_data1} - {DW_AT_upper_bound 0x10 DW_FORM_data1} - {DW_AT_name foo__fp1_range_type} - {DW_AT_type :$fp1_base_type} - } - - DW_TAG_variable { - {DW_AT_name pck__fp1_range_var} - {DW_AT_type :$fp1_range_type} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol pck__fp1_range_var] - } SPECIAL_expr} - {external 1 flag} - } + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name pck.ads + DW_AT_comp_dir /tmp + } { + declare_labels fp1_base_type fp2_base_type fp3_small \ + fp3_base_type fp1_range_type + + fp1_base_type: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed_fixed + DW_AT_name pck__fp1_type + DW_AT_binary_scale -4 DW_FORM_sdata + } + + DW_TAG_variable { + DW_AT_name pck__fp1_var + DW_AT_type :$fp1_base_type + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol pck__fp1_var] + }] SPECIAL_expr + DW_AT_external 1 flag + } + + DW_TAG_variable { + DW_AT_name pck__fp1_var2 + DW_AT_type :$fp1_base_type + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol pck__fp1_var2] + }] SPECIAL_expr + DW_AT_external 1 flag + } + + fp2_base_type: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed_fixed + DW_AT_name pck__fp2_type + DW_AT_decimal_scale -2 DW_FORM_sdata + } + + DW_TAG_variable { + DW_AT_name pck__fp2_var + DW_AT_type :$fp2_base_type + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol pck__fp2_var] + }] SPECIAL_expr + DW_AT_external 1 flag + } + + fp3_small: DW_TAG_constant { + DW_AT_GNU_numerator 1 DW_FORM_data1 + DW_AT_GNU_denominator 30 DW_FORM_sdata + } + + fp3_base_type: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed_fixed + DW_AT_name pck__fp3_type + DW_AT_small :$fp3_small + } + + DW_TAG_variable { + DW_AT_name pck__fp3_var + DW_AT_type :$fp3_base_type + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol pck__fp3_var] + }] SPECIAL_expr + DW_AT_external 1 flag + } + + fp1_range_type: DW_TAG_subrange_type { + DW_AT_lower_bound 0xf0 DW_FORM_data1 + DW_AT_upper_bound 0x10 DW_FORM_data1 + DW_AT_name foo__fp1_range_type + DW_AT_type :$fp1_base_type + } + + DW_TAG_variable { + DW_AT_name pck__fp1_range_var + DW_AT_type :$fp1_range_type + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol pck__fp1_range_var] + }] SPECIAL_expr + DW_AT_external 1 flag + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp index 25a73a6..6611bf3 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp @@ -20,7 +20,7 @@ load_lib dwarf.exp # This test can only be run on targets which support DWARF-2 and use gas. require dwarf2_support -standard_testfile dw2-lines.c -dw2.S +standard_testfile dw2-lines.c -dw2.S -dw2-one-diridx.S with_shared_gdb { set func_info_vars [get_func_info bar] @@ -33,49 +33,61 @@ proc line_for { l } { return [expr $line + 1] } -set asm_file [standard_output_file $srcfile2] -Dwarf::assemble $asm_file { - declare_labels Llines - global srcdir subdir srcfile objdir - global func_info_vars - foreach var $func_info_vars { - global $var - } +# A helper proc to create the DWARF assembly for the test. +# If ONE_DIRIDX is true, then the directory table will be limited +# to one entry. +proc create_dwarf_assembly {source_file one_diridx} { + set asm_file [standard_output_file $source_file] + Dwarf::assemble $asm_file { + declare_labels Llines + global srcdir subdir srcfile objdir + global func_info_vars + upvar one_diridx one_diridx + foreach var $func_info_vars { + global $var + } - cu { version 5 } { - compile_unit { - {language @DW_LANG_Mips_Assembler} - {name $srcfile} - {comp_dir $objdir} - {stmt_list $Llines DW_FORM_sec_offset} - {producer "GNU AS 2.35.2"} - } { - subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc "$bar_start + $bar_len" addr} + cu { version 5 } { + compile_unit { + DW_AT_language @DW_LANG_Mips_Assembler + DW_AT_name $srcfile + DW_AT_comp_dir $objdir + DW_AT_stmt_list $Llines DW_FORM_sec_offset + DW_AT_producer "GNU AS 2.35.2" + } { + subprogram { + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc "$bar_start + $bar_len" addr + } } } - } - lines [list version 5] Llines { - set diridx1 [include_dir "${srcdir}/${subdir}"] - set diridx2 [include_dir "${srcdir}/${subdir}"] - file_name "$srcfile" $diridx1 - file_name "$srcfile" $diridx2 - - program { - DW_LNE_set_address bar_label - line [line_for bar_label] - DW_LNS_copy + lines [list version 5] Llines { + set diridx1 [include_dir "${srcdir}/${subdir}"] + file_name "$srcfile" $diridx1 + if {!$one_diridx} { + set diridx2 [include_dir "${srcdir}/${subdir}"] + file_name "$srcfile" $diridx2 + } else { + file_name "$srcfile" $diridx1 + } + program { + DW_LNE_set_address bar_label + line [line_for bar_label] + DW_LNS_copy - DW_LNE_set_address $bar_end - DW_LNE_end_sequence + DW_LNE_set_address $bar_end + DW_LNE_end_sequence + } } } + + return $asm_file } +set asm_file [create_dwarf_assembly $srcfile2 false] if { [prepare_for_testing "failed to prepare" ${testfile} \ [list $srcfile $asm_file] {nodebug}] } { return -1 @@ -90,3 +102,13 @@ gdb_test_multiple "ptype bar" "" { pass $gdb_test_name } } + +# Test whether gdb crashes in the case where the number of +# directory indexes is only one. +set asm_file [create_dwarf_assembly $srcfile3 true] +if {[prepare_for_testing "failed to prepare" ${testfile}-one-diridx \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +gdb_test "ptype bar" ".*" "do not crash with only one directory table entry" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp index 309f9d8..ef48038 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp @@ -29,28 +29,28 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {name file1.txt} - {language @DW_LANG_C} - {MACRO_AT_range { func }} + DW_AT_name file1.txt + DW_AT_language @DW_LANG_C + MACRO_AT_range { func } } { int_label: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } subprogram { - {external 1 flag} - {MACRO_AT_func { func }} + DW_AT_external 1 flag + MACRO_AT_func { func } } { formal_parameter { - {name param} - {variable_parameter 1 flag} - {type :$int_label} - {location { + DW_AT_name param + DW_AT_variable_parameter 1 flag + DW_AT_type :$int_label + DW_AT_location [subst { addr [gdb_target_symbol ptr] deref - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp index 2781cf3..ecf0614 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp @@ -78,29 +78,29 @@ proc do_test { start_label func_name tag } { cu {} { compile_unit { - {producer "gcc" } - {language @DW_LANG_C} - {name ${srcfile3}} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile3} + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { callee_subprog_label: subprogram { - {external 1 flag} - {name callee} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name callee + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$callee_subprog_label} - {low_pc $start_label addr} - {high_pc line_label_6 addr} - {call_file 1 data1} - {call_line 18 data1} + DW_AT_abstract_origin %$callee_subprog_label + DW_AT_low_pc $start_label addr + DW_AT_high_pc line_label_6 addr + DW_AT_call_file 1 data1 + DW_AT_call_line 18 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp index 2004dfb..3d08ac0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp @@ -68,29 +68,29 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {producer "gcc" } - {language @DW_LANG_C} - {name ${srcfile3}} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile3} + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { callee_subprog_label: subprogram { - {external 1 flag} - {name callee} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name callee + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$callee_subprog_label} - {low_pc line_label_3 addr} - {high_pc line_label_5 addr} - {call_file 1 data1} - {call_line 18 data1} + DW_AT_abstract_origin %$callee_subprog_label + DW_AT_low_pc line_label_3 addr + DW_AT_high_pc line_label_5 addr + DW_AT_call_file 1 data1 + DW_AT_call_line 18 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp index f7d220c..ad914b9 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp @@ -57,29 +57,29 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {producer "gcc" } - {language @DW_LANG_C} - {name ${srcfile3}} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile3} + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { callee_subprog_label: subprogram { - {external 1 flag} - {name callee} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name callee + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$callee_subprog_label} - {low_pc line_label_3 addr} - {high_pc line_label_5 addr} - {call_file 1 data1} - {call_line 18 data1} + DW_AT_abstract_origin %$callee_subprog_label + DW_AT_low_pc line_label_3 addr + DW_AT_high_pc line_label_5 addr + DW_AT_call_file 1 data1 + DW_AT_call_line 18 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-many-frames.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-many-frames.exp index 795f1e0..e8668e0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-many-frames.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-many-frames.exp @@ -58,116 +58,116 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-inline-stepping.c} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-inline-stepping.c + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name ddd} - {low_pc $ddd_start addr} - {high_pc "$ddd_start + $ddd_len" addr} + DW_AT_external 1 flag + DW_AT_name ddd + DW_AT_low_pc $ddd_start addr + DW_AT_high_pc "$ddd_start + $ddd_len" addr } subprogram { - {external 1 flag} - {name eee} - {low_pc $eee_start addr} - {high_pc "$eee_start + $eee_len" addr} + DW_AT_external 1 flag + DW_AT_name eee + DW_AT_low_pc $eee_start addr + DW_AT_high_pc "$eee_start + $eee_len" addr } subprogram { - {external 1 flag} - {name jjj} - {low_pc $jjj_start addr} - {high_pc "$jjj_start + $jjj_len" addr} + DW_AT_external 1 flag + DW_AT_name jjj + DW_AT_low_pc $jjj_start addr + DW_AT_high_pc "$jjj_start + $jjj_len" addr } subprogram { - {external 1 flag} - {name kkk} - {low_pc $kkk_start addr} - {high_pc "$kkk_start + $kkk_len" addr} + DW_AT_external 1 flag + DW_AT_name kkk + DW_AT_low_pc $kkk_start addr + DW_AT_high_pc "$kkk_start + $kkk_len" addr } aaa_label: subprogram { - {name aaa} - {inline 3 data1} + DW_AT_name aaa + DW_AT_inline 3 data1 } bbb_label: subprogram { - {name bbb} - {inline 3 data1} + DW_AT_name bbb + DW_AT_inline 3 data1 } ccc_label: subprogram { - {name ccc} - {inline 3 data1} + DW_AT_name ccc + DW_AT_inline 3 data1 } ggg_label: subprogram { - {name ggg} - {inline 3 data1} + DW_AT_name ggg + DW_AT_inline 3 data1 } hhh_label: subprogram { - {name hhh} - {inline 3 data1} + DW_AT_name hhh + DW_AT_inline 3 data1 } iii_label: subprogram { - {name iii} - {inline 3 data1} + DW_AT_name iii + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$aaa_label} - {low_pc main_label2 addr} - {high_pc main_label3 addr} - {call_file 1 data1} - {call_line $call_in_main data1} + DW_AT_abstract_origin %$aaa_label + DW_AT_low_pc main_label2 addr + DW_AT_high_pc main_label3 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_main data1 } { inlined_subroutine { - {abstract_origin %$bbb_label} - {low_pc main_label2 addr} - {high_pc main_label3 addr} - {call_file 1 data1} - {call_line $call_in_aaa data1} + DW_AT_abstract_origin %$bbb_label + DW_AT_low_pc main_label2 addr + DW_AT_high_pc main_label3 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_aaa data1 } { inlined_subroutine { - {abstract_origin %$ccc_label} - {low_pc main_label2 addr} - {high_pc main_label3 addr} - {call_file 1 data1} - {call_line $call_in_bbb data1} + DW_AT_abstract_origin %$ccc_label + DW_AT_low_pc main_label2 addr + DW_AT_high_pc main_label3 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_bbb data1 } } } } subprogram { - {external 1 flag} - {name fff} - {low_pc $fff_start addr} - {high_pc "$fff_start + $fff_len" addr} + DW_AT_external 1 flag + DW_AT_name fff + DW_AT_low_pc $fff_start addr + DW_AT_high_pc "$fff_start + $fff_len" addr } { inlined_subroutine { - {abstract_origin %$ggg_label} - {low_pc fff_label addr} - {high_pc main_label2 addr} - {call_file 1 data1} - {call_line $call_in_fff data1} + DW_AT_abstract_origin %$ggg_label + DW_AT_low_pc fff_label addr + DW_AT_high_pc main_label2 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_fff data1 } { inlined_subroutine { - {abstract_origin %$hhh_label} - {low_pc fff_label addr} - {high_pc fff_label2 addr} - {call_file 1 data1} - {call_line $call_in_ggg data1} + DW_AT_abstract_origin %$hhh_label + DW_AT_low_pc fff_label addr + DW_AT_high_pc fff_label2 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_ggg data1 } { inlined_subroutine { - {abstract_origin %$iii_label} - {low_pc fff_label addr} - {high_pc fff_label2 addr} - {call_file 1 data1} - {call_line $call_in_hhh data1} + DW_AT_abstract_origin %$iii_label + DW_AT_low_pc fff_label addr + DW_AT_high_pc fff_label2 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_in_hhh data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp index 12812dd..a4309d4 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp @@ -47,29 +47,29 @@ Dwarf::assemble $asm_file { # time of writing this, GCC for x86-64 doesn't make use of # skip_prologue_using_sal, while clang does. compile_unit { - {producer "clang xxxx" } - {language @DW_LANG_C} - {name ${srcfile3}} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "clang xxxx" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile3} + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { callee_subprog_label: subprogram { - {external 1 flag} - {name callee} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name callee + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$callee_subprog_label} - {low_pc line_label_1 addr} - {high_pc line_label_2 addr} - {call_file 1 data1} - {call_line 21 data1} + DW_AT_abstract_origin %$callee_subprog_label + DW_AT_low_pc line_label_1 addr + DW_AT_high_pc line_label_2 addr + DW_AT_call_file 1 data1 + DW_AT_call_line 21 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-stepping.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-stepping.exp index 840d813..a544616 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-stepping.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-stepping.exp @@ -49,34 +49,34 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-inline-stepping.c} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-inline-stepping.c + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc "$bar_start + $bar_len" addr} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc "$bar_start + $bar_len" addr } foo_prog: subprogram { - {name foo} - {inline 3 data1} + DW_AT_name foo + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$foo_prog} - {low_pc main_label2 addr} - {high_pc main_label3 addr} - {call_file 1 data1} - {call_line $call_line data1} + DW_AT_abstract_origin %$foo_prog + DW_AT_low_pc main_label2 addr + DW_AT_high_pc main_label3 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $call_line data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-with-lexical-scope.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-with-lexical-scope.exp index 320aa34..2674c17 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-with-lexical-scope.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-with-lexical-scope.exp @@ -43,59 +43,59 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C99} - {name $srcfile} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C99 + DW_AT_name $srcfile + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { int_label: base_type { - {name "int"} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } func_label: subprogram { - {name func} - {inline @DW_INL_declared_inlined} + DW_AT_name func + DW_AT_inline @DW_INL_declared_inlined } { num_label: DW_TAG_variable { - {name num} - {type :$int_label} + DW_AT_name num + DW_AT_type :$int_label } lexical_block { } { value_label: DW_TAG_variable { - {name value} - {type :$int_label} + DW_AT_name value + DW_AT_type :$int_label } } } subprogram { - {name main} - {external 1 flag} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_name main + DW_AT_external 1 flag + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } { inlined_subroutine { - {abstract_origin %$func_label} - {low_pc main_label addr} - {high_pc main_label2 addr} - {call_file 1 data1} - {call_line $func_call data1} + DW_AT_abstract_origin %$func_label + DW_AT_low_pc main_label addr + DW_AT_high_pc main_label2 addr + DW_AT_call_file 1 data1 + DW_AT_call_line $func_call data1 } { DW_TAG_variable { - {abstract_origin %$num_label} - {location {addr $global_num_addr} SPECIAL_expr} + DW_AT_abstract_origin %$num_label + DW_AT_location [subst {addr $global_num_addr}] SPECIAL_expr } lexical_block { - {low_pc scope_label1 addr} - {high_pc scope_label2 addr} + DW_AT_low_pc scope_label1 addr + DW_AT_high_pc scope_label2 addr } { DW_TAG_variable { - {abstract_origin %$value_label} - {location {addr $global_value_addr} SPECIAL_expr} + DW_AT_abstract_origin %$value_label + DW_AT_location [subst {addr $global_value_addr}] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp index e65d1b9..8e99cb4 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error-2.exp @@ -29,10 +29,12 @@ Dwarf::assemble $asm_file { declare_labels label1 cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {MACRO_AT_range { main }} - {DW_AT_specification %$label1} + MACRO_AT_range { main } + DW_AT_specification %$label1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error.exp index bfdd1a7..ded5f10 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-error.exp @@ -26,16 +26,20 @@ Dwarf::assemble $asm_file { declare_labels label1 cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {MACRO_AT_range { main }} - {DW_AT_specification %$label1} + MACRO_AT_range { main } + DW_AT_specification %$label1 } } } cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { label1: } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp index 3e91a51..0ae6004 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp @@ -30,22 +30,26 @@ Dwarf::assemble $asm_file { declare_labels label1 label2 cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {MACRO_AT_range { main }} - {DW_AT_specification %$label1} + MACRO_AT_range { main } + DW_AT_specification %$label1 } label2: subprogram { - {DW_AT_name main} + DW_AT_name main } } } cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { label1: subprogram { - {DW_AT_specification %$label2} + DW_AT_specification %$label2 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-symbol.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-symbol.exp index dba8b83..fc72cf7 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-symbol.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-symbol.exp @@ -27,36 +27,36 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {stmt_list $L1 DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_stmt_list $L1 DW_FORM_sec_offset } { tag_variable { - {name var1} - {abstract_origin %$var_label} - {const_value 1 DW_FORM_sdata} + DW_AT_name var1 + DW_AT_abstract_origin %$var_label + DW_AT_const_value 1 DW_FORM_sdata } subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } int_label: base_type { - {byte_size 4 udata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size 4 udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } } } cu {} { compile_unit { - {language @DW_LANG_C} - {stmt_list $L2 DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_stmt_list $L2 DW_FORM_sec_offset } { var_label: tag_variable { - {name "var1"} - {type %$int_label} - {decl_file 1} - {decl_line 1} + DW_AT_name "var1" + DW_AT_type %$int_label + DW_AT_decl_file 1 + DW_AT_decl_line 1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-is-stmt-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-is-stmt-2.exp index 49091f7..77bac52 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-is-stmt-2.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-is-stmt-2.exp @@ -42,16 +42,16 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-is-stmt.c} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-is-stmt.c + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } {} } } @@ -179,7 +179,7 @@ foreach entry $locs { # through. This is checking that the is-stmt marked lines are # displayed differently (without addresses) to addresses that are # mid-way through a line, or not marked as is-stmt. -clean_restart $binfile +clean_restart $::testfile runto_main foreach entry $locs { diff --git a/gdb/testsuite/gdb.dwarf2/dw2-is-stmt.exp b/gdb/testsuite/gdb.dwarf2/dw2-is-stmt.exp index 65d9559..1b9ccaa 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-is-stmt.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-is-stmt.exp @@ -42,16 +42,16 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-is-stmt.c} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-is-stmt.c + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } {} } } @@ -116,7 +116,7 @@ gdb_test "step" "/\\* main end \\*/" \ # Restart the test. This time, stop at a location we know is marked # as a statement. -clean_restart ${binfile} +clean_restart ${::testfile} runto_main gdb_breakpoint "*line_label_3" @@ -129,7 +129,7 @@ gdb_test "step" "/\\* main end \\*/" \ # Restart the test, this time, step through line by line, ensure we # only stop at the places where is-stmt is true. -clean_restart ${binfile} +clean_restart ${::testfile} runto_main # Get the values of the labels where we expect to stop. @@ -161,7 +161,7 @@ with_test_prefix "step to line_label_5" { # Now restart the test, and place a breakpoint by line number. GDB # should select the location that is marked as is-stmt. -clean_restart ${binfile} +clean_restart ${::testfile} runto_main set linum [gdb_get_line_number "main, set var to 0"] gdb_breakpoint "$srcfile:$linum" @@ -171,7 +171,7 @@ gdb_assert { $ll3 == $pc } "check initial \$pc" # Restart the test again, this time we will test stepping by # instruction. -clean_restart ${binfile} +clean_restart ${::testfile} runto_main # We will be at line_label_1 at this point - we already tested this diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp b/gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp index ae7f97e..a973a11 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-lexical-block-bare.exp @@ -24,29 +24,29 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {MACRO_AT_range {main}} + MACRO_AT_range {main} } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {DW_AT_external 1 flag} + MACRO_AT_func {main} + DW_AT_external 1 flag } { DW_TAG_lexical_block { } { DW_TAG_variable { - {DW_AT_name testvar} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name testvar + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol main] - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp index d46f003..144e62e 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp @@ -32,21 +32,21 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-line-number-zero.c} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-line-number-zero.c + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } subprogram { - {external 1 flag} - {MACRO_AT_func {bar1}} + DW_AT_external 1 flag + MACRO_AT_func {bar1} } subprogram { - {external 1 flag} - {MACRO_AT_func {bar2}} + DW_AT_external 1 flag + MACRO_AT_func {bar2} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp index 16ca54e7..6eacf0b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp @@ -59,21 +59,21 @@ proc test_1 { _cv _cdw64 _lv _ldw64 {_string_form ""}} { cu { version $cv is_64 $cdw64 } { compile_unit { - {language @DW_LANG_C} - {name $srcfile} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc "$bar_start + $bar_len" addr} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc "$bar_start + $bar_len" addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.exp b/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.exp index 01eab48..7627e8e 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.exp @@ -27,7 +27,7 @@ standard_testfile .S set executable ${testfile} if {[prepare_for_testing_full "failed to prepare" \ - [list $testfile c++ $testfile-main.cc {c++ debug} \ + [list $testfile c++ $testfile-main.cc {c++ nodebug} \ $srcfile {}]]} { return -1 } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-main-no-line-number.exp b/gdb/testsuite/gdb.dwarf2/dw2-main-no-line-number.exp index 309875a..e05e4c9 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-main-no-line-number.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-main-no-line-number.exp @@ -33,12 +33,12 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name $srcfile} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp b/gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp index 44b1726..998b614 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-missing-cu-tag.exp @@ -31,8 +31,8 @@ Dwarf::assemble $asm_file { # We should have either one of DW_TAG_compile_unit, # DW_TAG_partial_unit, or DW_TAG_type_unit here. subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S index c09c6db..06a93ac 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S @@ -114,7 +114,11 @@ die221: .byte 0x0 - .section .debug_str +#ifdef __arm__ + .section .debug_str,"MS",%progbits,1 +#else + .section .debug_str,"MS",@progbits,1 +#endif .LASF1: .string "2.mod" .LASF0: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp index a8fa524..0092969 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-multiple-debug-info.exp @@ -31,6 +31,6 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" "$binfile" object \ return -1 } -clean_restart $binfile +clean_restart $::testfile gdb_test "ptype a" "type = class sp1::A .*" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-namespaceless-anonymous.exp b/gdb/testsuite/gdb.dwarf2/dw2-namespaceless-anonymous.exp index d930801..ebbe6c0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-namespaceless-anonymous.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-namespaceless-anonymous.exp @@ -27,26 +27,26 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels myint myint: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name myint} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name myint } DW_TAG_namespace {} { DW_TAG_variable { - {DW_AT_name v} - {DW_AT_linkage_name _ZN12_GLOBAL__N_11vE} - {DW_AT_location { + DW_AT_name v + DW_AT_linkage_name _ZN12_GLOBAL__N_11vE + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol _ZN12_GLOBAL__N_11vE] - } SPECIAL_expr} - {DW_AT_type :$myint} + }] SPECIAL_expr + DW_AT_type :$myint } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-noloc.exp b/gdb/testsuite/gdb.dwarf2/dw2-noloc.exp index 86ea143..526f88a 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-noloc.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-noloc.exp @@ -28,167 +28,167 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name $srcfile} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { declare_labels integer_label set int_size [get_sizeof "int" 4] integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } DW_TAG_variable { - {DW_AT_name file_locno_resolvable} - {DW_AT_type :$integer_label} + DW_AT_name file_locno_resolvable + DW_AT_type :$integer_label } DW_TAG_variable { - {DW_AT_name file_locno_unresolvable} - {DW_AT_type :$integer_label} + DW_AT_name file_locno_unresolvable + DW_AT_type :$integer_label } DW_TAG_variable { - {DW_AT_name file_locempty_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name file_locempty_resolvable + DW_AT_type :$integer_label + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name file_locempty_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name file_locempty_unresolvable + DW_AT_type :$integer_label + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name file_locaddr_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name file_locaddr_resolvable + DW_AT_type :$integer_label + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol file_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name file_locaddr_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name file_locaddr_unresolvable + DW_AT_type :$integer_label + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol file_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name file_extern_locno_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} + DW_AT_name file_extern_locno_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name file_extern_locno_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} + DW_AT_name file_extern_locno_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name file_extern_locempty_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name file_extern_locempty_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name file_extern_locempty_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name file_extern_locempty_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name file_extern_locaddr_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name file_extern_locaddr_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol file_extern_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name file_extern_locaddr_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name file_extern_locaddr_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol file_extern_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name main_local_locno_resolvable} - {DW_AT_type :$integer_label} + DW_AT_name main_local_locno_resolvable + DW_AT_type :$integer_label } DW_TAG_variable { - {DW_AT_name main_local_locno_unresolvable} - {DW_AT_type :$integer_label} + DW_AT_name main_local_locno_unresolvable + DW_AT_type :$integer_label } DW_TAG_variable { - {DW_AT_name main_local_locempty_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name main_local_locempty_resolvable + DW_AT_type :$integer_label + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name main_local_locempty_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name main_local_locempty_unresolvable + DW_AT_type :$integer_label + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name main_local_locaddr_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name main_local_locaddr_resolvable + DW_AT_type :$integer_label + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol main_local_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name main_local_locaddr_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_location { + DW_AT_name main_local_locaddr_unresolvable + DW_AT_type :$integer_label + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol main_local_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name main_extern_locno_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} + DW_AT_name main_extern_locno_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name main_extern_locno_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} + DW_AT_name main_extern_locno_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name main_extern_locempty_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name main_extern_locempty_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name main_extern_locempty_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name main_extern_locempty_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location {} DW_FORM_block1 } DW_TAG_variable { - {DW_AT_name main_extern_locaddr_resolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name main_extern_locaddr_resolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol main_extern_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name main_extern_locaddr_unresolvable} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name main_extern_locaddr_unresolvable + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol main_extern_locaddr_resolvable] - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp index 486a4e8..866df3a 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp @@ -46,74 +46,74 @@ proc build_test_program {} { cu { addr_size 4 } { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C99} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C99 + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels int_label struct_label pointer_label \ array_label int_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } array_label: DW_TAG_array_type { - {DW_AT_name foo__array_type} - {DW_AT_type :$int_label} + DW_AT_name foo__array_type + DW_AT_type :$int_label } { DW_TAG_subrange_type { - {DW_AT_type :$int_label} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 127 DW_FORM_data1} + DW_AT_type :$int_label + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 127 DW_FORM_data1 } } struct_label: DW_TAG_structure_type { - {DW_AT_name "foo"} - {DW_AT_byte_size 12 DW_FORM_sdata} + DW_AT_name "foo" + DW_AT_byte_size 12 DW_FORM_sdata } { member { - {name a} - {type :$int_label} - {data_member_location 0 data1} + DW_AT_name a + DW_AT_type :$int_label + DW_AT_data_member_location 0 data1 } member { - {name x} - {type :$array_label} - {data_member_location 4 data1} + DW_AT_name x + DW_AT_type :$array_label + DW_AT_data_member_location 4 data1 } member { - {name y} - {type :$pointer_label} - {data_member_location 8 data1} + DW_AT_name y + DW_AT_type :$pointer_label + DW_AT_data_member_location 8 data1 } } pointer_label: DW_TAG_pointer_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_type :$struct_label} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_type :$struct_label } DW_TAG_subprogram { - {DW_AT_name func01} - {DW_AT_type :$int_label} - {external 1 flag} - {MACRO_AT_func {func01}} + DW_AT_name func01 + DW_AT_type :$int_label + DW_AT_external 1 flag + MACRO_AT_func {func01} } { DW_TAG_variable { - {DW_AT_name ptr} - {DW_AT_type :$pointer_label} - {DW_AT_location {} DW_FORM_block1} + DW_AT_name ptr + DW_AT_type :$pointer_label + DW_AT_location {} DW_FORM_block1 } } DW_TAG_subprogram { - {DW_AT_name main} - {DW_AT_type :$int_label} - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_name main + DW_AT_type :$int_label + DW_AT_external 1 flag + MACRO_AT_func {main} } { } } @@ -134,7 +134,7 @@ set re_address_class "@\[^\r\n\]+" proc do_console_test {} { global binfile - clean_restart $binfile + clean_restart $::testfile with_test_prefix "console" { gdb_test_no_output "set print object on" @@ -173,7 +173,7 @@ proc do_mi_test {} { global binfile with_test_prefix "mi" { - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-out-of-range-end-of-seq.exp b/gdb/testsuite/gdb.dwarf2/dw2-out-of-range-end-of-seq.exp index 79c03c7..70db471 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-out-of-range-end-of-seq.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-out-of-range-end-of-seq.exp @@ -39,15 +39,15 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name $srcfile} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start} - {high_pc $main_end addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start + DW_AT_high_pc $main_end addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp index eea17b0..cf94c71 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp @@ -30,21 +30,21 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-prologue-end.c} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-prologue-end.c + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name foo} - {low_pc foo_label addr} - {high_pc foo_end addr} + DW_AT_external 1 flag + DW_AT_name foo + DW_AT_low_pc foo_label addr + DW_AT_high_pc foo_end addr } subprogram { - {external 1 flag} - {name bar} - {low_pc bar_label addr} - {high_pc bar_end addr} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc bar_label addr + DW_AT_high_pc bar_end addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end.exp b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end.exp index 23d8c26..8e66abe 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end.exp @@ -32,15 +32,15 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-prologue-end.c} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-prologue-end.c + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc "$main_start + $main_len" addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc "$main_start + $main_len" addr } } } @@ -91,7 +91,7 @@ set prologue_end_line [gdb_get_line_number "main assign o"] gdb_test "frame" ".*main \\\(\\\) at \[^\r\n\]*:$prologue_end_line\r\n.*" with_test_prefix "ignore-prologue-end" { - clean_restart $binfile + clean_restart $::testfile gdb_test_no_output "maintenance set ignore-prologue-end-flag on" if ![runto_main] { diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp index e63bbc3..9e39f6b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp @@ -45,22 +45,22 @@ Dwarf::assemble $asm_file { # .debug_ranges data then the test achieves its objective. cu { label cu_label } { compile_unit { - {language @DW_LANG_C} - {name dw-ranges-base.c} - {stmt_list $L DW_FORM_sec_offset} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw-ranges-base.c + DW_AT_stmt_list $L DW_FORM_sec_offset + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name main} + DW_AT_external 1 flag + DW_AT_name main } subprogram { - {external 1 flag} - {name frame2} + DW_AT_external 1 flag + DW_AT_name frame2 } subprogram { - {external 1 flag} - {name frame3} + DW_AT_external 1 flag + DW_AT_name frame3 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp index 9fea8a8..56aab60 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp @@ -70,49 +70,49 @@ proc do_test {suffix} { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw-ranges-func2.c} - {stmt_list $L DW_FORM_sec_offset} - {low_pc 0 addr} - {ranges ${cu_ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw-ranges-func2.c + DW_AT_stmt_list $L DW_FORM_sec_offset + DW_AT_low_pc 0 addr + DW_AT_ranges ${cu_ranges_label} DW_FORM_sec_offset } { integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } volatile_label: DW_TAG_volatile_type { - {type :$integer_label} + DW_AT_type :$integer_label } DW_TAG_variable { - {name e} - {external 1 flag} - {type :$volatile_label} - {location {addr $e_var} SPECIAL_expr} + DW_AT_name e + DW_AT_external 1 flag + DW_AT_type :$volatile_label + DW_AT_location [subst {addr $e_var}] SPECIAL_expr } subprogram { - {external 1 flag} - {name main} - {DW_AT_type :$integer_label} - {low_pc $main_start addr} - {high_pc $main_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_type :$integer_label + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len DW_FORM_data4 } subprogram { - {external 1 flag} - {name foo} - {ranges ${func_ranges_label} DW_FORM_sec_offset} + DW_AT_external 1 flag + DW_AT_name foo + DW_AT_ranges ${func_ranges_label} DW_FORM_sec_offset } subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc $bar_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc $bar_len DW_FORM_data4 } subprogram { - {external 1 flag} - {name baz} - {low_pc $baz_start addr} - {high_pc $baz_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name baz + DW_AT_low_pc $baz_start addr + DW_AT_high_pc $baz_len DW_FORM_data4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-overlap.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-overlap.exp index 8e7d51e..75c874e 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-overlap.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-overlap.exp @@ -44,13 +44,13 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C_plus_plus} - {name $srcfile} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name quux} + DW_AT_external 1 flag + DW_AT_name quux } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp index ea0fc03..fa1e03b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp @@ -61,31 +61,31 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw-ranges-psym.c} - {low_pc 0 addr} + DW_AT_language @DW_LANG_C + DW_AT_name dw-ranges-psym.c + DW_AT_low_pc 0 addr } { integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } subprogram { - {external 1 flag} - {name foo} - {ranges ${func_ranges_label} DW_FORM_sec_offset} + DW_AT_external 1 flag + DW_AT_name foo + DW_AT_ranges ${func_ranges_label} DW_FORM_sec_offset } subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc $bar_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc $bar_len DW_FORM_data4 } subprogram { - {external 1 flag} - {name baz} - {low_pc $baz_start addr} - {high_pc $baz_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name baz + DW_AT_low_pc $baz_start addr + DW_AT_high_pc $baz_len DW_FORM_data4 } } } @@ -117,7 +117,7 @@ if ![runto_main] { # the hole is there in the symbol table, but not the partial symbol table, # we run into: # (gdb) bt -# warning: (Internal error: pc 0x555555554619 in read in psymtab, \ +# warning: (Internal error: pc 0x555555554619 in read in psymtab, # but not in symtab.) # ... # (gdb) diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp index e8c9890..6440722 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp @@ -63,35 +63,35 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw-ranges-psym.c} - {low_pc 0 addr} - {ranges ${cu_ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw-ranges-psym.c + DW_AT_low_pc 0 addr + DW_AT_ranges ${cu_ranges_label} DW_FORM_sec_offset } { integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } volatile_label: DW_TAG_volatile_type { - {type :$integer_label} + DW_AT_type :$integer_label } subprogram { - {external 1 flag} - {name someothername} - {ranges ${func_ranges_label} DW_FORM_sec_offset} + DW_AT_external 1 flag + DW_AT_name someothername + DW_AT_ranges ${func_ranges_label} DW_FORM_sec_offset } subprogram { - {external 1 flag} - {name bar} - {low_pc $bar_start addr} - {high_pc $bar_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc $bar_len DW_FORM_data4 } subprogram { - {external 1 flag} - {name baz} - {low_pc $baz_start addr} - {high_pc $baz_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name baz + DW_AT_low_pc $baz_start addr + DW_AT_high_pc $baz_len DW_FORM_data4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-regno-invalid.exp b/gdb/testsuite/gdb.dwarf2/dw2-regno-invalid.exp index 5f3c324..7cfeb58 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-regno-invalid.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-regno-invalid.exp @@ -27,27 +27,27 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {MACRO_AT_range {main}} + MACRO_AT_range {main} } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_subprogram { - {DW_AT_external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } { DW_TAG_variable { - {DW_AT_name bregx} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_location { + DW_AT_name bregx + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_location { DW_OP_bregx 0xffffffff 0 - } SPECIAL_expr} + } SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S index cd999f4..551dda7 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S @@ -160,7 +160,11 @@ d: .byte 0 .byte 0 .byte 0 - .section .debug_str +#ifdef __arm__ + .section .debug_str,"MS",%progbits,1 +#else + .section .debug_str,"MS",@progbits,1 +#endif .LASF2: .string "GNU C 4.7.0 20110727 (experimental)" .LASF0: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-skipped-line-entries.exp b/gdb/testsuite/gdb.dwarf2/dw2-skipped-line-entries.exp index 2c2b5ff..1d86c61 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-skipped-line-entries.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-skipped-line-entries.exp @@ -40,14 +40,14 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name $::srcfile} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $::srcfile + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-step-between-different-inline-functions.exp b/gdb/testsuite/gdb.dwarf2/dw2-step-between-different-inline-functions.exp index a2f36cf..1eb1e38 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-step-between-different-inline-functions.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-step-between-different-inline-functions.exp @@ -79,48 +79,48 @@ Dwarf::assemble $asm_file { cu { version 4 } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { bar_label: subprogram { - {external 1 flag} - {name bar} - {decl_file 1 data1} - {decl_line $bar_decl_line data1} - {decl_column 1 data1} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_decl_file 1 data1 + DW_AT_decl_line $bar_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_inline 3 data1 } baz_label: subprogram { - {external 1 flag} - {name baz} - {decl_file 1 data1} - {decl_line $baz_decl_line data1} - {decl_column 1 data1} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name baz + DW_AT_decl_file 1 data1 + DW_AT_decl_line $baz_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_inline 3 data1 } subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $foo_decl_line data1} - {decl_column 1 data1} - {ranges ${ranges_label_foo} DW_FORM_sec_offset} - {external 1 flag} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_ranges ${ranges_label_foo} DW_FORM_sec_offset + DW_AT_external 1 flag } { inlined_subroutine { - {abstract_origin %$bar_label} - {call_file 1 data1} - {call_line $foo_src_2 data1} - {ranges ${ranges_label_bar} DW_FORM_sec_offset} + DW_AT_abstract_origin %$bar_label + DW_AT_call_file 1 data1 + DW_AT_call_line $foo_src_2 data1 + DW_AT_ranges ${ranges_label_bar} DW_FORM_sec_offset } inlined_subroutine { - {abstract_origin %$baz_label} - {call_file 1 data1} - {call_line $foo_src_3 data1} - {ranges ${ranges_label_baz} DW_FORM_sec_offset} + DW_AT_abstract_origin %$baz_label + DW_AT_call_file 1 data1 + DW_AT_call_line $foo_src_3 data1 + DW_AT_ranges ${ranges_label_baz} DW_FORM_sec_offset } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-step-between-inline-func-blocks.exp b/gdb/testsuite/gdb.dwarf2/dw2-step-between-inline-func-blocks.exp index ea8c7d3..1a76c58 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-step-between-inline-func-blocks.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-step-between-inline-func-blocks.exp @@ -71,34 +71,34 @@ Dwarf::assemble $asm_file { cu { version 4 } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name ${srcfile}} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { bar_label: subprogram { - {external 1 flag} - {name bar} - {decl_file 1 data1} - {decl_line $bar_decl_line data1} - {decl_column 1 data1} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name bar + DW_AT_decl_file 1 data1 + DW_AT_decl_line $bar_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_inline 3 data1 } subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $foo_decl_line data1} - {decl_column 1 data1} - {ranges ${ranges_label_foo} DW_FORM_sec_offset} - {external 1 flag} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_ranges ${ranges_label_foo} DW_FORM_sec_offset + DW_AT_external 1 flag } { inlined_subroutine { - {abstract_origin %$bar_label} - {call_file 1 data1} - {call_line $foo_src_3 data1} - {ranges ${ranges_label_bar} DW_FORM_sec_offset} + DW_AT_abstract_origin %$bar_label + DW_AT_call_file 1 data1 + DW_AT_call_line $foo_src_3 data1 + DW_AT_ranges ${ranges_label_bar} DW_FORM_sec_offset } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-step-out-of-function-no-stmt.exp b/gdb/testsuite/gdb.dwarf2/dw2-step-out-of-function-no-stmt.exp index a2d197b..3eaaa52 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-step-out-of-function-no-stmt.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-step-out-of-function-no-stmt.exp @@ -50,17 +50,17 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name $srcfile} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } subprogram { - {external 1 flag} - {MACRO_AT_func {bar}} + DW_AT_external 1 flag + MACRO_AT_func {bar} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-strp.S b/gdb/testsuite/gdb.dwarf2/dw2-strp.S index c7ede95..db3e64f 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-strp.S +++ b/gdb/testsuite/gdb.dwarf2/dw2-strp.S @@ -163,7 +163,11 @@ .byte 0x0 /* Terminator */ /* String table */ - .section .debug_str +#ifdef __arm__ + .section .debug_str,"MS",%progbits,1 +#else + .section .debug_str,"MS",@progbits,1 +#endif .Lproducer: .string "GNU C 3.3.3" .Lchar_str: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes-lookup.exp b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes-lookup.exp index aaa32ae..ccee277 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes-lookup.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes-lookup.exp @@ -54,23 +54,23 @@ Dwarf::assemble $asm_file { cu {} { partial_label: partial_unit { - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name myint} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name myint } } } cu {} { compile_unit { - {language @DW_LANG_C} - {DW_AT_name bla.c} + DW_AT_language @DW_LANG_C + DW_AT_name bla.c } { imported_unit { - {import $partial_label ref_addr} + DW_AT_import $partial_label ref_addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp index fce4346..3e34c3c 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp @@ -38,11 +38,11 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { imported_unit { - {import $partial_label ref_addr} + DW_AT_import $partial_label ref_addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unexpected-entry-pc.exp b/gdb/testsuite/gdb.dwarf2/dw2-unexpected-entry-pc.exp index d8b738d..fb257f0 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-unexpected-entry-pc.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-unexpected-entry-pc.exp @@ -102,32 +102,32 @@ proc run_test { entry_label dwarf_version with_line_table } { cu { version $dwarf_version } { compile_unit { - {producer "gcc"} - {language @DW_LANG_C} - {name $::srcfile} - {comp_dir /tmp} - {stmt_list $lines_table DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_C + DW_AT_name $::srcfile + DW_AT_comp_dir /tmp + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { inline_func: subprogram { - {name bar} - {inline @DW_INL_declared_inlined} + DW_AT_name bar + DW_AT_inline @DW_INL_declared_inlined } subprogram { - {name foo} - {decl_file 1 data1} - {decl_line $::foo_decl_line data1} - {decl_column 1 data1} - {low_pc $::foo_start addr} - {high_pc $::foo_len $::ptr_type} - {external 1 flag} + DW_AT_name foo + DW_AT_decl_file 1 data1 + DW_AT_decl_line $::foo_decl_line data1 + DW_AT_decl_column 1 data1 + DW_AT_low_pc $::foo_start addr + DW_AT_high_pc $::foo_len $::ptr_type + DW_AT_external 1 flag } { inlined_subroutine { - {abstract_origin %$inline_func} - {call_file 1 data1} - {call_line $::bar_call_line data1} - {entry_pc $entry_label addr} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_abstract_origin %$inline_func + DW_AT_call_file 1 data1 + DW_AT_call_line $::bar_call_line data1 + DW_AT_entry_pc $entry_label addr + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp index 0822c98..fece767 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp @@ -51,41 +51,41 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_Mips_Assembler} + DW_AT_language @DW_LANG_Mips_Assembler } { unspecified_type_label: unspecified_type {} DW_TAG_subprogram { - {name foo} - {low_pc $foo_start addr} - {high_pc $foo_end addr} - {type :$unspecified_type_label} + DW_AT_name foo + DW_AT_low_pc $foo_start addr + DW_AT_high_pc $foo_end addr + DW_AT_type :$unspecified_type_label } } } cu {} { compile_unit { - {language @DW_LANG_Mips_Assembler} - {producer "GNU AS 2.39.0"} + DW_AT_language @DW_LANG_Mips_Assembler + DW_AT_producer "GNU AS 2.39.0" } { DW_TAG_subprogram { - {name bar} - {low_pc $bar_start addr} - {high_pc $bar_end addr} + DW_AT_name bar + DW_AT_low_pc $bar_start addr + DW_AT_high_pc $bar_end addr } } } cu { version 2 } { compile_unit { - {language @DW_LANG_Mips_Assembler} - {producer "GNU AS 2.40.0"} + DW_AT_language @DW_LANG_Mips_Assembler + DW_AT_producer "GNU AS 2.40.0" } { DW_TAG_subprogram { - {name foo2} - {low_pc $foo2_start addr} - {high_pc $foo2_end addr} + DW_AT_name foo2 + DW_AT_low_pc $foo2_start addr + DW_AT_high_pc $foo2_end addr } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unusual-field-names.exp b/gdb/testsuite/gdb.dwarf2/dw2-unusual-field-names.exp index 0a306dd..6632a86 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-unusual-field-names.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-unusual-field-names.exp @@ -59,49 +59,49 @@ proc run_test { field_name } { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels itype ptype stype itype: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } stype: DW_TAG_structure_type { - {DW_AT_name "foo"} - {DW_AT_byte_size $int_size DW_FORM_sdata} + DW_AT_name "foo" + DW_AT_byte_size $int_size DW_FORM_sdata } { member { - {name $field_name} - {type :$itype} - {data_member_location 0 data1} + DW_AT_name $field_name + DW_AT_type :$itype + DW_AT_data_member_location 0 data1 } } ptype: DW_TAG_pointer_type { - {DW_AT_type :$stype} + DW_AT_type :$stype } DW_TAG_variable { - {DW_AT_name obj} - {DW_AT_type :$stype} - {DW_AT_location { + DW_AT_name obj + DW_AT_type :$stype + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol obj] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } DW_TAG_variable { - {DW_AT_name ptr} - {DW_AT_type :$ptype} - {DW_AT_location { + DW_AT_name ptr + DW_AT_type :$ptype + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol ptr] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-using-debug-str.exp b/gdb/testsuite/gdb.dwarf2/dw2-using-debug-str.exp index e46cbe5..6d8d9b1 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-using-debug-str.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-using-debug-str.exp @@ -34,51 +34,51 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name ${srcfile}} - } { + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + } { declare_labels int4_type struct_type int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } struct_type: DW_TAG_structure_type { - {DW_AT_name "foo_t" DW_FORM_strp} - {DW_AT_byte_size 12 DW_FORM_sdata} + DW_AT_name "foo_t" DW_FORM_strp + DW_AT_byte_size 12 DW_FORM_sdata } { member { - {name "aa" DW_FORM_strp} - {type :$int4_type} - {data_member_location 0 data1} + DW_AT_name "aa" DW_FORM_strp + DW_AT_type :$int4_type + DW_AT_data_member_location 0 data1 } member { - {name "bb" DW_FORM_strp} - {type :$int4_type} - {data_member_location 4 data1} + DW_AT_name "bb" DW_FORM_strp + DW_AT_type :$int4_type + DW_AT_data_member_location 4 data1 } member { - {name "cc" DW_FORM_strp} - {type :$int4_type} - {data_member_location 8 data1} + DW_AT_name "cc" DW_FORM_strp + DW_AT_type :$int4_type + DW_AT_data_member_location 8 data1 } } DW_TAG_variable { - {DW_AT_name global_var DW_FORM_strp} - {DW_AT_type :$struct_type} - {DW_AT_location { + DW_AT_name global_var DW_FORM_strp + DW_AT_type :$struct_type + DW_AT_location [subst { DW_OP_addr [gdb_target_symbol global_var] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } subprogram { - {external 1 flag} - {name main DW_FORM_strp} - {MACRO_AT_range {main}} + DW_AT_external 1 flag + DW_AT_name main DW_FORM_strp + MACRO_AT_range {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.exp b/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.exp index f021f42..c6234d5 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.exp @@ -34,7 +34,7 @@ test save_vars { GDBFLAGS } { set GDBFLAGS "$GDBFLAGS --readnow" - clean_restart ${binfile} + clean_restart ${::testfile} } with_test_prefix "readnow" { diff --git a/gdb/testsuite/gdb.dwarf2/dw2-vendor-extended-opcode.exp b/gdb/testsuite/gdb.dwarf2/dw2-vendor-extended-opcode.exp index 3e4ffc4..6432c9d 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-vendor-extended-opcode.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-vendor-extended-opcode.exp @@ -34,13 +34,13 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name dw2-vendor-extended-opcode.c} - {stmt_list $Llines DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name dw2-vendor-extended-opcode.c + DW_AT_stmt_list $Llines DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp index 0c76c87..35eaa16 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-weird-type-len.exp @@ -35,52 +35,52 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels integer_label foo_t_label bar_t_label foo_t_label: DW_TAG_structure_type { - {name foo_t} - {byte_size 3 DW_FORM_sdata} + DW_AT_name foo_t + DW_AT_byte_size 3 DW_FORM_sdata } { member { - {name field} - {type :$integer_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name field + DW_AT_type :$integer_label + DW_AT_data_member_location 0 DW_FORM_sdata } } integer_label: DW_TAG_base_type { - {DW_AT_byte_size 3 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 3 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } bar_t_label: DW_TAG_structure_type { - {name bar_t} - {byte_size 3 DW_FORM_sdata} + DW_AT_name bar_t + DW_AT_byte_size 3 DW_FORM_sdata } { member { - {name f} - {type :$foo_t_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name f + DW_AT_type :$foo_t_label + DW_AT_data_member_location 0 DW_FORM_sdata } } DW_TAG_subprogram { - {name main} - {low_pc $main_start addr} - {high_pc $main_len data8} - {DW_AT_type :$integer_label} + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len data8 + DW_AT_type :$integer_label } DW_TAG_subprogram { - {name get_bar} - {low_pc $get_bar_start addr} - {high_pc $get_bar_len data8} - {DW_AT_type :$bar_t_label} + DW_AT_name get_bar + DW_AT_low_pc $get_bar_start addr + DW_AT_high_pc $get_bar_len data8 + DW_AT_type :$bar_t_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-wrong-mangled-name.exp b/gdb/testsuite/gdb.dwarf2/dw2-wrong-mangled-name.exp index 33b1515..f892d70 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-wrong-mangled-name.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-wrong-mangled-name.exp @@ -33,20 +33,20 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C_plus_plus} - {name $srcfile} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile } { subprogram { - {MACRO_AT_range {func_demangled_test}} - {linkage_name "_FUNC_WRONG_MANGLED__"} - {name "func_demangled_test"} - {external 1 flag} + MACRO_AT_range {func_demangled_test} + DW_AT_linkage_name "_FUNC_WRONG_MANGLED__" + DW_AT_name "func_demangled_test" + DW_AT_external 1 flag } subprogram { - {MACRO_AT_range {main}} - {external 1 flag} - {name main} - {main_subprogram 1 flag} + MACRO_AT_range {main} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_main_subprogram 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp index 221bf7b..d5faf6f 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp @@ -26,7 +26,8 @@ standard_testfile .c -shlib.c -dw.S # Test for presence of complaint, with the lib relocated. proc_with_prefix test_relocated { exec_path lib_path complaint_re readnow_p } { - clean_restart $exec_path + clean_restart + gdb_load $exec_path gdb_load_shlib $lib_path if { ![runto_main] } { @@ -95,13 +96,13 @@ foreach_with_prefix ranges_sect {ranges rnglists} { cu {} { compile_unit { - {language @DW_LANG_C} - {name $srcfile2} - {ranges ${ranges_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile2 + DW_AT_ranges ${ranges_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name foo} + DW_AT_external 1 flag + DW_AT_name foo } } } @@ -122,13 +123,13 @@ foreach_with_prefix ranges_sect {ranges rnglists} { version 5 } { compile_unit { - {language @DW_LANG_C} - {name $srcfile2} - {ranges ${rnglists_label} DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile2 + DW_AT_ranges ${rnglists_label} DW_FORM_sec_offset } { subprogram { - {external 1 flag} - {name foo} + DW_AT_external 1 flag + DW_AT_name foo } } } diff --git a/gdb/testsuite/gdb.dwarf2/dwz-unused-pu.exp b/gdb/testsuite/gdb.dwarf2/dwz-unused-pu.exp index b7dc275..d9daedf 100644 --- a/gdb/testsuite/gdb.dwarf2/dwz-unused-pu.exp +++ b/gdb/testsuite/gdb.dwarf2/dwz-unused-pu.exp @@ -28,9 +28,11 @@ Dwarf::assemble $asm_file { declare_labels partial_label int_label int_label2 cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { subprogram { - {MACRO_AT_func { main }} + MACRO_AT_func { main } } } } @@ -38,15 +40,15 @@ Dwarf::assemble $asm_file { cu {} { partial_unit {} { int_label: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } constant { - {name the_int} - {type :$int_label} - {const_value 99 data1} + DW_AT_name the_int + DW_AT_type :$int_label + DW_AT_const_value 99 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dwz.exp b/gdb/testsuite/gdb.dwarf2/dwz.exp index 1d214c1..ebccea6 100644 --- a/gdb/testsuite/gdb.dwarf2/dwz.exp +++ b/gdb/testsuite/gdb.dwarf2/dwz.exp @@ -28,49 +28,53 @@ Dwarf::assemble $asm_file { cu {} { partial_label: partial_unit {} { subprogram { - {MACRO_AT_func { main }} + MACRO_AT_func { main } } } } cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { int_label2: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } constant { - {name the_int} - {type :$int_label2} - {const_value 99 data1} + DW_AT_name the_int + DW_AT_type :$int_label2 + DW_AT_const_value 99 data1 } constant { - {name other_int} - {type :$int_label2} - {const_value 99 data1} + DW_AT_name other_int + DW_AT_type :$int_label2 + DW_AT_const_value 99 data1 } } } cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { imported_unit { - {import $partial_label ref_addr} + DW_AT_import $partial_label ref_addr } int_label: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } constant { - {name the_int} - {type :$int_label} - {const_value 23 data1} + DW_AT_name the_int + DW_AT_type :$int_label + DW_AT_const_value 23 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp b/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp index 055e69c..080e999 100644 --- a/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp +++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid.exp @@ -13,160 +13,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -load_lib dwarf.exp - -# This test can only be run on targets which support DWARF-2 and use gas. -require dwarf2_support - -# No remote host testing either. -require {!is_remote host} - - -# Lots of source files since we test a few cases and make new files -# for each. -# The tests are: -# ok - the main file refers to a dwz and the buildids match -# mismatch - the buildids do not match -# fallback - the buildids do not match but a match is found via buildid -standard_testfile main.c \ - dwzbuildid-ok-base.S dwzbuildid-ok-sep.S \ - dwzbuildid-mismatch-base.S dwzbuildid-mismatch-sep.S \ - dwzbuildid-fallback-base.S dwzbuildid-fallback-sep.S \ - dwzbuildid-fallback-ok.S - -# Write some assembly that just has a .gnu_debugaltlink section. -proc write_just_debugaltlink {filename dwzname buildid} { - set asm_file [standard_output_file $filename] - - Dwarf::assemble $asm_file { - upvar dwzname dwzname - upvar buildid buildid - - gnu_debugaltlink $dwzname $buildid - - # Only the DWARF reader checks .gnu_debugaltlink, so make sure - # there is a bit of DWARF in here. - cu { label cu_start } { - compile_unit {{language @DW_LANG_C}} { - } - } - aranges {} cu_start { - arange {} 0 0 - } - } -} - -# Write some DWARF that also sets the buildid. -proc write_dwarf_file {filename buildid {value 99}} { - set asm_file [standard_output_file $filename] - - Dwarf::assemble $asm_file { - declare_labels int_label int_label2 - - upvar buildid buildid - upvar value value - - build_id $buildid - - cu { label cu_start } { - compile_unit {{language @DW_LANG_C}} { - int_label2: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} - } - - constant { - {name the_int} - {type :$int_label2} - {const_value $value data1} - } - } - } - - aranges {} cu_start { - arange {} 0 0 - } - } -} - -if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ - object {nodebug}] != "" } { - return -1 -} - -# The values don't really matter, just whether they are equal. -set ok_prefix 01 -set ok_suffix 02030405060708091011121314151617181920 -set ok_suffix2 020304050607080910111213141516171819ff -set ok_buildid ${ok_prefix}${ok_suffix} -set ok_buildid2 ${ok_prefix}${ok_suffix2} -set bad_buildid [string repeat ff 20] - -set debugdir [standard_output_file {}] -set basedir $debugdir/.build-id -file mkdir $basedir $basedir/$ok_prefix - -# Test where the separate debuginfo's buildid matches. -write_just_debugaltlink $srcfile2 ${binfile}3.o $ok_buildid -write_dwarf_file $srcfile3 $ok_buildid - -# Test where the separate debuginfo's buildid does not match. -write_just_debugaltlink $srcfile4 ${binfile}5.o $ok_buildid -write_dwarf_file $srcfile5 $bad_buildid - -# Test where the separate debuginfo's buildid does not match, but then -# we find a match in the .build-id directory. -write_just_debugaltlink $srcfile6 ${binfile}7.o $ok_buildid2 -# Use 77 as the value so that if we load the bad debuginfo, we will -# see the wrong result. -write_dwarf_file $srcfile7 $bad_buildid 77 -write_dwarf_file $srcfile8 $ok_buildid2 - -# Compile everything. -for {set i 2} {$i <= 8} {incr i} { - if {[gdb_compile [standard_output_file [set srcfile$i]] \ - ${binfile}$i.o object nodebug] != ""} { - return -1 - } -} - -# Copy a file into the .build-id place for the "fallback" test. -file copy -force -- ${binfile}8.o $basedir/$ok_prefix/$ok_suffix2.debug - -proc do_test {} { - clean_restart - - gdb_test_no_output "set debug-file-directory $::debugdir" \ - "set debug-file-directory" - - gdb_load ${::binfile}-${::testname} - - if {![runto_main]} { - return - } - - if {$::testname == "mismatch"} { - gdb_test "print the_int" \ - "(No symbol table is loaded|No symbol \"the_int\" in current context).*" - } else { - gdb_test "print the_int" " = 99" - } -} - -foreach_with_prefix testname { ok mismatch fallback } { - if { $testname == "ok" } { - set objs [list ${binfile}1.o ${binfile}2.o] - } elseif { $testname == "mismatch" } { - set objs [list ${binfile}1.o ${binfile}4.o] - } elseif { $testname == "fallback" } { - set objs [list ${binfile}1.o ${binfile}6.o] - } - - if {[gdb_compile $objs ${binfile}-$testname executable {quiet}] != ""} { - unsupported "compilation failed" - continue - } - - do_test -} +set scenario gnu +source $srcdir/$subdir/dwzbuildid.tcl diff --git a/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl b/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl new file mode 100644 index 0000000..1aa889a --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid.tcl @@ -0,0 +1,188 @@ +# Copyright 2013-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/>. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +# No remote host testing either. +require {!is_remote host} + + +# Lots of source files since we test a few cases and make new files +# for each. +# The tests are: +# ok - the main file refers to a dwz and the buildids match +# mismatch - the buildids do not match +# fallback - the buildids do not match but a match is found via buildid +standard_testfile main.c \ + dwzbuildid-ok-base.S dwzbuildid-ok-sep.S \ + dwzbuildid-mismatch-base.S dwzbuildid-mismatch-sep.S \ + dwzbuildid-fallback-base.S dwzbuildid-fallback-sep.S \ + dwzbuildid-fallback-ok.S + +# Write some assembly that just has a .gnu_debugaltlink section. +proc write_just_debugaltlink {filename dwzname buildid} { + set asm_file [standard_output_file $filename] + + Dwarf::assemble $asm_file { + upvar dwzname dwzname + upvar buildid buildid + + if {$::scenario == "gnu"} { + gnu_debugaltlink $dwzname $buildid + } else { + debug_sup 0 $dwzname $buildid + } + + # Only the DWARF reader checks .gnu_debugaltlink, so make sure + # there is a bit of DWARF in here. + cu { label cu_start } { + compile_unit { + DW_AT_language @DW_LANG_C + } { + } + } + aranges {} cu_start { + arange {} 0 0 + } + } +} + +# Write some DWARF that also sets the buildid. +proc write_dwarf_file {filename buildid {value 99}} { + set asm_file [standard_output_file $filename] + + Dwarf::assemble $asm_file { + declare_labels int_label int_label2 + + upvar buildid buildid + upvar value value + + if {$::scenario == "gnu"} { + build_id $buildid + } else { + debug_sup 1 "" $buildid + } + + cu { label cu_start } { + compile_unit { + DW_AT_language @DW_LANG_C + } { + int_label2: base_type { + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed + } + + constant { + DW_AT_name the_int + DW_AT_type :$int_label2 + DW_AT_const_value $value data1 + } + } + } + + aranges {} cu_start { + arange {} 0 0 + } + } +} + +if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ + object {nodebug}] != "" } { + return -1 +} + +# The values don't really matter, just whether they are equal. +set ok_prefix 01 +set ok_suffix 02030405060708091011121314151617181920 +set ok_suffix2 020304050607080910111213141516171819ff +set ok_buildid ${ok_prefix}${ok_suffix} +set ok_buildid2 ${ok_prefix}${ok_suffix2} +set bad_buildid [string repeat ff 20] + +set debugdir [standard_output_file {}] +set basedir $debugdir/.build-id +file mkdir $basedir $basedir/$ok_prefix + +# Test where the separate debuginfo's buildid matches. +write_just_debugaltlink $srcfile2 ${binfile}3.o $ok_buildid +write_dwarf_file $srcfile3 $ok_buildid + +# Test where the separate debuginfo's buildid does not match. +write_just_debugaltlink $srcfile4 ${binfile}5.o $ok_buildid +write_dwarf_file $srcfile5 $bad_buildid + +# Test where the separate debuginfo's buildid does not match, but then +# we find a match in the .build-id directory. +write_just_debugaltlink $srcfile6 ${binfile}7.o $ok_buildid2 +# Use 77 as the value so that if we load the bad debuginfo, we will +# see the wrong result. +write_dwarf_file $srcfile7 $bad_buildid 77 +write_dwarf_file $srcfile8 $ok_buildid2 + +# Compile everything. +for {set i 2} {$i <= 8} {incr i} { + if {[gdb_compile [standard_output_file [set srcfile$i]] \ + ${binfile}$i.o object nodebug] != ""} { + return -1 + } +} + +# Copy a file into the .build-id place for the "fallback" test. +file copy -force -- ${binfile}8.o $basedir/$ok_prefix/$ok_suffix2.debug + +proc do_test {} { + clean_restart + + gdb_test_no_output "set debug-file-directory $::debugdir" \ + "set debug-file-directory" + + gdb_load ${::binfile}-${::testname} + + if {![runto_main]} { + return + } + + if {$::testname == "mismatch"} { + gdb_test "print the_int" \ + "(No symbol table is loaded|No symbol \"the_int\" in current context).*" + } else { + gdb_test "print the_int" " = 99" + } +} + +set tests {ok mismatch} +if {$scenario == "gnu"} { + lappend tests fallback +} +foreach_with_prefix testname $tests { + if { $testname == "ok" } { + set objs [list ${binfile}1.o ${binfile}2.o] + } elseif { $testname == "mismatch" } { + set objs [list ${binfile}1.o ${binfile}4.o] + } elseif { $testname == "fallback" } { + set objs [list ${binfile}1.o ${binfile}6.o] + } + + if {[gdb_compile $objs ${binfile}-$testname executable {quiet}] != ""} { + unsupported "compilation failed" + continue + } + + do_test +} diff --git a/gdb/testsuite/gdb.testsuite/lmap.exp b/gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp index da03722..047626c 100644 --- a/gdb/testsuite/gdb.testsuite/lmap.exp +++ b/gdb/testsuite/gdb.dwarf2/dwzbuildid5.exp @@ -1,4 +1,5 @@ -# Copyright 2023-2025 Free Software Foundation, Inc. +# 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 @@ -12,9 +13,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -set one 1 -set l1 { $one 2 } -set res1 [lmap item $l1 {expr $item + 1}] -gdb_assert { [lindex $res1 0] == 2 } -gdb_assert { [lindex $res1 1] == 3 } -gdb_assert { $item == 2 } +set scenario dwarf5 +source $srcdir/$subdir/dwzbuildid.tcl diff --git a/gdb/testsuite/gdb.dwarf2/dwznolink.exp b/gdb/testsuite/gdb.dwarf2/dwznolink.exp index 91fe369..b568055 100644 --- a/gdb/testsuite/gdb.dwarf2/dwznolink.exp +++ b/gdb/testsuite/gdb.dwarf2/dwznolink.exp @@ -30,11 +30,13 @@ set asm_file [standard_output_file $srcfile2] # one point, this caused gdb crashes. Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { constant { - {name 0 DW_FORM_GNU_strp_alt} - {type 97 DW_FORM_GNU_ref_alt} - {const_value 99 data1} + DW_AT_name 0 DW_FORM_GNU_strp_alt + DW_AT_type 97 DW_FORM_GNU_ref_alt + DW_AT_const_value 99 data1 } } } @@ -49,5 +51,5 @@ if {[build_executable $testfile.exp $testfile \ clean_restart gdb_test "file -readnow $binfile" \ - "could not read '.gnu_debugaltlink' section" \ + "could not find supplementary DWARF file" \ "file $testfile" diff --git a/gdb/testsuite/gdb.dwarf2/dyn-type-unallocated.exp b/gdb/testsuite/gdb.dwarf2/dyn-type-unallocated.exp index 09af96c..e4248d0 100644 --- a/gdb/testsuite/gdb.dwarf2/dyn-type-unallocated.exp +++ b/gdb/testsuite/gdb.dwarf2/dyn-type-unallocated.exp @@ -66,57 +66,57 @@ Dwarf::assemble $asm_file { global srcfile compile_unit { - {producer "gcc" } - {language @DW_LANG_Fortran90} - {name ${srcfile}} - {low_pc 0 addr} - } { + DW_AT_producer "gcc" + DW_AT_language @DW_LANG_Fortran90 + DW_AT_name ${srcfile} + DW_AT_low_pc 0 addr + } { declare_labels array_type_label integer_type_label - integer_type_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} - } + integer_type_label: DW_TAG_base_type { + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer + } array_type_label: DW_TAG_array_type { - {DW_AT_type :$integer_type_label} - {DW_AT_data_location { + DW_AT_type :$integer_type_label + DW_AT_data_location { DW_OP_push_object_address DW_OP_deref - } SPECIAL_expr} - {DW_AT_allocated { + } SPECIAL_expr + DW_AT_allocated { DW_OP_lit0 - } SPECIAL_expr} + } SPECIAL_expr } { DW_TAG_subrange_type { - {DW_AT_type :$integer_type_label} - {DW_AT_lower_bound { + DW_AT_type :$integer_type_label + DW_AT_lower_bound { DW_OP_skip -3 - } SPECIAL_expr} - {DW_AT_upper_bound { + } SPECIAL_expr + DW_AT_upper_bound { DW_OP_skip -3 - } SPECIAL_expr} - {DW_AT_byte_stride { + } SPECIAL_expr + DW_AT_byte_stride { DW_OP_skip -3 - } SPECIAL_expr} + } SPECIAL_expr } } DW_TAG_variable { - {DW_AT_location { - DW_OP_addr [gdb_target_symbol dyn_object] - } SPECIAL_expr} - {name "dyn_object"} - {type :$array_type_label} + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol dyn_object] + }] SPECIAL_expr + DW_AT_name "dyn_object" + DW_AT_type :$array_type_label } subprogram { - {external 1 flag} - {DW_AT_name main} - {DW_AT_low_pc $main_start DW_FORM_addr} - {DW_AT_high_pc $main_end DW_FORM_addr} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start DW_FORM_addr + DW_AT_high_pc $main_end DW_FORM_addr } - } + } } } diff --git a/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp b/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp new file mode 100644 index 0000000..a5cf54d --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp @@ -0,0 +1,96 @@ +# 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 DW_AT_data_bit_offset with an expression. This is a DWARF +# extension, but expected to be in DWARF 6. See +# https://dwarfstd.org/issues/250501.1.html + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile ada-array-bound.c -debug.S + +# Set up the DWARF for the test. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile + + cu {} { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name $srcfile + } { + declare_labels byte array struct + + byte: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name byte + } + + array: DW_TAG_array_type { + DW_AT_name array_type + DW_AT_type :$byte + } { + DW_TAG_subrange_type { + DW_AT_type :$byte + DW_AT_upper_bound 3 DW_FORM_sdata + } + } + + struct: DW_TAG_structure_type { + DW_AT_name discriminated + DW_AT_byte_size 4 DW_FORM_sdata + } { + DW_TAG_member { + DW_AT_name disc + DW_AT_type :$byte + DW_AT_data_member_location 0 DW_FORM_sdata + } + + # We know this is always at offset 1 but use an + # expression just to test this code path. This is a + # DWARF extension. See + # https://dwarfstd.org/issues/250501.1.html. + DW_TAG_member { + DW_AT_name nums + DW_AT_type :$array + DW_AT_data_bit_offset {DW_OP_lit8} SPECIAL_expr + } + } + + DW_TAG_variable { + DW_AT_name "value" + DW_AT_type :$struct + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "our_data"] + }] SPECIAL_expr + } + } + } +} + +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}]} { + return -1 +} + +gdb_test_no_output "set language ada" +gdb_test "print value" \ + [string_to_regexp " = (disc => 3, nums => (7, 11, 13))"] diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp index 1e06212..331cfc2 100644 --- a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp +++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp @@ -34,83 +34,83 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Ada95} - {DW_AT_name foo.adb} - {DW_AT_comp_dir /tmp} - } { - declare_labels integer_label array_label array_ptr_label \ - array_typedef_label - set ptr_size [get_sizeof "void *" 96] + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_Ada95 + DW_AT_name foo.adb + DW_AT_comp_dir /tmp + } { + declare_labels integer_label array_label array_ptr_label \ + array_typedef_label + set ptr_size [get_sizeof "void *" 96] set int_size [get_sizeof "int" 4] - integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} - } + integer_label: DW_TAG_base_type { + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer + } array_label: DW_TAG_array_type { - {DW_AT_name foo__array_type} - {DW_AT_type :$integer_label} - {external 1 flag} + DW_AT_name foo__array_type + DW_AT_type :$integer_label + DW_AT_external 1 flag } { DW_TAG_subrange_type { - {DW_AT_type :$integer_label} - {DW_AT_lower_bound { - DW_OP_push_object_address - DW_OP_const1u [expr {2 * $int_size}] - DW_OP_minus - DW_OP_deref_size $int_size - } SPECIAL_expr} - {DW_AT_upper_bound { - DW_OP_push_object_address + DW_AT_type :$integer_label + DW_AT_lower_bound [subst { + DW_OP_push_object_address + DW_OP_const1u [expr {2 * $int_size}] + DW_OP_minus + DW_OP_deref_size $int_size + }] SPECIAL_expr + DW_AT_upper_bound [subst { + DW_OP_push_object_address DW_OP_const1u $int_size - DW_OP_minus - DW_OP_deref_size $int_size - } SPECIAL_expr} + DW_OP_minus + DW_OP_deref_size $int_size + }] SPECIAL_expr } } - array_ptr_label: DW_TAG_pointer_type { - {DW_AT_byte_size $ptr_size DW_FORM_data1} - {DW_AT_type :$array_label} - } - array_typedef_label: DW_TAG_typedef { - {DW_AT_name "foo__array_ptr"} - {DW_AT_type :$array_ptr_label} - } - DW_TAG_variable { - {DW_AT_name foo__three_ptr} - {DW_AT_type :$array_ptr_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_1_ptr] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__three_ptr_tdef} - {DW_AT_type :$array_typedef_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_1_ptr] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__five_ptr} - {DW_AT_type :$array_ptr_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_2_ptr] - } SPECIAL_expr} - {external 1 flag} - } - DW_TAG_variable { - {DW_AT_name foo__five_ptr_tdef} - {DW_AT_type :$array_typedef_label} - {DW_AT_location { - DW_OP_addr [gdb_target_symbol table_2_ptr] - } SPECIAL_expr} - {external 1 flag} - } + array_ptr_label: DW_TAG_pointer_type { + DW_AT_byte_size $ptr_size DW_FORM_data1 + DW_AT_type :$array_label + } + array_typedef_label: DW_TAG_typedef { + DW_AT_name "foo__array_ptr" + DW_AT_type :$array_ptr_label + } + DW_TAG_variable { + DW_AT_name foo__three_ptr + DW_AT_type :$array_ptr_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_1_ptr] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__three_ptr_tdef + DW_AT_type :$array_typedef_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_1_ptr] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__five_ptr + DW_AT_type :$array_ptr_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_2_ptr] + }] SPECIAL_expr + DW_AT_external 1 flag + } + DW_TAG_variable { + DW_AT_name foo__five_ptr_tdef + DW_AT_type :$array_typedef_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol table_2_ptr] + }] SPECIAL_expr + DW_AT_external 1 flag + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/enqueued-cu-base-addr.exp b/gdb/testsuite/gdb.dwarf2/enqueued-cu-base-addr.exp index 621b2e7..96287dd 100644 --- a/gdb/testsuite/gdb.dwarf2/enqueued-cu-base-addr.exp +++ b/gdb/testsuite/gdb.dwarf2/enqueued-cu-base-addr.exp @@ -37,28 +37,28 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C_plus_plus} - {name "cu1"} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "cu1" } { DW_TAG_variable { - {name foo} - {type %$int_label} - {const_value 1 DW_FORM_sdata} + DW_AT_name foo + DW_AT_type %$int_label + DW_AT_const_value 1 DW_FORM_sdata } } } cu {} { compile_unit { - {language @DW_LANG_C_plus_plus} - {name "cu2"} - {ranges ${ranges_label} sec_offset} - {low_pc {[lindex $main_func 0]}} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "cu2" + DW_AT_ranges ${ranges_label} sec_offset + DW_AT_low_pc [lindex $main_func 0] } { int_label: base_type { - {byte_size 4 udata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size 4 udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } } } diff --git a/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp b/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp index 44d58a8..f84f0f3 100644 --- a/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp +++ b/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp @@ -31,7 +31,7 @@ if {[gdb_compile "$srcdir/$subdir/$srcfile" "$binfile" executable {c++}] != ""} return } -clean_restart $binfile +clean_restart $::testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.dwarf2/enum-type.exp b/gdb/testsuite/gdb.dwarf2/enum-type.exp index 121a350..f077c0a 100644 --- a/gdb/testsuite/gdb.dwarf2/enum-type.exp +++ b/gdb/testsuite/gdb.dwarf2/enum-type.exp @@ -26,41 +26,41 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels integer_label uinteger_label - integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} - } + integer_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int + } - uinteger_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name {unsigned int}} - } + uinteger_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name {unsigned int} + } DW_TAG_enumeration_type { - {DW_AT_name E} - {DW_AT_type :$integer_label} + DW_AT_name E + DW_AT_type :$integer_label } { DW_TAG_enumerator { - {DW_AT_name ONE} - {DW_AT_const_value 1 DW_FORM_sdata} + DW_AT_name ONE + DW_AT_const_value 1 DW_FORM_sdata } } DW_TAG_enumeration_type { - {DW_AT_name EU} - {DW_AT_type :$uinteger_label} + DW_AT_name EU + DW_AT_type :$uinteger_label } { DW_TAG_enumerator { - {DW_AT_name TWO} - {DW_AT_const_value 2 DW_FORM_sdata} + DW_AT_name TWO + DW_AT_const_value 2 DW_FORM_sdata } } } @@ -68,34 +68,34 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name tmp.c} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name tmp.c + DW_AT_comp_dir /tmp } { declare_labels integer_label forward integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_enumeration_type { - {DW_AT_specification :$forward} + DW_AT_specification :$forward } { DW_TAG_enumerator { - {DW_AT_name val1} - {DW_AT_const_value 1 DW_FORM_sdata} + DW_AT_name val1 + DW_AT_const_value 1 DW_FORM_sdata } } DW_TAG_namespace { - {DW_AT_name ns} + DW_AT_name ns } { forward: DW_TAG_enumeration_type { - {DW_AT_name e} - {DW_AT_type :$integer_label} - {DW_AT_declaration 1 flag} + DW_AT_name e + DW_AT_type :$integer_label + DW_AT_declaration 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/fission-absolute-dwo.exp b/gdb/testsuite/gdb.dwarf2/fission-absolute-dwo.exp index 4f354cd..640d4d2 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-absolute-dwo.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-absolute-dwo.exp @@ -40,53 +40,53 @@ Dwarf::assemble $asm_file { set debug_addr_lbl [debug_addr_label] compile_unit { - {language @DW_LANG_C} - {name ${srcfile}} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - } { + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + } { declare_labels int4_type struct_type int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } struct_type: DW_TAG_structure_type { - {DW_AT_name "foo_t"} - {DW_AT_byte_size 12 DW_FORM_sdata} + DW_AT_name "foo_t" + DW_AT_byte_size 12 DW_FORM_sdata } { member { - {name "aa"} - {type :$int4_type} - {data_member_location 0 data1} + DW_AT_name "aa" + DW_AT_type :$int4_type + DW_AT_data_member_location 0 data1 } member { - {name "bb"} - {type :$int4_type} - {data_member_location 4 data1} + DW_AT_name "bb" + DW_AT_type :$int4_type + DW_AT_data_member_location 4 data1 } member { - {name "cc"} - {type :$int4_type} - {data_member_location 8 data1} + DW_AT_name "cc" + DW_AT_type :$int4_type + DW_AT_data_member_location 8 data1 } } DW_TAG_variable { - {DW_AT_name global_var} - {DW_AT_type :$struct_type} - {DW_AT_location { + DW_AT_name global_var + DW_AT_type :$struct_type + DW_AT_location [subst { DW_OP_GNU_addr_index [gdb_target_symbol global_var] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } subprogram { - {external 1 flag} - {DW_AT_name main DW_FORM_string} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + DW_AT_name main DW_FORM_string + MACRO_AT_func {main} } } } @@ -94,11 +94,11 @@ Dwarf::assemble $asm_file { # The information that will remain in the .o file. cu {} { compile_unit { - {DW_AT_GNU_dwo_name ${binfile}.dwo DW_FORM_strp} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - {DW_AT_GNU_addr_base $debug_addr_lbl} - } { + DW_AT_GNU_dwo_name ${binfile}.dwo DW_FORM_strp + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + DW_AT_GNU_addr_base $debug_addr_lbl + } { # Nothing. } } diff --git a/gdb/testsuite/gdb.dwarf2/fission-base.exp b/gdb/testsuite/gdb.dwarf2/fission-base.exp index 4d18ea0..9f70f30 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-base.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-base.exp @@ -35,7 +35,7 @@ if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \ return -1 } -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp b/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp new file mode 100644 index 0000000..5f778e6 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp @@ -0,0 +1,88 @@ +# 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/>. + +# Check support for a DW_FORM_strx attribute in a dwo file. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile main.c -dw.S -dwo.S + +set main_asm_file [standard_output_file $srcfile2] +set dwo_asm_file [standard_output_file $srcfile3] + +# Debug info in the main file. +Dwarf::assemble $main_asm_file { + cu { + version 5 + dwo_id 0xF00D + } { + compile_unit { + DW_AT_dwo_name ${::gdb_test_file_name}.dwo DW_FORM_strp + } {} + } +} + +# Debug info in the DWO file. +Dwarf::assemble $dwo_asm_file { + debug_str_offsets { dwo 1 } int + + cu { + fission 1 + version 5 + dwo_id 0xF00D + } { + compile_unit {} { + declare_labels int4_type + + int4_type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name 0 DW_FORM_strx_id + } + + DW_TAG_variable { + DW_AT_name global_var + DW_AT_type :$int4_type + DW_AT_location { + DW_OP_const1u 12 + DW_OP_stack_value + } SPECIAL_expr + } + } + } +} + +# Build main file. +if { [build_executable "${testfile}.exp" $binfile \ + [list ${srcfile} ${main_asm_file}] {nodebug}] } { + return +} + +# Build DWO file. +set dwo_file [standard_output_file ${testfile}.dwo] +if { [gdb_compile_shlib $dwo_asm_file $dwo_file nodebug] != "" } { + return +} + +if { [is_remote host] } { + gdb_remote_download host $dwo_file +} + +clean_restart $::testfile + +gdb_test "ptype global_var" "type = int" diff --git a/gdb/testsuite/gdb.dwarf2/fission-loclists-pie.exp b/gdb/testsuite/gdb.dwarf2/fission-loclists-pie.exp index 5be2e8e..aa54718 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-loclists-pie.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-loclists-pie.exp @@ -40,7 +40,7 @@ if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" \ return -1 } -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.dwarf2/fission-loclists.exp b/gdb/testsuite/gdb.dwarf2/fission-loclists.exp index 95c1fac..59cd10b 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-loclists.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-loclists.exp @@ -35,7 +35,7 @@ if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \ return -1 } -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.dwarf2/fission-mix.exp b/gdb/testsuite/gdb.dwarf2/fission-mix.exp index e4741c3..e6a430c 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-mix.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-mix.exp @@ -35,7 +35,7 @@ if {[gdb_compile "$objfile $objfile2" $binfile executable {debug}] != "" } { return -1 } -clean_restart $binfile +clean_restart $::testfile gdb_test "break -q main" "Breakpoint .*" diff --git a/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp index 44e72d6..ff498c9 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp @@ -51,29 +51,29 @@ Dwarf::assemble $asm_file_1 { set debug_addr_lbl [debug_addr_label] compile_unit { - {language @DW_LANG_C} - {name ${srcfile}} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - } { + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + } { int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } subprogram { - {external 1 flag} - {DW_AT_name func DW_FORM_string} - {MACRO_AT_func {func}} - {DW_AT_type :$int4_type} + DW_AT_external 1 flag + DW_AT_name func DW_FORM_string + MACRO_AT_func {func} + DW_AT_type :$int4_type } { DW_TAG_formal_parameter { - {DW_AT_name arg} - {DW_AT_type :$int4_type} - {DW_AT_location { + DW_AT_name arg + DW_AT_type :$int4_type + DW_AT_location [subst { DW_OP_GNU_addr_index [gdb_target_symbol global_param] - } SPECIAL_expr} + }] SPECIAL_expr } } } @@ -100,12 +100,12 @@ Dwarf::assemble $asm_file_1 { # The information that will remain in the .o file. cu {} { compile_unit { - {DW_AT_GNU_dwo_name ${binfile}-1-dw.dwo DW_FORM_strp} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - {DW_AT_GNU_addr_base $debug_addr_lbl} - {stmt_list $lines_table DW_FORM_sec_offset} - } { + DW_AT_GNU_dwo_name ${binfile}-1-dw.dwo DW_FORM_strp + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + DW_AT_GNU_addr_base $debug_addr_lbl + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + } { # Nothing. } } @@ -131,24 +131,24 @@ Dwarf::assemble $asm_file_2 { set debug_addr_lbl [debug_addr_label] compile_unit { - {language @DW_LANG_C} - {name ${srcfile}} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8} - } { + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8 + } { int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } subprogram { - {external 1 flag} - {DW_AT_name main DW_FORM_string} - {MACRO_AT_func {main}} - {DW_AT_type :$int4_type} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 29 data1} + DW_AT_external 1 flag + DW_AT_name main DW_FORM_string + MACRO_AT_func {main} + DW_AT_type :$int4_type + DW_AT_decl_file 1 data1 + DW_AT_decl_line 29 data1 } } } @@ -182,12 +182,12 @@ Dwarf::assemble $asm_file_2 { # The information that will remain in the .o file. cu {} { compile_unit { - {DW_AT_GNU_dwo_name ${binfile}-2-dw.dwo DW_FORM_strp} - {DW_AT_comp_dir ${objdir}} - {DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8} - {DW_AT_GNU_addr_base $debug_addr_lbl} - {stmt_list $lines_table DW_FORM_sec_offset} - } { + DW_AT_GNU_dwo_name ${binfile}-2-dw.dwo DW_FORM_strp + DW_AT_comp_dir ${objdir} + DW_AT_GNU_dwo_id 0x4567 DW_FORM_data8 + DW_AT_GNU_addr_base $debug_addr_lbl + DW_AT_stmt_list $lines_table DW_FORM_sec_offset + } { # Nothing. } } @@ -203,7 +203,7 @@ if [build_executable_and_dwo_files "$testfile.exp" "${binfile}" {nodebug} \ return -1 } -clean_restart $binfile +clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.dwarf2/fission-relative-dwo.exp b/gdb/testsuite/gdb.dwarf2/fission-relative-dwo.exp index 5590156..e605aef 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-relative-dwo.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-relative-dwo.exp @@ -37,53 +37,53 @@ Dwarf::assemble $asm_file { set debug_addr_base [debug_addr_label] compile_unit { - {language @DW_LANG_C} - {name ${srcfile}} - {DW_AT_comp_dir .} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - } { + DW_AT_language @DW_LANG_C + DW_AT_name ${srcfile} + DW_AT_comp_dir . + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + } { declare_labels int4_type struct_type int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } struct_type: DW_TAG_structure_type { - {DW_AT_name "foo_t"} - {DW_AT_byte_size 12 DW_FORM_sdata} + DW_AT_name "foo_t" + DW_AT_byte_size 12 DW_FORM_sdata } { member { - {name "aa"} - {type :$int4_type} - {data_member_location 0 data1} + DW_AT_name "aa" + DW_AT_type :$int4_type + DW_AT_data_member_location 0 data1 } member { - {name "bb"} - {type :$int4_type} - {data_member_location 4 data1} + DW_AT_name "bb" + DW_AT_type :$int4_type + DW_AT_data_member_location 4 data1 } member { - {name "cc"} - {type :$int4_type} - {data_member_location 8 data1} + DW_AT_name "cc" + DW_AT_type :$int4_type + DW_AT_data_member_location 8 data1 } } DW_TAG_variable { - {DW_AT_name global_var} - {DW_AT_type :$struct_type} - {DW_AT_location { + DW_AT_name global_var + DW_AT_type :$struct_type + DW_AT_location [subst { DW_OP_GNU_addr_index [gdb_target_symbol global_var] - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } subprogram { - {external 1 flag} - {DW_AT_name main DW_FORM_string} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + DW_AT_name main DW_FORM_string + MACRO_AT_func {main} } } } @@ -91,11 +91,11 @@ Dwarf::assemble $asm_file { # The information that will remain in the .o file. cu {} { compile_unit { - {DW_AT_GNU_dwo_name ${gdb_test_file_name}.dwo DW_FORM_strp} - {DW_AT_comp_dir .} - {DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8} - {DW_AT_GNU_addr_base $debug_addr_base} - } { + DW_AT_GNU_dwo_name ${gdb_test_file_name}.dwo DW_FORM_strp + DW_AT_comp_dir . + DW_AT_GNU_dwo_id 0x1234 DW_FORM_data8 + DW_AT_GNU_addr_base $debug_addr_base + } { # Nothing. } } diff --git a/gdb/testsuite/gdb.dwarf2/fission-reread.exp b/gdb/testsuite/gdb.dwarf2/fission-reread.exp index 6821747..238afb1 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-reread.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-reread.exp @@ -62,7 +62,7 @@ pass "$testfile - unload" remote_file target delete $dwo save_vars { GDBFLAGS } { append GDBFLAGS " -iex \"maint set dwarf synchronous on\"" - clean_restart $binfile + clean_restart $::testfile } set output_dir [standard_output_file ""] set cmd "save gdb-index" diff --git a/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp b/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp index 0a02f7c..58cda29 100644 --- a/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp +++ b/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp @@ -33,7 +33,7 @@ Dwarf::assemble $main_asm_file { dwo_id 0xF00D } { compile_unit { - {DW_AT_dwo_name ${::gdb_test_file_name}.dwo DW_FORM_strp} + DW_AT_dwo_name ${::gdb_test_file_name}.dwo DW_FORM_strp } {} } } @@ -46,9 +46,9 @@ Dwarf::assemble $dwo_asm_file { } 0xCAFE "the_type" { type_unit {} { the_type: base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } } } @@ -62,18 +62,18 @@ Dwarf::assemble $dwo_asm_file { declare_labels int4_type int4_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_variable { - {DW_AT_name global_var} - {DW_AT_type :$int4_type} - {DW_AT_location { + DW_AT_name global_var + DW_AT_type :$int4_type + DW_AT_location { DW_OP_const1u 12 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/formdata16.exp b/gdb/testsuite/gdb.dwarf2/formdata16.exp index 70c7cc4..c08183e 100644 --- a/gdb/testsuite/gdb.dwarf2/formdata16.exp +++ b/gdb/testsuite/gdb.dwarf2/formdata16.exp @@ -50,33 +50,33 @@ Dwarf::assemble $asm_file { declare_labels int_label sint_label int_label: DW_TAG_base_type { - {DW_AT_byte_size 16 DW_FORM_udata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name "__uint128"} + DW_AT_byte_size 16 DW_FORM_udata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "__uint128" } sint_label: DW_TAG_base_type { - {DW_AT_byte_size 16 DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "__int128"} + DW_AT_byte_size 16 DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "__int128" } DW_TAG_variable { - {name xxx} - {type :$int_label} - {const_value $pair DW_FORM_data16} + DW_AT_name xxx + DW_AT_type :$int_label + DW_AT_const_value $pair DW_FORM_data16 } DW_TAG_variable { - {name yyy} - {type :$int_label} - {const_value $pair2 DW_FORM_data16} + DW_AT_name yyy + DW_AT_type :$int_label + DW_AT_const_value $pair2 DW_FORM_data16 } DW_TAG_variable { - {name sss} - {type :$sint_label} - {const_value $negative DW_FORM_data16} + DW_AT_name sss + DW_AT_type :$sint_label + DW_AT_const_value $negative DW_FORM_data16 } } } diff --git a/gdb/testsuite/gdb.dwarf2/fortran-var-string.exp b/gdb/testsuite/gdb.dwarf2/fortran-var-string.exp index e4a1270..b751900 100644 --- a/gdb/testsuite/gdb.dwarf2/fortran-var-string.exp +++ b/gdb/testsuite/gdb.dwarf2/fortran-var-string.exp @@ -40,92 +40,92 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_Fortran90} - {DW_AT_name fortran-var-string.f90} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_Fortran90 + DW_AT_name fortran-var-string.f90 + DW_AT_comp_dir /tmp + } { declare_labels integer_label string_label array_lb_label \ array_ub_label DW_TAG_subprogram { - {name main} - {low_pc $main_helper_start addr} - {high_pc $main_helper_len data8} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 1 data1} + DW_AT_name main + DW_AT_low_pc $main_helper_start addr + DW_AT_high_pc $main_helper_len data8 + DW_AT_type :$integer_label + DW_AT_decl_file 1 data1 + DW_AT_decl_line 1 data1 } DW_TAG_subprogram { - {name test_1_func} - {low_pc $main_start addr} - {high_pc $main_len data8} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 2 data1} + DW_AT_name test_1_func + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len data8 + DW_AT_type :$integer_label + DW_AT_decl_file 1 data1 + DW_AT_decl_line 2 data1 } { formal_parameter { - {name arg1} - {type :$string_label} + DW_AT_name arg1 + DW_AT_type :$string_label } } DW_TAG_subprogram { - {name test_2_func} - {low_pc $main_start addr} - {high_pc $main_len data8} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 3 data1} + DW_AT_name test_2_func + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len data8 + DW_AT_type :$integer_label + DW_AT_decl_file 1 data1 + DW_AT_decl_line 3 data1 } { formal_parameter { - {name arg1} - {type :$array_ub_label} + DW_AT_name arg1 + DW_AT_type :$array_ub_label } } DW_TAG_subprogram { - {name test_3_func} - {low_pc $main_start addr} - {high_pc $main_len data8} - {DW_AT_type :$integer_label} - {DW_AT_decl_file 1 data1} - {DW_AT_decl_line 4 data1} + DW_AT_name test_3_func + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len data8 + DW_AT_type :$integer_label + DW_AT_decl_file 1 data1 + DW_AT_decl_line 4 data1 } { formal_parameter { - {name arg1} - {type :$array_lb_label} + DW_AT_name arg1 + DW_AT_type :$array_lb_label } } integer_label: DW_TAG_base_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } string_label: DW_TAG_string_type { - {DW_AT_byte_size $int_size DW_FORM_sdata} - {DW_AT_name .str.arg} - {DW_AT_string_length {} DW_FORM_block1} + DW_AT_byte_size $int_size DW_FORM_sdata + DW_AT_name .str.arg + DW_AT_string_length {} DW_FORM_block1 } array_lb_label: DW_TAG_array_type { - {DW_AT_ordering 1 data1} - {DW_AT_type :$integer_label} + DW_AT_ordering 1 data1 + DW_AT_type :$integer_label } { DW_TAG_subrange_type { - {DW_AT_lower_bound {} DW_FORM_block1} - {DW_AT_upper_bound 10 DW_FORM_data1} + DW_AT_lower_bound {} DW_FORM_block1 + DW_AT_upper_bound 10 DW_FORM_data1 } } array_ub_label: DW_TAG_array_type { - {DW_AT_ordering 1 data1} - {DW_AT_type :$integer_label} + DW_AT_ordering 1 data1 + DW_AT_type :$integer_label } { DW_TAG_subrange_type { - {DW_AT_upper_bound {} DW_FORM_block1} + DW_AT_upper_bound {} DW_FORM_block1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp index e92e582..7d55f73 100644 --- a/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp +++ b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp @@ -20,6 +20,7 @@ load_lib dwarf.exp # This test can only be run on targets which support DWARF-2 and use gas. require dwarf2_support +require !readnow standard_testfile main.c -debug.S @@ -32,40 +33,40 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { # The new indexer has special code to compute the full # name of an object that uses a specification that appears # later in the DWARF. DW_TAG_variable { - {DW_AT_specification %$spec} - {DW_AT_location { + DW_AT_specification %$spec + DW_AT_location { DW_OP_const1u 23 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } } } cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels myint myint: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name myint} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name myint } DW_TAG_namespace { - {DW_AT_name ns} + DW_AT_name ns } { spec: DW_TAG_variable { - {DW_AT_name v} - {DW_AT_type :$myint} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_name v + DW_AT_type :$myint + DW_AT_declaration 1 DW_FORM_flag_present } } } @@ -98,6 +99,11 @@ foreach_with_prefix worker_threads $worker_threads_list { gdb_load $binfile + set index [have_index $binfile] + if { ![string eq $index ""] } { + return + } + gdb_test "pipe maint print objfiles | grep ns::v" \ "$ws+qualified:$ws+ns::v" \ "v has parent ns" diff --git a/gdb/testsuite/gdb.dwarf2/forward-spec.exp b/gdb/testsuite/gdb.dwarf2/forward-spec.exp index 6c38be8..e534da2 100644 --- a/gdb/testsuite/gdb.dwarf2/forward-spec.exp +++ b/gdb/testsuite/gdb.dwarf2/forward-spec.exp @@ -32,9 +32,9 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels spec myint @@ -43,26 +43,26 @@ Dwarf::assemble $asm_file { # name of an object that uses a specification that appears # later in the DWARF. DW_TAG_variable { - {DW_AT_specification :$spec} - {DW_AT_location { + DW_AT_specification :$spec + DW_AT_location { DW_OP_const1u 23 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } myint: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name myint} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name myint } DW_TAG_namespace { - {DW_AT_name ns} + DW_AT_name ns } { spec: DW_TAG_variable { - {DW_AT_name v} - {DW_AT_type :$myint} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_name v + DW_AT_type :$myint + DW_AT_declaration 1 DW_FORM_flag_present } } } diff --git a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp index ef7cf92..ad19ce7 100644 --- a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp +++ b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp @@ -46,44 +46,44 @@ Dwarf::assemble $dwarf_asm { cu { label cu_label addr_size 4 } { DW_TAG_compile_unit { - {DW_AT_name $srcfile} - {DW_AT_stmt_list $stmt_list DW_FORM_sec_offset} - {DW_AT_language @DW_LANG_C99} - {DW_AT_low_pc __cu_low_pc DW_FORM_addr} - {DW_AT_high_pc __cu_high_pc DW_FORM_addr} + DW_AT_name $srcfile + DW_AT_stmt_list $stmt_list DW_FORM_sec_offset + DW_AT_language @DW_LANG_C99 + DW_AT_low_pc __cu_low_pc DW_FORM_addr + DW_AT_high_pc __cu_high_pc DW_FORM_addr } { DW_TAG_subprogram { - {DW_AT_name "_start"} - {DW_AT_low_pc __start_low_pc DW_FORM_addr} - {DW_AT_high_pc __start_high_pc DW_FORM_addr} + DW_AT_name "_start" + DW_AT_low_pc __start_low_pc DW_FORM_addr + DW_AT_high_pc __start_high_pc DW_FORM_addr } { DW_TAG_inlined_subroutine { - {DW_AT_abstract_origin :$foo_subprogram} - {DW_AT_low_pc __foo_low_pc DW_FORM_addr} - {DW_AT_high_pc __foo_high_pc DW_FORM_addr} - {DW_AT_call_file 1 DW_FORM_data1} - {DW_AT_call_line 13 DW_FORM_data1} + DW_AT_abstract_origin :$foo_subprogram + DW_AT_low_pc __foo_low_pc DW_FORM_addr + DW_AT_high_pc __foo_high_pc DW_FORM_addr + DW_AT_call_file 1 DW_FORM_data1 + DW_AT_call_line 13 DW_FORM_data1 } { DW_TAG_inlined_subroutine { - {DW_AT_abstract_origin :$bar_subprogram} - {DW_AT_low_pc __bar_low_pc DW_FORM_addr} - {DW_AT_high_pc __bar_high_pc DW_FORM_addr} - {DW_AT_call_file 1 DW_FORM_data1} - {DW_AT_call_line 7 DW_FORM_data1} + DW_AT_abstract_origin :$bar_subprogram + DW_AT_low_pc __bar_low_pc DW_FORM_addr + DW_AT_high_pc __bar_high_pc DW_FORM_addr + DW_AT_call_file 1 DW_FORM_data1 + DW_AT_call_line 7 DW_FORM_data1 } } } foo_subprogram: DW_TAG_subprogram { - {DW_AT_name "foo"} - {DW_AT_prototyped 1 DW_FORM_flag_present} - {DW_AT_inline 0x1 DW_FORM_data1} + DW_AT_name "foo" + DW_AT_prototyped 1 DW_FORM_flag_present + DW_AT_inline 0x1 DW_FORM_data1 } bar_subprogram: DW_TAG_subprogram { - {DW_AT_name "bar"} - {DW_AT_prototyped 1 DW_FORM_flag_present} - {DW_AT_inline 0x1 DW_FORM_data1} + DW_AT_name "bar" + DW_AT_prototyped 1 DW_FORM_flag_present + DW_AT_inline 0x1 DW_FORM_data1 } } } @@ -106,7 +106,7 @@ if { [build_executable ${testfile}.exp ${testfile} "$srcfile $dwarf_asm" \ return } -clean_restart $binfile +clean_restart $::testfile if { [gdb_starti_cmd] != 0 } { fail "failed to run to first instruction" diff --git a/gdb/testsuite/gdb.dwarf2/gdb-add-index-symlink.exp b/gdb/testsuite/gdb.dwarf2/gdb-add-index-symlink.exp index cd05925..9233637 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-add-index-symlink.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-add-index-symlink.exp @@ -56,7 +56,8 @@ if { [ensure_gdb_index $symlink] == -1 } { # Ok, we have a copy of $binfile with an index. # Restart gdb and verify the index was used. -clean_restart $symlink +clean_restart +gdb_load $symlink gdb_test "mt print objfiles ${testfile}" \ "(gdb_index|debug_names).*" \ "index used" diff --git a/gdb/testsuite/gdb.dwarf2/gdb-add-index.exp b/gdb/testsuite/gdb.dwarf2/gdb-add-index.exp index 3285d1c..0fbd3a2 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-add-index.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-add-index.exp @@ -33,7 +33,7 @@ if { [ensure_gdb_index $binfile] == -1 } { # Ok, we have a copy of $binfile with an index. # Restart gdb and verify the index was used. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test "mt print objfiles ${testfile}" \ "(gdb_index|debug_names).*" \ "index used" diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index-tilde.exp b/gdb/testsuite/gdb.dwarf2/gdb-index-tilde.exp index c0d5225..a8c5c39 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-index-tilde.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-index-tilde.exp @@ -47,7 +47,7 @@ if { [prepare_for_testing "failed to prepare" "${testfile}" ${srcfile}] } { } # Start GDB and load in the executable. -clean_restart ${binfile} +clean_restart ${::testfile} # If the executable was built with an index, or lacks the debug # information required to create an index, then we'll not be able to diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index-types-dwarf5.exp b/gdb/testsuite/gdb.dwarf2/gdb-index-types-dwarf5.exp index d6f5e48..a47d73a 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-index-types-dwarf5.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-index-types-dwarf5.exp @@ -13,6 +13,10 @@ # 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 test checks that .gdb_index is in use, which isn't the case +# with readnow. +require !readnow + standard_testfile set flags {} @@ -29,7 +33,7 @@ if { [ensure_gdb_index $binfile] != 1 } { return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} # Verify that .gdb_index section is not ignored. set index [have_index $binfile] diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index.exp b/gdb/testsuite/gdb.dwarf2/gdb-index.exp index ebeb62b..f7c3337 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-index.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-index.exp @@ -98,20 +98,24 @@ set test "check if index present" set filter "gdb_index|debug_names|Psymtabs|Cooked" set cmd "pipe mt print objfiles ${testfile} | grep -E \"$filter\"" set cmd_re [string_to_regexp $cmd] +set testfile_with_index bla gdb_test_multiple $cmd $test { -re ^$cmd_re { exp_continue } -re "gdb_index.*${gdb_prompt} $" { - set binfile_with_index $binfile + set testfile_with_index $testfile + set binfile_with_index [standard_output_file $testfile_with_index] set host_binfile_with_index [gdb_remote_download host $binfile] } -re "debug_names.*${gdb_prompt} $" { - set binfile_with_index $binfile + set testfile_with_index $testfile + set binfile_with_index [standard_output_file $testfile_with_index] set host_binfile_with_index [gdb_remote_download host $binfile] } -re "(Psymtabs|Cooked).*${gdb_prompt} $" { lassign [local_add_gdb_index $binfile] binfile_with_index host_binfile_with_index + set testfile_with_index [file tail $binfile_with_index] if { ${binfile_with_index} == "" } { return -1 } @@ -124,7 +128,7 @@ gdb_test_multiple $cmd $test { # Ok, we have a copy of $binfile with an index. # Restart gdb and verify the index was used. -clean_restart ${binfile_with_index} +clean_restart $testfile_with_index gdb_test "mt print objfiles ${testfile}" \ "(gdb_index|debug_names).*" \ "index used" diff --git a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp index c4496f1..be3a648 100644 --- a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp +++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp @@ -39,54 +39,54 @@ proc test_1 { name dwarf_version offset_size addr_size ref_addr_size two_cu } { is_64 $is_64 } { compile_unit { - { producer "GNU C 4.4.3" } - { language @DW_LANG_C89 } - { name 1.c } + DW_AT_producer "GNU C 4.4.3" + DW_AT_language @DW_LANG_C89 + DW_AT_name 1.c } { declare_labels struct_label variable_label int_label pointer_label int_label: base_type { - { byte_size 4 DW_FORM_sdata } - { DW_AT_encoding @DW_ATE_signed } - { name int } + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } struct_label: structure_type { - { name s } - { byte_size 4 sdata } + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - { name f } - { type :$int_label } - { data_member_location 0 data1 } + DW_AT_name f + DW_AT_type :$int_label + DW_AT_data_member_location 0 data1 } } pointer_label: pointer_type { - { byte_size $Dwarf::_cu_addr_size sdata } - { type :$struct_label } + DW_AT_byte_size $Dwarf::_cu_addr_size sdata + DW_AT_type :$struct_label } variable_label: DW_TAG_variable { - { name v } - { location { + DW_AT_name v + DW_AT_location { DW_OP_implicit_value 0x1 0x1 0x1 0x1 - } SPECIAL_expr} - { type :$struct_label "DW_FORM_ref$ref_addr_size" } + } SPECIAL_expr + DW_AT_type :$struct_label "DW_FORM_ref$ref_addr_size" } if { !$two_cu } { subprogram { - {MACRO_AT_func {main}} - { type :$int_label } - { external 1 flag } + MACRO_AT_func {main} + DW_AT_type :$int_label + DW_AT_external 1 flag } { DW_TAG_variable { - { name p } - { location { + DW_AT_name p + DW_AT_location [subst { GNU_implicit_pointer $variable_label 0 - } SPECIAL_expr } - { type :$pointer_label "DW_FORM_ref$ref_addr_size" } + }] SPECIAL_expr + DW_AT_type :$pointer_label "DW_FORM_ref$ref_addr_size" } } } @@ -100,21 +100,21 @@ proc test_1 { name dwarf_version offset_size addr_size ref_addr_size two_cu } { is_64 $is_64 } { compile_unit { - { producer "GNU C 4.4.3" } - { language @DW_LANG_C89 } - { name 1.c } + DW_AT_producer "GNU C 4.4.3" + DW_AT_language @DW_LANG_C89 + DW_AT_name 1.c } { subprogram { - { MACRO_AT_func {main} } - { type %$int_label } - { external 1 flag } + MACRO_AT_func {main} + DW_AT_type %$int_label + DW_AT_external 1 flag } { DW_TAG_variable { - { name p } - { location { + DW_AT_name p + DW_AT_location [subst { GNU_implicit_pointer $variable_label 0 - } SPECIAL_expr } - { type %$pointer_label } + }] SPECIAL_expr + DW_AT_type %$pointer_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp index 79fcf61..7feb983 100644 --- a/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp +++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp @@ -25,51 +25,51 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu { version 3 addr_size 4 } { compile_unit { - {producer "GNU C 4.4.3"} - {language @DW_LANG_C89} - {name 1.c} + DW_AT_producer "GNU C 4.4.3" + DW_AT_language @DW_LANG_C89 + DW_AT_name 1.c } { declare_labels int_label struct_label pointer_label variable_label int_label: base_type { - {byte_size 4 sdata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } struct_label: structure_type { - {name s} - {byte_size 4 sdata} + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - {name f} - {type :$int_label} - {data_member_location 0 data1} + DW_AT_name f + DW_AT_type :$int_label + DW_AT_data_member_location 0 data1 } } subprogram { - {MACRO_AT_func { main }} - {type :$int_label} - {external 1 flag} + MACRO_AT_func { main } + DW_AT_type :$int_label + DW_AT_external 1 flag } { pointer_label: pointer_type { - {byte_size 4 sdata} - {type :$struct_label} + DW_AT_byte_size 4 sdata + DW_AT_type :$struct_label } variable_label: DW_TAG_variable { - {name v} - {location {} DW_FORM_block1} - {type :$struct_label} + DW_AT_name v + DW_AT_location {} DW_FORM_block1 + DW_AT_type :$struct_label } DW_TAG_variable { - {name p} - {location { + DW_AT_name p + DW_AT_location [subst { GNU_implicit_pointer $variable_label 0 - } SPECIAL_expr} - {type :$pointer_label} + }] SPECIAL_expr + DW_AT_type :$pointer_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/implptrconst.exp b/gdb/testsuite/gdb.dwarf2/implptrconst.exp index f3d47a2..8e735ca 100644 --- a/gdb/testsuite/gdb.dwarf2/implptrconst.exp +++ b/gdb/testsuite/gdb.dwarf2/implptrconst.exp @@ -33,51 +33,51 @@ Dwarf::assemble $asm_file { declare_labels var_label ptr_label byte_label: base_type { - {name byte} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name byte + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } size_type_label: base_type { - {name sizetype} - {encoding @DW_ATE_unsigned} - {byte_size 4 DW_FORM_sdata} + DW_AT_name sizetype + DW_AT_encoding @DW_ATE_unsigned + DW_AT_byte_size 4 DW_FORM_sdata } array_label: array_type { - {type :$byte_label} + DW_AT_type :$byte_label } { subrange_type { - {type :$size_type_label} - {upper_bound 7 DW_FORM_data1} + DW_AT_type :$size_type_label + DW_AT_upper_bound 7 DW_FORM_data1 } } var_label: DW_TAG_variable { - {name b} - {type :$array_label} - {const_value rstuvwxy DW_FORM_block1} + DW_AT_name b + DW_AT_type :$array_label + DW_AT_const_value rstuvwxy DW_FORM_block1 } ptr_label: pointer_type { - {byte_size 4 DW_FORM_sdata} - {type :$byte_label} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_type :$byte_label } DW_TAG_variable { - {name c} - {type :$ptr_label} - {location { + DW_AT_name c + DW_AT_type :$ptr_label + DW_AT_location [subst { GNU_implicit_pointer $var_label 0 - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {name d} - {type :$ptr_label} - {location { + DW_AT_name d + DW_AT_type :$ptr_label + DW_AT_location [subst { GNU_implicit_pointer $var_label 2 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/implptrpiece.exp b/gdb/testsuite/gdb.dwarf2/implptrpiece.exp index 9654483..58c5e66 100644 --- a/gdb/testsuite/gdb.dwarf2/implptrpiece.exp +++ b/gdb/testsuite/gdb.dwarf2/implptrpiece.exp @@ -36,48 +36,48 @@ Dwarf::assemble $asm_file { declare_labels var_label struct_label: structure_type { - {name S} - {byte_size 4 DW_FORM_sdata} + DW_AT_name S + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name a} - {type :$short_type_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name a + DW_AT_type :$short_type_label + DW_AT_data_member_location 0 DW_FORM_sdata } member { - {name b} - {type :$char_type_label} - {data_member_location 2 DW_FORM_sdata} + DW_AT_name b + DW_AT_type :$char_type_label + DW_AT_data_member_location 2 DW_FORM_sdata } member { - {name c} - {type :$char_type_label} - {data_member_location 3 DW_FORM_sdata} + DW_AT_name c + DW_AT_type :$char_type_label + DW_AT_data_member_location 3 DW_FORM_sdata } } short_type_label: base_type { - {name "short int"} - {encoding @DW_ATE_signed} - {byte_size 2 DW_FORM_sdata} + DW_AT_name "short int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 2 DW_FORM_sdata } char_type_label: base_type { - {name "signed char"} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name "signed char" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } # See comment above to understand the pointer size. ptr_label: pointer_type { - {byte_size 2 DW_FORM_sdata} - {type :$char_type_label} + DW_AT_byte_size 2 DW_FORM_sdata + DW_AT_type :$char_type_label } var_label: DW_TAG_variable { - {name s} - {type :$struct_label} - {location { + DW_AT_name s + DW_AT_type :$struct_label + DW_AT_location { const2u 0x5678 stack_value piece 2 @@ -87,15 +87,15 @@ Dwarf::assemble $asm_file { const1u 3 stack_value piece 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_variable { - {name p} - {type :$ptr_label} - {location { + DW_AT_name p + DW_AT_type :$ptr_label + DW_AT_location [subst { GNU_implicit_pointer $var_label 2 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/implref-array.exp b/gdb/testsuite/gdb.dwarf2/implref-array.exp index 4f7bb4b..1236537 100644 --- a/gdb/testsuite/gdb.dwarf2/implref-array.exp +++ b/gdb/testsuite/gdb.dwarf2/implref-array.exp @@ -51,7 +51,7 @@ Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int_label sizetype_label array_label variable_label ref_label set int_size [get_sizeof "int" -1] @@ -61,48 +61,52 @@ Dwarf::assemble ${asm_file} { set addr_size [get_sizeof "void *" -1] int_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } sizetype_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name "sizetype"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "sizetype" } array_label: DW_TAG_array_type { - {DW_AT_type :${int_label}} + DW_AT_type :${int_label} } { DW_TAG_subrange_type { - {DW_AT_type :${sizetype_label}} - {DW_AT_lower_bound 0 DW_FORM_udata} - {DW_AT_upper_bound ${upper_bound} DW_FORM_udata} + DW_AT_type :${sizetype_label} + DW_AT_lower_bound 0 DW_FORM_udata + DW_AT_upper_bound ${upper_bound} DW_FORM_udata } } ref_label: DW_TAG_reference_type { - {DW_AT_byte_size ${addr_size} DW_FORM_udata} - {DW_AT_type :${array_label}} + DW_AT_byte_size ${addr_size} DW_FORM_udata + DW_AT_type :${array_label} } variable_label: DW_TAG_variable { - {DW_AT_name "array"} - {DW_AT_type :${array_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "array"]} SPECIAL_expr} + DW_AT_name "array" + DW_AT_type :${array_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "array"] + }] SPECIAL_expr } DW_TAG_subprogram { - {MACRO_AT_func { "main" }} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } { DW_TAG_variable { - {DW_AT_name "ref"} - {DW_AT_type :${ref_label}} - {DW_AT_location {DW_OP_GNU_implicit_pointer ${variable_label} 0} SPECIAL_expr} + DW_AT_name "ref" + DW_AT_type :${ref_label} + DW_AT_location [subst { + DW_OP_GNU_implicit_pointer ${variable_label} 0 + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/implref-const.exp b/gdb/testsuite/gdb.dwarf2/implref-const.exp index 57ccfcd..ec19eed 100644 --- a/gdb/testsuite/gdb.dwarf2/implref-const.exp +++ b/gdb/testsuite/gdb.dwarf2/implref-const.exp @@ -45,7 +45,7 @@ if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int_label const_label variable_label ref_label set int_size [get_sizeof "int" -1] @@ -55,35 +55,37 @@ Dwarf::assemble ${asm_file} { set var_value 42 int_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } ref_label: DW_TAG_reference_type { - {DW_AT_byte_size ${addr_size} DW_FORM_udata} - {DW_AT_type :${int_label}} + DW_AT_byte_size ${addr_size} DW_FORM_udata + DW_AT_type :${int_label} } const_label: DW_TAG_const_type { - {DW_AT_type :${ref_label}} + DW_AT_type :${ref_label} } DW_TAG_subprogram { - {MACRO_AT_func { "main" }} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } { variable_label: DW_TAG_variable { - {DW_AT_name "var"} - {DW_AT_type :${int_label}} - {DW_AT_const_value ${var_value} DW_FORM_udata} + DW_AT_name "var" + DW_AT_type :${int_label} + DW_AT_const_value ${var_value} DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "ref"} - {DW_AT_type :${const_label}} - {DW_AT_location {DW_OP_GNU_implicit_pointer ${variable_label} 0} SPECIAL_expr} + DW_AT_name "ref" + DW_AT_type :${const_label} + DW_AT_location [subst { + DW_OP_GNU_implicit_pointer ${variable_label} 0 + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/implref-global.exp b/gdb/testsuite/gdb.dwarf2/implref-global.exp index 5d9e679..cb885ef 100644 --- a/gdb/testsuite/gdb.dwarf2/implref-global.exp +++ b/gdb/testsuite/gdb.dwarf2/implref-global.exp @@ -47,7 +47,7 @@ if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int_label variable_label ref_label set int_size [get_sizeof "int" -1] @@ -56,32 +56,36 @@ Dwarf::assemble ${asm_file} { set addr_size [get_sizeof "void *" -1] int_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } ref_label: DW_TAG_reference_type { - {DW_AT_byte_size ${addr_size} DW_FORM_udata} - {DW_AT_type :${int_label}} + DW_AT_byte_size ${addr_size} DW_FORM_udata + DW_AT_type :${int_label} } variable_label: DW_TAG_variable { - {DW_AT_name "global_var"} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "global_var"]} SPECIAL_expr} + DW_AT_name "global_var" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "global_var"] + }] SPECIAL_expr } DW_TAG_subprogram { - {MACRO_AT_func { "main" }} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } { DW_TAG_variable { - {DW_AT_name "ref"} - {DW_AT_type :${ref_label}} - {DW_AT_location {DW_OP_GNU_implicit_pointer ${variable_label} 0} SPECIAL_expr} + DW_AT_name "ref" + DW_AT_type :${ref_label} + DW_AT_location [subst { + DW_OP_GNU_implicit_pointer ${variable_label} 0 + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/implref-struct.exp b/gdb/testsuite/gdb.dwarf2/implref-struct.exp index 1add485..9dc3b1b 100644 --- a/gdb/testsuite/gdb.dwarf2/implref-struct.exp +++ b/gdb/testsuite/gdb.dwarf2/implref-struct.exp @@ -47,7 +47,7 @@ if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug c++}] Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int_label struct_label variable_label ref_label set int_size [get_sizeof "int" -1] @@ -61,62 +61,68 @@ Dwarf::assemble ${asm_file} { set c_offset 8 int_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } struct_label: DW_TAG_structure_type { - {DW_AT_name "S"} - {DW_AT_byte_size ${S_size} DW_FORM_udata} + DW_AT_name "S" + DW_AT_byte_size ${S_size} DW_FORM_udata } { DW_TAG_member { - {DW_AT_name "a"} - {DW_AT_type :${int_label}} - {DW_AT_data_member_location 0 DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :${int_label} + DW_AT_data_member_location 0 DW_FORM_udata } DW_TAG_member { - {DW_AT_name "b"} - {DW_AT_type :${int_label}} - {DW_AT_data_member_location ${b_offset} DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :${int_label} + DW_AT_data_member_location ${b_offset} DW_FORM_udata } DW_TAG_member { - {DW_AT_name "c"} - {DW_AT_type :${int_label}} - {DW_AT_data_member_location ${c_offset} DW_FORM_udata} + DW_AT_name "c" + DW_AT_type :${int_label} + DW_AT_data_member_location ${c_offset} DW_FORM_udata } } ref_label: DW_TAG_reference_type { - {DW_AT_byte_size ${addr_size} DW_FORM_udata} - {DW_AT_type :${struct_label}} + DW_AT_byte_size ${addr_size} DW_FORM_udata + DW_AT_type :${struct_label} } variable_label: DW_TAG_variable { - {DW_AT_name "s1"} - {DW_AT_type :${struct_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "s1"]} SPECIAL_expr} + DW_AT_name "s1" + DW_AT_type :${struct_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "s1"] + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "s2"} - {DW_AT_type :${struct_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "s2"]} SPECIAL_expr} + DW_AT_name "s2" + DW_AT_type :${struct_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "s2"] + }] SPECIAL_expr } DW_TAG_subprogram { - {MACRO_AT_func { "main" }} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } { DW_TAG_variable { - {DW_AT_name "ref"} - {DW_AT_type :${ref_label}} - {DW_AT_location {DW_OP_GNU_implicit_pointer ${variable_label} 0} SPECIAL_expr} + DW_AT_name "ref" + DW_AT_type :${ref_label} + DW_AT_location [subst { + DW_OP_GNU_implicit_pointer ${variable_label} 0 + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-abstract-const-value.exp b/gdb/testsuite/gdb.dwarf2/imported-unit-abstract-const-value.exp index 2517a2a..7141d6b 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit-abstract-const-value.exp +++ b/gdb/testsuite/gdb.dwarf2/imported-unit-abstract-const-value.exp @@ -40,40 +40,40 @@ Dwarf::assemble $asm_file { cu {} { cu_label: partial_unit { - {language @DW_LANG_C} - {name "imported_unit.c"} + DW_AT_language @DW_LANG_C + DW_AT_name "imported_unit.c" } { int_label: base_type { - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } aaa_label: DW_TAG_variable { - {name aaa} - {type :$int_label} - {const_value 1 DW_FORM_sdata} + DW_AT_name aaa + DW_AT_type :$int_label + DW_AT_const_value 1 DW_FORM_sdata } main_label: subprogram { - {name main} - {type :$int_label} - {external 1 flag} + DW_AT_name main + DW_AT_type :$int_label + DW_AT_external 1 flag } } } cu {} { compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { DW_TAG_variable { - {abstract_origin %$aaa_label} + DW_AT_abstract_origin %$aaa_label } subprogram { - {abstract_origin %$main_label} - {MACRO_AT_range {main}} + DW_AT_abstract_origin %$main_label + MACRO_AT_range {main} } } } diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl index 65c3466..de1195a 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl +++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp.tcl @@ -38,34 +38,34 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @$lang} - {name "<artificial>"} + DW_AT_language @$lang + DW_AT_name "<artificial>" } { imported_unit { - {import %$cu_label} + DW_AT_import %$cu_label } } } cu {} { cu_label: compile_unit { - {producer "gcc"} - {language @$lang} - {name ${srcfile}} - {comp_dir "/tmp"} - {low_pc 0 addr} - {stmt_list ${lines_label} DW_FORM_sec_offset} + DW_AT_producer "gcc" + DW_AT_language @$lang + DW_AT_name ${srcfile} + DW_AT_comp_dir "/tmp" + DW_AT_low_pc 0 addr + DW_AT_stmt_list ${lines_label} DW_FORM_sec_offset } { callee_subprog_label: subprogram { - {external 1 flag} - {name callee} - {inline 3 data1} + DW_AT_external 1 flag + DW_AT_name callee + DW_AT_inline 3 data1 } subprogram { - {external 1 flag} - {name func} - {low_pc $func_start addr} - {high_pc "$func_start + $func_len" addr} + DW_AT_external 1 flag + DW_AT_name func + DW_AT_low_pc $func_start addr + DW_AT_high_pc "$func_start + $func_len" addr } { } } diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-c.exp b/gdb/testsuite/gdb.dwarf2/imported-unit-c.exp index 521ccc3..4ccda52 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit-c.exp +++ b/gdb/testsuite/gdb.dwarf2/imported-unit-c.exp @@ -22,52 +22,52 @@ Dwarf::assemble $asm_file { # imported CU 1: inty unsigned cu {} { cu_label: compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { int_label: base_type { - {byte_size $int_size sdata} - {encoding @DW_ATE_unsigned} - {name {unsigned int}} + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name {unsigned int} + } + DW_TAG_typedef { + DW_AT_name inty + DW_AT_type :$int_label } - DW_TAG_typedef { - {DW_AT_name inty} - {DW_AT_type :$int_label} - } } } # imported CU 2: inty signed cu {} { cu2_label: compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { int2_label: base_type { - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} - {name {int}} + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name {int} + } + DW_TAG_typedef { + DW_AT_name inty + DW_AT_type :$int2_label } - DW_TAG_typedef { - {DW_AT_name inty} - {DW_AT_type :$int2_label} - } } } # main CU cu {} { compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { imported_unit { - {import %$cu2_label} + DW_AT_import %$cu2_label } subprogram { - {MACRO_AT_func {main}} - {external 1 flag} + MACRO_AT_func {main} + DW_AT_external 1 flag } } } @@ -75,16 +75,16 @@ Dwarf::assemble $asm_file { # foo CU cu {} { compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { imported_unit { - {import %$cu_label} + DW_AT_import %$cu_label } subprogram { - {MACRO_AT_func {foo}} - {external 1 flag} + MACRO_AT_func {foo} + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-runto-main.exp b/gdb/testsuite/gdb.dwarf2/imported-unit-runto-main.exp index c4bacb1..12dc69e 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit-runto-main.exp +++ b/gdb/testsuite/gdb.dwarf2/imported-unit-runto-main.exp @@ -37,31 +37,31 @@ Dwarf::assemble $asm_file { cu {} { cu_label: partial_unit { - {language @DW_LANG_C} - {name "imported_unit.c"} + DW_AT_language @DW_LANG_C + DW_AT_name "imported_unit.c" } { int_label: base_type { - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } main_label: subprogram { - {name main} - {type :$int_label} - {external 1 flag} + DW_AT_name main + DW_AT_type :$int_label + DW_AT_external 1 flag } } } cu {} { compile_unit { - {language @DW_LANG_C} - {name "<artificial>"} + DW_AT_language @DW_LANG_C + DW_AT_name "<artificial>" } { subprogram { - {abstract_origin %$main_label} - {MACRO_AT_range {main}} + DW_AT_abstract_origin %$main_label + MACRO_AT_range {main} } } } @@ -77,6 +77,6 @@ if { [ensure_gdb_index $binfile] == -1 } { return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto main diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit.exp b/gdb/testsuite/gdb.dwarf2/imported-unit.exp index e5df67e..2c17f2d 100644 --- a/gdb/testsuite/gdb.dwarf2/imported-unit.exp +++ b/gdb/testsuite/gdb.dwarf2/imported-unit.exp @@ -52,27 +52,27 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C_plus_plus} - {name "<artificial>"} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "<artificial>" } { imported_unit { - {import %$cu_label} + DW_AT_import %$cu_label } subprogram { - {abstract_origin %$main_label} - {MACRO_AT_range {main}} + DW_AT_abstract_origin %$main_label + MACRO_AT_range {main} } { subprogram { - {abstract_origin %$doit_label} - {MACRO_AT_range {doit}} + DW_AT_abstract_origin %$doit_label + MACRO_AT_range {doit} } { formal_parameter { - {abstract_origin %$doit_self_label} + DW_AT_abstract_origin %$doit_self_label } } DW_TAG_variable { - {abstract_origin %$foo_label} - {location 4 data1} + DW_AT_abstract_origin %$foo_label + DW_AT_location 4 data1 } } } @@ -80,43 +80,43 @@ Dwarf::assemble $asm_file { cu {} { cu_label: compile_unit { - {language @DW_LANG_C_plus_plus} - {name "imported_unit.c"} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "imported_unit.c" } { int_label: base_type { - {byte_size $int_size sdata} - {encoding @DW_ATE_signed} - {name int} + DW_AT_byte_size $int_size sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } main_label: subprogram { - {name main} - {type :$int_label} - {external 1 flag} + DW_AT_name main + DW_AT_type :$int_label + DW_AT_external 1 flag } { Foo_label: class_type { - {name Foo} - {byte_size 1 sdata} + DW_AT_name Foo + DW_AT_byte_size 1 sdata } { doit_label: subprogram { - {name doit} - {type :$int_label} - {accessibility 1 DW_FORM_data1} + DW_AT_name doit + DW_AT_type :$int_label + DW_AT_accessibility 1 DW_FORM_data1 } { doit_self_label: formal_parameter { - {name this} - {artificial 1 DW_FORM_flag_present} - {type :$Foo_pointer_type} + DW_AT_name this + DW_AT_artificial 1 DW_FORM_flag_present + DW_AT_type :$Foo_pointer_type } } Foo_pointer_type: pointer_type { - {byte_size $addr_size sdata} - {type :$Foo_label} + DW_AT_byte_size $addr_size sdata + DW_AT_type :$Foo_label } } foo_label: DW_TAG_variable { - {name foo} - {type :$Foo_label} + DW_AT_name foo + DW_AT_type :$Foo_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/info-locals-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/info-locals-optimized-out.exp index 76e20b6..59c9669 100644 --- a/gdb/testsuite/gdb.dwarf2/info-locals-optimized-out.exp +++ b/gdb/testsuite/gdb.dwarf2/info-locals-optimized-out.exp @@ -32,31 +32,31 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels int_type_label # int int_type_label: base_type { - {name "int"} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } DW_TAG_subprogram { - {MACRO_AT_func { main }} - {DW_AT_external 1 flag} + MACRO_AT_func { main } + DW_AT_external 1 flag } { # A variable completely optimized out. DW_TAG_variable { - {name "opt_out"} - {type :$int_type_label} + DW_AT_name "opt_out" + DW_AT_type :$int_type_label } DW_TAG_variable { - {name const_bytes} - {type :$int_type_label} - {const_value "\x01\x01\x01\x01" DW_FORM_block1} + DW_AT_name const_bytes + DW_AT_type :$int_type_label + DW_AT_const_value "\x01\x01\x01\x01" DW_FORM_block1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/inlined_subroutine-inheritance.exp b/gdb/testsuite/gdb.dwarf2/inlined_subroutine-inheritance.exp index b26650c..7236662 100644 --- a/gdb/testsuite/gdb.dwarf2/inlined_subroutine-inheritance.exp +++ b/gdb/testsuite/gdb.dwarf2/inlined_subroutine-inheritance.exp @@ -38,21 +38,21 @@ Dwarf::assemble $asm_file { cu {} { Db: compile_unit { - {language @DW_LANG_C99} - {name "<artificial>"} + DW_AT_language @DW_LANG_C99 + DW_AT_name "<artificial>" } { D72f8: subprogram { - {abstract_origin %$D272519} - {low_pc 0xb9e20 addr} - {high_pc 0x1f5 data4} + DW_AT_abstract_origin %$D272519 + DW_AT_low_pc 0xb9e20 addr + DW_AT_high_pc 0x1f5 data4 } { D736e: inlined_subroutine { - {abstract_origin %$D26b227} - {low_pc 0xb9efc addr} - {high_pc 0xc data4} + DW_AT_abstract_origin %$D26b227 + DW_AT_low_pc 0xb9efc addr + DW_AT_high_pc 0xc data4 } { formal_parameter { - {abstract_origin %$D274c42} + DW_AT_abstract_origin %$D274c42 } } } @@ -61,53 +61,53 @@ Dwarf::assemble $asm_file { cu {} { D266465: compile_unit { - {language @DW_LANG_C99} + DW_AT_language @DW_LANG_C99 } { D266477: typedef { - {name "size_t"} - {type :$D266483} + DW_AT_name "size_t" + DW_AT_type :$D266483 } D266483: base_type { - {byte_size 8 sdata} - {encoding @DW_ATE_unsigned} + DW_AT_byte_size 8 sdata + DW_AT_encoding @DW_ATE_unsigned } D266496: pointer_type { - {byte_size 8 sdata} + DW_AT_byte_size 8 sdata } D266498: restrict_type { - {type :$D266496} + DW_AT_type :$D266496 } D266ad3: pointer_type { - {byte_size 8 sdata} - {type :$D266ade} + DW_AT_byte_size 8 sdata + DW_AT_type :$D266ade } D266ad9: restrict_type { - {type :$D266ad3} + DW_AT_type :$D266ad3 } D266ade: const_type {} D26b227: subprogram { - {external 1 flag} - {name "memcpy"} - {type :$D266496} + DW_AT_external 1 flag + DW_AT_name "memcpy" + DW_AT_type :$D266496 } { D26b237: formal_parameter { - {name "__dest"} - {type :$D266498} + DW_AT_name "__dest" + DW_AT_type :$D266498 } formal_parameter { - {name "__src"} - {type :$D266ad9} + DW_AT_name "__src" + DW_AT_type :$D266ad9 } formal_parameter { - {name "__len"} - {type :$D266477} + DW_AT_name "__len" + DW_AT_type :$D266477 } } } @@ -115,85 +115,85 @@ Dwarf::assemble $asm_file { cu {} { D26d8b1: compile_unit { - {language @DW_LANG_C99} + DW_AT_language @DW_LANG_C99 } { D26d8c3: typedef { - {name "size_t"} - {type :$D26d8cf} + DW_AT_name "size_t" + DW_AT_type :$D26d8cf } D26d8cf: base_type { - {byte_size 8 sdata} - {encoding @DW_ATE_unsigned} - {name "long unsigned int"} + DW_AT_byte_size 8 sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "long unsigned int" } D26d944: pointer_type { - {byte_size 8 sdata} + DW_AT_byte_size 8 sdata } D26d946: restrict_type { - {type :$D26d944} + DW_AT_type :$D26d944 } D26e103: structure_type { - {name "__object"} - {byte_size 12 sdata} + DW_AT_name "__object" + DW_AT_byte_size 12 sdata } { member { - {name "__ob_next"} - {type :$D26e145} - {data_member_location 0 sdata} + DW_AT_name "__ob_next" + DW_AT_type :$D26e145 + DW_AT_data_member_location 0 sdata } } D26e145: pointer_type { - {byte_size 8 sdata} - {type :$D26e103} + DW_AT_byte_size 8 sdata + DW_AT_type :$D26e103 } D26e415: typedef { - {name "PyObject"} - {type :$D26e103} + DW_AT_name "PyObject" + DW_AT_type :$D26e103 } D26e48c: pointer_type { - {byte_size 8 sdata} - {type :$D26e415} + DW_AT_byte_size 8 sdata + DW_AT_type :$D26e415 } D26df00: pointer_type { - {byte_size 8 sdata} - {type :$D26df0b} + DW_AT_byte_size 8 sdata + DW_AT_type :$D26df0b } D26df06: restrict_type { - {type :$D26df00} + DW_AT_type :$D26df00 } D26df0b: const_type {} D272519: subprogram { - {name "bytes_repeat"} - {type :$D26e48c} + DW_AT_name "bytes_repeat" + DW_AT_type :$D26e48c } D274c1a: subprogram { - {external 1 flag} - {name "memcpy"} - {type :$D26d944} + DW_AT_external 1 flag + DW_AT_name "memcpy" + DW_AT_type :$D26d944 } { formal_parameter { - {name "__dest"} - {type :$D26d946} + DW_AT_name "__dest" + DW_AT_type :$D26d946 } formal_parameter { - {name "__src"} - {type :$D26df06} + DW_AT_name "__src" + DW_AT_type :$D26df06 } D274c42: formal_parameter { - {name "__len"} - {type :$D26d8c3} + DW_AT_name "__len" + DW_AT_type :$D26d8c3 } } } diff --git a/gdb/testsuite/gdb.dwarf2/intbits.c b/gdb/testsuite/gdb.dwarf2/intbits.c index 82e6ae8..909d283 100644 --- a/gdb/testsuite/gdb.dwarf2/intbits.c +++ b/gdb/testsuite/gdb.dwarf2/intbits.c @@ -41,6 +41,9 @@ unsigned char be30_1_off[4] = { 0x80, 0, 0, 2 }; here, to catch any situation where gdb tries to use the memory. */ unsigned char u32_0[4] = { 0xff, 0xff, 0xff, 0xff }; +/* An 8 bit slot holding a 3 bit value. */ +unsigned char just_bit_0 = 5; + int main (void) { diff --git a/gdb/testsuite/gdb.dwarf2/intbits.exp b/gdb/testsuite/gdb.dwarf2/intbits.exp index 7b50e15..ec77c2d 100644 --- a/gdb/testsuite/gdb.dwarf2/intbits.exp +++ b/gdb/testsuite/gdb.dwarf2/intbits.exp @@ -33,139 +33,162 @@ if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels i7_type u1_type u17_type u31_type \ - u31_1_type u32_0_type u0_0_type be30_1_type + u31_1_type u32_0_type u0_0_type be30_1_type just_bit_type i7_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "i7"} - {DW_AT_byte_size 2 DW_FORM_udata} - {DW_AT_bit_size 7 DW_FORM_implicit_const} + DW_AT_encoding @DW_ATE_signed + DW_AT_endianity @DW_END_little + DW_AT_name "i7" + DW_AT_byte_size 2 DW_FORM_udata + DW_AT_bit_size 7 DW_FORM_implicit_const } DW_TAG_variable { - {DW_AT_name "v_i16_m1"} - {DW_AT_type :${i7_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "i16_m1"]} - SPECIAL_expr} + DW_AT_name "v_i16_m1" + DW_AT_type :${i7_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "i16_m1"] + }] SPECIAL_expr } u1_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_boolean} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u1"} - {DW_AT_byte_size 2 DW_FORM_udata} - {DW_AT_bit_size 1 DW_FORM_udata} - {DW_AT_data_bit_offset 2 DW_FORM_udata} + DW_AT_encoding @DW_ATE_boolean + DW_AT_endianity @DW_END_little + DW_AT_name "u1" + DW_AT_byte_size 2 DW_FORM_udata + DW_AT_bit_size 1 DW_FORM_udata + DW_AT_data_bit_offset 2 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u16_1"} - {DW_AT_type :${u1_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u16_1"]} - SPECIAL_expr} + DW_AT_name "v_u16_1" + DW_AT_type :${u1_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u16_1"] + }] SPECIAL_expr } u17_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u17"} - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_bit_size 17 DW_FORM_udata} + DW_AT_encoding @DW_ATE_signed + DW_AT_endianity @DW_END_little + DW_AT_name "u17" + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_bit_size 17 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u32_m2"} - {DW_AT_type :${u17_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_m2"]} - SPECIAL_expr} + DW_AT_name "v_u32_m2" + DW_AT_type :${u17_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u32_m2"] + }] SPECIAL_expr } u31_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u31"} - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_bit_size 31 DW_FORM_udata} + DW_AT_encoding @DW_ATE_unsigned + DW_AT_endianity @DW_END_little + DW_AT_name "u31" + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_bit_size 31 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u32_1"} - {DW_AT_type :${u31_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_1"]} - SPECIAL_expr} + DW_AT_name "v_u32_1" + DW_AT_type :${u31_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u32_1"] + }] SPECIAL_expr } u31_1_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u31_1"} - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_bit_size 31 DW_FORM_udata} - {DW_AT_data_bit_offset 1 DW_FORM_udata} + DW_AT_encoding @DW_ATE_unsigned + DW_AT_endianity @DW_END_little + DW_AT_name "u31_1" + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_bit_size 31 DW_FORM_udata + DW_AT_data_bit_offset 1 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u32_1_off"} - {DW_AT_type :${u31_1_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_1_off"]} - SPECIAL_expr} + DW_AT_name "v_u32_1_off" + DW_AT_type :${u31_1_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u32_1_off"] + }] SPECIAL_expr } be30_1_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_endianity @DW_END_big} - {DW_AT_name "be30_1"} - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_bit_size 30 DW_FORM_udata} - {DW_AT_data_bit_offset 1 DW_FORM_udata} + DW_AT_encoding @DW_ATE_unsigned + DW_AT_endianity @DW_END_big + DW_AT_name "be30_1" + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_bit_size 30 DW_FORM_udata + DW_AT_data_bit_offset 1 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_be30_1_off"} - {DW_AT_type :${be30_1_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "be30_1_off"]} - SPECIAL_expr} + DW_AT_name "v_be30_1_off" + DW_AT_type :${be30_1_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "be30_1_off"] + }] SPECIAL_expr } u32_0_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u32_0"} - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_bit_size 0 DW_FORM_udata} + DW_AT_encoding @DW_ATE_unsigned + DW_AT_endianity @DW_END_little + DW_AT_name "u32_0" + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_bit_size 0 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u32_0"} - {DW_AT_type :${u32_0_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_0"]} - SPECIAL_expr} + DW_AT_name "v_u32_0" + DW_AT_type :${u32_0_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u32_0"] + }] SPECIAL_expr } u0_0_type: DW_TAG_base_type { - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_endianity @DW_END_little} - {DW_AT_name "u0_0"} - {DW_AT_byte_size 0 DW_FORM_udata} + DW_AT_encoding @DW_ATE_unsigned + DW_AT_endianity @DW_END_little + DW_AT_name "u0_0" + DW_AT_byte_size 0 DW_FORM_udata } DW_TAG_variable { - {DW_AT_name "v_u0_0"} - {DW_AT_type :${u0_0_type}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_0"]} - SPECIAL_expr} + DW_AT_name "v_u0_0" + DW_AT_type :${u0_0_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "u32_0"] + }] SPECIAL_expr + } + + just_bit_type: DW_TAG_base_type { + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "just_bit_type" + DW_AT_bit_size 3 DW_FORM_udata + } + + DW_TAG_variable { + DW_AT_name "v_just_bit" + DW_AT_type :${just_bit_type} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "just_bit_0"] + }] SPECIAL_expr } } } @@ -197,3 +220,6 @@ gdb_test "x/4xb &v_u32_1_off" ":\t0x0e\t0x00\t0x00\t0x00" gdb_test "print v_be30_1_off" "= 1" gdb_test "print v_be30_1_off = 7" " = 7" gdb_test "x/4xb &v_be30_1_off" ":\t0x00\t0x00\t0x00\t0x0e" + +gdb_test "print/x v_just_bit" " = 0x5" +gdb_test "print/x (just_bit_type) 5" " = 0x5" diff --git a/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp index 6e10b6c..fb4bf3a 100644 --- a/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/loc-sec-offset.exp @@ -53,27 +53,27 @@ foreach_with_prefix is_64 {false true} { DW_TAG_compile_unit { } { int_type1: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "foo"} - {DW_AT_location $foo_location_list DW_FORM_sec_offset} - {DW_AT_type :$int_type1} + DW_AT_name "foo" + DW_AT_location $foo_location_list DW_FORM_sec_offset + DW_AT_type :$int_type1 } DW_TAG_subprogram { - {DW_AT_name "func1"} - {DW_AT_low_pc $func1_addr} - {DW_AT_high_pc $func1_len DW_FORM_udata} + DW_AT_name "func1" + DW_AT_low_pc $func1_addr + DW_AT_high_pc $func1_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func2"} - {DW_AT_low_pc $func2_addr} - {DW_AT_high_pc $func2_len DW_FORM_udata} + DW_AT_name "func2" + DW_AT_low_pc $func2_addr + DW_AT_high_pc $func2_len DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp index ea871d6..2a8b457 100644 --- a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp +++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp @@ -154,38 +154,38 @@ Dwarf::assemble ${asm_file} { cu { label cu_label } { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {name ${::srcfile}} - {stmt_list $L DW_FORM_sec_offset} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name ${::srcfile} + DW_AT_stmt_list $L DW_FORM_sec_offset } { declare_labels int_label class_A_label class_B_label \ B_ptr_label int_label: DW_TAG_base_type { - {DW_AT_byte_size ${::long_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${::long_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } class_A_label: DW_TAG_class_type { - {DW_AT_name "A"} - {DW_AT_byte_size ${::struct_A_size} DW_FORM_sdata} + DW_AT_name "A" + DW_AT_byte_size ${::struct_A_size} DW_FORM_sdata } { DW_TAG_member { - {DW_AT_name "a"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location ${::A_a} DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :$int_label + DW_AT_data_member_location ${::A_a} DW_FORM_udata } DW_TAG_member { - {DW_AT_name "x"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location ${::A_x} DW_FORM_udata} + DW_AT_name "x" + DW_AT_type :$int_label + DW_AT_data_member_location ${::A_x} DW_FORM_udata } } class_B_label: DW_TAG_class_type { - {DW_AT_name "B"} - {DW_AT_byte_size ${::struct_B_size} DW_FORM_sdata} + DW_AT_name "B" + DW_AT_byte_size ${::struct_B_size} DW_FORM_sdata } { # While there are easier / better ways to specify an # offset used by DW_AT_data_member_location than that @@ -201,45 +201,47 @@ Dwarf::assemble ${asm_file} { # by decode_locdesc(); this is why those opcodes were # chosen. DW_TAG_inheritance { - {DW_AT_type :$class_A_label} - {DW_AT_data_member_location { + DW_AT_type :$class_A_label + DW_AT_data_member_location [subst { DW_OP_constu ${::B_a} DW_OP_plus DW_OP_pick 0 - DW_OP_drop} SPECIAL_expr} - {DW_AT_accessibility 1 DW_FORM_data1} + DW_OP_drop}] SPECIAL_expr + DW_AT_accessibility 1 DW_FORM_data1 } DW_TAG_member { - {DW_AT_name "b"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location ${::B_b} DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :$int_label + DW_AT_data_member_location ${::B_b} DW_FORM_udata } DW_TAG_member { - {DW_AT_name "x2"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location ${::B_x2} DW_FORM_udata} + DW_AT_name "x2" + DW_AT_type :$int_label + DW_AT_data_member_location ${::B_x2} DW_FORM_udata } } B_ptr_label: DW_TAG_pointer_type { - {DW_AT_type :$class_B_label} - {DW_AT_byte_size ${::addr_size} DW_FORM_sdata} + DW_AT_type :$class_B_label + DW_AT_byte_size ${::addr_size} DW_FORM_sdata } DW_TAG_variable { - {DW_AT_name "g_A"} - {DW_AT_type :$class_A_label} - {DW_AT_external 1 flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_A"]} \ - SPECIAL_expr} + DW_AT_name "g_A" + DW_AT_type :$class_A_label + DW_AT_external 1 flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "g_A"] + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "g_B"} - {DW_AT_type :$class_B_label} - {DW_AT_external 1 flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_B"]} \ - SPECIAL_expr} + DW_AT_name "g_B" + DW_AT_type :$class_B_label + DW_AT_external 1 flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "g_B"] + }] SPECIAL_expr } # We can't use MACRO_AT for the definitions of foo and bar @@ -247,23 +249,23 @@ Dwarf::assemble ${asm_file} { # flags. Therefore, we list the name, low_pc, and high_pc # explicitly. DW_TAG_subprogram { - {DW_AT_name foo} - {DW_AT_low_pc $foo_start DW_FORM_addr} - {DW_AT_high_pc $foo_end DW_FORM_addr} - {DW_AT_type :${B_ptr_label}} - {DW_AT_external 1 flag} + DW_AT_name foo + DW_AT_low_pc $foo_start DW_FORM_addr + DW_AT_high_pc $foo_end DW_FORM_addr + DW_AT_type :${B_ptr_label} + DW_AT_external 1 flag } DW_TAG_subprogram { - {DW_AT_name bar} - {DW_AT_low_pc $bar_start DW_FORM_addr} - {DW_AT_high_pc $bar_end DW_FORM_addr} - {DW_AT_type :${B_ptr_label}} - {DW_AT_external 1 flag} + DW_AT_name bar + DW_AT_low_pc $bar_start DW_FORM_addr + DW_AT_high_pc $bar_end DW_FORM_addr + DW_AT_type :${B_ptr_label} + DW_AT_external 1 flag } { DW_TAG_formal_parameter { - {DW_AT_name v} - {DW_AT_type :${B_ptr_label}} + DW_AT_name v + DW_AT_type :${B_ptr_label} } } } @@ -330,7 +332,7 @@ if {[gdb_compile_shlib [list $libsrc $asm_file] $lib_so \ ### Second GDB session. with_test_prefix "second session" { - clean_restart $binfile + clean_restart $::testfile # Again, do whatever is necessary to make sure that the shared library is # loaded for remote targets. diff --git a/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp b/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp index b0c9d7d..021129d 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp +++ b/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp @@ -57,30 +57,30 @@ foreach_with_prefix is_64 {false true} { declare_labels int_type DW_TAG_compile_unit { - {DW_AT_loclists_base cu_table DW_FORM_sec_offset} + DW_AT_loclists_base cu_table DW_FORM_sec_offset } { int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "foo"} - {DW_AT_location 1 DW_FORM_loclistx} - {DW_AT_type :$int_type} + DW_AT_name "foo" + DW_AT_location 1 DW_FORM_loclistx + DW_AT_type :$int_type } DW_TAG_subprogram { - {DW_AT_name "func1"} - {DW_AT_low_pc $func1_addr} - {DW_AT_high_pc $func1_len DW_FORM_udata} + DW_AT_name "func1" + DW_AT_low_pc $func1_addr + DW_AT_high_pc $func1_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func2"} - {DW_AT_low_pc $func2_addr} - {DW_AT_high_pc $func2_len DW_FORM_udata} + DW_AT_name "func2" + DW_AT_low_pc $func2_addr + DW_AT_high_pc $func2_len DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp index 38512cd..e39ca19 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/loclists-sec-offset.exp @@ -66,27 +66,27 @@ foreach_with_prefix is_64 {false true} { DW_TAG_compile_unit { } { int_type1: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "foo"} - {DW_AT_location $foo_location_list DW_FORM_sec_offset} - {DW_AT_type :$int_type1} + DW_AT_name "foo" + DW_AT_location $foo_location_list DW_FORM_sec_offset + DW_AT_type :$int_type1 } DW_TAG_subprogram { - {DW_AT_name "func1"} - {DW_AT_low_pc $func1_addr} - {DW_AT_high_pc $func1_len DW_FORM_udata} + DW_AT_name "func1" + DW_AT_low_pc $func1_addr + DW_AT_high_pc $func1_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func2"} - {DW_AT_low_pc $func2_addr} - {DW_AT_high_pc $func2_len DW_FORM_udata} + DW_AT_name "func2" + DW_AT_low_pc $func2_addr + DW_AT_high_pc $func2_len DW_FORM_udata } } } @@ -100,30 +100,30 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_loclists_base cu2_table DW_FORM_sec_offset} + DW_AT_loclists_base cu2_table DW_FORM_sec_offset } { int_type2: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "bar"} - {DW_AT_location $bar_location_list DW_FORM_sec_offset} - {DW_AT_type :$int_type2} + DW_AT_name "bar" + DW_AT_location $bar_location_list DW_FORM_sec_offset + DW_AT_type :$int_type2 } DW_TAG_subprogram { - {DW_AT_name "func3"} - {DW_AT_low_pc $func3_addr} - {DW_AT_high_pc $func3_len DW_FORM_udata} + DW_AT_name "func3" + DW_AT_low_pc $func3_addr + DW_AT_high_pc $func3_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func4"} - {DW_AT_low_pc $func4_addr} - {DW_AT_high_pc $func4_len DW_FORM_udata} + DW_AT_name "func4" + DW_AT_low_pc $func4_addr + DW_AT_high_pc $func4_len DW_FORM_udata } } } @@ -138,27 +138,27 @@ foreach_with_prefix is_64 {false true} { DW_TAG_compile_unit { } { int_type3: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "baz"} - {DW_AT_location $baz_location_list DW_FORM_sec_offset} - {DW_AT_type :$int_type3} + DW_AT_name "baz" + DW_AT_location $baz_location_list DW_FORM_sec_offset + DW_AT_type :$int_type3 } DW_TAG_subprogram { - {DW_AT_name "func5"} - {DW_AT_low_pc $func5_addr} - {DW_AT_high_pc $func5_len DW_FORM_udata} + DW_AT_name "func5" + DW_AT_low_pc $func5_addr + DW_AT_high_pc $func5_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func6"} - {DW_AT_low_pc $func6_addr} - {DW_AT_high_pc $func6_len DW_FORM_udata} + DW_AT_name "func6" + DW_AT_low_pc $func6_addr + DW_AT_high_pc $func6_len DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/loclists-start-end.exp b/gdb/testsuite/gdb.dwarf2/loclists-start-end.exp index 2569896..876a8b2 100644 --- a/gdb/testsuite/gdb.dwarf2/loclists-start-end.exp +++ b/gdb/testsuite/gdb.dwarf2/loclists-start-end.exp @@ -48,30 +48,30 @@ foreach_with_prefix is_64 {false true} { declare_labels int_type DW_TAG_compile_unit { - {DW_AT_loclists_base cu_table DW_FORM_sec_offset} + DW_AT_loclists_base cu_table DW_FORM_sec_offset } { int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } DW_TAG_variable { - {DW_AT_name "foo"} - {DW_AT_location 1 DW_FORM_loclistx} - {DW_AT_type :$int_type} + DW_AT_name "foo" + DW_AT_location 1 DW_FORM_loclistx + DW_AT_type :$int_type } DW_TAG_subprogram { - {DW_AT_name "func1"} - {DW_AT_low_pc $func1_addr} - {DW_AT_high_pc $func1_len DW_FORM_udata} + DW_AT_name "func1" + DW_AT_low_pc $func1_addr + DW_AT_high_pc $func1_len DW_FORM_udata } DW_TAG_subprogram { - {DW_AT_name "func2"} - {DW_AT_low_pc $func2_addr} - {DW_AT_high_pc $func2_len DW_FORM_udata} + DW_AT_name "func2" + DW_AT_low_pc $func2_addr + DW_AT_high_pc $func2_len DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/macro-complaints.exp b/gdb/testsuite/gdb.dwarf2/macro-complaints.exp index 7b0b27a..17e18c0 100644 --- a/gdb/testsuite/gdb.dwarf2/macro-complaints.exp +++ b/gdb/testsuite/gdb.dwarf2/macro-complaints.exp @@ -36,20 +36,20 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name $::srcfile} - {DW_AT_macros $cu_macro1 DW_FORM_sec_offset} - {DW_AT_stmt_list $L DW_FORM_sec_offset} + DW_AT_name $::srcfile + DW_AT_macros $cu_macro1 DW_FORM_sec_offset + DW_AT_stmt_list $L DW_FORM_sec_offset } { declare_labels int_type int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$int_type} + MACRO_AT_func {main} + DW_AT_type :$int_type } } } diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp new file mode 100644 index 0000000..d4407d7 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp @@ -0,0 +1,75 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +require dwarf2_support + +# The do_test proc comes from macro-source-path.exp.tcl. +source $srcdir/$subdir/macro-source-path.exp.tcl + +# When adding a test here, please consider adding an equivalent case to +# `gdb.base/macro-source-path.exp`. + +# The following tests are based on the output of `clang-14 -gdwarf-4 +# -fdebug-macro -g3 <file>` (using its built-in assembler). With -gdwarf-4, +# clang produces a .debug_macinfo section, not a .debug_macro section. But +# this test still creates a .debug_macro section, that's good enough for what +# we want to test. + +## test.c +do_test filename 4 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test dot-filename 4 "test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test dot-dot-cwd 4 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test absolute-cwd 4 "/tmp/cwd/test.c" 1 { +} { + {"test.c" 0} +} + +## ../other/test.c +do_test dot-dot-other 4 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test absolute-other 4 "/tmp/other/test.c" 1 { + "/tmp" +} { + {"other/test.c" 1} +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp new file mode 100644 index 0000000..23a40ba --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp @@ -0,0 +1,79 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +require dwarf2_support + +# The do_test proc comes from macro-source-path.exp.tcl. +source $srcdir/$subdir/macro-source-path.exp.tcl + +# When adding a test here, please consider adding an equivalent case to +# `gdb.base/macro-source-path.exp`. + +# The following tests are based on the output of `clang-14 -gdwarf-5 +# -fdebug-macro -g3 <file>` (using its built-in assembler) + +## test.c +do_test filename 5 "test.c" 0 { + "/tmp/cwd" +} { + {"test.c" 0} +} + +## ./test.c +do_test dot-filename 5 "test.c" 1 { + "/tmp/cwd" + "." +} { + {"test.c" 0} + {"test.c" 1} +} + +## ../cwd/test.c +do_test dot-dot-cwd 5 "../cwd/test.c" 0 { + "/tmp/cwd" +} { + {"../cwd/test.c" 0} +} + +## /tmp/cwd/test.c +do_test absolute-cwd 5 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"/tmp/cwd/test.c" 0} + {"test.c" 0} +} + +## ../other/test.c +do_test dot-dot-other 5 "../other/test.c" 0 { + "/tmp/cwd" +} { + {"../other/test.c" 0} +} + +## /tmp/other/test.c +do_test absolute-other 5 "/tmp/other/test.c" 1 { + "/tmp/cwd" + "/tmp" +} { + {"/tmp/other/test.c" 0} + {"other/test.c" 1} +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp new file mode 100644 index 0000000..99f7857 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp @@ -0,0 +1,74 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +require dwarf2_support + +# The do_test proc comes from macro-source-path.exp.tcl. +source $srcdir/$subdir/macro-source-path.exp.tcl + +# When adding a test here, please consider adding an equivalent case to +# `gdb.base/macro-source-path.exp`. + +# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.34 (Ubuntu 20.04). It generates a v5 +# .debug_macro section, but a v3 .debug_line section. + +## test.c +do_test filename 3 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test dot-filename 3 "./test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test dot-dot-cwd 3 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test absolute-cwd 3 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 1} +} + +## ../other/test.c +do_test dot-dot-other 3 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test absolute-other 3 "/tmp/other/test.c" 1 { + "/tmp/other" +} { + {"test.c" 1} +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp new file mode 100644 index 0000000..569b409 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp @@ -0,0 +1,74 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +require dwarf2_support + +# The do_test proc comes from macro-source-path.exp.tcl. +source $srcdir/$subdir/macro-source-path.exp.tcl + +# When adding a test here, please consider adding an equivalent case to +# `gdb.base/macro-source-path.exp`. + +# The following tests are based on the output of `gcc -gdwarf-4 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.38. With -gdwarf-4, gcc generates a +# v4 (pre-standard) .debug_macro section. + +## test.c +do_test filename 4 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test dot-filename 4 "./test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test dot-dot-cwd 4 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test absolute-cwd 4 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 1} +} + +## ../other/test.c +do_test dot-dot-other 4 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test absolute-other 4 "/tmp/other/test.c" 1 { + "/tmp/other" +} { + {"test.c" 1} +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp new file mode 100644 index 0000000..0517d29 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp @@ -0,0 +1,85 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +require dwarf2_support + +# The do_test proc comes from macro-source-path.exp.tcl. +source $srcdir/$subdir/macro-source-path.exp.tcl + +# When adding a test here, please consider adding an equivalent case to +# `gdb.base/macro-source-path.exp`. + +# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.38. + +## test.c +do_test filename 5 "test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 0} + {"test.c" 0} +} + +## ./test.c +do_test dot-filename 5 "./test.c" 1 { + "/tmp/cwd" + "." +} { + {"test.c" 1} + {"test.c" 1} +} + +## ../cwd/test.c +do_test dot-dot-cwd 5 "../cwd/test.c" 1 { + "/tmp/cwd" + "../cwd" +} { + {"test.c" 1} + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test absolute-cwd 5 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" + "/tmp/cwd" +} { + {"test.c" 1} + {"test.c" 0} +} + +## ../other/test.c +do_test dot-dot-other 5 "../other/test.c" 1 { + "/tmp/cwd" + "../other" +} { + {"test.c" 1} + {"test.c" 1} +} + +## /tmp/other/test.c +do_test absolute-other 5 "/tmp/other/test.c" 1 { + "/tmp/cwd" + "/tmp/other" +} { + {"test.c" 1} + {"test.c" 1} +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp deleted file mode 100644 index 1318f8e..0000000 --- a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp +++ /dev/null @@ -1,407 +0,0 @@ -# This testcase is part of GDB, the GNU debugger. - -# Copyright 2022-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/>. - -# Generate binaries imitating different ways source file paths can be passed to -# compilers. Test printing macros from those binaries. - -load_lib dwarf.exp - -require dwarf2_support - -standard_testfile .c - -lassign [function_range main $srcdir/$subdir/$srcfile] \ - main_start main_len - -# Run one test. -# -# - TEST_NAME is the name of the test, used to differentiate the binaries. -# - LINES_VERSION is the version of the version of the .debug_line section to -# generate. -# - DW_AT_NAME is the string to put in the compilation unit's DW_AT_name -# attribute. -# - MAIN_FILE_IDX is the file index the .debug_line and .debug_macro sections -# will use to refer to the main file. -# - DIRECTORIES is a list of directories to put in the .debug_line section -# header -# - FILE_NAMES is a list of {name, directory index} pairs describing the files -# names to put in the .debug_line section header. - -proc do_test { test_name lines_version DW_AT_name main_file_idx directories - file_names } { - with_test_prefix "test_name=$test_name" { - foreach_with_prefix is_64 {true false} { - # So we can access them in Dwarf::assemble... - set ::lines_version $lines_version - set ::DW_AT_name $DW_AT_name - set ::main_file_idx $main_file_idx - set ::directories $directories - set ::file_names $file_names - set ::is_64 $is_64 - set 32_or_64 [expr $is_64 ? 64 : 32] - - set asm_file [standard_output_file ${::testfile}-${test_name}-${32_or_64}.S] - Dwarf::assemble $asm_file { - declare_labels Llines cu_macros - - # DW_AT_comp_dir is always the current working directory - # from which the compiler was invoked. We pretend the compiler was - # always launched from /tmp/cwd. - set comp_dir "/tmp/cwd" - - cu {} { - DW_TAG_compile_unit { - {DW_AT_producer "My C Compiler"} - {DW_AT_language @DW_LANG_C11} - {DW_AT_name $::DW_AT_name} - {DW_AT_comp_dir $comp_dir} - {DW_AT_stmt_list $Llines DW_FORM_sec_offset} - {DW_AT_macros $cu_macros DW_FORM_sec_offset} - } { - declare_labels int_type - - int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} - } - - DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$int_type} - } - } - } - - # Define the .debug_line section. - lines [list version $::lines_version] "Llines" { - foreach directory $::directories { - include_dir $directory - } - - foreach file_name $::file_names { - lassign $file_name name dir_index - file_name $name $dir_index - } - - # A line number program just good enough so that GDB can - # figure out we are stopped in main. - program { - DW_LNS_set_file $::main_file_idx - DW_LNE_set_address $::main_start - line 10 - DW_LNS_copy - - DW_LNE_set_address "$::main_start + $::main_len" - DW_LNE_end_sequence - } - } - - # Define the .debug_macro section. - macro { - cu_macros: unit { - "debug-line-offset-label" $Llines - "is-64" $::is_64 - } { - # A macro defined outside the main file, as if it was defined - # on the command line with -D. - # - # Clang has this bug where it puts the macros defined on - # the command-line after the main file portion (see - # PR 29034). We're not trying to replicate that here, - # this is not in the scope of this test. - define 0 "ONE 1" - define_strp 0 "THREE 3" - start_file 0 $::main_file_idx - # A macro defined at line 1 of the main file. - define 1 "TWO 2" - end_file - } - } - } - - if { [prepare_for_testing "failed to prepare" ${::testfile}-${test_name}-${32_or_64} \ - [list $::srcfile $asm_file] {nodebug}] } { - return - } - - with_complaints 5 { - gdb_test_multiple "print main" "no complaints" { - -wrap -re "During symbol reading: .*" { - fail $gdb_test_name - } - -wrap -re "" { - pass $gdb_test_name - } - } - } - - if ![runto_main] { - return - } - - gdb_test "print ONE" " = 1" - gdb_test "print TWO" " = 2" - gdb_test "print THREE" " = 3" - } - } -} - -# When adding a test here, please consider adding an equivalent case to the test -# of the same name in gdb.base. - -# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, -# gcc 11 paired with gas from binutils 2.38. - -## test.c -do_test gcc11-ld238-dw5-filename 5 "test.c" 1 { - "/tmp/cwd" -} { - {"test.c" 0} - {"test.c" 0} -} - -## ./test.c -do_test gcc11-ld238-dw5-dot-filename 5 "./test.c" 1 { - "/tmp/cwd" - "." -} { - {"test.c" 1} - {"test.c" 1} -} - -## ../cwd/test.c -do_test gcc11-ld238-dw5-dot-dot-cwd 5 "../cwd/test.c" 1 { - "/tmp/cwd" - "../cwd" -} { - {"test.c" 1} - {"test.c" 1} -} - -## /tmp/cwd/test.c -do_test gcc11-ld238-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 { - "/tmp/cwd" - "/tmp/cwd" -} { - {"test.c" 1} - {"test.c" 0} -} - -## ../other/test.c -do_test gcc11-ld238-dw5-dot-dot-other 5 "../other/test.c" 1 { - "/tmp/cwd" - "../other" -} { - {"test.c" 1} - {"test.c" 1} -} - -## /tmp/other/test.c -do_test gcc11-ld238-dw5-absolute-other 5 "/tmp/other/test.c" 1 { - "/tmp/cwd" - "/tmp/other" -} { - {"test.c" 1} - {"test.c" 1} -} - -# The following tests are based on the output of `gcc -gdwarf-4 -g3 <file>`, -# gcc 11 paired with gas from binutils 2.38. With -gdwarf-4, gcc generates a -# v4 (pre-standard) .debug_macro section. - -## test.c -do_test gcc11-ld238-dw4-filename 4 "test.c" 1 { -} { - {"test.c" 0} -} - -## ./test.c -do_test gcc11-ld238-dw4-dot-filename 4 "./test.c" 1 { - "." -} { - {"test.c" 1} -} - -## ../cwd/test.c -do_test gcc11-ld238-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 { - "../cwd" -} { - {"test.c" 1} -} - -## /tmp/cwd/test.c -do_test gcc11-ld238-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 { - "/tmp/cwd" -} { - {"test.c" 1} -} - -## ../other/test.c -do_test gcc11-ld238-dw4-dot-dot-other 4 "../other/test.c" 1 { - "../other" -} { - {"test.c" 1} -} - -## /tmp/other/test.c -do_test gcc11-ld238-dw4-absolute-other 4 "/tmp/other/test.c" 1 { - "/tmp/other" -} { - {"test.c" 1} -} - -# The following tests are based on the output of `clang-14 -gdwarf-5 -# -fdebug-macro -g3 <file>` (using its built-in assembler) - -## test.c -do_test clang14-dw5-filename 5 "test.c" 0 { - "/tmp/cwd" -} { - {"test.c" 0} -} - -## ./test.c -do_test clang14-dw5-dot-filename 5 "test.c" 1 { - "/tmp/cwd" - "." -} { - {"test.c" 0} - {"test.c" 1} -} - -## ../cwd/test.c -do_test clang14-dw5-dot-dot-cwd 5 "../cwd/test.c" 0 { - "/tmp/cwd" -} { - {"../cwd/test.c" 0} -} - -## /tmp/cwd/test.c -do_test clang14-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 { - "/tmp/cwd" -} { - {"/tmp/cwd/test.c" 0} - {"test.c" 0} -} - -## ../other/test.c -do_test clang14-dw5-dot-dot-other 5 "../other/test.c" 0 { - "/tmp/cwd" -} { - {"../other/test.c" 0} -} - -## /tmp/other/test.c -do_test clang14-dw5-absolute-other 5 "/tmp/other/test.c" 1 { - "/tmp/cwd" - "/tmp" -} { - {"/tmp/other/test.c" 0} - {"other/test.c" 1} -} - -# The following tests are based on the output of `clang-14 -gdwarf-4 -# -fdebug-macro -g3 <file>` (using its built-in assembler). With -gdwarf-4, -# clang produces a .debug_macinfo section, not a .debug_macro section. But -# this test still creates a .debug_macro section, that's good enough for what -# we want to test. - -## test.c -do_test clang14-dw4-filename 4 "test.c" 1 { -} { - {"test.c" 0} -} - -## ./test.c -do_test clang14-dw4-dot-filename 4 "test.c" 1 { - "." -} { - {"test.c" 1} -} - -## ../cwd/test.c -do_test clang14-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 { - "../cwd" -} { - {"test.c" 1} -} - -## /tmp/cwd/test.c -do_test clang14-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 { -} { - {"test.c" 0} -} - -## ../other/test.c -do_test clang14-dw4-dot-dot-other 4 "../other/test.c" 1 { - "../other" -} { - {"test.c" 1} -} - -## /tmp/other/test.c -do_test clang14-dw4-absolute-other 4 "/tmp/other/test.c" 1 { - "/tmp" -} { - {"other/test.c" 1} -} - -# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, -# gcc 11 paired with gas from binutils 2.34 (Ubuntu 20.04). It generates a v5 -# .debug_macro section, but a v3 .debug_line section. - -## test.c -do_test gcc11-ld234-dw5-filename 3 "test.c" 1 { -} { - {"test.c" 0} -} - -## ./test.c -do_test gcc11-ld234-dw5-dot-filename 3 "./test.c" 1 { - "." -} { - {"test.c" 1} -} - -## ../cwd/test.c -do_test gcc11-ld234-dw5-dot-dot-cwd 3 "../cwd/test.c" 1 { - "../cwd" -} { - {"test.c" 1} -} - -## /tmp/cwd/test.c -do_test gcc11-ld234-dw5-absolute-cwd 3 "/tmp/cwd/test.c" 1 { - "/tmp/cwd" -} { - {"test.c" 1} -} - -## ../other/test.c -do_test gcc11-ld234-dw5-dot-dot-other 3 "../other/test.c" 1 { - "../other" -} { - {"test.c" 1} -} - -## /tmp/other/test.c -do_test gcc11-ld234-dw5-absolute-other 3 "/tmp/other/test.c" 1 { - "/tmp/other" -} { - {"test.c" 1} -} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl new file mode 100644 index 0000000..b71d55d --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl @@ -0,0 +1,161 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022-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/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. +# +# The entry points for this test are in the various +# gdb.dwarf2/macro-source-path-*.exp files. + +standard_testfile macro-source-path.c + +lassign [function_range main $srcdir/$subdir/$srcfile] \ + main_start main_len + +# Run one test. +# +# - TEST_NAME is the name of the test, used to differentiate the binaries. +# - LINES_VERSION is the version of the version of the .debug_line section to +# generate. +# - DW_AT_NAME is the string to put in the compilation unit's DW_AT_name +# attribute. +# - MAIN_FILE_IDX is the file index the .debug_line and .debug_macro sections +# will use to refer to the main file. +# - DIRECTORIES is a list of directories to put in the .debug_line section +# header +# - FILE_NAMES is a list of {name, directory index} pairs describing the files +# names to put in the .debug_line section header. + +proc do_test { test_name lines_version DW_AT_name main_file_idx directories + file_names } { + with_test_prefix "test_name=$test_name" { + foreach_with_prefix is_64 {true false} { + # So we can access them in Dwarf::assemble... + set ::lines_version $lines_version + set ::DW_AT_name $DW_AT_name + set ::main_file_idx $main_file_idx + set ::directories $directories + set ::file_names $file_names + set ::is_64 $is_64 + set 32_or_64 [expr $is_64 ? 64 : 32] + + set asm_file [standard_output_file ${::testfile}-${test_name}-${32_or_64}.S] + Dwarf::assemble $asm_file { + declare_labels Llines cu_macros + + # DW_AT_comp_dir is always the current working directory + # from which the compiler was invoked. We pretend the compiler was + # always launched from /tmp/cwd. + set comp_dir "/tmp/cwd" + + cu {} { + DW_TAG_compile_unit { + DW_AT_producer "My C Compiler" + DW_AT_language @DW_LANG_C11 + DW_AT_name $::DW_AT_name + DW_AT_comp_dir $comp_dir + DW_AT_stmt_list $Llines DW_FORM_sec_offset + DW_AT_macros $cu_macros DW_FORM_sec_offset + } { + declare_labels int_type + + int_type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int + } + + DW_TAG_subprogram { + MACRO_AT_func {main} + DW_AT_type :$int_type + } + } + } + + # Define the .debug_line section. + lines [list version $::lines_version] "Llines" { + foreach directory $::directories { + include_dir $directory + } + + foreach file_name $::file_names { + lassign $file_name name dir_index + file_name $name $dir_index + } + + # A line number program just good enough so that GDB can + # figure out we are stopped in main. + program { + DW_LNS_set_file $::main_file_idx + DW_LNE_set_address $::main_start + line 10 + DW_LNS_copy + + DW_LNE_set_address "$::main_start + $::main_len" + DW_LNE_end_sequence + } + } + + # Define the .debug_macro section. + macro { + cu_macros: unit { + "debug-line-offset-label" $Llines + "is-64" $::is_64 + } { + # A macro defined outside the main file, as if it was defined + # on the command line with -D. + # + # Clang has this bug where it puts the macros defined on + # the command-line after the main file portion (see + # PR 29034). We're not trying to replicate that here, + # this is not in the scope of this test. + define 0 "ONE 1" + define_strp 0 "THREE 3" + start_file 0 $::main_file_idx + # A macro defined at line 1 of the main file. + define 1 "TWO 2" + end_file + } + } + } + + if { [prepare_for_testing "failed to prepare" ${::testfile}-${test_name}-${32_or_64} \ + [list $::srcfile $asm_file] {nodebug}] } { + return + } + + with_complaints 5 { + gdb_test_multiple "print main" "no complaints" { + -wrap -re "During symbol reading: .*" { + fail $gdb_test_name + } + -wrap -re "" { + pass $gdb_test_name + } + } + } + + if ![runto_main] { + return + } + + gdb_test "print ONE" " = 1" + gdb_test "print TWO" " = 2" + gdb_test "print THREE" " = 3" + } + } +} diff --git a/gdb/testsuite/gdb.dwarf2/main-subprogram.exp b/gdb/testsuite/gdb.dwarf2/main-subprogram.exp index 467cf20..0200316 100644 --- a/gdb/testsuite/gdb.dwarf2/main-subprogram.exp +++ b/gdb/testsuite/gdb.dwarf2/main-subprogram.exp @@ -31,22 +31,22 @@ Dwarf::assemble $asm_file { # so choose a language that isn't C and that gdb is unlikely # to implement. DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_PLI} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_language @DW_LANG_PLI + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels type - type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} - } + type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int + } DW_TAG_subprogram { - {MACRO_AT_func {mymain}} - {type :$type} - {DW_AT_main_subprogram 1 flag} + MACRO_AT_func {mymain} + DW_AT_type :$type + DW_AT_main_subprogram 1 flag } { } } diff --git a/gdb/testsuite/gdb.dwarf2/mega-enum.exp b/gdb/testsuite/gdb.dwarf2/mega-enum.exp index 7482edb..7817fbf 100644 --- a/gdb/testsuite/gdb.dwarf2/mega-enum.exp +++ b/gdb/testsuite/gdb.dwarf2/mega-enum.exp @@ -26,21 +26,21 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_enumeration_type { - {DW_AT_name mega_enum} - {DW_AT_type :$integer_label} + DW_AT_name mega_enum + DW_AT_type :$integer_label } { # In the past gdb used a 'short' for the field count. # But this fails if there are too many fields. If the @@ -48,8 +48,8 @@ Dwarf::assemble $asm_file { # so use a number that's just big enough. for {set i 0} {$i < 65538} {incr i} { DW_TAG_enumerator { - {DW_AT_name DEI_$i} - {DW_AT_const_value $i DW_FORM_sdata} + DW_AT_name DEI_$i + DW_AT_const_value $i DW_FORM_sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/method-ptr.exp b/gdb/testsuite/gdb.dwarf2/method-ptr.exp index 867527c..828166f 100644 --- a/gdb/testsuite/gdb.dwarf2/method-ptr.exp +++ b/gdb/testsuite/gdb.dwarf2/method-ptr.exp @@ -28,48 +28,50 @@ Dwarf::assemble $asm_file { declare_labels ptr_label subr_label memptr_label cu {} { - compile_unit {{language @DW_LANG_C_plus_plus}} { + compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { int_label: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } float_label: base_type { - {name float} - {encoding @DW_ATE_float} - {byte_size 4 DW_FORM_sdata} + DW_AT_name float + DW_AT_encoding @DW_ATE_float + DW_AT_byte_size 4 DW_FORM_sdata } struct_label: structure_type { - {name S} - {byte_size 1 DW_FORM_sdata} + DW_AT_name S + DW_AT_byte_size 1 DW_FORM_sdata } ptr_label: pointer_type { - {type :$struct_label} + DW_AT_type :$struct_label } subr_label: subroutine_type { - {type :$int_label} + DW_AT_type :$int_label } { formal_parameter { - {type :$ptr_label} - {artificial 1 DW_FORM_flag_present} + DW_AT_type :$ptr_label + DW_AT_artificial 1 DW_FORM_flag_present } formal_parameter { - {type :$float_label} + DW_AT_type :$float_label } } memptr_label: ptr_to_member_type { - {type :$subr_label} - {containing_type :$struct_label} + DW_AT_type :$subr_label + DW_AT_containing_type :$struct_label } typedef { - {name the_typedef} - {type :$memptr_label} + DW_AT_name the_typedef + DW_AT_type :$memptr_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/missing-line-table.exp b/gdb/testsuite/gdb.dwarf2/missing-line-table.exp index 835686e..977a016 100644 --- a/gdb/testsuite/gdb.dwarf2/missing-line-table.exp +++ b/gdb/testsuite/gdb.dwarf2/missing-line-table.exp @@ -38,19 +38,19 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name missing-line-table.c} - {stmt_list $Llines DW_FORM_sec_offset} - {DW_AT_low_pc $::foo_start DW_FORM_addr} - {DW_AT_high_pc $::main_end DW_FORM_addr} + DW_AT_language @DW_LANG_C + DW_AT_name missing-line-table.c + DW_AT_stmt_list $Llines DW_FORM_sec_offset + DW_AT_low_pc $::foo_start DW_FORM_addr + DW_AT_high_pc $::main_end DW_FORM_addr } { subprogram { - {external 1 flag} - {MACRO_AT_func {main}} + DW_AT_external 1 flag + MACRO_AT_func {main} } subprogram { - {external 1 flag} - {MACRO_AT_func {foo}} + DW_AT_external 1 flag + MACRO_AT_func {foo} } } } diff --git a/gdb/testsuite/gdb.dwarf2/missing-sig-type.exp b/gdb/testsuite/gdb.dwarf2/missing-sig-type.exp index 947f024..a3eaae9 100644 --- a/gdb/testsuite/gdb.dwarf2/missing-sig-type.exp +++ b/gdb/testsuite/gdb.dwarf2/missing-sig-type.exp @@ -30,8 +30,8 @@ Dwarf::assemble $asm_file { # This signature is intentionally wrong. typedef_label: typedef { - {name foo} - {type 0xee22334455667788 ref_sig8 } + DW_AT_name foo + DW_AT_type 0xee22334455667788 ref_sig8 } } } @@ -39,9 +39,9 @@ Dwarf::assemble $asm_file { tu {} 0x1122334455667788 the_type { type_unit {} { the_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp index 108c9c7..ee6992b 100644 --- a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp +++ b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp @@ -40,112 +40,112 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int float template_var1 template_var2 template_var3 int: DW_TAG_base_type { - {DW_AT_name "int"} - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed } float: base_type { - {DW_AT_name float} - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_float} + DW_AT_name float + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_float } DW_TAG_subprogram { - {DW_AT_name "main"} - {DW_AT_low_pc $::main_start DW_FORM_addr} - {DW_AT_high_pc $::main_end DW_FORM_addr} - {DW_AT_type :$int} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "main" + DW_AT_low_pc $::main_start DW_FORM_addr + DW_AT_high_pc $::main_end DW_FORM_addr + DW_AT_type :$int + DW_AT_external 1 DW_FORM_flag } { DW_TAG_variable { - {DW_AT_name "var1"} - {DW_AT_type :$template_var1} + DW_AT_name "var1" + DW_AT_type :$template_var1 } DW_TAG_variable { - {DW_AT_name "var2"} - {DW_AT_type :$template_var2} + DW_AT_name "var2" + DW_AT_type :$template_var2 } DW_TAG_variable { - {DW_AT_name "var3"} - {DW_AT_type :$template_var3} + DW_AT_name "var3" + DW_AT_type :$template_var3 } } # A variable whose type is a template instantiation with two # template parameters, one unnamed. template_var1: DW_TAG_structure_type { - {DW_AT_name "template_var1<int, float>"} + DW_AT_name "template_var1<int, float>" } { DW_TAG_member { - {DW_AT_name "me"} - {DW_AT_type :$int} + DW_AT_name "me" + DW_AT_type :$int } DW_TAG_member { - {DW_AT_name "me2"} - {DW_AT_type :$float} + DW_AT_name "me2" + DW_AT_type :$float } DW_TAG_template_type_param { - {DW_AT_type :$int} + DW_AT_type :$int } DW_TAG_template_type_param { - {DW_AT_name "second"} - {DW_AT_type :$float} + DW_AT_name "second" + DW_AT_type :$float } } # A variable whose type is a template instantiation with two # template parameters, both unnamed. template_var2: DW_TAG_class_type { - {DW_AT_name "template_var2<int, float>"} + DW_AT_name "template_var2<int, float>" } { DW_TAG_member { - {DW_AT_name "me"} - {DW_AT_type :$int} + DW_AT_name "me" + DW_AT_type :$int } DW_TAG_member { - {DW_AT_name "me2"} - {DW_AT_type :$float} + DW_AT_name "me2" + DW_AT_type :$float } DW_TAG_template_type_param { - {DW_AT_type :$int} + DW_AT_type :$int } DW_TAG_template_type_param { - {DW_AT_type :$float} + DW_AT_type :$float } } # A variable whose type is a template instantiation with four # template arguments, two types, two values, all unnamed. template_var3: DW_TAG_structure_type { - {DW_AT_name "template_var3<0, int, 11, float>"} + DW_AT_name "template_var3<0, int, 11, float>" } { DW_TAG_member { - {DW_AT_name "me"} - {DW_AT_type :$int} + DW_AT_name "me" + DW_AT_type :$int } DW_TAG_member { - {DW_AT_name "me2"} - {DW_AT_type :$float} + DW_AT_name "me2" + DW_AT_type :$float } DW_TAG_template_value_param { - {DW_AT_type :$int} - {DW_AT_const_value 0 DW_FORM_sdata} + DW_AT_type :$int + DW_AT_const_value 0 DW_FORM_sdata } DW_TAG_template_type_param { - {DW_AT_type :$int} + DW_AT_type :$int } DW_TAG_template_value_param { - {DW_AT_type :$int} - {DW_AT_const_value 11 DW_FORM_sdata} + DW_AT_type :$int + DW_AT_const_value 11 DW_FORM_sdata } DW_TAG_template_type_param { - {DW_AT_type :$float} + DW_AT_type :$float } } } diff --git a/gdb/testsuite/gdb.dwarf2/missing-type-name.exp b/gdb/testsuite/gdb.dwarf2/missing-type-name.exp index 91997f7..68a5552 100644 --- a/gdb/testsuite/gdb.dwarf2/missing-type-name.exp +++ b/gdb/testsuite/gdb.dwarf2/missing-type-name.exp @@ -44,48 +44,52 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "GNU C 8.1"} - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_producer "GNU C 8.1" + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels main_type int_type ptr_type main_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed } int_type: DW_TAG_base_type { - {DW_AT_byte_size 0 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} + DW_AT_byte_size 0 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed } ptr_type: DW_TAG_pointer_type { - {DW_AT_type :$int_type} + DW_AT_type :$int_type } - DW_TAG_subprogram { - {MACRO_AT_func func} - {type :$int_type} + DW_TAG_subprogram { + MACRO_AT_func func + DW_AT_type :$int_type } - DW_TAG_subprogram { - {MACRO_AT_func main} - {type :$main_type} + DW_TAG_subprogram { + MACRO_AT_func main + DW_AT_type :$main_type } DW_TAG_variable { - {DW_AT_name "var_a"} - {DW_AT_type :$main_type} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + DW_AT_name "var_a" + DW_AT_type :$main_type + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_a"] + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "var_ptr"} - {DW_AT_type :$ptr_type} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_ptr"]} SPECIAL_expr} + DW_AT_name "var_ptr" + DW_AT_type :$ptr_type + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_ptr"] + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/multidictionary.exp b/gdb/testsuite/gdb.dwarf2/multidictionary.exp index 3458f7c..4fdf985 100644 --- a/gdb/testsuite/gdb.dwarf2/multidictionary.exp +++ b/gdb/testsuite/gdb.dwarf2/multidictionary.exp @@ -35,40 +35,40 @@ Dwarf::assemble $asm_file { cu {} { D45d9: compile_unit { - {language @DW_LANG_C_plus_plus} - {name "SerialPortUtils.cpp"} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "SerialPortUtils.cpp" } { D5079: base_type { - {byte_size 1 sdata} - {encoding @DW_ATE_unsigned} - {name "char"} + DW_AT_byte_size 1 sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "char" } D5080: const_type { - {type :$D5079} + DW_AT_type :$D5079 } D50a9: pointer_type { - {byte_size 4 sdata} - {type :$D5080} + DW_AT_byte_size 4 sdata + DW_AT_type :$D5080 } D50af: const_type { - {type :$D50a9} + DW_AT_type :$D50a9 } D5ab2: subprogram { - {external 1 flag} - {linkage_name "_Z18SerialSyncWriteStrPKc"} + DW_AT_external 1 flag + DW_AT_linkage_name "_Z18SerialSyncWriteStrPKc" } { D5ac2: formal_parameter { - {name "msg"} - {type :$D50af} + DW_AT_name "msg" + DW_AT_type :$D50af } D5ace: lexical_block {} { D5acf: DW_TAG_variable { - {name "p"} - {type :$D50a9} + DW_AT_name "p" + DW_AT_type :$D50a9 } } } @@ -77,34 +77,34 @@ Dwarf::assemble $asm_file { cu {} { D2135f: compile_unit { - {language @DW_LANG_C_plus_plus} - {name "Main.cpp"} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name "Main.cpp" } { D2216a: base_type { - {byte_size 1 sdata} - {encoding @DW_ATE_unsigned_char} - {name "char"} + DW_AT_byte_size 1 sdata + DW_AT_encoding @DW_ATE_unsigned_char + DW_AT_name "char" } D22171: const_type { - {type :$D2216a} + DW_AT_type :$D2216a } D226c4: pointer_type { - {byte_size 4 sdata} - {type :$D22171} + DW_AT_byte_size 4 sdata + DW_AT_type :$D22171 } D226ca: const_type { - {type :$D226c4} + DW_AT_type :$D226c4 } D245da: subprogram { - {name "PrintPanicMsg"} + DW_AT_name "PrintPanicMsg" } { D245e6: formal_parameter { - {name "msg"} - {type :$D226ca} + DW_AT_name "msg" + DW_AT_type :$D226ca } } } @@ -112,28 +112,28 @@ Dwarf::assemble $asm_file { cu {} { D41c21: compile_unit { - {language @DW_LANG_C99} - {name "<artificial>"} + DW_AT_language @DW_LANG_C99 + DW_AT_name "<artificial>" } { - D42025: subprogram { - {abstract_origin %$D245da} - {low_pc 0x80b60 addr} - {high_pc 0x6c data4} - } { + D42025: subprogram { + DW_AT_abstract_origin %$D245da + DW_AT_low_pc 0x80b60 addr + DW_AT_high_pc 0x6c data4 + } { D42038: formal_parameter { - {abstract_origin %$D245e6} + DW_AT_abstract_origin %$D245e6 } D42045: inlined_subroutine { - {abstract_origin %$D5ab2} - {low_pc 0x8060 addr} - {high_pc 0xc data4} - } { - D420b5: formal_parameter { - {abstract_origin %$D5ac2} - } - } - } + DW_AT_abstract_origin %$D5ab2 + DW_AT_low_pc 0x8060 addr + DW_AT_high_pc 0xc data4 + } { + D420b5: formal_parameter { + DW_AT_abstract_origin %$D5ac2 + } + } + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/nameless-enum.exp b/gdb/testsuite/gdb.dwarf2/nameless-enum.exp index 1610b7c..6d42fb7 100644 --- a/gdb/testsuite/gdb.dwarf2/nameless-enum.exp +++ b/gdb/testsuite/gdb.dwarf2/nameless-enum.exp @@ -27,25 +27,25 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_D} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_D + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } DW_TAG_enumeration_type { - {DW_AT_type :$integer_label} - {DW_AT_enum_class 1 DW_FORM_flag} + DW_AT_type :$integer_label + DW_AT_enum_class 1 DW_FORM_flag } { DW_TAG_enumerator { - {DW_AT_name VALUE} - {DW_AT_const_value 17 DW_FORM_sdata} + DW_AT_name VALUE + DW_AT_const_value 17 DW_FORM_sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/negative-data-member-location.exp b/gdb/testsuite/gdb.dwarf2/negative-data-member-location.exp index 365204f..48f272e 100644 --- a/gdb/testsuite/gdb.dwarf2/negative-data-member-location.exp +++ b/gdb/testsuite/gdb.dwarf2/negative-data-member-location.exp @@ -31,33 +31,35 @@ set asm_file [standard_output_file ${srcfile2}] Dwarf::assemble ${asm_file} { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C99} - {DW_AT_producer "GNU C++17 11.1.0 -mtune=generic -march=x86-64 -g3 -O0"} - {name ${::srcfile}} + DW_AT_language @DW_LANG_C99 + DW_AT_producer "GNU C++17 11.1.0 -mtune=generic -march=x86-64 -g3 -O0" + DW_AT_name ${::srcfile} } { declare_labels int_label struct_label int_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } struct_label: DW_TAG_structure_type { - {DW_AT_name "the_struct"} - {DW_AT_byte_size 4 DW_FORM_udata} + DW_AT_name "the_struct" + DW_AT_byte_size 4 DW_FORM_udata } { DW_TAG_member { - {DW_AT_name "field"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location -1 DW_FORM_sdata} + DW_AT_name "field" + DW_AT_type :$int_label + DW_AT_data_member_location -1 DW_FORM_sdata } } DW_TAG_variable { - {DW_AT_name "s"} - {DW_AT_type :$struct_label} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "s"]} SPECIAL_expr} + DW_AT_name "s" + DW_AT_type :$struct_label + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "s"] + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp b/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp index 7475d7a..05e625f 100644 --- a/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp +++ b/gdb/testsuite/gdb.dwarf2/no-gnu-debuglink.exp @@ -38,7 +38,7 @@ if { [build_executable $testfile.exp $testfile [list $srcfile $asm_file]] } { clean_restart gdb_test_no_output "maint set dwarf synchronous on" -set msg "\r\nwarning: could not find '\.gnu_debugaltlink' file for \[^\r\n\]*" +set msg "\r\nwarning: could not find supplementary DWARF file \[^\r\n\]*" gdb_test "file $binfile" "$msg" "file command" set question "Load new symbol table from .*\? .y or n. " diff --git a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp index 4aef19a..93c3dea 100644 --- a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp +++ b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp @@ -31,165 +31,165 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {DW_AT_name $srcfile} + DW_AT_name $srcfile } { declare_labels int_type_label char_type_label \ struct_s_label struct_t_label array_a9_label \ char_ptr_label implicit_a_label stack_b_label int_type_label: base_type { - {name "int"} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } char_type_label: base_type { - {name "char"} - {encoding @DW_ATE_unsigned} - {byte_size 1 DW_FORM_sdata} + DW_AT_name "char" + DW_AT_encoding @DW_ATE_unsigned + DW_AT_byte_size 1 DW_FORM_sdata } char_ptr_label: pointer_type { - {type :$char_type_label} + DW_AT_type :$char_type_label } struct_s_label: structure_type { - {name s} - {byte_size 4 DW_FORM_sdata} + DW_AT_name s + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name a} - {type :$int_type_label} - {data_member_location 0 DW_FORM_udata} - {bit_size 8 DW_FORM_udata} + DW_AT_name a + DW_AT_type :$int_type_label + DW_AT_data_member_location 0 DW_FORM_udata + DW_AT_bit_size 8 DW_FORM_udata } member { - {name b} - {type :$int_type_label} - {data_bit_offset 8 DW_FORM_udata} - {bit_size 24 DW_FORM_udata} + DW_AT_name b + DW_AT_type :$int_type_label + DW_AT_data_bit_offset 8 DW_FORM_udata + DW_AT_bit_size 24 DW_FORM_udata } } struct_t_label: structure_type { - {name t} - {byte_size 4 DW_FORM_sdata} + DW_AT_name t + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name a} - {type :$int_type_label} - {data_member_location 0 DW_FORM_udata} - {bit_size 9 DW_FORM_udata} + DW_AT_name a + DW_AT_type :$int_type_label + DW_AT_data_member_location 0 DW_FORM_udata + DW_AT_bit_size 9 DW_FORM_udata } member { - {name b} - {type :$int_type_label} - {data_bit_offset 9 DW_FORM_udata} - {bit_size 23 DW_FORM_udata} + DW_AT_name b + DW_AT_type :$int_type_label + DW_AT_data_bit_offset 9 DW_FORM_udata + DW_AT_bit_size 23 DW_FORM_udata } } array_a9_label: array_type { - {type :$char_type_label} + DW_AT_type :$char_type_label } { subrange_type { - {type :$int_type_label} - {upper_bound 8 DW_FORM_udata} + DW_AT_type :$int_type_label + DW_AT_upper_bound 8 DW_FORM_udata } } DW_TAG_subprogram { - {MACRO_AT_func {main}} - {DW_AT_external 1 flag} + MACRO_AT_func {main} + DW_AT_external 1 flag } { # Simple variable without location. DW_TAG_variable { - {name undef_int} - {type :$int_type_label} + DW_AT_name undef_int + DW_AT_type :$int_type_label } # Struct variable without location. DW_TAG_variable { - {name undef_s} - {type :$struct_s_label} + DW_AT_name undef_s + DW_AT_type :$struct_s_label } # Composite location: byte-aligned pieces. DW_TAG_variable { - {name def_s} - {type :$struct_s_label} - {location { + DW_AT_name def_s + DW_AT_type :$struct_s_label + DW_AT_location { const1u 0 stack_value bit_piece 8 0 const1s -1 stack_value bit_piece 24 0 - } SPECIAL_expr} + } SPECIAL_expr } # Composite location: non-byte-aligned pieces. DW_TAG_variable { - {name def_t} - {type :$struct_t_label} - {location { + DW_AT_name def_t + DW_AT_type :$struct_t_label + DW_AT_location { const2s -184 stack_value bit_piece 9 0 const4u 1752286 stack_value bit_piece 23 0 - } SPECIAL_expr} + } SPECIAL_expr } # Composite location with some empty pieces. DW_TAG_variable { - {name part_def_a} - {type :$array_a9_label} - {location { + DW_AT_name part_def_a + DW_AT_type :$array_a9_label + DW_AT_location { piece 3 const4u 0xf1927314 stack_value piece 4 piece 2 - } SPECIAL_expr} + } SPECIAL_expr } # Implicit location: immediate value. DW_TAG_variable { - {name def_implicit_s} - {type :$struct_s_label} - {location { + DW_AT_name def_implicit_s + DW_AT_type :$struct_s_label + DW_AT_location { implicit_value 0x12 0x34 0x56 0x78 - } SPECIAL_expr} + } SPECIAL_expr } # Implicit location: immediate value for whole array, with # excess bytes. implicit_a_label: DW_TAG_variable { - {name def_implicit_a} - {type :$array_a9_label} - {location { + DW_AT_name def_implicit_a + DW_AT_type :$array_a9_label + DW_AT_location { implicit_value 0x1 0x12 0x23 0x34 0x45 \ 0x56 0x67 0x78 0x89 0x9a 0xab - } SPECIAL_expr} + } SPECIAL_expr } # Implicit pointer into immediate value. DW_TAG_variable { - {name implicit_a_ptr} - {type :$char_ptr_label} - {location { + DW_AT_name implicit_a_ptr + DW_AT_type :$char_ptr_label + DW_AT_location [subst { implicit_pointer $implicit_a_label 5 - } SPECIAL_expr} + }] SPECIAL_expr } # Stack-value location. stack_b_label: DW_TAG_variable { - {name def_stack_b} - {type :$struct_t_label} - {location { + DW_AT_name def_stack_b + DW_AT_type :$struct_t_label + DW_AT_location { const4u 0x1a2b3c4d stack_value - } SPECIAL_expr} + } SPECIAL_expr } # Implicit pointer into stack value. DW_TAG_variable { - {name implicit_b_ptr} - {type :$char_ptr_label} - {location { + DW_AT_name implicit_b_ptr + DW_AT_type :$char_ptr_label + DW_AT_location [subst { implicit_pointer $stack_b_label 1 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/nostaticblock.exp b/gdb/testsuite/gdb.dwarf2/nostaticblock.exp index 2cc8338..0d5943c 100644 --- a/gdb/testsuite/gdb.dwarf2/nostaticblock.exp +++ b/gdb/testsuite/gdb.dwarf2/nostaticblock.exp @@ -26,8 +26,8 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {low_pc 0x104320 DW_FORM_addr} - {high_pc 0x1045ed DW_FORM_addr} + DW_AT_low_pc 0x104320 DW_FORM_addr + DW_AT_high_pc 0x1045ed DW_FORM_addr } { } } diff --git a/gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp b/gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp index 757212b..b4d275c 100644 --- a/gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp +++ b/gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp @@ -44,37 +44,37 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name opaque_before} + DW_AT_language @DW_LANG_C + DW_AT_name opaque_before } { imported_unit { - {import $partial_unit_with_opaque ref_addr} + DW_AT_import $partial_unit_with_opaque ref_addr } imported_unit { - {import $partial_unit_defining_a ref_addr} + DW_AT_import $partial_unit_defining_a ref_addr } } } cu {} { compile_unit { - {language @DW_LANG_C} - {name opaque_after} + DW_AT_language @DW_LANG_C + DW_AT_name opaque_after } { imported_unit { - {import $partial_unit_defining_b ref_addr} + DW_AT_import $partial_unit_defining_b ref_addr } imported_unit { - {import $partial_unit_with_opaque ref_addr} + DW_AT_import $partial_unit_with_opaque ref_addr } } } cu {} { partial_unit_with_opaque: partial_unit { - {name "partial_unit_with_opaque"} + DW_AT_name "partial_unit_with_opaque" } { # Normally gdb doesn't add opaque types to the symbol table # but there are times when it will, and in order to exercise @@ -82,89 +82,89 @@ Dwarf::assemble $asm_file { # By giving it a size of 1 we achieve this. opaque_struct_a_label: structure_type { - {name struct_a} - {declaration 1 flag} - {byte_size 1 DW_FORM_sdata} + DW_AT_name struct_a + DW_AT_declaration 1 flag + DW_AT_byte_size 1 DW_FORM_sdata } opaque_struct_b_label: structure_type { - {name struct_b} - {declaration 1 flag} - {byte_size 1 DW_FORM_sdata} + DW_AT_name struct_b + DW_AT_declaration 1 flag + DW_AT_byte_size 1 DW_FORM_sdata } DW_TAG_variable { - {name variable_a} - {type :$opaque_struct_a_label} - {external 1 flag} - {declaration 1 flag} + DW_AT_name variable_a + DW_AT_type :$opaque_struct_a_label + DW_AT_external 1 flag + DW_AT_declaration 1 flag } DW_TAG_variable { - {name variable_b} - {type :$opaque_struct_b_label} - {external 1 flag} - {declaration 1 flag} + DW_AT_name variable_b + DW_AT_type :$opaque_struct_b_label + DW_AT_external 1 flag + DW_AT_declaration 1 flag } } } cu {} { partial_unit_defining_a: partial_unit { - {name "partial_unit_defining_a"} + DW_AT_name "partial_unit_defining_a" } { char_type1_label: base_type { - {name "signed char"} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name "signed char" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } struct_a_label: structure_type { - {name struct_a} - {byte_size 1 DW_FORM_sdata} + DW_AT_name struct_a + DW_AT_byte_size 1 DW_FORM_sdata } { member { - {name xyz} - {type :$char_type1_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name xyz + DW_AT_type :$char_type1_label + DW_AT_data_member_location 0 DW_FORM_sdata } } DW_TAG_variable { - {name variable_a} - {type :$struct_a_label} - {external 1 flag} - {linkage_name variable_a} + DW_AT_name variable_a + DW_AT_type :$struct_a_label + DW_AT_external 1 flag + DW_AT_linkage_name variable_a } } } cu {} { partial_unit_defining_b: partial_unit { - {name "partial_unit_defining_b"} + DW_AT_name "partial_unit_defining_b" } { char_type2_label: base_type { - {name "signed char"} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name "signed char" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } struct_b_label: structure_type { - {name struct_b} - {byte_size 1 DW_FORM_sdata} + DW_AT_name struct_b + DW_AT_byte_size 1 DW_FORM_sdata } { member { - {name xyz} - {type :$char_type2_label} - {data_member_location 0 DW_FORM_sdata} + DW_AT_name xyz + DW_AT_type :$char_type2_label + DW_AT_data_member_location 0 DW_FORM_sdata } } DW_TAG_variable { - {name variable_b} - {type :$struct_b_label} - {external 1 flag} - {linkage_name variable_b} + DW_AT_name variable_b + DW_AT_type :$struct_b_label + DW_AT_external 1 flag + DW_AT_linkage_name variable_b } } } @@ -173,11 +173,11 @@ Dwarf::assemble $asm_file { # so keep this separate. cu {} { compile_unit { - {language @DW_LANG_C} - {name main} + DW_AT_language @DW_LANG_C + DW_AT_name main } { subprogram { - {MACRO_AT_func { main }} + MACRO_AT_func { main } } } } diff --git a/gdb/testsuite/gdb.dwarf2/opt-out-not-implptr.exp b/gdb/testsuite/gdb.dwarf2/opt-out-not-implptr.exp index e5334f2..8c60d03 100644 --- a/gdb/testsuite/gdb.dwarf2/opt-out-not-implptr.exp +++ b/gdb/testsuite/gdb.dwarf2/opt-out-not-implptr.exp @@ -30,57 +30,57 @@ Dwarf::assemble $asm_file { declare_labels i64_type i32_type i64_array i32_array i64_type: base_type { - {name "int64_t"} - {encoding @DW_ATE_signed} - {byte_size 8 DW_FORM_sdata} + DW_AT_name "int64_t" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 8 DW_FORM_sdata } i32_type: base_type { - {name "int32_t"} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "int32_t" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } i64_array: DW_TAG_array_type { - {DW_AT_name array_type} - {DW_AT_type :$i64_type} + DW_AT_name array_type + DW_AT_type :$i64_type } { DW_TAG_subrange_type { - {DW_AT_type :$i64_type} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 3 DW_FORM_data1} + DW_AT_type :$i64_type + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 3 DW_FORM_data1 } } i32_array: DW_TAG_array_type { - {DW_AT_name array_type} - {DW_AT_type :$i32_type} + DW_AT_name array_type + DW_AT_type :$i32_type } { DW_TAG_subrange_type { - {DW_AT_type :$i32_type} - {DW_AT_lower_bound 0 DW_FORM_data1} - {DW_AT_upper_bound 3 DW_FORM_data1} + DW_AT_type :$i32_type + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 3 DW_FORM_data1 } } DW_TAG_variable { - {name i64_noptr} - {type :$i64_array} - {location { + DW_AT_name i64_noptr + DW_AT_type :$i64_array + DW_AT_location [subst { DW_OP_constu $::c64 DW_OP_stack_value DW_OP_piece 8 - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {name i32_noptr} - {type :$i32_array} - {location { + DW_AT_name i32_noptr + DW_AT_type :$i32_array + DW_AT_location [subst { DW_OP_constu $::c32 DW_OP_stack_value DW_OP_piece 4 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/pr11465.S b/gdb/testsuite/gdb.dwarf2/pr11465.S index fed98bc..f3f2c57 100644 --- a/gdb/testsuite/gdb.dwarf2/pr11465.S +++ b/gdb/testsuite/gdb.dwarf2/pr11465.S @@ -344,7 +344,11 @@ die149: .uleb128 0x16 /* DW_TAG_variable */ .byte 0x0 .byte 0x0 .byte 0x0 - .section .debug_str +#ifdef __arm__ + .section .debug_str,"MS",%progbits,1 +#else + .section .debug_str,"MS",@progbits,1 +#endif .LASF0: .string "_ZN1N1fE" .LASF7: diff --git a/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp b/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp index 0545b35..d6cb4c1 100644 --- a/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp +++ b/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp @@ -49,14 +49,14 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_ranges 1 DW_FORM_rnglistx} - {DW_AT_rnglists_base cu_table DW_FORM_sec_offset} + DW_AT_ranges 1 DW_FORM_rnglistx + DW_AT_rnglists_base cu_table DW_FORM_sec_offset } { # This tests a DW_AT_ranges attribute of form DW_FORM_rnglistx on a # function, which was buggy at some point. DW_TAG_subprogram { - {DW_AT_name "foo"} - {DW_AT_ranges 2 DW_FORM_rnglistx} + DW_AT_name "foo" + DW_AT_ranges 2 DW_FORM_rnglistx } } } diff --git a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp index 7c65dcd..5b12ae4 100644 --- a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp +++ b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp @@ -43,11 +43,11 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_ranges $cu1_range_list DW_FORM_sec_offset} + DW_AT_ranges $cu1_range_list DW_FORM_sec_offset } { DW_TAG_subprogram { - {DW_AT_name "foo"} - {DW_AT_ranges $foo_range_list DW_FORM_sec_offset} + DW_AT_name "foo" + DW_AT_ranges $foo_range_list DW_FORM_sec_offset } } } @@ -61,12 +61,12 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_ranges $cu2_range_list DW_FORM_sec_offset} - {DW_AT_rnglists_base cu2_table DW_FORM_sec_offset} + DW_AT_ranges $cu2_range_list DW_FORM_sec_offset + DW_AT_rnglists_base cu2_table DW_FORM_sec_offset } { DW_TAG_subprogram { - {DW_AT_name "bar"} - {DW_AT_ranges $bar_range_list DW_FORM_sec_offset} + DW_AT_name "bar" + DW_AT_ranges $bar_range_list DW_FORM_sec_offset } } } @@ -79,11 +79,11 @@ foreach_with_prefix is_64 {false true} { is_64 $is_64 } { DW_TAG_compile_unit { - {DW_AT_ranges $cu3_range_list DW_FORM_sec_offset} + DW_AT_ranges $cu3_range_list DW_FORM_sec_offset } { DW_TAG_subprogram { - {DW_AT_name "baz"} - {DW_AT_ranges $baz_range_list DW_FORM_sec_offset} + DW_AT_name "baz" + DW_AT_ranges $baz_range_list DW_FORM_sec_offset } } } diff --git a/gdb/testsuite/gdb.dwarf2/rust-enum.exp b/gdb/testsuite/gdb.dwarf2/rust-enum.exp index 89d4a16..87e710e 100644 --- a/gdb/testsuite/gdb.dwarf2/rust-enum.exp +++ b/gdb/testsuite/gdb.dwarf2/rust-enum.exp @@ -30,64 +30,64 @@ Dwarf::assemble $asm_file { cu { addr_size 4 } { compile_unit { - {name file1.txt} - {language @DW_LANG_Rust} + DW_AT_name file1.txt + DW_AT_language @DW_LANG_Rust } { uinteger_label: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name {unsigned integer}} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name {unsigned integer} } one_label: structure_type { - {name One} - {byte_size 1 DW_FORM_sdata} + DW_AT_name One + DW_AT_byte_size 1 DW_FORM_sdata } { member { - {name __0} - {type :$uinteger_label} - {data_member_location 0 data1} + DW_AT_name __0 + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 } } two_label: structure_type { - {name Two} - {byte_size 1 DW_FORM_sdata} + DW_AT_name Two + DW_AT_byte_size 1 DW_FORM_sdata } { member { - {name __0} - {type :$uinteger_label} - {data_member_location 0 data1} + DW_AT_name __0 + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 } } simple_label: structure_type { - {name Simple} - {byte_size 2 DW_FORM_sdata} + DW_AT_name Simple + DW_AT_byte_size 2 DW_FORM_sdata } { variant_part { - {discr :$discr_1_label DW_FORM_ref4} + DW_AT_discr :$discr_1_label DW_FORM_ref4 } { discr_1_label: member { - {type :$uinteger_label} - {data_member_location 0 data1} - {artificial 1 DW_FORM_flag_present} + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 + DW_AT_artificial 1 DW_FORM_flag_present } variant { - {discr_value 65 udata} + DW_AT_discr_value 65 udata } { member { - {type :$one_label} - {data_member_location 1 data1} + DW_AT_type :$one_label + DW_AT_data_member_location 1 data1 } } variant { } { member { - {type :$two_label} - {data_member_location 1 data1} + DW_AT_type :$two_label + DW_AT_data_member_location 1 data1 } } } @@ -96,14 +96,14 @@ Dwarf::assemble $asm_file { # In PR rust/31005, a constant Rust enum value could not # be correctly resolved. DW_TAG_variable { - {name constant_variable} - {const_value 0x4141 udata} - {type :$simple_label} + DW_AT_name constant_variable + DW_AT_const_value 0x4141 udata + DW_AT_type :$simple_label } DW_TAG_variable { - {name constant_variable2} - {const_value "AA" DW_FORM_block1} - {type :$simple_label} + DW_AT_name constant_variable2 + DW_AT_const_value "AA" DW_FORM_block1 + DW_AT_type :$simple_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/self-spec.exp b/gdb/testsuite/gdb.dwarf2/self-spec.exp index 2136623..3d6c853 100644 --- a/gdb/testsuite/gdb.dwarf2/self-spec.exp +++ b/gdb/testsuite/gdb.dwarf2/self-spec.exp @@ -26,12 +26,14 @@ standard_testfile main.c .S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C_plus_plus}} { + compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { # Check handling of self-referencing DIE. declare_labels c1 c1: class_type { - {name class1} - {specification :$c1} + DW_AT_name class1 + DW_AT_specification :$c1 } # Check handling of self-referencing child DIE. Regression test @@ -39,11 +41,11 @@ Dwarf::assemble $asm_file { declare_labels f1 abstract_f1 f1_l abstract_f1: subprogram {} f1: subprogram { - {MACRO_AT_func {main}} - {abstract_origin :$abstract_f1} + MACRO_AT_func {main} + DW_AT_abstract_origin :$abstract_f1 } { f1_l: label { - {abstract_origin :$f1_l} + DW_AT_abstract_origin :$f1_l } } } diff --git a/gdb/testsuite/gdb.dwarf2/short-build-id.exp b/gdb/testsuite/gdb.dwarf2/short-build-id.exp index 51c6cef..439b2b2 100644 --- a/gdb/testsuite/gdb.dwarf2/short-build-id.exp +++ b/gdb/testsuite/gdb.dwarf2/short-build-id.exp @@ -50,17 +50,19 @@ proc run_test { buildid } { build_id $buildid cu { label cu_start } { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { int_label2: base_type { - {name int} - {byte_size 4 sdata} - {encoding @DW_ATE_signed} + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed } constant { - {name the_int} - {type :$int_label2} - {const_value 99 data1} + DW_AT_name the_int + DW_AT_type :$int_label2 + DW_AT_const_value 99 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/shortpiece.exp b/gdb/testsuite/gdb.dwarf2/shortpiece.exp index c9bf490..64d5b55 100644 --- a/gdb/testsuite/gdb.dwarf2/shortpiece.exp +++ b/gdb/testsuite/gdb.dwarf2/shortpiece.exp @@ -30,90 +30,90 @@ Dwarf::assemble $asm_file { declare_labels int_label ushort_label struct_label struct_label_2 int_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_udata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name "myint"} + DW_AT_byte_size 4 DW_FORM_udata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "myint" } ushort_label: DW_TAG_base_type { - {DW_AT_byte_size 2 DW_FORM_udata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name "myushort"} + DW_AT_byte_size 2 DW_FORM_udata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name "myushort" } struct_label: DW_TAG_structure_type { - {DW_AT_name "S"} - {DW_AT_byte_size 8 DW_FORM_udata} + DW_AT_name "S" + DW_AT_byte_size 8 DW_FORM_udata } { DW_TAG_member { - {DW_AT_name "a"} - {DW_AT_type :${int_label}} - {DW_AT_data_member_location 0 DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :${int_label} + DW_AT_data_member_location 0 DW_FORM_udata } DW_TAG_member { - {DW_AT_name "b"} - {DW_AT_type :${ushort_label}} - {DW_AT_data_member_location 4 DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :${ushort_label} + DW_AT_data_member_location 4 DW_FORM_udata } } struct_label_2: DW_TAG_structure_type { - {DW_AT_name "S_2"} - {DW_AT_byte_size 6 DW_FORM_udata} + DW_AT_name "S_2" + DW_AT_byte_size 6 DW_FORM_udata } { DW_TAG_member { - {DW_AT_name "a"} - {DW_AT_type :${int_label}} - {DW_AT_data_member_location 0 DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :${int_label} + DW_AT_data_member_location 0 DW_FORM_udata } DW_TAG_member { - {DW_AT_name "b"} - {DW_AT_type :${ushort_label}} - {DW_AT_data_member_location 4 DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :${ushort_label} + DW_AT_data_member_location 4 DW_FORM_udata } } DW_TAG_variable { - {DW_AT_name "s1"} - {DW_AT_type :${struct_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location { + DW_AT_name "s1" + DW_AT_type :${struct_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location { DW_OP_constu 1 DW_OP_stack_value DW_OP_piece 4 DW_OP_constu 0 DW_OP_stack_value DW_OP_piece 2 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "s2"} - {DW_AT_type :${struct_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location { + DW_AT_name "s2" + DW_AT_type :${struct_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location { DW_OP_constu 1 DW_OP_stack_value DW_OP_piece 4 DW_OP_constu 0 DW_OP_stack_value DW_OP_piece 8 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "s3"} - {DW_AT_type :${struct_label_2}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location { + DW_AT_name "s3" + DW_AT_type :${struct_label_2} + DW_AT_external 1 DW_FORM_flag + DW_AT_location { DW_OP_constu 0 DW_OP_stack_value DW_OP_piece 4 DW_OP_constu 1 DW_OP_stack_value DW_OP_piece 2 - } SPECIAL_expr} + } SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp b/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp index 6be8283..8b139fa 100644 --- a/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp +++ b/gdb/testsuite/gdb.dwarf2/static-optimized-out.exp @@ -28,21 +28,19 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - { - language @DW_LANG_C - } + DW_AT_language @DW_LANG_C } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_variable { - {name var} - {type :$integer_label} + DW_AT_name var + DW_AT_type :$integer_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/staticvirtual.exp b/gdb/testsuite/gdb.dwarf2/staticvirtual.exp index e04c500..9fa1a2b 100644 --- a/gdb/testsuite/gdb.dwarf2/staticvirtual.exp +++ b/gdb/testsuite/gdb.dwarf2/staticvirtual.exp @@ -25,18 +25,20 @@ standard_testfile main.c -dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C_plus_plus}} { + compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { structure_type { - {name S} - {byte_size 1 DW_FORM_sdata} + DW_AT_name S + DW_AT_byte_size 1 DW_FORM_sdata } { subprogram { - {low_pc 0x1000 addr} - {high_pc 0x2000 addr} - {name ~S} - {external 1 flag} - {virtuality @DW_VIRTUALITY_virtual} - {vtable_elem_location {const1u 1} SPECIAL_expr} + DW_AT_low_pc 0x1000 addr + DW_AT_high_pc 0x2000 addr + DW_AT_name ~S + DW_AT_external 1 flag + DW_AT_virtuality @DW_VIRTUALITY_virtual + DW_AT_vtable_elem_location {const1u 1} SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/struct-decl.exp b/gdb/testsuite/gdb.dwarf2/struct-decl.exp index e389216..bc857a7 100644 --- a/gdb/testsuite/gdb.dwarf2/struct-decl.exp +++ b/gdb/testsuite/gdb.dwarf2/struct-decl.exp @@ -30,9 +30,9 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C_plus_plus + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels origin @@ -42,14 +42,14 @@ Dwarf::assemble $asm_file { # which meant that if a method referred back to them via a # specification, it would get the wrong name. DW_TAG_structure_type { - {DW_AT_byte_size 8 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name the_type} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_byte_size 8 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name the_type + DW_AT_declaration 1 DW_FORM_flag_present } { origin: DW_TAG_subprogram { - {DW_AT_name "method"} - {DW_AT_declaration 1 DW_FORM_flag_present} + DW_AT_name "method" + DW_AT_declaration 1 DW_FORM_flag_present } } @@ -57,8 +57,8 @@ Dwarf::assemble $asm_file { # range that is valid in the program, so we use the main # function's range. DW_TAG_subprogram { - {DW_AT_specification :$origin} - {MACRO_AT_range main} + DW_AT_specification :$origin + MACRO_AT_range main } } } diff --git a/gdb/testsuite/gdb.dwarf2/struct-with-sig-2.exp b/gdb/testsuite/gdb.dwarf2/struct-with-sig-2.exp index 02a492d..a527263 100644 --- a/gdb/testsuite/gdb.dwarf2/struct-with-sig-2.exp +++ b/gdb/testsuite/gdb.dwarf2/struct-with-sig-2.exp @@ -34,18 +34,18 @@ Dwarf::assemble $asm_file { declare_labels int_type the_type_i: structure_type { - {name s} - {byte_size 4 sdata} + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - {name i} - {type :$int_type} + DW_AT_name i + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } @@ -55,18 +55,18 @@ Dwarf::assemble $asm_file { declare_labels int_type the_type_j: structure_type { - {name s} - {byte_size 4 sdata} + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - {name j} - {type :$int_type} + DW_AT_name j + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } @@ -88,32 +88,32 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name main.c} + DW_AT_language @DW_LANG_C + DW_AT_name main.c } { structure_type { - {name s} - {signature 0x0000000000000001 ref_sig8} - {declaration 1 flag} + DW_AT_name s + DW_AT_signature 0x0000000000000001 ref_sig8 + DW_AT_declaration 1 flag } DW_TAG_subprogram { - {MACRO_AT_func {main}} + MACRO_AT_func {main} } } } cu {} { compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name foo.c} + DW_AT_language @DW_LANG_C + DW_AT_name foo.c } { structure_type { - {name s} - {signature 0x0000000000000002 ref_sig8} - {declaration 1 flag} + DW_AT_name s + DW_AT_signature 0x0000000000000002 ref_sig8 + DW_AT_declaration 1 flag } DW_TAG_subprogram { - {MACRO_AT_func {foo}} + MACRO_AT_func {foo} } } } diff --git a/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp b/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp index 9861327..7e15999 100644 --- a/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp +++ b/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp @@ -24,32 +24,32 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name main.c} + DW_AT_language @DW_LANG_C + DW_AT_name main.c } { structure_type { - {name s} - {signature 0x0000000000000001 ref_sig8} - {declaration 1 flag} + DW_AT_name s + DW_AT_signature 0x0000000000000001 ref_sig8 + DW_AT_declaration 1 flag } DW_TAG_subprogram { - {MACRO_AT_func {main}} + MACRO_AT_func {main} } } } cu {} { compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name foo.c} + DW_AT_language @DW_LANG_C + DW_AT_name foo.c } { structure_type { - {name s} - {signature 0x0000000000000002 ref_sig8} - {declaration 1 flag} + DW_AT_name s + DW_AT_signature 0x0000000000000002 ref_sig8 + DW_AT_declaration 1 flag } DW_TAG_subprogram { - {MACRO_AT_func {foo}} + MACRO_AT_func {foo} } } } @@ -59,18 +59,18 @@ Dwarf::assemble $asm_file { declare_labels int_type the_type_i: structure_type { - {name s} - {byte_size 4 sdata} + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - {name i} - {type :$int_type} + DW_AT_name i + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } @@ -80,18 +80,18 @@ Dwarf::assemble $asm_file { declare_labels int_type the_type_j: structure_type { - {name s} - {byte_size 4 sdata} + DW_AT_name s + DW_AT_byte_size 4 sdata } { member { - {name j} - {type :$int_type} + DW_AT_name j + DW_AT_type :$int_type } } int_type: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/subrange-enum.exp b/gdb/testsuite/gdb.dwarf2/subrange-enum.exp index 9df5774..339cb49 100644 --- a/gdb/testsuite/gdb.dwarf2/subrange-enum.exp +++ b/gdb/testsuite/gdb.dwarf2/subrange-enum.exp @@ -26,43 +26,45 @@ standard_testfile main.c -dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { declare_labels integer_label enum_label subrange_label - integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} - } + integer_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer + } enum_label: DW_TAG_enumeration_type { - {DW_AT_name E} - {DW_AT_type :$integer_label} + DW_AT_name E + DW_AT_type :$integer_label } { DW_TAG_enumerator { - {DW_AT_name ONE} - {DW_AT_const_value 1 DW_FORM_sdata} + DW_AT_name ONE + DW_AT_const_value 1 DW_FORM_sdata } DW_TAG_enumerator { - {DW_AT_name TWO} - {DW_AT_const_value 2 DW_FORM_sdata} + DW_AT_name TWO + DW_AT_const_value 2 DW_FORM_sdata } DW_TAG_enumerator { - {DW_AT_name THREE} - {DW_AT_const_value 3 DW_FORM_sdata} + DW_AT_name THREE + DW_AT_const_value 3 DW_FORM_sdata } } subrange_label: DW_TAG_subrange_type { - {lower_bound 1 DW_FORM_sdata} - {upper_bound 2 DW_FORM_sdata} - {type :$enum_label} + DW_AT_lower_bound 1 DW_FORM_sdata + DW_AT_upper_bound 2 DW_FORM_sdata + DW_AT_type :$enum_label } DW_TAG_variable { - {name rangeval} - {type :$subrange_label} - {const_value 2 DW_FORM_udata} + DW_AT_name rangeval + DW_AT_type :$subrange_label + DW_AT_const_value 2 DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/subrange.exp b/gdb/testsuite/gdb.dwarf2/subrange.exp index 2cc7472..3e0326f 100644 --- a/gdb/testsuite/gdb.dwarf2/subrange.exp +++ b/gdb/testsuite/gdb.dwarf2/subrange.exp @@ -25,35 +25,37 @@ standard_testfile method-ptr.cc -dw.S set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { - compile_unit {{language @DW_LANG_Pascal83}} { + compile_unit { + DW_AT_language @DW_LANG_Pascal83 + } { declare_labels byte_label typedef_label array_label # A subrange's underlying type that is a typedef. byte_label: base_type { - {name byte} - {encoding @DW_ATE_unsigned} - {byte_size 1 DW_FORM_sdata} + DW_AT_name byte + DW_AT_encoding @DW_ATE_unsigned + DW_AT_byte_size 1 DW_FORM_sdata } typedef_label: typedef { - {name byte_typedef} - {type :$byte_label} + DW_AT_name byte_typedef + DW_AT_type :$byte_label } array_label: array_type { - {type :$byte_label} + DW_AT_type :$byte_label } { subrange_type { - {lower_bound 0 DW_FORM_sdata} - {upper_bound 191 DW_FORM_sdata} - {byte_stride 2 DW_FORM_sdata} - {type :$typedef_label} + DW_AT_lower_bound 0 DW_FORM_sdata + DW_AT_upper_bound 191 DW_FORM_sdata + DW_AT_byte_stride 2 DW_FORM_sdata + DW_AT_type :$typedef_label } } typedef { - {name TByteArray} - {type :$array_label} + DW_AT_name TByteArray + DW_AT_type :$array_label } # This subrange's underlying type is signed, but the bounds are @@ -61,21 +63,21 @@ Dwarf::assemble $asm_file { declare_labels signed_byte_label subrange_with_buggy_negative_bounds_label signed_byte_label: base_type { - {name signed_byte} - {encoding @DW_ATE_signed} - {byte_size 1 DW_FORM_sdata} + DW_AT_name signed_byte + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 1 DW_FORM_sdata } # The bounds mean -16 to -12. subrange_with_buggy_negative_bounds_label: subrange_type { - {lower_bound 0xf0 DW_FORM_udata} - {upper_bound 0xf4 DW_FORM_udata} - {type :$signed_byte_label} + DW_AT_lower_bound 0xf0 DW_FORM_udata + DW_AT_upper_bound 0xf4 DW_FORM_udata + DW_AT_type :$signed_byte_label } DW_TAG_variable { - {name subrange_with_buggy_negative_bounds_variable} - {type :$subrange_with_buggy_negative_bounds_label} + DW_AT_name subrange_with_buggy_negative_bounds_variable + DW_AT_type :$subrange_with_buggy_negative_bounds_label } # This subrange's base type is 16-bytes long (although the bounds fit in @@ -83,19 +85,19 @@ Dwarf::assemble $asm_file { declare_labels a_16_byte_integer_label a_16_byte_subrange_label a_16_byte_integer_label: base_type { - {byte_size 16 udata} - {encoding @DW_ATE_signed} + DW_AT_byte_size 16 udata + DW_AT_encoding @DW_ATE_signed } a_16_byte_subrange_label: subrange_type { - {lower_bound -9223372036854775808 DW_FORM_sdata} - {upper_bound 9223372036854775807 DW_FORM_sdata} - {type :$a_16_byte_integer_label} + DW_AT_lower_bound -9223372036854775808 DW_FORM_sdata + DW_AT_upper_bound 9223372036854775807 DW_FORM_sdata + DW_AT_type :$a_16_byte_integer_label } DW_TAG_variable { - {name a_16_byte_subrange_variable} - {type :$a_16_byte_subrange_label} + DW_AT_name a_16_byte_subrange_variable + DW_AT_type :$a_16_byte_subrange_label } } } diff --git a/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_fail.exp b/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_fail.exp index e69d9b4..6efd458 100644 --- a/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_fail.exp +++ b/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_fail.exp @@ -63,23 +63,23 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name symbol_needs_eval.c} - {DW_AT_comp_dir /tmp} + DW_AT_name symbol_needs_eval.c + DW_AT_comp_dir /tmp } { declare_labels int_type_label # define int type int_type_label: DW_TAG_base_type { - {DW_AT_name "int"} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_byte_size $int_size DW_FORM_sdata} + DW_AT_name "int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size $int_size DW_FORM_sdata } # define artificial variable a DW_TAG_variable { - {DW_AT_name a} - {DW_AT_type :$int_type_label} - {DW_AT_location { + DW_AT_name a + DW_AT_type :$int_type_label + DW_AT_location [subst { DW_OP_addr $exec_mask_var DW_OP_deref_size $int_size @@ -91,8 +91,8 @@ Dwarf::assemble $asm_file { DW_OP_skip 3 DW_OP_bregx $dwarf_regnum 0 DW_OP_stack_value - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_timeout.exp b/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_timeout.exp index a6773d5..61a40eb 100644 --- a/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_timeout.exp +++ b/gdb/testsuite/gdb.dwarf2/symbol_needs_eval_timeout.exp @@ -63,40 +63,40 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name symbol_needs_eval.c} - {DW_AT_comp_dir /tmp} + DW_AT_name symbol_needs_eval.c + DW_AT_comp_dir /tmp } { declare_labels int_type_label # define int type int_type_label: DW_TAG_base_type { - {DW_AT_name "int"} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_byte_size $int_size DW_FORM_sdata} + DW_AT_name "int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size $int_size DW_FORM_sdata } # add info for variable exec_mask DW_TAG_variable { - {DW_AT_name exec_mask} - {DW_AT_type :$int_type_label} - {DW_AT_location { + DW_AT_name exec_mask + DW_AT_type :$int_type_label + DW_AT_location [subst { DW_OP_addr $exec_mask_var - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } # add info for subprogram main DW_TAG_subprogram { - {MACRO_AT_func { main }} - {DW_AT_frame_base { + MACRO_AT_func { main } + DW_AT_frame_base [subst { DW_OP_regx $dwarf_regnum - } SPECIAL_expr} + }] SPECIAL_expr } { # define artificial variable a DW_TAG_variable { - {DW_AT_name a} - {DW_AT_type :$int_type_label} - {DW_AT_location { + DW_AT_name a + DW_AT_type :$int_type_label + DW_AT_location [subst { DW_OP_lit1 DW_OP_addr $exec_mask_var DW_OP_deref_size $int_size @@ -112,8 +112,8 @@ Dwarf::assemble $asm_file { # conditional jump to DW_OP_drop DW_OP_bra -9 DW_OP_stack_value - } SPECIAL_expr} - {external 1 flag} + }] SPECIAL_expr + DW_AT_external 1 flag } } } diff --git a/gdb/testsuite/gdb.dwarf2/symtab-producer.exp b/gdb/testsuite/gdb.dwarf2/symtab-producer.exp index 1734a77..2826ba7 100644 --- a/gdb/testsuite/gdb.dwarf2/symtab-producer.exp +++ b/gdb/testsuite/gdb.dwarf2/symtab-producer.exp @@ -26,46 +26,46 @@ set asm_file [standard_output_file $srcfile2] Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "ACME Compiler Company"} - {DW_AT_language @DW_LANG_C} - {DW_AT_name symtab-producer-dw.c} - {DW_AT_comp_dir /tmp} + DW_AT_producer "ACME Compiler Company" + DW_AT_language @DW_LANG_C + DW_AT_name symtab-producer-dw.c + DW_AT_comp_dir /tmp } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_variable { - {DW_AT_name with_producer} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_const_value 42 DW_FORM_sdata} + DW_AT_name with_producer + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_const_value 42 DW_FORM_sdata } } } cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C} - {DW_AT_name symtab-producer2-dw.c} - {DW_AT_comp_dir /tmp} + DW_AT_language @DW_LANG_C + DW_AT_name symtab-producer2-dw.c + DW_AT_comp_dir /tmp } { declare_labels integer_label integer_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name integer} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name integer } DW_TAG_variable { - {DW_AT_name without_producer} - {DW_AT_type :$integer_label} - {DW_AT_external 1 flag} - {DW_AT_const_value 43 DW_FORM_sdata} + DW_AT_name without_producer + DW_AT_type :$integer_label + DW_AT_external 1 flag + DW_AT_const_value 43 DW_FORM_sdata } } } diff --git a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp index 60b49a5..52d9b32 100644 --- a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp +++ b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp @@ -35,19 +35,19 @@ Dwarf::assemble $asm_file { cu { label cu_start } { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels templated_subprogram int int: DW_TAG_base_type { - {DW_AT_name "int"} - {DW_AT_byte_size 4 DW_FORM_data1} - {DW_AT_encoding @DW_ATE_signed} + DW_AT_name "int" + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed } # The templated subprogram. templated_subprogram: DW_TAG_subprogram { - {DW_AT_name "apply"} + DW_AT_name "apply" } # The template specialization. @@ -55,12 +55,12 @@ Dwarf::assemble $asm_file { # The low and high PC are phony: we just need an address range that # is valid in the program, so we use the main function's range. DW_TAG_subprogram { - {DW_AT_specification :$templated_subprogram} - {MACRO_AT_range main} + DW_AT_specification :$templated_subprogram + MACRO_AT_range main } { DW_TAG_template_type_param { - {DW_AT_name "T"} - {DW_AT_type :$int DW_FORM_ref4} + DW_AT_name "T" + DW_AT_type :$int DW_FORM_ref4 } } } diff --git a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp index 1135709..b80ce97 100644 --- a/gdb/testsuite/gdb.dwarf2/typeddwarf.exp +++ b/gdb/testsuite/gdb.dwarf2/typeddwarf.exp @@ -78,7 +78,7 @@ proc scan_gdb_tests {} { continue } - eval $test_cmd + {*}$test_cmd } close $fd } diff --git a/gdb/testsuite/gdb.dwarf2/typedef-void-finish.exp b/gdb/testsuite/gdb.dwarf2/typedef-void-finish.exp index e59286d..a96c1ac 100644 --- a/gdb/testsuite/gdb.dwarf2/typedef-void-finish.exp +++ b/gdb/testsuite/gdb.dwarf2/typedef-void-finish.exp @@ -31,29 +31,29 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "GNU C 8.1"} - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_producer "GNU C 8.1" + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels main_type void_typedef main_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed } void_typedef: DW_TAG_typedef { - {name foo} + DW_AT_name foo } - DW_TAG_subprogram { - {MACRO_AT_func {func}} - {type :$void_typedef} + DW_TAG_subprogram { + MACRO_AT_func {func} + DW_AT_type :$void_typedef } - DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$main_type} + DW_TAG_subprogram { + MACRO_AT_func {main} + DW_AT_type :$main_type } } } diff --git a/gdb/testsuite/gdb.dwarf2/utf-rust.exp b/gdb/testsuite/gdb.dwarf2/utf-rust.exp index 3380f8d..9ab9bf5 100644 --- a/gdb/testsuite/gdb.dwarf2/utf-rust.exp +++ b/gdb/testsuite/gdb.dwarf2/utf-rust.exp @@ -34,19 +34,19 @@ Dwarf::assemble $asm_file { # both 32- and 64-bit machines. cu { addr_size 4 } { compile_unit { - {name file1.txt} - {language @DW_LANG_Rust} + DW_AT_name file1.txt + DW_AT_language @DW_LANG_Rust } { - char_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_UTF} - {DW_AT_name char} - } + char_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_UTF + DW_AT_name char + } DW_TAG_variable { - {name cvalue} - {type :$char_label} - {const_value 97 DW_FORM_udata} + DW_AT_name cvalue + DW_AT_type :$char_label + DW_AT_const_value 97 DW_FORM_udata } } } diff --git a/gdb/testsuite/gdb.dwarf2/var-access.exp b/gdb/testsuite/gdb.dwarf2/var-access.exp index 347d276..6889cc2 100644 --- a/gdb/testsuite/gdb.dwarf2/var-access.exp +++ b/gdb/testsuite/gdb.dwarf2/var-access.exp @@ -54,8 +54,8 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} + DW_AT_name $srcfile + DW_AT_comp_dir /tmp } { declare_labels char_type_label declare_labels int_type_label short_type_label @@ -64,131 +64,131 @@ Dwarf::assemble $asm_file { # char char_type_label: base_type { - {name "char"} - {encoding @DW_ATE_unsigned_char} - {byte_size 1 DW_FORM_sdata} + DW_AT_name "char" + DW_AT_encoding @DW_ATE_unsigned_char + DW_AT_byte_size 1 DW_FORM_sdata } # int int_type_label: base_type { - {name "int"} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "int" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } # char [8] array_a8_label: array_type { - {type :$char_type_label} + DW_AT_type :$char_type_label } { subrange_type { - {type :$int_type_label} - {upper_bound 7 DW_FORM_udata} + DW_AT_type :$int_type_label + DW_AT_upper_bound 7 DW_FORM_udata } } # struct s { char a, b, c, d; }; struct_s_label: structure_type { - {name "s"} - {byte_size 4 DW_FORM_sdata} + DW_AT_name "s" + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name "a"} - {type :$char_type_label} - {data_member_location 0 DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :$char_type_label + DW_AT_data_member_location 0 DW_FORM_udata } member { - {name "b"} - {type :$char_type_label} - {data_member_location 1 DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :$char_type_label + DW_AT_data_member_location 1 DW_FORM_udata } member { - {name "c"} - {type :$char_type_label} - {data_member_location 2 DW_FORM_udata} + DW_AT_name "c" + DW_AT_type :$char_type_label + DW_AT_data_member_location 2 DW_FORM_udata } member { - {name "d"} - {type :$char_type_label} - {data_member_location 3 DW_FORM_udata} + DW_AT_name "d" + DW_AT_type :$char_type_label + DW_AT_data_member_location 3 DW_FORM_udata } } # struct t { int u, x:9, y:13, z:10; }; struct_t_label: structure_type { - {name "t"} - {byte_size 8 DW_FORM_sdata} + DW_AT_name "t" + DW_AT_byte_size 8 DW_FORM_sdata } { member { - {name "u"} - {type :$int_type_label} + DW_AT_name "u" + DW_AT_type :$int_type_label } member { - {name "x"} - {type :$int_type_label} - {data_member_location 4 DW_FORM_udata} - {bit_size 9 DW_FORM_udata} + DW_AT_name "x" + DW_AT_type :$int_type_label + DW_AT_data_member_location 4 DW_FORM_udata + DW_AT_bit_size 9 DW_FORM_udata } member { - {name "y"} - {type :$int_type_label} - {data_bit_offset 41 DW_FORM_udata} - {bit_size 13 DW_FORM_udata} + DW_AT_name "y" + DW_AT_type :$int_type_label + DW_AT_data_bit_offset 41 DW_FORM_udata + DW_AT_bit_size 13 DW_FORM_udata } member { - {name "z"} - {type :$int_type_label} - {data_bit_offset 54 DW_FORM_udata} - {bit_size 10 DW_FORM_udata} + DW_AT_name "z" + DW_AT_type :$int_type_label + DW_AT_data_bit_offset 54 DW_FORM_udata + DW_AT_bit_size 10 DW_FORM_udata } } # struct st { struct s s; struct t t; }; struct_st_label: structure_type { - {name "st"} - {byte_size 12 DW_FORM_udata} + DW_AT_name "st" + DW_AT_byte_size 12 DW_FORM_udata } { member { - {name "s"} - {type :$struct_s_label} + DW_AT_name "s" + DW_AT_type :$struct_s_label } member { - {name "t"} - {type :$struct_t_label} - {data_member_location 4 DW_FORM_udata} + DW_AT_name "t" + DW_AT_type :$struct_t_label + DW_AT_data_member_location 4 DW_FORM_udata } } DW_TAG_subprogram { - {MACRO_AT_func { main }} - {DW_AT_external 1 flag} + MACRO_AT_func { main } + DW_AT_external 1 flag } { # Simple memory location. DW_TAG_variable { - {name "a"} - {type :$array_a8_label} - {location { + DW_AT_name "a" + DW_AT_type :$array_a8_label + DW_AT_location [subst { addr $buf_var - } SPECIAL_expr} + }] SPECIAL_expr } # Memory pieces: two bytes from &buf[2], and two bytes # from &buf[0]. DW_TAG_variable { - {name "s1"} - {type :$struct_s_label} - {location { + DW_AT_name "s1" + DW_AT_type :$struct_s_label + DW_AT_location [subst { addr $buf_var plus_uconst 2 piece 2 addr $buf_var piece 2 - } SPECIAL_expr} + }] SPECIAL_expr } # Register- and memory pieces: one byte each from r0, # &buf[4], r1, and &buf[5]. DW_TAG_variable { - {name "s2"} - {type :$struct_s_label} - {location { + DW_AT_name "s2" + DW_AT_type :$struct_s_label + DW_AT_location [subst { regx [lindex $dwarf_regnum 0] piece 1 addr "$buf_var + 4" @@ -197,41 +197,41 @@ Dwarf::assemble $asm_file { piece 1 addr "$buf_var + 5" piece 1 - } SPECIAL_expr} + }] SPECIAL_expr } # Memory pieces for bitfield access: 8 bytes optimized # out, 3 bytes from &buf[3], and 1 byte from &buf[1]. DW_TAG_variable { - {name "st1"} - {type :$struct_st_label} - {location { + DW_AT_name "st1" + DW_AT_type :$struct_st_label + DW_AT_location [subst { piece 8 addr "$buf_var + 3" piece 3 addr "$buf_var + 1" piece 1 - } SPECIAL_expr} + }] SPECIAL_expr } # Register pieces for bitfield access: 4 bytes optimized # out, 3 bytes from r0, and 1 byte from r1. DW_TAG_variable { - {name "t2"} - {type :$struct_t_label} - {location { + DW_AT_name "t2" + DW_AT_type :$struct_t_label + DW_AT_location [subst { piece 4 regx [lindex $dwarf_regnum 0] piece 3 regx [lindex $dwarf_regnum 1] piece 1 - } SPECIAL_expr} + }] SPECIAL_expr } # One piece per bitfield, using piece offsets: 32 bits of # an implicit value, 9 bits of a stack value, 13 bits of # r0, and 10 bits of buf. DW_TAG_variable { - {name "t3"} - {type :$struct_t_label} - {location { + DW_AT_name "t3" + DW_AT_type :$struct_t_label + DW_AT_location [subst { implicit_value 0x12 0x34 0x56 0x78 0x9a bit_piece 32 4 const2s -280 @@ -241,7 +241,7 @@ Dwarf::assemble $asm_file { bit_piece 13 14 addr $buf_var bit_piece 10 42 - } SPECIAL_expr} + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.dwarf2/variant.exp b/gdb/testsuite/gdb.dwarf2/variant.exp index ce504f2..93abcbd 100644 --- a/gdb/testsuite/gdb.dwarf2/variant.exp +++ b/gdb/testsuite/gdb.dwarf2/variant.exp @@ -36,125 +36,125 @@ Dwarf::assemble $asm_file { # both 32- and 64-bit machines. cu { addr_size 4 } { compile_unit { - {name file1.txt} - {language @DW_LANG_Rust} + DW_AT_name file1.txt + DW_AT_language @DW_LANG_Rust } { - uinteger_label: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_unsigned} - {DW_AT_name {unsigned integer}} - } - - int8_label: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name i8} - } + uinteger_label: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned + DW_AT_name {unsigned integer} + } + + int8_label: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name i8 + } float_label: base_type { - {name float} - {encoding @DW_ATE_float} - {byte_size 4 DW_FORM_sdata} + DW_AT_name float + DW_AT_encoding @DW_ATE_float + DW_AT_byte_size 4 DW_FORM_sdata } one_label: structure_type { - {name One} - {byte_size 4 DW_FORM_sdata} + DW_AT_name One + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name __0} - {type :$uinteger_label} - {data_member_location 0 data1} + DW_AT_name __0 + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 } } two_label: structure_type { - {name Two} - {byte_size 4 DW_FORM_sdata} + DW_AT_name Two + DW_AT_byte_size 4 DW_FORM_sdata } { member { - {name __0} - {type :$float_label} - {data_member_location 0 data1} + DW_AT_name __0 + DW_AT_type :$float_label + DW_AT_data_member_location 0 data1 } } structure_type { - {name Simple} - {byte_size 8 DW_FORM_sdata} + DW_AT_name Simple + DW_AT_byte_size 8 DW_FORM_sdata } { variant_part { - {discr :$discr_1_label DW_FORM_ref4} + DW_AT_discr :$discr_1_label DW_FORM_ref4 } { discr_1_label: member { - {type :$uinteger_label} - {data_member_location 0 data1} - {artificial 1 DW_FORM_flag_present} + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 + DW_AT_artificial 1 DW_FORM_flag_present } variant { - {discr_value 23 udata} + DW_AT_discr_value 23 udata } { member { - {type :$one_label} - {data_member_location 4 data1} + DW_AT_type :$one_label + DW_AT_data_member_location 4 data1 } } variant { - {discr_value 1 udata} + DW_AT_discr_value 1 udata } { member { - {type :$two_label} - {data_member_location 4 data1} + DW_AT_type :$two_label + DW_AT_data_member_location 4 data1 } } } } structure_type { - {name Defaulted} - {byte_size 8 DW_FORM_sdata} + DW_AT_name Defaulted + DW_AT_byte_size 8 DW_FORM_sdata } { variant_part { - {discr :$discr_2_label DW_FORM_ref4} + DW_AT_discr :$discr_2_label DW_FORM_ref4 } { discr_2_label: member { - {type :$uinteger_label} - {data_member_location 0 data1} - {artificial 1 DW_FORM_flag_present} + DW_AT_type :$uinteger_label + DW_AT_data_member_location 0 data1 + DW_AT_artificial 1 DW_FORM_flag_present } variant { } { member { - {type :$one_label} - {data_member_location 4 data1} + DW_AT_type :$one_label + DW_AT_data_member_location 4 data1 } } variant { - {discr_value 1 udata} + DW_AT_discr_value 1 udata } { member { - {type :$two_label} - {data_member_location 4 data1} + DW_AT_type :$two_label + DW_AT_data_member_location 4 data1 } } } } structure_type { - {name Univariant} - {byte_size 8 DW_FORM_sdata} + DW_AT_name Univariant + DW_AT_byte_size 8 DW_FORM_sdata } { variant_part { } { variant { } { member { - {type :$one_label} - {data_member_location 4 data1} + DW_AT_type :$one_label + DW_AT_data_member_location 4 data1 } } } @@ -163,24 +163,24 @@ Dwarf::assemble $asm_file { # Rust won't emit a negative discriminant like this, but # we want to test the code path anyway. structure_type { - {name Negative} - {byte_size 8 DW_FORM_sdata} + DW_AT_name Negative + DW_AT_byte_size 8 DW_FORM_sdata } { variant_part { - {discr :$discr_3_label DW_FORM_ref4} + DW_AT_discr :$discr_3_label DW_FORM_ref4 } { discr_3_label: member { - {type :$int8_label} - {data_member_location 0 data1} - {artificial 1 DW_FORM_flag_present} + DW_AT_type :$int8_label + DW_AT_data_member_location 0 data1 + DW_AT_artificial 1 DW_FORM_flag_present } variant { - {discr_value -1 sdata} + DW_AT_discr_value -1 sdata } { member { - {type :$one_label} - {data_member_location 4 data1} + DW_AT_type :$one_label + DW_AT_data_member_location 4 data1 } } @@ -190,8 +190,8 @@ Dwarf::assemble $asm_file { variant { } { member { - {type :$two_label} - {data_member_location 4 data1} + DW_AT_type :$two_label + DW_AT_data_member_location 4 data1 } } } diff --git a/gdb/testsuite/gdb.dwarf2/varval.exp b/gdb/testsuite/gdb.dwarf2/varval.exp index 0693f43..8f132bb 100644 --- a/gdb/testsuite/gdb.dwarf2/varval.exp +++ b/gdb/testsuite/gdb.dwarf2/varval.exp @@ -50,7 +50,7 @@ proc setup_exec { arg_bad } { cu {} { DW_TAG_compile_unit { - {DW_AT_language @DW_LANG_C_plus_plus} + DW_AT_language @DW_LANG_C_plus_plus } { declare_labels int_label ptr_label struct_label var_a_label \ var_b_label var_c_label var_p_label var_bad_label \ @@ -61,179 +61,193 @@ proc setup_exec { arg_bad } { int_label: DW_TAG_base_type { - {DW_AT_byte_size ${int_size} DW_FORM_udata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name "int"} + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" } ptr_label: DW_TAG_pointer_type { - {DW_AT_type :$int_label} + DW_AT_type :$int_label } var_a_label: DW_TAG_variable { - {DW_AT_name "var_a"} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + DW_AT_name "var_a" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_a"] + }] SPECIAL_expr } var_a_abstract_label: DW_TAG_variable { - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } var_b_label: DW_TAG_variable { - {DW_AT_name "var_b"} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr} + DW_AT_name "var_b" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_b"] + }] SPECIAL_expr } var_c_label: DW_TAG_variable { - {DW_AT_name "var_c"} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_const_value 53 DW_FORM_sdata} + DW_AT_name "var_c" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_const_value 53 DW_FORM_sdata } var_p_label: DW_TAG_variable { - {DW_AT_name "var_p"} - {DW_AT_type :${ptr_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_p"]} SPECIAL_expr} + DW_AT_name "var_p" + DW_AT_type :${ptr_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_p"] + }] SPECIAL_expr } if { $bad } { var_bad_label: DW_TAG_variable { - {DW_AT_name "var_bad"} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + DW_AT_name "var_bad" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } } struct_label: DW_TAG_structure_type { - {DW_AT_byte_size 8*$int_size DW_FORM_sdata} + DW_AT_byte_size 8*$int_size DW_FORM_sdata } { DW_TAG_member { - {DW_AT_name "a"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 0*$int_size DW_FORM_udata} + DW_AT_name "a" + DW_AT_type :$int_label + DW_AT_data_member_location 0*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "b"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 1*$int_size DW_FORM_udata} + DW_AT_name "b" + DW_AT_type :$int_label + DW_AT_data_member_location 1*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "c"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 2*$int_size DW_FORM_udata} + DW_AT_name "c" + DW_AT_type :$int_label + DW_AT_data_member_location 2*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "d"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 3*$int_size DW_FORM_udata} + DW_AT_name "d" + DW_AT_type :$int_label + DW_AT_data_member_location 3*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "e"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 4*$int_size DW_FORM_udata} + DW_AT_name "e" + DW_AT_type :$int_label + DW_AT_data_member_location 4*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "f"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 5*$int_size DW_FORM_udata} + DW_AT_name "f" + DW_AT_type :$int_label + DW_AT_data_member_location 5*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "g"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 6*$int_size DW_FORM_udata} + DW_AT_name "g" + DW_AT_type :$int_label + DW_AT_data_member_location 6*$int_size DW_FORM_udata } DW_TAG_member { - {DW_AT_name "h"} - {DW_AT_type :$int_label} - {DW_AT_data_member_location 7*$int_size DW_FORM_udata} + DW_AT_name "h" + DW_AT_type :$int_label + DW_AT_data_member_location 7*$int_size DW_FORM_udata } } var_s_label: DW_TAG_variable { - {DW_AT_name "var_s"} - {DW_AT_type :${struct_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_s"]} SPECIAL_expr} + DW_AT_name "var_s" + DW_AT_type :${struct_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_s"] + }] SPECIAL_expr } var_untyped_label: DW_TAG_variable { - {DW_AT_name "var_untyped"} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr} + DW_AT_name "var_untyped" + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_b"] + }] SPECIAL_expr } int_array_label: DW_TAG_array_type { - {DW_AT_type :${int_label}} + DW_AT_type :${int_label} } { DW_TAG_subrange_type {} } varval3_decl_label: DW_TAG_variable { - {DW_AT_name "varval3"} - {DW_AT_type :${int_array_label}} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_declaration 1 DW_FORM_flag} + DW_AT_name "varval3" + DW_AT_type :${int_array_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_declaration 1 DW_FORM_flag } int_array_of_1_label: DW_TAG_array_type { - {DW_AT_type :${int_label}} + DW_AT_type :${int_label} } { DW_TAG_subrange_type { - {DW_AT_type :$int_label} - {DW_AT_upper_bound 0 DW_FORM_data1} + DW_AT_type :$int_label + DW_AT_upper_bound 0 DW_FORM_data1 } } varval3_def_label: DW_TAG_variable { - {DW_AT_name "varval3"} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_type :${int_array_of_1_label}} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + DW_AT_name "varval3" + DW_AT_external 1 DW_FORM_flag + DW_AT_type :${int_array_of_1_label} + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_a"] + }] SPECIAL_expr } DW_TAG_subprogram { - {MACRO_AT_func { "main" }} - {DW_AT_type :${int_label}} - {DW_AT_external 1 DW_FORM_flag} + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag } { varval_label: DW_TAG_variable { - {DW_AT_name "varval"} - {DW_AT_type :${int_label}} - {DW_AT_location { + DW_AT_name "varval" + DW_AT_type :${int_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_a_label} DW_OP_const1s 0 DW_OP_or DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } varval2_label: DW_TAG_variable { - {DW_AT_name "varval2"} - {DW_AT_type :${int_label}} - {DW_AT_location { + DW_AT_name "varval2" + DW_AT_type :${int_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_a_abstract_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } var_a_concrete_label: DW_TAG_variable { - {DW_AT_abstract_origin :${var_a_abstract_label}} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + DW_AT_abstract_origin :${var_a_abstract_label} + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_a"] + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "constval"} - {DW_AT_type :${int_label}} - {DW_AT_location { + DW_AT_name "constval" + DW_AT_type :${int_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_c_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "mixedval"} - {DW_AT_type :${int_label}} - {DW_AT_location { + DW_AT_name "mixedval" + DW_AT_type :${int_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_c_label} DW_OP_GNU_variable_value ${var_b_label} DW_OP_div @@ -244,55 +258,55 @@ proc setup_exec { arg_bad } { DW_OP_GNU_variable_value ${varval_label} DW_OP_minus DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "pointerval"} - {DW_AT_type :${ptr_label}} - {DW_AT_location { + DW_AT_name "pointerval" + DW_AT_type :${ptr_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_p_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } if { $bad } { DW_TAG_variable { - {DW_AT_name "badval"} - {DW_AT_type :${int_label}} - {DW_AT_location { + DW_AT_name "badval" + DW_AT_type :${int_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_bad_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } } DW_TAG_variable { - {DW_AT_name "structval"} - {DW_AT_type :${struct_label}} - {DW_AT_location { + DW_AT_name "structval" + DW_AT_type :${struct_label} + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_s_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "untypedval"} - {DW_AT_location { + DW_AT_name "untypedval" + DW_AT_location [subst { DW_OP_GNU_variable_value ${var_untyped_label} DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } if { $bad } { DW_TAG_variable { - {DW_AT_name "bad_die_val1"} - {DW_AT_location { + DW_AT_name "bad_die_val1" + DW_AT_location { DW_OP_GNU_variable_value 0xabcdef11 DW_OP_stack_value - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "bad_die_val2"} - {DW_AT_location { + DW_AT_name "bad_die_val2" + DW_AT_location [subst { DW_OP_GNU_variable_value ${ptr_label}+1 DW_OP_stack_value - } SPECIAL_expr} + }] SPECIAL_expr } } } @@ -348,6 +362,6 @@ if ![runto_main] { } gdb_test "print badval" "value has been optimized out" gdb_test "print bad_die_val1" \ - "invalid dwarf2 offset 0xabcdef11" + {DWARF Error: could not find unit containing offset 0xabcdef11 \[in module .*/varval\]} gdb_test "print bad_die_val2" \ "Bad DW_OP_GNU_variable_value DIE\\." diff --git a/gdb/testsuite/gdb.dwarf2/void-type.exp b/gdb/testsuite/gdb.dwarf2/void-type.exp index 64bebe1..10f5738 100644 --- a/gdb/testsuite/gdb.dwarf2/void-type.exp +++ b/gdb/testsuite/gdb.dwarf2/void-type.exp @@ -38,50 +38,54 @@ Dwarf::assemble $asm_file { cu {} { DW_TAG_compile_unit { - {DW_AT_producer "Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.5.212 Build 20150212"} - {DW_AT_language @DW_LANG_C} - {DW_AT_name $srcfile} - {DW_AT_comp_dir /tmp} - } { + DW_AT_producer "Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.5.212 Build 20150212" + DW_AT_language @DW_LANG_C + DW_AT_name $srcfile + DW_AT_comp_dir /tmp + } { declare_labels int_type void_type ptr_type int_type: DW_TAG_base_type { - {DW_AT_byte_size 4 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name int} + DW_AT_byte_size 4 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name int } void_type: DW_TAG_base_type { - {DW_AT_byte_size 0 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name void} + DW_AT_byte_size 0 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name void } ptr_type: DW_TAG_pointer_type { - {DW_AT_type :$void_type} + DW_AT_type :$void_type } - DW_TAG_subprogram { - {MACRO_AT_func {func}} - {type :$void_type} + DW_TAG_subprogram { + MACRO_AT_func {func} + DW_AT_type :$void_type } - DW_TAG_subprogram { - {MACRO_AT_func {main}} - {type :$int_type} + DW_TAG_subprogram { + MACRO_AT_func {main} + DW_AT_type :$int_type } DW_TAG_variable { - {DW_AT_name "var_a"} - {DW_AT_type :$int_type} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + DW_AT_name "var_a" + DW_AT_type :$int_type + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_a"] + }] SPECIAL_expr } DW_TAG_variable { - {DW_AT_name "var_ptr"} - {DW_AT_type :$ptr_type} - {DW_AT_external 1 DW_FORM_flag} - {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_ptr"]} SPECIAL_expr} + DW_AT_name "var_ptr" + DW_AT_type :$ptr_type + DW_AT_external 1 DW_FORM_flag + DW_AT_location [subst { + DW_OP_addr [gdb_target_symbol "var_ptr"] + }] SPECIAL_expr } } } diff --git a/gdb/testsuite/gdb.fortran/allocated.exp b/gdb/testsuite/gdb.fortran/allocated.exp index a000b6e..7cf1367 100644 --- a/gdb/testsuite/gdb.fortran/allocated.exp +++ b/gdb/testsuite/gdb.fortran/allocated.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/array-bounds.exp b/gdb/testsuite/gdb.fortran/array-bounds.exp index fb8ee86..9efd95f 100644 --- a/gdb/testsuite/gdb.fortran/array-bounds.exp +++ b/gdb/testsuite/gdb.fortran/array-bounds.exp @@ -34,8 +34,8 @@ if {![fortran_runto_main]} { # GCC outputs incorrect range debug info for -m32, gcc PR debug/54934. set expect_xfail \ [expr \ - [test_compiler_info {gfortran-*} f90] \ - && [is_ilp32_target]] + {[test_compiler_info {gfortran-*} f90] + && [is_ilp32_target]}] set re_ok [string_to_regexp (4294967296:4294967297)] set re_xfail [string_to_regexp (0:1)] diff --git a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp index 8c19c85..72c7c5e 100644 --- a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp +++ b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } @@ -53,7 +53,7 @@ gdb_test_multiple $cmd $cmd { # slice. for { set j 1 } { $j < 6 } { incr j } { for { set i 1 } { $i < 6 } { incr i } { - set val [expr ((($i - 1) * 2) + (($j - 1) * 20)) + 1] + set val [expr {((($i - 1) * 2) + (($j - 1) * 20)) + 1}] gdb_test "print ${varname} ($i,$j)" " = $val" } } @@ -106,7 +106,7 @@ gdb_test "print str (26:1:-2)" " = 'zxvtrpnljhfdb'" # existing value in memory. gdb_test_no_output "set fortran repack-array-slices on" set element_size [get_integer_valueof "sizeof (array (1,1))" "unknown"] -set slice_size [expr $element_size * 4] +set slice_size [expr {$element_size * 4}] gdb_test_no_output "set max-value-size $slice_size" gdb_test "print array (1:2, 1:2)" "= \\(\\(1, 2\\) \\(11, 12\\)\\)" gdb_test "print array (2:3, 2:3)" "= \\(\\(12, 13\\) \\(22, 23\\)\\)" diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp index b1e3dad..7d4f96e 100644 --- a/gdb/testsuite/gdb.fortran/array-slices.exp +++ b/gdb/testsuite/gdb.fortran/array-slices.exp @@ -56,9 +56,9 @@ proc array_slice_to_var { slice_str } { proc run_test { repack } { global binfile gdb_prompt - clean_restart ${binfile} + clean_restart ${::testfile} - if ![fortran_runto_main] { + if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/associated.exp b/gdb/testsuite/gdb.fortran/associated.exp index c900ce7..9297220 100644 --- a/gdb/testsuite/gdb.fortran/associated.exp +++ b/gdb/testsuite/gdb.fortran/associated.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/assumedrank.exp b/gdb/testsuite/gdb.fortran/assumedrank.exp index 159608f..45e8c09 100644 --- a/gdb/testsuite/gdb.fortran/assumedrank.exp +++ b/gdb/testsuite/gdb.fortran/assumedrank.exp @@ -32,7 +32,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { untested "could not run to main" return -1 } diff --git a/gdb/testsuite/gdb.fortran/call-no-debug.exp b/gdb/testsuite/gdb.fortran/call-no-debug.exp index 1b158c4..96ccdd7 100644 --- a/gdb/testsuite/gdb.fortran/call-no-debug.exp +++ b/gdb/testsuite/gdb.fortran/call-no-debug.exp @@ -22,7 +22,7 @@ standard_testfile call-no-debug-prog.f90 call-no-debug-func.f90 load_lib fortran.exp if {[prepare_for_testing_full "failed to prepare" \ - [list ${binfile} [list debug f90] \ + [list $testfile [list debug f90] \ $srcfile [list debug f90] \ $srcfile2 [list nodebug f90]]]} { return -1 @@ -67,7 +67,7 @@ proc find_mangled_name { name } { set some_func [find_mangled_name "some_func"] set string_func [find_mangled_name "string_func"] -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/charset.exp b/gdb/testsuite/gdb.fortran/charset.exp index 0f5ee3d..cd117d4 100644 --- a/gdb/testsuite/gdb.fortran/charset.exp +++ b/gdb/testsuite/gdb.fortran/charset.exp @@ -30,7 +30,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug addi return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return } diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp index 241cc83..d860b2c 100644 --- a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp +++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp @@ -26,7 +26,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/common-block.exp b/gdb/testsuite/gdb.fortran/common-block.exp index 6f3e55d..f27f3ad 100644 --- a/gdb/testsuite/gdb.fortran/common-block.exp +++ b/gdb/testsuite/gdb.fortran/common-block.exp @@ -4,12 +4,12 @@ # 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/>. diff --git a/gdb/testsuite/gdb.fortran/completion.exp b/gdb/testsuite/gdb.fortran/completion.exp index 0961207..5038251 100644 --- a/gdb/testsuite/gdb.fortran/completion.exp +++ b/gdb/testsuite/gdb.fortran/completion.exp @@ -26,7 +26,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/debug-expr.exp b/gdb/testsuite/gdb.fortran/debug-expr.exp index 6e84b24..d872ad6 100644 --- a/gdb/testsuite/gdb.fortran/debug-expr.exp +++ b/gdb/testsuite/gdb.fortran/debug-expr.exp @@ -28,7 +28,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} { return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/empty-string.exp b/gdb/testsuite/gdb.fortran/empty-string.exp index 531af45..17ee5e5 100644 --- a/gdb/testsuite/gdb.fortran/empty-string.exp +++ b/gdb/testsuite/gdb.fortran/empty-string.exp @@ -24,7 +24,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} { return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/exprs.exp b/gdb/testsuite/gdb.fortran/exprs.exp index 72efb56..323a2ab 100644 --- a/gdb/testsuite/gdb.fortran/exprs.exp +++ b/gdb/testsuite/gdb.fortran/exprs.exp @@ -232,7 +232,7 @@ proc test_arithmetic_expressions {} { gdb_test "p 6.0 / 3.0" " = 2" "real divided by real" # Test exponentiation with various operands - + gdb_test "p 2 ** 3" " = 8" "int powered by int" gdb_test "p 2 ** 2 ** 3" " = 256" "combined exponentiation expression" gdb_test "p (2 ** 2) ** 3" " = 64" "combined exponentiation expression in specified order" diff --git a/gdb/testsuite/gdb.fortran/huge.exp b/gdb/testsuite/gdb.fortran/huge.exp index 35bc6c8..f7c50d7 100644 --- a/gdb/testsuite/gdb.fortran/huge.exp +++ b/gdb/testsuite/gdb.fortran/huge.exp @@ -27,7 +27,7 @@ load_lib fortran.exp standard_testfile .F90 -set max [expr 2 * 1024 * 1024] +set max [expr {2 * 1024 * 1024}] set min 16 set opts {} @@ -35,7 +35,7 @@ lappend opts debug lappend opts f90 set compilation_succeeded 0 -for { set size [expr $max] } { $size >= $min } { set size [expr $size / 2] } { +for { set size [expr {$max}] } { $size >= $min } { set size [expr {$size / 2}] } { set try_opts [concat $opts [list additional_flags=-DCRASH_GDB=$size]] with_test_prefix CRASH_GDB=$size { if { [build_executable $testfile.exp $testfile $srcfile $try_opts] == -1 } { @@ -49,7 +49,7 @@ for { set size [expr $max] } { $size >= $min } { set size [expr $size / 2] } { require {expr $compilation_succeeded} # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart ${::testfile} save_vars { timeout } { set timeout 30 @@ -92,6 +92,6 @@ save_vars { timeout } { unsupported $test } else { # At 112 passes with and without the fix, so use 111. - gdb_assert {$space_used < [expr 111 * 4 * $size] } $test + gdb_assert {$space_used < [expr {111 * 4 * $size}] } $test } } diff --git a/gdb/testsuite/gdb.fortran/info-main.exp b/gdb/testsuite/gdb.fortran/info-main.exp index 4178886..6cdfd15 100644 --- a/gdb/testsuite/gdb.fortran/info-main.exp +++ b/gdb/testsuite/gdb.fortran/info-main.exp @@ -29,7 +29,7 @@ save_vars { GDBFLAGS } { gdb_test "info main" "simple" "info main prior to start" -if ![fortran_runto_main] { +if {![fortran_runto_main]} { untested "could not run to main" return -1 } diff --git a/gdb/testsuite/gdb.fortran/intrinsic-precedence.exp b/gdb/testsuite/gdb.fortran/intrinsic-precedence.exp index 02f5ff3..93f1da9 100644 --- a/gdb/testsuite/gdb.fortran/intrinsic-precedence.exp +++ b/gdb/testsuite/gdb.fortran/intrinsic-precedence.exp @@ -33,7 +33,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/intvar-array.exp b/gdb/testsuite/gdb.fortran/intvar-array.exp index 68b674c..52314ed 100644 --- a/gdb/testsuite/gdb.fortran/intvar-array.exp +++ b/gdb/testsuite/gdb.fortran/intvar-array.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/intvar-dynamic-types.exp b/gdb/testsuite/gdb.fortran/intvar-dynamic-types.exp index b28bf5c..201f020 100644 --- a/gdb/testsuite/gdb.fortran/intvar-dynamic-types.exp +++ b/gdb/testsuite/gdb.fortran/intvar-dynamic-types.exp @@ -24,7 +24,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/lbound-ubound.exp b/gdb/testsuite/gdb.fortran/lbound-ubound.exp index f8e256c..143c5be 100644 --- a/gdb/testsuite/gdb.fortran/lbound-ubound.exp +++ b/gdb/testsuite/gdb.fortran/lbound-ubound.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } @@ -160,7 +160,7 @@ while { $test_count < 500 } { # Finally, check that asking for a dimension above the valid # range gives the expected error. - set bad_dim [expr $upper_dim + 1] + set bad_dim [expr {$upper_dim + 1}] gdb_test "p lbound ($array_name, $bad_dim)" \ "LBOUND dimension must be from 1 to $upper_dim" \ "check error message for lbound of dim = $bad_dim" diff --git a/gdb/testsuite/gdb.fortran/library-module.exp b/gdb/testsuite/gdb.fortran/library-module.exp index ec35ef1..07867ee 100644 --- a/gdb/testsuite/gdb.fortran/library-module.exp +++ b/gdb/testsuite/gdb.fortran/library-module.exp @@ -17,7 +17,7 @@ load_lib fortran.exp require allow_fortran_tests -standard_testfile library-module-main.f90 +standard_testfile library-module-main.f90 set srclibfile ${testfile}-lib.f90 set libfile [standard_output_file ${testfile}-lib.so] diff --git a/gdb/testsuite/gdb.fortran/limited-length.exp b/gdb/testsuite/gdb.fortran/limited-length.exp index 38c5286..9c65d48 100644 --- a/gdb/testsuite/gdb.fortran/limited-length.exp +++ b/gdb/testsuite/gdb.fortran/limited-length.exp @@ -80,7 +80,7 @@ with_test_prefix "with standard max-value size" { # Set the max-value-size so we can only print 50 elements. set elements 50 set elem_size [get_valueof "/d" "sizeof(large_1d_array(1))" "*unknown*"] -gdb_test_no_output "set max-value-size [expr $elem_size * $elements]" +gdb_test_no_output "set max-value-size [expr {$elem_size * $elements}]" with_test_prefix "with reduced max-value size" { gdb_test "print large_4d_array" \ diff --git a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp index ac8f742..e3b9fb5 100644 --- a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp +++ b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp @@ -28,7 +28,7 @@ require allow_fortran_tests standard_testfile mixed-lang-stack.c mixed-lang-stack.cpp mixed-lang-stack.f90 if {[prepare_for_testing_full "failed to prepare" \ - [list ${binfile} {debug f90 additional_flags=-lstdc++} \ + [list $testfile {debug f90 additional_flags=-lstdc++} \ $srcfile {debug} \ $srcfile2 {debug c++ additional_flags=-std=c++11} \ $srcfile3 {debug f90}]]} { @@ -43,9 +43,9 @@ proc run_tests { lang } { with_test_prefix "lang=${lang}" { global binfile hex have_index - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp index 30988a2..2496f66 100644 --- a/gdb/testsuite/gdb.fortran/module.exp +++ b/gdb/testsuite/gdb.fortran/module.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}] } # Test automatic language detection before the inferior starts. It tests the # effect of expected: -# (gdb) show language +# (gdb) show language # The current source language is "auto; currently fortran". gdb_test "p modmany::var_i" " = 14" "stopped language detection" @@ -131,6 +131,6 @@ gdb_test "show language" {The current source language is "(auto; currently )?for # gcc-4.4.2: The main program is always $fmain in .symtab so "runto" above # works. But DWARF DW_TAG_subprogram contains the name specified by # the "program" Fortran statement. -if [gdb_breakpoint "module"] { +if {[gdb_breakpoint "module"]} { pass "setting breakpoint at module" } diff --git a/gdb/testsuite/gdb.fortran/multi-dim.exp b/gdb/testsuite/gdb.fortran/multi-dim.exp index efd225a..0a719fe 100644 --- a/gdb/testsuite/gdb.fortran/multi-dim.exp +++ b/gdb/testsuite/gdb.fortran/multi-dim.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {debug f90} return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return } diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp index 10846cf..fce6314 100644 --- a/gdb/testsuite/gdb.fortran/namelist.exp +++ b/gdb/testsuite/gdb.fortran/namelist.exp @@ -38,8 +38,8 @@ gdb_continue_to_breakpoint "Display namelist" # DW_TAG_namelist is supported starting gcc 4.9. set supported [expr \ - [test_compiler_info {gfortran-*} f90] \ - && [gcc_major_version {gfortran-*} f90] >= 4.9] + {[test_compiler_info {gfortran-*} f90] + && [gcc_major_version {gfortran-*} f90] >= 4.9}] if { $supported } { gdb_test "ptype nml" \ "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml" diff --git a/gdb/testsuite/gdb.fortran/nested-funcs.exp b/gdb/testsuite/gdb.fortran/nested-funcs.exp index 63917c5..c92a8c1 100755 --- a/gdb/testsuite/gdb.fortran/nested-funcs.exp +++ b/gdb/testsuite/gdb.fortran/nested-funcs.exp @@ -14,7 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # This testcase is supposed to test DWARF static link which is usually -# used together with nested functions. +# used together with nested functions. require allow_fortran_tests diff --git a/gdb/testsuite/gdb.fortran/oop_extend_type.exp b/gdb/testsuite/gdb.fortran/oop_extend_type.exp index f2e64e9..9f443d9 100755 --- a/gdb/testsuite/gdb.fortran/oop_extend_type.exp +++ b/gdb/testsuite/gdb.fortran/oop_extend_type.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { perror "could not run to main" return -1 } diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp index 9920616..47ca74a 100644 --- a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp +++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/print_type.exp b/gdb/testsuite/gdb.fortran/print_type.exp index c08f501..6d2457f 100755 --- a/gdb/testsuite/gdb.fortran/print_type.exp +++ b/gdb/testsuite/gdb.fortran/print_type.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/rank.exp b/gdb/testsuite/gdb.fortran/rank.exp index c61ae98..e998ead 100644 --- a/gdb/testsuite/gdb.fortran/rank.exp +++ b/gdb/testsuite/gdb.fortran/rank.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/shape.exp b/gdb/testsuite/gdb.fortran/shape.exp index e525bf7..7a6bc9b 100644 --- a/gdb/testsuite/gdb.fortran/shape.exp +++ b/gdb/testsuite/gdb.fortran/shape.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp index bca971d..ab0411a 100644 --- a/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp +++ b/gdb/testsuite/gdb.fortran/short-circuit-argument-list.exp @@ -48,12 +48,12 @@ reset_called_flags # a(x,y) .OR./.AND. a(a,b) correctly. foreach_with_prefix truth_table_index {1 2 3 4} { gdb_test "p truth_table($truth_table_index, 1) .OR. truth_table($truth_table_index, 2)" \ - "[expr $truth_table_index > 1 ? \".TRUE.\" : \".FALSE.\"]" + "[expr {$truth_table_index > 1 ? ".TRUE." : ".FALSE."}]" } foreach_with_prefix truth_table_index {1 2 3 4} { gdb_test "p truth_table($truth_table_index, 1) .AND. truth_table($truth_table_index, 2)" \ - "[expr $truth_table_index > 3 ? \".TRUE.\" : \".FALSE.\"]" + "[expr {$truth_table_index > 3 ? ".TRUE." : ".FALSE."}]" } # Vary number of function arguments to skip. @@ -78,14 +78,14 @@ with_test_prefix "nested call not skipped" { gdb_test "p function_one_arg(.FALSE. .OR. function_no_arg())" \ " = .TRUE." gdb_test "p calls" \ - " = \\\( function_no_arg_called = [expr $prime + 1], function_no_arg_false_called = $prime, function_one_arg_called = [expr $prime + 1], function_two_arg_called = $prime, function_array_called = $prime \\\)" + " = \\\( function_no_arg_called = [expr {$prime + 1}], function_no_arg_false_called = $prime, function_one_arg_called = [expr {$prime + 1}], function_two_arg_called = $prime, function_array_called = $prime \\\)" } with_test_prefix "nested call skipped" { gdb_test "p function_one_arg(.TRUE. .OR. function_no_arg())" \ " = .TRUE." gdb_test "p calls" \ - " = \\\( function_no_arg_called = [expr $prime + 1], function_no_arg_false_called = $prime, function_one_arg_called = [expr $prime + 2], function_two_arg_called = $prime, function_array_called = $prime \\\)" + " = \\\( function_no_arg_called = [expr {$prime + 1}], function_no_arg_false_called = $prime, function_one_arg_called = [expr {$prime + 2}], function_two_arg_called = $prime, function_array_called = $prime \\\)" } # Vary number of components in the expression to skip. diff --git a/gdb/testsuite/gdb.fortran/size.exp b/gdb/testsuite/gdb.fortran/size.exp index dd6340f..5bc7db2 100644 --- a/gdb/testsuite/gdb.fortran/size.exp +++ b/gdb/testsuite/gdb.fortran/size.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/sizeof.exp b/gdb/testsuite/gdb.fortran/sizeof.exp index aa22107..c0a9fd3 100644 --- a/gdb/testsuite/gdb.fortran/sizeof.exp +++ b/gdb/testsuite/gdb.fortran/sizeof.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp index c444228..03bc2ce 100644 --- a/gdb/testsuite/gdb.fortran/types.exp +++ b/gdb/testsuite/gdb.fortran/types.exp @@ -25,7 +25,7 @@ proc test_integer_literal_types_accepted {} { # Test various decimal values. # Should be integer*4 probably. - gdb_test "pt 123" "type = int" + gdb_test "pt 123" "type = int" } proc test_character_literal_types_accepted {} { diff --git a/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp b/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp index 8d9fc25..b766e1d 100644 --- a/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp +++ b/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-array.exp b/gdb/testsuite/gdb.fortran/vla-array.exp index 092a19a..7c2d48d 100644 --- a/gdb/testsuite/gdb.fortran/vla-array.exp +++ b/gdb/testsuite/gdb.fortran/vla-array.exp @@ -23,7 +23,7 @@ if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { untested "could not run to main" return -1 } @@ -34,12 +34,12 @@ gdb_continue_to_breakpoint "arr_vla1-print" # GFortran emits DW_TAG_structure_type for strings and it has only # DW_AT_declaration tag. This results in <incomplete type> in gdb. -if [test_compiler_info "gfortran*" f90] { setup_xfail *-*-* gcc/101826 } +if {[test_compiler_info "gfortran*" f90]} { setup_xfail *-*-* gcc/101826 } gdb_test "print arr_vla1" \ " = \\\('vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary'\\\)" \ "print vla string array" -if [test_compiler_info "gfortran*" f90] { setup_xfail *-*-* gcc/101826 } +if {[test_compiler_info "gfortran*" f90]} { setup_xfail *-*-* gcc/101826 } gdb_test "ptype arr_vla1" \ "type = character\\*12 \\(5\\)" \ "print variable length string array type" diff --git a/gdb/testsuite/gdb.fortran/vla-datatypes.exp b/gdb/testsuite/gdb.fortran/vla-datatypes.exp index a4ea89d..6f2bb3a 100644 --- a/gdb/testsuite/gdb.fortran/vla-datatypes.exp +++ b/gdb/testsuite/gdb.fortran/vla-datatypes.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ # check that all fortran standard datatypes will be # handled correctly when using as VLA's -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-history.exp b/gdb/testsuite/gdb.fortran/vla-history.exp index d51ded4..6dcc31c 100644 --- a/gdb/testsuite/gdb.fortran/vla-history.exp +++ b/gdb/testsuite/gdb.fortran/vla-history.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-ptr-info.exp b/gdb/testsuite/gdb.fortran/vla-ptr-info.exp index 1a4efc7..9f63e60 100644 --- a/gdb/testsuite/gdb.fortran/vla-ptr-info.exp +++ b/gdb/testsuite/gdb.fortran/vla-ptr-info.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp b/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp index 7d95787..6809d8c 100644 --- a/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp +++ b/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-ptype.exp b/gdb/testsuite/gdb.fortran/vla-ptype.exp index ca75afc..4c72d62 100644 --- a/gdb/testsuite/gdb.fortran/vla-ptype.exp +++ b/gdb/testsuite/gdb.fortran/vla-ptype.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-sizeof.exp b/gdb/testsuite/gdb.fortran/vla-sizeof.exp index da9eaa1..ede677f 100644 --- a/gdb/testsuite/gdb.fortran/vla-sizeof.exp +++ b/gdb/testsuite/gdb.fortran/vla-sizeof.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-value-sub-arbitrary.exp b/gdb/testsuite/gdb.fortran/vla-value-sub-arbitrary.exp index f33231a..7cd9cd8 100644 --- a/gdb/testsuite/gdb.fortran/vla-value-sub-arbitrary.exp +++ b/gdb/testsuite/gdb.fortran/vla-value-sub-arbitrary.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-value-sub-finish.exp b/gdb/testsuite/gdb.fortran/vla-value-sub-finish.exp index 01d717e..ef40dff 100644 --- a/gdb/testsuite/gdb.fortran/vla-value-sub-finish.exp +++ b/gdb/testsuite/gdb.fortran/vla-value-sub-finish.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-value-sub.exp b/gdb/testsuite/gdb.fortran/vla-value-sub.exp index e3103bd..566125e 100644 --- a/gdb/testsuite/gdb.fortran/vla-value-sub.exp +++ b/gdb/testsuite/gdb.fortran/vla-value-sub.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/vla-value.exp b/gdb/testsuite/gdb.fortran/vla-value.exp index fc2864b..687b14c 100644 --- a/gdb/testsuite/gdb.fortran/vla-value.exp +++ b/gdb/testsuite/gdb.fortran/vla-value.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.fortran/whatis_type.exp b/gdb/testsuite/gdb.fortran/whatis_type.exp index 8cbddc1..8891eac 100644 --- a/gdb/testsuite/gdb.fortran/whatis_type.exp +++ b/gdb/testsuite/gdb.fortran/whatis_type.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -if ![fortran_runto_main] { +if {![fortran_runto_main]} { return } diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp index 2252b79..5229446 100644 --- a/gdb/testsuite/gdb.gdb/index-file.exp +++ b/gdb/testsuite/gdb.gdb/index-file.exp @@ -30,9 +30,17 @@ if { $filename eq "" } { return -1 } +# If FILENAME is a libtool wrapper, then we need to get the path of the real +# executable. +set filename [selftest_libtool_get_real_gdb_executable $filename] +if { $filename eq "" } { + return -1 +} + with_timeout_factor $timeout_factor { # Start GDB, load FILENAME. - clean_restart $filename + clean_restart + gdb_load $filename } # Record how many worker threads GDB is using. @@ -99,7 +107,7 @@ proc check_symbol_table_usage { filename } { _ _ _ symbol_table_offset shortcut_offset # The length of the symbol hash table (in entries). - set len [expr ($shortcut_offset - $symbol_table_offset) / 8] + set len [expr {($shortcut_offset - $symbol_table_offset) / 8}] # Now walk the hash table and count how many entries are in use. set offset $symbol_table_offset @@ -119,7 +127,7 @@ proc check_symbol_table_usage { filename } { close $fp # Calculate how full the cache is. - set pct [expr (100 * double($count)) / $len] + set pct [expr {(100 * double($count)) / $len}] # Write our results out to the gdb.log. verbose -log "Hash table size: $len" @@ -145,7 +153,7 @@ if { $worker_threads > 1 } { clean_restart # Adjust the number of threads to use. - set reduced_threads [expr $worker_threads / 2] + set reduced_threads [expr {$worker_threads / 2}] gdb_test_no_output "maint set worker-threads $reduced_threads" with_timeout_factor $timeout_factor { diff --git a/gdb/testsuite/gdb.gdb/python-helper.exp b/gdb/testsuite/gdb.gdb/python-helper.exp index 4b9adb0..33243c9 100644 --- a/gdb/testsuite/gdb.gdb/python-helper.exp +++ b/gdb/testsuite/gdb.gdb/python-helper.exp @@ -264,13 +264,31 @@ proc test_python_helper {} { gdb_test -prompt $outer_prompt_re "print varobj_table" \ "htab_t with ${::decimal} elements" + set inferior_list_supported 1 + set inferior_list_unsupported_re "type = intrusive_list" + gdb_test_multiple "what inferior_list" "" -prompt $outer_prompt_re { + -re -wrap $inferior_list_unsupported_re { + set inferior_list_supported 0 + pass $gdb_test_name + } + -re -wrap "" { + pass $gdb_test_name + } + } + # Test the intrusive_list pretty-printer. A bug occurred in the # pretty-printer for lists with more than one element. Verify that # we see both elements of the inferior_list list being printed. - gdb_test -prompt $outer_prompt_re "print inferior_list" "intrusive list of inferior = {.*, num = 1,.*, num = 2,.*}" + set test "print inferior_list" + if { $inferior_list_supported } { + gdb_test -prompt $outer_prompt_re $test \ + "intrusive list of inferior = {.*, num = 1,.*, num = 2,.*}" + } else { + unsupported $test + } return 0 } # Use the self-test framework to run the test. -do_self_tests captured_main test_python_helper +do_self_tests test_python_helper diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp index 1cf9265..7fa320e 100644 --- a/gdb/testsuite/gdb.gdb/selftest.exp +++ b/gdb/testsuite/gdb.gdb/selftest.exp @@ -56,7 +56,7 @@ proc test_with_self { } { } # start the "xgdb" process - if [target_info exists gdb,noinferiorio] { + if {[target_info exists gdb,noinferiorio]} { # With no way to interact with the inferior GDB, all we can do # is let it run. send_gdb "continue\n" @@ -98,7 +98,7 @@ proc test_with_self { } { } # kill the xgdb process - if ![target_info exists gdb,nointerrupts] { + if {![target_info exists gdb,nointerrupts]} { set description "send ^C to child process" send_gdb "\003" # "Thread 1" is displayed iff Guile support is linked in. @@ -147,7 +147,7 @@ proc test_with_self { } { # Switch back to the GDB thread if Guile support is linked in. # "signal SIGINT" could also switch the current thread. gdb_test "thread 1" {\[Switching to thread 1 .*\].*} - + # get a stack trace # # This fails on some linux systems for unknown reasons. On the @@ -167,5 +167,5 @@ proc test_with_self { } { save_vars { INTERNAL_GDBFLAGS } { set INTERNAL_GDBFLAGS [string map {"-q" ""} $INTERNAL_GDBFLAGS] - do_self_tests captured_main test_with_self + do_self_tests test_with_self } diff --git a/gdb/testsuite/gdb.gdb/unittest.exp b/gdb/testsuite/gdb.gdb/unittest.exp index 795a32b..38955ca 100644 --- a/gdb/testsuite/gdb.gdb/unittest.exp +++ b/gdb/testsuite/gdb.gdb/unittest.exp @@ -63,7 +63,7 @@ proc run_selftests { binfile } { gdb_exit gdb_start } else { - clean_restart ${binfile} + clean_restart ${::testfile} } if { [is_remote host] } { diff --git a/gdb/testsuite/gdb.go/basic-types.exp b/gdb/testsuite/gdb.go/basic-types.exp index 3d4bfd5..53ce4fa 100644 --- a/gdb/testsuite/gdb.go/basic-types.exp +++ b/gdb/testsuite/gdb.go/basic-types.exp @@ -25,7 +25,7 @@ require allow_go_tests proc test_integer_literal_types_accepted {} { # Test various decimal values. - gdb_test "pt 123" "type = int" + gdb_test "pt 123" "type = int" gdb_test "pt void(42)" "type = void" gdb_test "pt byte(42)" "type = uint8" @@ -102,7 +102,7 @@ proc test_complex_literal_types_accepted {} { clean_restart -if [set_lang_go] { +if {[set_lang_go]} { test_integer_literal_types_accepted test_logical_literal_types_accepted test_character_literal_types_accepted diff --git a/gdb/testsuite/gdb.go/integers.exp b/gdb/testsuite/gdb.go/integers.exp index d58c771..50ea9a8 100644 --- a/gdb/testsuite/gdb.go/integers.exp +++ b/gdb/testsuite/gdb.go/integers.exp @@ -44,9 +44,9 @@ gdb_test "print i" ".* = 0" "print i before assigned to 1" gdb_test "next" "i = 1" "next to 'i = 1' line" gdb_test "next" "j = 2" "next to 'j = 2' line" -# At that point, +# At that point, # i should be equal to 1 -gdb_test "print i" " = 1" +gdb_test "print i" " = 1" # but j should still be equal to zero gdb_test "print j" " = 0" "test j value before assignment" diff --git a/gdb/testsuite/gdb.go/package.exp b/gdb/testsuite/gdb.go/package.exp index c30b8c0..180b48a 100644 --- a/gdb/testsuite/gdb.go/package.exp +++ b/gdb/testsuite/gdb.go/package.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${testfile}2.go" "${binfile}2.o" object untested "failed to compile" return -1 } - + if { [gdb_compile "${srcdir}/${subdir}/${testfile}1.go ${binfile}2.o" "${binfile}" executable "debug go libdir=[standard_output_file {}]"] != "" } { untested "failed to compile" return -1 diff --git a/gdb/testsuite/gdb.go/print.exp b/gdb/testsuite/gdb.go/print.exp index 85cb6a1..a02b746 100644 --- a/gdb/testsuite/gdb.go/print.exp +++ b/gdb/testsuite/gdb.go/print.exp @@ -58,7 +58,7 @@ proc test_float_rejected {} { clean_restart -if [set_lang_go] { +if {[set_lang_go]} { test_float_accepted test_float_rejected } else { diff --git a/gdb/testsuite/gdb.guile/scm-arch.exp b/gdb/testsuite/gdb.guile/scm-arch.exp index bd64c4b..752c2d8 100644 --- a/gdb/testsuite/gdb.guile/scm-arch.exp +++ b/gdb/testsuite/gdb.guile/scm-arch.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-block.exp b/gdb/testsuite/gdb.guile/scm-block.exp index 266e714..65e2275 100644 --- a/gdb/testsuite/gdb.guile/scm-block.exp +++ b/gdb/testsuite/gdb.guile/scm-block.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-breakpoint.exp b/gdb/testsuite/gdb.guile/scm-breakpoint.exp index 8694530..3b90d99 100644 --- a/gdb/testsuite/gdb.guile/scm-breakpoint.exp +++ b/gdb/testsuite/gdb.guile/scm-breakpoint.exp @@ -32,7 +32,7 @@ proc_with_prefix test_bkpt_basic { } { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -65,7 +65,7 @@ proc_with_prefix test_bkpt_basic { } { "scm-breakpoint\.c:${mult_line}*" \ "check multiply breakpoint location" - # Check hit and ignore counts. + # Check hit and ignore counts. gdb_test "guile (print (breakpoint-hit-count mult-bkpt))" \ "= 1" "check multiply breakpoint hit count" gdb_scm_test_silent_cmd "guile (set-breakpoint-ignore-count! mult-bkpt 4)" \ @@ -105,7 +105,7 @@ proc_with_prefix test_bkpt_deletion { } { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -141,7 +141,7 @@ proc_with_prefix test_bkpt_cond_and_cmds { } { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -188,7 +188,7 @@ proc_with_prefix test_bkpt_invisible { } { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -238,10 +238,10 @@ proc_with_prefix test_watchpoints { } { clean_restart ${testfile} # Disable hardware watchpoints if necessary. - if [target_info exists gdb,no_hardware_watchpoints] { + if {[target_info exists gdb,no_hardware_watchpoints]} { gdb_test_no_output "set can-use-hw-watchpoints 0" "" } - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -273,10 +273,10 @@ proc_with_prefix test_bkpt_internal { } { clean_restart ${testfile} # Disable hardware watchpoints if necessary. - if [target_info exists gdb,no_hardware_watchpoints] { + if {[target_info exists gdb,no_hardware_watchpoints]} { gdb_test_no_output "set can-use-hw-watchpoints 0" "" } - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -304,10 +304,10 @@ proc_with_prefix test_bkpt_eval_funcs { } { clean_restart ${testfile} # Disable hardware watchpoints if necessary. - if [target_info exists gdb,no_hardware_watchpoints] { + if {[target_info exists gdb,no_hardware_watchpoints]} { gdb_test_no_output "set can-use-hw-watchpoints 0" "" } - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -451,7 +451,7 @@ proc_with_prefix test_bkpt_registration {} { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -490,7 +490,7 @@ proc_with_prefix test_bkpt_temporary { } { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return 0 } delete_breakpoints @@ -556,7 +556,7 @@ proc_with_prefix test_catchpoints {} { # Start with a fresh gdb. clean_restart ${testfile} - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-cmd.exp b/gdb/testsuite/gdb.guile/scm-cmd.exp index 9caca24..36abb00 100644 --- a/gdb/testsuite/gdb.guile/scm-cmd.exp +++ b/gdb/testsuite/gdb.guile/scm-cmd.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -71,6 +71,65 @@ gdb_test_multiline "input subcommand" \ gdb_test "prefix-cmd subcmd ugh" "subcmd output, arg = ugh" "call subcmd" +# Create a sub-command using a partial, but still unique, prefix. + +gdb_test_multiline "sub-command using partial prefix" \ + "guile" "" \ + "(register-command! (make-command \"prefix subcmd2\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display (format #f \"subcmd2 output, arg = ~a\\n\" arg)))))" "" \ + "end" "" + +gdb_test "prefix-cmd subcmd2 ugh" "subcmd2 output, arg = ugh" "call subcmd2" + +# Now create a second prefix, similar to the first. + +gdb_test_multiline "create prefix-xxx prefix command" \ + "guile" "" \ + "(register-command! (make-command \"prefix-xxx\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:completer-class COMPLETE_NONE" "" \ + " #:prefix? #t))" "" \ + "end" "" + +# Now create a sub-command using an ambiguous prefix. + +gdb_test_multiline "sub-command using ambiguous partial prefix" \ + "guile" "" \ + "(register-command! (make-command \"prefix subcmd3\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display (format #f \"subcmd3 output, arg = ~a\\n\" arg)))))" "" \ + "end" \ + [multi_line \ + "Out of range: could not find command prefix 'prefix' in position 1: \"prefix subcmd3\"" \ + "Error while executing Scheme code\\."] + +# Check for errors when creating a command with an unknown prefix. + +gdb_test_multiline "try to create 'unknown-prefix subcmd'" \ + "guile" "" \ + "(register-command! (make-command \"unknown-prefix subcmd\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display \"called unknown-prefix subcmd\"))))" "" \ + "end" \ + [multi_line \ + "Out of range: could not find command prefix 'unknown-prefix' in position 1: \"unknown-prefix subcmd\"" \ + "Error while executing Scheme code\\."] + +gdb_test_multiline "try to create 'prefix-cmd unknown-prefix subcmd'" \ + "guile" "" \ + "(register-command! (make-command \"prefix-cmd unknown-prefix subcmd\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display \"called prefix-cmd unknown-prefix subcmd\"))))" "" \ + "end" \ + [multi_line \ + "Out of range: could not find command prefix 'prefix-cmd unknown-prefix' in position 1: \"prefix-cmd unknown-prefix subcmd\"" \ + "Error while executing Scheme code\\."] + # Test a subcommand in an existing GDB prefix. gdb_test_multiline "input new subcommand" \ diff --git a/gdb/testsuite/gdb.guile/scm-color.exp b/gdb/testsuite/gdb.guile/scm-color.exp index bbc9e71..4c6a9c2 100644 --- a/gdb/testsuite/gdb.guile/scm-color.exp +++ b/gdb/testsuite/gdb.guile/scm-color.exp @@ -19,8 +19,12 @@ load_lib gdb-guile.exp require allow_guile_tests +require {!is_remote host} -clean_restart +# Start GDB with styling support. +with_ansi_styling_terminal { + clean_restart +} gdb_install_guile_utils gdb_install_guile_module @@ -108,3 +112,8 @@ gdb_test [concat "guile " \ "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ "escape sequences" +# Ensure that turning styling off means no escape sequences. +gdb_test_no_output "set style enabled off" +gdb_test_no_output "guile (display (color-escape-sequence c_red #t))" +gdb_test_no_output "guile (display (color-escape-sequence c_red #f))" +gdb_test_no_output "set style enabled on" diff --git a/gdb/testsuite/gdb.guile/scm-disasm.exp b/gdb/testsuite/gdb.guile/scm-disasm.exp index 5541a60..bd551ad 100644 --- a/gdb/testsuite/gdb.guile/scm-disasm.exp +++ b/gdb/testsuite/gdb.guile/scm-disasm.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-equal.exp b/gdb/testsuite/gdb.guile/scm-equal.exp index 0450d62..2a87139 100644 --- a/gdb/testsuite/gdb.guile/scm-equal.exp +++ b/gdb/testsuite/gdb.guile/scm-equal.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-frame-args.exp b/gdb/testsuite/gdb.guile/scm-frame-args.exp index c519087..9c1e831 100644 --- a/gdb/testsuite/gdb.guile/scm-frame-args.exp +++ b/gdb/testsuite/gdb.guile/scm-frame-args.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-frame-inline.exp b/gdb/testsuite/gdb.guile/scm-frame-inline.exp index a2fe11d..02884f7 100644 --- a/gdb/testsuite/gdb.guile/scm-frame-inline.exp +++ b/gdb/testsuite/gdb.guile/scm-frame-inline.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![runto_main] { +if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp index b5ec73f..821567e 100644 --- a/gdb/testsuite/gdb.guile/scm-frame.exp +++ b/gdb/testsuite/gdb.guile/scm-frame.exp @@ -28,7 +28,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { # The following tests require execution. -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -52,7 +52,7 @@ gdb_test "guile (print (frame-read-var bf1 \"b\"))" \ "\"bar\"" "test b" # Test the read-var function in another block other than the current -# block (in this case, the super block). Test thar read-var is reading +# block (in this case, the super block). Test that read-var is reading # the correct variables of i and f but they are the correct value and type. gdb_scm_test_silent_cmd "guile (define sb (block-superblock (frame-block bf1)))" \ "get superblock" diff --git a/gdb/testsuite/gdb.guile/scm-iterator.exp b/gdb/testsuite/gdb.guile/scm-iterator.exp index 43d776b..188b5ef 100644 --- a/gdb/testsuite/gdb.guile/scm-iterator.exp +++ b/gdb/testsuite/gdb.guile/scm-iterator.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-lazy-string.exp b/gdb/testsuite/gdb.guile/scm-lazy-string.exp index c5d09ae..eaee001 100644 --- a/gdb/testsuite/gdb.guile/scm-lazy-string.exp +++ b/gdb/testsuite/gdb.guile/scm-lazy-string.exp @@ -31,7 +31,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { # The following tests require execution. -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-math.exp b/gdb/testsuite/gdb.guile/scm-math.exp index 8b21909..17b54d1 100644 --- a/gdb/testsuite/gdb.guile/scm-math.exp +++ b/gdb/testsuite/gdb.guile/scm-math.exp @@ -167,21 +167,21 @@ proc test_value_numeric_ops {} { # TCL 8.5 required here. Use lookup table instead? proc get_max_int { size } { - return [expr "(1 << ($size - 1)) - 1"] + return [expr {(1 << ($size - 1)) - 1}] } # Return the min signed int of size SIZE. # TCL 8.5 required here. Use lookup table instead? proc get_min_int { size } { - return [expr "-(1 << ($size - 1))"] + return [expr {-(1 << ($size - 1))}] } # Return the max unsigned int of size SIZE. # TCL 8.5 required here. Use lookup table instead? proc get_max_uint { size } { - return [expr "(1 << $size) - 1"] + return [expr {(1 << $size) - 1}] } # Helper routine for test_value_numeric_ranges. @@ -252,7 +252,7 @@ proc test_value_numeric_ranges {} { proc test_make_pointer_value { size } { set max [get_max_uint $size] - set max_hex [string repeat "f" [expr "$size / 4"]] + set max_hex [string repeat "f" [expr {$size / 4}]] gdb_test "gu (print (make-value $max #:type void-pointer-type))" \ "= 0x$max_hex" "test make-value void* max" @@ -337,7 +337,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c}]} { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-objfile-script.exp b/gdb/testsuite/gdb.guile/scm-objfile-script.exp index b6d9369..88cd18c 100644 --- a/gdb/testsuite/gdb.guile/scm-objfile-script.exp +++ b/gdb/testsuite/gdb.guile/scm-objfile-script.exp @@ -41,7 +41,7 @@ gdb_load ${binfile} # Verify gdb loaded the script. gdb_test "info auto-load guile-scripts" "Yes.*/${testfile}-gdb.scm.*" -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-objfile.exp b/gdb/testsuite/gdb.guile/scm-objfile.exp index e0018c4..09256df 100644 --- a/gdb/testsuite/gdb.guile/scm-objfile.exp +++ b/gdb/testsuite/gdb.guile/scm-objfile.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-parameter.exp b/gdb/testsuite/gdb.guile/scm-parameter.exp index 8ab5d93..5483b81 100644 --- a/gdb/testsuite/gdb.guile/scm-parameter.exp +++ b/gdb/testsuite/gdb.guile/scm-parameter.exp @@ -26,7 +26,7 @@ gdb_install_guile_utils gdb_install_guile_module proc scm_param_test_maybe_no_output { command pattern args } { - if [string length $pattern] { + if {[string length $pattern]} { gdb_test $command $pattern $args } else { gdb_test_no_output $command $args @@ -39,7 +39,8 @@ if { [is_remote host] } { gdb_test "guile (print (parameter-value \"directories\"))" \ "\\\$cdir.\\\$cwd" } else { - set escaped_directory [string_to_regexp "$srcdir/$subdir"] + set directory [host_file_normalize "$::srcdir/$::subdir"] + set escaped_directory [string_to_regexp $directory] gdb_test "guile (print (parameter-value \"directories\"))" \ "$escaped_directory.\\\$cdir.\\\$cwd" } @@ -67,9 +68,19 @@ with_test_prefix "test-param" { gdb_test_no_output "set print test-param off" gdb_test "show print test-param" "The state of the Test Parameter is off." "show parameter off" gdb_test "guile (print (parameter-value test-param))" "= #f" "parameter value, false" - gdb_test "help show print test-param" "Show the state of the boolean test-param.*" "show help" - gdb_test "help set print test-param" "Set the state of the boolean test-param.*" "set help" - gdb_test "help set print" "set print test-param -- Set the state of the boolean test-param.*" "general help" + gdb_test "help show print test-param" \ + [multi_line \ + "^Show the state of the boolean test-param\\." \ + "When enabled, test param does something useful\\. When disabled, does nothing\\."] \ + "show help" + gdb_test "help set print test-param" \ + [multi_line \ + "^Set the state of the boolean test-param\\." \ + "When enabled, test param does something useful\\. When disabled, does nothing\\."] \ + "set help" + gdb_test "help set print" \ + "set print test-param -- Set the state of the boolean test-param.*" \ + "general help" gdb_test "guile (print (parameter? test-param))" "= #t" gdb_test "guile (print (parameter? 42))" "= #f" @@ -99,7 +110,7 @@ with_test_prefix "test-enum-param" { gdb_test_no_output "set print test-enum-param two" gdb_test "show print test-enum-param" "The state of the enum is two." "show new value" gdb_test "guile (print (parameter-value test-enum-param))" "two" "enum parameter value, two" - gdb_test "set print test-enum-param three" "Undefined item: \"three\".*" "set invalid enum parameter" + gdb_test "set print test-enum-param three" "Undefined item: \"three\".*" "set invalid enum parameter" } # Test integer parameters. @@ -295,7 +306,7 @@ with_test_prefix "test-file-param" { gdb_test_no_output "set test-file-param bar.txt" gdb_test "show test-file-param" "The name of the file is bar.txt." "show new value" gdb_test "guile (print (parameter-value test-file-param))" "bar.txt" " new parameter value" - gdb_test "set test-file-param" "Argument required.*" + gdb_test "set test-file-param" "Argument required.*" } # Test a parameter that is not documented. @@ -314,9 +325,17 @@ with_test_prefix "test-undocumented-param" { gdb_test "show print test-undoc-param" "The state of the Test Parameter is on." "show parameter on" gdb_test_no_output "set print test-undoc-param off" gdb_test "show print test-undoc-param" "The state of the Test Parameter is off." "show parameter off" - gdb_test "help show print test-undoc-param" "This command is not documented." "show help" - gdb_test "help set print test-undoc-param" "This command is not documented." "set help" - gdb_test "help set print" "set print test-undoc-param -- This command is not documented.*" "general help" + gdb_test "help show print test-undoc-param" \ + [multi_line \ + "^Show the current value of 'print test-undoc-param'\\." \ + "This command is not documented\\."] \ + "show help" + gdb_test "help set print test-undoc-param" \ + [multi_line \ + "Set the current value of 'print test-undoc-param'\\." \ + "This command is not documented\\."] \ + "set help" + gdb_test "help set print" "set print test-undoc-param -- Set the current value of 'print test-undoc-param'\\..*" "general help" } # Test a parameter with a restricted range, where we need to notify the user @@ -379,60 +398,218 @@ gdb_test_no_output "guile (register-parameter! prev-ambig)" with_test_prefix "previously-ambiguous" { gdb_test "guile (print (parameter-value prev-ambig))" "= #f" "parameter value, false" - gdb_test "show print s" "Command is not documented is off." "show parameter off" + gdb_test "show print s" \ + "The current value of 'print s' is off\\." "show parameter off" gdb_test_no_output "set print s on" - gdb_test "show print s" "Command is not documented is on." "show parameter on" + gdb_test "show print s" \ + "The current value of 'print s' is on\\." "show parameter on" gdb_test "guile (print (parameter-value prev-ambig))" "= #t" "parameter value, true" - gdb_test "help show print s" "This command is not documented." "show help" - gdb_test "help set print s" "This command is not documented." "set help" - gdb_test "help set print" "set print s -- This command is not documented.*" "general help" + gdb_test "help show print s" \ + [multi_line \ + "^Show the current value of 'print s'\\." \ + "This command is not documented\\."] \ + "show help" + gdb_test "help set print s" \ + [multi_line \ + "Set the current value of 'print s'\\." \ + "This command is not documented\\."] \ + "set help" + gdb_test "help set print" \ + "set print s -- Set the current value of 'print s'\\..*" \ + "general help" } -rename scm_param_test_maybe_no_output "" - -# Test a color parameter. +gdb_test_multiline "create set/show foo1 prefix commands" \ + "guile" "" \ + "(register-command! (make-command \"set foo1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "(register-command! (make-command \"show foo1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "end" -with_ansi_styling_terminal { - # This enables 256 colors support and disables colors approximation. - setenv TERM xterm-256color - setenv COLORTERM truecolor +gdb_test_multiline "create set/show foo1 baz1 prefix commands" \ + "guile" "" \ + "(register-command! (make-command \"set foo1 baz1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "(register-command! (make-command \"show foo1 baz1\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "end" - # Start with a fresh gdb. - gdb_exit - gdb_start - gdb_reinitialize_dir $srcdir/$subdir +gdb_test_multiline "create 'foo bar' parameter" \ + "guile" "" \ + "(register-parameter! (make-parameter \"foo bar\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:parameter-type PARAM_BOOLEAN" "" \ + " #:show-func (lambda (self value)" "" \ + " (format #f \"The state of 'foo bar' is ~a.\" value))" "" \ + " #:initial-value #t))" "" \ + "end" - gdb_install_guile_utils - gdb_install_guile_module +gdb_test "show foo1 bar" "^The state of 'foo bar' is on\\." "show parameter 'foo bar'" - # We use "." here instead of ":" so that this works on win32 too. - set escaped_directory [string_to_regexp "$srcdir/$subdir"] +gdb_test_multiline "create set/show foo2 prefix commands" \ + "guile" "" \ + "(register-command! (make-command \"set foo2\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "(register-command! (make-command \"show foo2\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:prefix? #t))" "" \ + "end" "" + +gdb_test_multiline "create ambiguous 'foo baz' parameter" \ + "guile" "" \ + "(register-parameter! (make-parameter \"foo baz\"" "" \ + " #:command-class COMMAND_OBSCURE" "" \ + " #:parameter-type PARAM_BOOLEAN" "" \ + " #:show-func (lambda (self value)" "" \ + " (format #f \"The state of 'foo baz' is ~a.\" value))" "" \ + " #:initial-value #t))" "" \ + "end" \ + [multi_line \ + "Out of range: could not find command prefix 'foo' in position 1: \"foo baz\"" \ + "Error while executing Scheme code."] - gdb_test_multiline "color gdb parameter" \ +with_test_prefix "empty doc string" { + gdb_test_multiline "empty doc string parameter" \ "guile" "" \ - "(define test-color-param" "" \ - " (make-parameter \"print test-color-param\"" "" \ - " #:command-class COMMAND_DATA" "" \ - " #:parameter-type PARAM_COLOR" "" \ - " #:doc \"When set, test param does something useful. When disabled, does nothing.\"" "" \ - " #:show-doc \"Show the state of the test-color-param.\"" "" \ - " #:set-doc \"Set the state of the test-color-param.\"" "" \ - " #:show-func (lambda (self value)" "" \ - " (format #f \"The state of the test-color-param is ~a.\" value))" "" \ - " #:initial-value (make-color \"green\")))" "" \ - "(register-parameter! test-color-param)" "" \ + "(register-parameter! (make-parameter \"empty-doc-string\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_ZINTEGER" "" \ + " #:doc \"\"" "" \ + " #:set-doc \"Set doc string.\"" "" \ + " #:show-doc \"Show doc string.\"))" "" \ "end" - with_test_prefix "test-color-param" { - with_test_prefix "initial-value" { - gdb_test "guile (print (parameter-value test-color-param))" "= #<gdb:color green COLORSPACE_ANSI_8COLOR>" "color parameter value (green)" - gdb_test "show print test-color-param" "The state of the test-color-param is green." "show initial value" - gdb_test_no_output "set print test-color-param 255" - } - with_test_prefix "new-value" { - gdb_test "show print test-color-param" "The state of the test-color-param is 255." "show new value" - gdb_test "guile (print (parameter-value test-color-param))" "= #<gdb:color 255 COLORSPACE_XTERM_256COLOR>" "color parameter value (255)" - gdb_test "set print test-color-param 256" "integer 256 out of range.*" "set invalid color parameter" + gdb_test "help set empty-doc-string" "^Set doc string\\." + gdb_test "help show empty-doc-string" "^Show doc string\\." +} + +with_test_prefix "set/show parameter" { + # This first set/show prefix command doesn't have an invoke + # method. As such, GDB installs the default invoke behaviour; set + # prints the full list of sub-commands, and show prints all the + # sub-command values. + gdb_test_multiline "Setup set/show parameter prefix with no invoke" \ + "guile" "" \ + "(register-command! (make-command \"set test-prefix\"" "" \ + " #:prefix? #t" "" \ + " #:command-class COMMAND_NONE))" ""\ + "(register-command! (make-command \"show test-prefix\"" "" \ + " #:prefix? #t" "" \ + " #:command-class COMMAND_NONE))" ""\ + "(register-parameter! (make-parameter \"test-prefix param-1\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_BOOLEAN))" "" \ + "(register-parameter! (make-parameter \"test-prefix param-2\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_UINTEGER))" "" \ + "(register-parameter! (make-parameter \"test-prefix param-3\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_STRING))" "" \ + "end" "" + + gdb_test "set test-prefix" \ + [multi_line \ + "List of \"set test-prefix\" subcommands:" \ + "" \ + "set test-prefix param-1 -- Set the current value of 'test-prefix param-1'." \ + "set test-prefix param-2 -- Set the current value of 'test-prefix param-2'." \ + "set test-prefix param-3 -- Set the current value of 'test-prefix param-3'." \ + "" \ + "Type \"help set test-prefix\" followed by subcommand name for full documentation\\." \ + "Type \"apropos word\" to search for commands related to \"word\"\\." \ + "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \ + "Command name abbreviations are allowed if unambiguous\\."] + + gdb_test "show test-prefix" \ + [multi_line \ + "test-prefix param-1: The current value of 'test-prefix param-1' is off\\." \ + "test-prefix param-2: The current value of 'test-prefix param-2' is 0\\." \ + "test-prefix param-3: The current value of 'test-prefix param-3' is \"\"\\."] + + # This next set/show prefix has an invoke method, which will be + # called instead of the default behaviour tested above. + gdb_test_multiline "Setup set/show parameter prefix with invoke" \ + "guile" "" \ + "(register-command! (make-command \"set test-prefix-2\"" "" \ + " #:prefix? #t" "" \ + " #:command-class COMMAND_NONE" ""\ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display \"invoke -- set\\n\"))))" "" \ + "(register-command! (make-command \"show test-prefix-2\"" "" \ + " #:prefix? #t" "" \ + " #:command-class COMMAND_NONE" ""\ + " #:invoke (lambda (self arg from-tty)" "" \ + " (display \"invoke -- show\\n\"))))" "" \ + "(register-parameter! (make-parameter \"test-prefix-2 param-1\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_BOOLEAN))" "" \ + "(register-parameter! (make-parameter \"test-prefix-2 param-2\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_UINTEGER))" "" \ + "(register-parameter! (make-parameter \"test-prefix-2 param-3\"" "" \ + " #:command-class COMMAND_NONE" "" \ + " #:parameter-type PARAM_STRING))" "" \ + "end" "" + + gdb_test "set test-prefix-2" "^invoke -- set" + + gdb_test "show test-prefix-2" "^invoke -- show" +} + +rename scm_param_test_maybe_no_output "" + +# Test a color parameter. + +if { ![is_remote host] } { + with_ansi_styling_terminal { + + # This enables 256 colors support and disables colors approximation. + setenv TERM xterm-256color + setenv COLORTERM truecolor + + # Start with a fresh gdb. + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + + gdb_install_guile_utils + gdb_install_guile_module + + # We use "." here instead of ":" so that this works on win32 too. + set escaped_directory [string_to_regexp "$srcdir/$subdir"] + + gdb_test_multiline "color gdb parameter" \ + "guile" "" \ + "(define test-color-param" "" \ + " (make-parameter \"print test-color-param\"" "" \ + " #:command-class COMMAND_DATA" "" \ + " #:parameter-type PARAM_COLOR" "" \ + " #:doc \"When set, test param does something useful. When disabled, does nothing.\"" "" \ + " #:show-doc \"Show the state of the test-color-param.\"" "" \ + " #:set-doc \"Set the state of the test-color-param.\"" "" \ + " #:show-func (lambda (self value)" "" \ + " (format #f \"The state of the test-color-param is ~a.\" value))" "" \ + " #:initial-value (make-color \"green\")))" "" \ + "(register-parameter! test-color-param)" "" \ + "end" + + with_test_prefix "test-color-param" { + with_test_prefix "initial-value" { + gdb_test "guile (print (parameter-value test-color-param))" "= #<gdb:color green COLORSPACE_ANSI_8COLOR>" "color parameter value (green)" + gdb_test "show print test-color-param" "The state of the test-color-param is green." "show initial value" + gdb_test_no_output "set print test-color-param 255" + } + with_test_prefix "new-value" { + gdb_test "show print test-color-param" "The state of the test-color-param is 255." "show new value" + gdb_test "guile (print (parameter-value test-color-param))" "= #<gdb:color 255 COLORSPACE_XTERM_256COLOR>" "color parameter value (255)" + gdb_test "set print test-color-param 256" "integer 256 out of range.*" "set invalid color parameter" + } } } } diff --git a/gdb/testsuite/gdb.guile/scm-ports.exp b/gdb/testsuite/gdb.guile/scm-ports.exp index c67ebd2..a0af289 100644 --- a/gdb/testsuite/gdb.guile/scm-ports.exp +++ b/gdb/testsuite/gdb.guile/scm-ports.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -84,7 +84,7 @@ foreach variation $port_variations { # Test read/write of memory ports. proc test_mem_port_rw { buffered } { - if $buffered { + if {$buffered} { set mode "r+" } else { set mode "r+0" @@ -115,7 +115,7 @@ proc test_mem_port_rw { buffered } { "define new-value" gdb_test "guile (print (put-bytevector rw-mem-port (make-bytevector 1 new-value)))" \ "= #<unspecified>" - if $buffered { + if {$buffered} { # Value shouldn't be in memory yet. gdb_test "guile (print (value=? (parse-and-eval \"*(char*) \$sp\") byte-at-sp))" \ "= #t" \ diff --git a/gdb/testsuite/gdb.guile/scm-pretty-print.exp b/gdb/testsuite/gdb.guile/scm-pretty-print.exp index 09717a9..62fb8e2 100644 --- a/gdb/testsuite/gdb.guile/scm-pretty-print.exp +++ b/gdb/testsuite/gdb.guile/scm-pretty-print.exp @@ -33,9 +33,10 @@ proc run_lang_tests {exefile lang} { set nl "\[\r\n\]+" # Start with a fresh gdb. - clean_restart $exefile + clean_restart + gdb_load $exefile - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return } @@ -114,9 +115,9 @@ run_lang_tests "${binfile}-cxx" "c++" # Run various other tests. -clean_restart $binfile +clean_restart $::testfile -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-section-script.exp b/gdb/testsuite/gdb.guile/scm-section-script.exp index 4c0238d..3a68adc 100644 --- a/gdb/testsuite/gdb.guile/scm-section-script.exp +++ b/gdb/testsuite/gdb.guile/scm-section-script.exp @@ -94,7 +94,7 @@ gdb_test "info auto-load guile-scripts ${testfile}" "Yes.*${testfile}.scm.*" gdb_test "info auto-load guile-scripts no-script-matches-this" \ "No auto-load scripts matching no-script-matches-this." -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-symbol.exp b/gdb/testsuite/gdb.guile/scm-symbol.exp index b6ebffd..2ddd3f0 100644 --- a/gdb/testsuite/gdb.guile/scm-symbol.exp +++ b/gdb/testsuite/gdb.guile/scm-symbol.exp @@ -54,7 +54,7 @@ gdb_test "guile (print (symbol-value qq-var))" \ gdb_test "guile (print (symbol-needs-frame? qq-var))" \ "= #f" "print whether qq needs a frame" -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -141,9 +141,9 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" executable " return -1 } -clean_restart ${binfile}-cxx +clean_restart ${::testfile}-cxx -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -172,7 +172,7 @@ gdb_test "guile (print (= (symbol-addr-class cplusfunc) SYMBOL_LOC_BLOCK))" "= # # test as it unloads the object file in GDB. # Start with a fresh gdb. clean_restart ${testfile} -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-symtab.exp b/gdb/testsuite/gdb.guile/scm-symtab.exp index 621bbbe..c19b460 100644 --- a/gdb/testsuite/gdb.guile/scm-symtab.exp +++ b/gdb/testsuite/gdb.guile/scm-symtab.exp @@ -27,7 +27,7 @@ if {[prepare_for_testing "failed to prepare" $testfile \ return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -143,7 +143,7 @@ clean_restart ${testfile} # Test find-pc-line. # The following tests require execution. -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-type.exp b/gdb/testsuite/gdb.guile/scm-type.exp index 1167dd1..d974c86 100644 --- a/gdb/testsuite/gdb.guile/scm-type.exp +++ b/gdb/testsuite/gdb.guile/scm-type.exp @@ -38,13 +38,14 @@ proc build_inferior {exefile lang} { proc restart_gdb {exefile} { global srcdir subdir - clean_restart $exefile + clean_restart + gdb_load $exefile if { ![allow_guile_tests] } { return 0 } - if ![gdb_guile_runto_main] { + if {![gdb_guile_runto_main]} { return 0 } gdb_scm_test_silent_cmd "guile (use-modules (gdb iterator))" \ @@ -274,7 +275,7 @@ proc test_range {} { if { [build_inferior "${binfile}" "c"] < 0 } { return } -if ![restart_gdb "${binfile}"] { +if {![restart_gdb "${binfile}"]} { return } @@ -290,7 +291,7 @@ with_test_prefix "lang_c" { if { [build_inferior "${binfile}-cxx" "c++"] < 0 } { return } -if ![restart_gdb "${binfile}-cxx"] { +if {![restart_gdb "${binfile}-cxx"]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-value-cc.exp b/gdb/testsuite/gdb.guile/scm-value-cc.exp index 202f01e..f65be25 100644 --- a/gdb/testsuite/gdb.guile/scm-value-cc.exp +++ b/gdb/testsuite/gdb.guile/scm-value-cc.exp @@ -26,7 +26,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { return } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.guile/scm-value.exp b/gdb/testsuite/gdb.guile/scm-value.exp index 1567b13..ea77d8f 100644 --- a/gdb/testsuite/gdb.guile/scm-value.exp +++ b/gdb/testsuite/gdb.guile/scm-value.exp @@ -309,9 +309,10 @@ proc test_value_after_death {} { proc test_subscript_regression {exefile lang} { # Start with a fresh gdb. - clean_restart ${exefile} + clean_restart + gdb_load ${exefile} - if ![gdb_guile_runto_main ] { + if {![gdb_guile_runto_main ]} { return } @@ -427,7 +428,7 @@ if { [build_inferior "${binfile}" "c"] < 0 } { } # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_install_guile_utils gdb_install_guile_module @@ -437,7 +438,7 @@ test_value_hash # The following tests require execution. -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } @@ -446,7 +447,7 @@ test_inferior_function_call test_strings test_value_after_death -# Test either C or C++ values. +# Test either C or C++ values. test_subscript_regression "${binfile}" "c" diff --git a/gdb/testsuite/gdb.guile/types-module.exp b/gdb/testsuite/gdb.guile/types-module.exp index c9d7067..e8412cc 100644 --- a/gdb/testsuite/gdb.guile/types-module.exp +++ b/gdb/testsuite/gdb.guile/types-module.exp @@ -30,7 +30,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $flags] } { return -1 } -if ![gdb_guile_runto_main] { +if {![gdb_guile_runto_main]} { return } diff --git a/gdb/testsuite/gdb.linespec/cp-replace-typedefs-ns-template.exp b/gdb/testsuite/gdb.linespec/cp-replace-typedefs-ns-template.exp index 77757fc..db6ed69 100644 --- a/gdb/testsuite/gdb.linespec/cp-replace-typedefs-ns-template.exp +++ b/gdb/testsuite/gdb.linespec/cp-replace-typedefs-ns-template.exp @@ -93,7 +93,7 @@ foreach loc { "NS1::NS2::AliasTempl<int>::static_method<int>(NS1::NS2::object*)" "NS1::NS2::AliasTempl<int>::static_method<int>(NS1::NS2::object_p)" } { - if [test_compiler_info gcc*] { + if {[test_compiler_info gcc*]} { # While Clang emits "AliasTempl<int>" (etc.) typedefs, GCC # emits "AliasTempl" typedefs with no template parameter info. setup_xfail gcc/95437 *-*-* @@ -104,7 +104,7 @@ foreach loc { # instead of succeeding with e.g., "AliasTempl<int>" preserved in # the location text. If that ever happens, we'll need to update # these tests. - if [test_compiler_info gcc*] { + if {[test_compiler_info gcc*]} { check_setting_bp_fails "b $loc" } } diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp index 6c1c551..2f1cc84 100644 --- a/gdb/testsuite/gdb.linespec/cpcompletion.exp +++ b/gdb/testsuite/gdb.linespec/cpcompletion.exp @@ -779,7 +779,7 @@ proc test_makem_1 {arglist_list expected_list} { send_log "expecting $expected_list\n" # Do list equality via canonical strings. - if {[expr {[list {*}$expected_list] eq [list {*}$result]}]} { + if {[string eq $expected_list eq $result]} { pass "makem unit test: $arglist" } else { fail "makem unit test: $arglist" diff --git a/gdb/testsuite/gdb.linespec/explicit.exp b/gdb/testsuite/gdb.linespec/explicit.exp index 12eaa51..b859b44 100644 --- a/gdb/testsuite/gdb.linespec/explicit.exp +++ b/gdb/testsuite/gdb.linespec/explicit.exp @@ -608,7 +608,7 @@ namespace eval $testfile { } # Test interaction of condition command and explicit linespec conditons. - clean_restart [standard_output_file $exefile] + clean_restart $exefile set tst "condition_command overrides explicit linespec condition" if {![runto_main]} { diff --git a/gdb/testsuite/gdb.linespec/keywords.exp b/gdb/testsuite/gdb.linespec/keywords.exp index 42a9228..b1df13a 100644 --- a/gdb/testsuite/gdb.linespec/keywords.exp +++ b/gdb/testsuite/gdb.linespec/keywords.exp @@ -22,7 +22,7 @@ if {[prepare_for_testing "failed to prepare" $exefile $srcfile {debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.linespec/line-breakpoint-outside-function.exp b/gdb/testsuite/gdb.linespec/line-breakpoint-outside-function.exp index 012be6b..120ee6c 100644 --- a/gdb/testsuite/gdb.linespec/line-breakpoint-outside-function.exp +++ b/gdb/testsuite/gdb.linespec/line-breakpoint-outside-function.exp @@ -32,7 +32,7 @@ if {[build_executable "failed to prepare" ${testfile} ${srcfile} $opts]} { } proc do_test {} { - clean_restart $::binfile + clean_restart $::testfile # To make things easier, just so we don't have to deal with the question. gdb_test_no_output "set breakpoint pending on" diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp index 69744dd..86b55bb 100644 --- a/gdb/testsuite/gdb.linespec/linespec.exp +++ b/gdb/testsuite/gdb.linespec/linespec.exp @@ -194,6 +194,12 @@ gdb_test "break lspec.h:$line" \ "Breakpoint \[0-9\]+ at $hex: file .*lspec.h, line $line." \ "set breakpoint in f1" +# This should only have a single location -- in no_multi_locs. +set line [gdb_get_line_number no_multi_locs] +gdb_test "break $line" \ + "Breakpoint \[0-9\]+ at $hex: file .*$srcfile, line $line." \ + "set breakpoint at no_multi_locs" + # # Multi-inferior tests. # diff --git a/gdb/testsuite/gdb.linespec/ls-errs.exp b/gdb/testsuite/gdb.linespec/ls-errs.exp index 303fd9f..56f9467 100644 --- a/gdb/testsuite/gdb.linespec/ls-errs.exp +++ b/gdb/testsuite/gdb.linespec/ls-errs.exp @@ -22,7 +22,7 @@ proc do_test {lang} { standard_testfile set exefile $testfile - if [info exists compiler_info] { + if {[info exists compiler_info]} { # Unsetting compiler_info allows us to switch compilers # used by prepare_for_testing. unset compiler_info @@ -89,9 +89,8 @@ proc do_test {lang} { proc test_break {linespec msg_id args} { global error_messages - gdb_test "break $linespec" [string_to_regexp \ - [eval format \$error_messages($msg_id) \ - $args]] \ + gdb_test "break $linespec" \ + [string_to_regexp [format $error_messages($msg_id) {*}$args]] \ "'break $linespec'" } diff --git a/gdb/testsuite/gdb.linespec/lspec.cc b/gdb/testsuite/gdb.linespec/lspec.cc index bb660fb..ab0a193 100644 --- a/gdb/testsuite/gdb.linespec/lspec.cc +++ b/gdb/testsuite/gdb.linespec/lspec.cc @@ -13,6 +13,8 @@ int body_elsewhere() #include "body.h" } +void no_multi_locs () { {int var = 0;} } + int main() { return dupname(0) + m(0) + n(0) + f1() + f2() + body_elsewhere(); diff --git a/gdb/testsuite/gdb.linespec/macro-relative.exp b/gdb/testsuite/gdb.linespec/macro-relative.exp index 94ab16a..c076e02 100644 --- a/gdb/testsuite/gdb.linespec/macro-relative.exp +++ b/gdb/testsuite/gdb.linespec/macro-relative.exp @@ -41,7 +41,7 @@ clean_restart ${testfile} # Test macros respect DW_AT_comp_dir. # "list header_two_func" does not set exactly the one line we want. -if ![runto header_two_func] { +if {![runto header_two_func]} { return -1 } diff --git a/gdb/testsuite/gdb.linespec/skip-two.exp b/gdb/testsuite/gdb.linespec/skip-two.exp index 6e3ab30..cfd91da 100644 --- a/gdb/testsuite/gdb.linespec/skip-two.exp +++ b/gdb/testsuite/gdb.linespec/skip-two.exp @@ -31,7 +31,7 @@ if {[prepare_for_testing "failed to prepare" $execfile \ gdb_test "skip function dupname" \ {Function dupname will be skipped when stepping\.} -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -63,7 +63,7 @@ gdb_test_no_output "skip delete 1" gdb_test "skip file thefile.cc" \ {File thefile\.cc will be skipped when stepping\.} -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.linespec/thread.exp b/gdb/testsuite/gdb.linespec/thread.exp index d2f7b25..f5cdf8b 100644 --- a/gdb/testsuite/gdb.linespec/thread.exp +++ b/gdb/testsuite/gdb.linespec/thread.exp @@ -23,7 +23,7 @@ if {[prepare_for_testing "failed to prepare" $exefile $srcfile {debug}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.exp b/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.exp index 3fd9b81..0565681 100644 --- a/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.exp +++ b/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.exp @@ -42,7 +42,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" $objsfile object {}] != "" return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } @@ -54,7 +54,7 @@ if [mi_runto func_nofb_marker] { } # GDB could have crashed. -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/gdb2549.exp b/gdb/testsuite/gdb.mi/gdb2549.exp index 796c1fa..5aabc3b 100644 --- a/gdb/testsuite/gdb.mi/gdb2549.exp +++ b/gdb/testsuite/gdb.mi/gdb2549.exp @@ -94,7 +94,7 @@ proc register_tests { } { register_test 666 t $binary } -mi_clean_restart $binfile +mi_clean_restart $::testfile register_tests_no_exec diff --git a/gdb/testsuite/gdb.mi/gdb669.exp b/gdb/testsuite/gdb.mi/gdb669.exp index 086d3c1..da1db64 100644 --- a/gdb/testsuite/gdb.mi/gdb669.exp +++ b/gdb/testsuite/gdb.mi/gdb669.exp @@ -30,7 +30,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main check_mi_and_console_threads "at main" diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp index 587481c..9ef6fb7 100644 --- a/gdb/testsuite/gdb.mi/gdb701.exp +++ b/gdb/testsuite/gdb.mi/gdb701.exp @@ -35,7 +35,7 @@ if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable debug] != ""} { # If it doesn't, Bad Things Happen(TM). # Run to main -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main # Step over "foo = 0" diff --git a/gdb/testsuite/gdb.mi/gdb792.exp b/gdb/testsuite/gdb.mi/gdb792.exp index f894eea..64f218a 100644 --- a/gdb/testsuite/gdb.mi/gdb792.exp +++ b/gdb/testsuite/gdb.mi/gdb792.exp @@ -28,7 +28,7 @@ if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != "" return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main diff --git a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp index ff35109..5f9e49e 100644 --- a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp +++ b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp @@ -30,7 +30,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile \ save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\" -ex \"set mi-async\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_detect_async @@ -54,7 +54,7 @@ mi_send_resuming_command "exec-continue --thread-group i1" \ # We can't run a second inferior on stub targets. We can still test with one # inferior and ensure that the command has the desired effect. -set use_second_inferior [expr {![use_gdb_stub]}] +set use_second_inferior [expr {![use_gdb_stub] && [allow_multi_inferior_tests]}] if { $use_second_inferior } { mi_gdb_test "-add-inferior" \ diff --git a/gdb/testsuite/gdb.mi/mi-add-inferior.exp b/gdb/testsuite/gdb.mi/mi-add-inferior.exp index d110e68..8c4926f 100644 --- a/gdb/testsuite/gdb.mi/mi-add-inferior.exp +++ b/gdb/testsuite/gdb.mi/mi-add-inferior.exp @@ -26,7 +26,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -mi_clean_restart ${binfile} +mi_clean_restart ${::testfile} # Start execution to establish a connection. mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-async-run.exp b/gdb/testsuite/gdb.mi/mi-async-run.exp index 8352803..3df8769 100644 --- a/gdb/testsuite/gdb.mi/mi-async-run.exp +++ b/gdb/testsuite/gdb.mi/mi-async-run.exp @@ -35,7 +35,7 @@ proc test_async_run {} { set GDBFLAGS [concat $GDBFLAGS " -ex \"set mi-async on\""] - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-async.exp b/gdb/testsuite/gdb.mi/mi-async.exp index 09db7f9..1c4e06c 100644 --- a/gdb/testsuite/gdb.mi/mi-async.exp +++ b/gdb/testsuite/gdb.mi/mi-async.exp @@ -42,7 +42,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb save_vars { GDBFLAGS } { set GDBFLAGS [concat $GDBFLAGS " -ex \"set mi-async on\""] - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } } diff --git a/gdb/testsuite/gdb.mi/mi-break-qualified.exp b/gdb/testsuite/gdb.mi/mi-break-qualified.exp index b5e5e78..9adc2d9 100644 --- a/gdb/testsuite/gdb.mi/mi-break-qualified.exp +++ b/gdb/testsuite/gdb.mi/mi-break-qualified.exp @@ -93,7 +93,7 @@ proc test_break_qualified {} { "delete temp breakpoints" } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp index bb982c3..cb7c14b 100644 --- a/gdb/testsuite/gdb.mi/mi-break.exp +++ b/gdb/testsuite/gdb.mi/mi-break.exp @@ -346,7 +346,7 @@ proc_with_prefix test_forced_conditions {} { set loc [mi_make_breakpoint_loc -enabled "N"] set args [list -cond "bad" -locations "\\\[$loc\\\]"] - set bp [eval mi_make_breakpoint_multi $args] + set bp [mi_make_breakpoint_multi {*}$args] mi_gdb_test "-break-insert -c bad --force-condition callme" \ "${warning}\\^done,$bp" \ @@ -398,7 +398,7 @@ proc test_break {mi_mode} { } else { set start_ops "" } - if [mi_clean_restart $binfile $start_ops ] { + if [mi_clean_restart $::testfile $start_ops ] { return } diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-changed.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-changed.exp index 9cb91de..46561e4 100644 --- a/gdb/testsuite/gdb.mi/mi-breakpoint-changed.exp +++ b/gdb/testsuite/gdb.mi/mi-breakpoint-changed.exp @@ -48,7 +48,7 @@ proc test_insert_delete_modify { } { global lib_sl1 lib_sl2 global binfile - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_load_shlibs $lib_sl1 $lib_sl2 @@ -184,7 +184,7 @@ proc test_pending_resolved { } { global lib_sl1 lib_sl2 global mi_gdb_prompt - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } mi_load_shlibs $lib_sl1 $lib_sl2 @@ -279,7 +279,7 @@ proc test_auto_disable { } { global lib_sl1 lib_sl2 global binfile - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_load_shlibs $lib_sl1 $lib_sl2 diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp index cbf9f57..7995846 100644 --- a/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp +++ b/gdb/testsuite/gdb.mi/mi-breakpoint-multiple-locations.exp @@ -56,7 +56,7 @@ proc do_test { mi_version use_fix_flag expect_fixed_output } { global MIFLAGS decimal binfile set MIFLAGS "-i=mi${mi_version}" - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-breakpoint-script.exp b/gdb/testsuite/gdb.mi/mi-breakpoint-script.exp index af514e8..ce30d44 100644 --- a/gdb/testsuite/gdb.mi/mi-breakpoint-script.exp +++ b/gdb/testsuite/gdb.mi/mi-breakpoint-script.exp @@ -51,7 +51,7 @@ proc do_test { mi_version use_fix_flag expect_fixed_output } { save_vars { ::MIFLAGS } { set ::MIFLAGS "-i=mi${mi_version}" - mi_clean_restart $::binfile + mi_clean_restart $::testfile } if $use_fix_flag { diff --git a/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp b/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp index 9053b18..ec023e6 100644 --- a/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp +++ b/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return -1 } @@ -46,7 +46,7 @@ proc restart_for_test {} { global srcdir subdir binfile srcfile global main_lineno - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-catch-load.exp b/gdb/testsuite/gdb.mi/mi-catch-load.exp index a9a5fdc..3c36cc9 100644 --- a/gdb/testsuite/gdb.mi/mi-catch-load.exp +++ b/gdb/testsuite/gdb.mi/mi-catch-load.exp @@ -36,7 +36,7 @@ gdb_download_shlib $binfile2 # test -catch-load with_test_prefix "catch-load" { - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_locate_shlib $binfile2 mi_runto_main @@ -63,7 +63,7 @@ with_test_prefix "catch-load" { # test -catch-unload with_test_prefix "catch-unload" { - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_locate_shlib $binfile2 mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-cli.exp b/gdb/testsuite/gdb.mi/mi-cli.exp index a3ff7eb..b59a5ed 100644 --- a/gdb/testsuite/gdb.mi/mi-cli.exp +++ b/gdb/testsuite/gdb.mi/mi-cli.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_gdb_test "-interpreter-exec" \ {\^error,msg="-interpreter-exec: Usage: -interpreter-exec interp command"} \ diff --git a/gdb/testsuite/gdb.mi/mi-cmd-param-changed.exp b/gdb/testsuite/gdb.mi/mi-cmd-param-changed.exp index 5587b76..24d12c1 100644 --- a/gdb/testsuite/gdb.mi/mi-cmd-param-changed.exp +++ b/gdb/testsuite/gdb.mi/mi-cmd-param-changed.exp @@ -31,7 +31,7 @@ proc test_command_param_changed { } { global binfile with_test_prefix "cmd param" { - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_runto_main if { $scheduler_locking_supported } { diff --git a/gdb/testsuite/gdb.mi/mi-cmd-user-context.exp b/gdb/testsuite/gdb.mi/mi-cmd-user-context.exp index 806ed4c..324de5a 100644 --- a/gdb/testsuite/gdb.mi/mi-cmd-user-context.exp +++ b/gdb/testsuite/gdb.mi/mi-cmd-user-context.exp @@ -29,7 +29,7 @@ set main_break_line [gdb_get_line_number "main break line"] set any "\[^\r\n\]*" -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_create_breakpoint "$srcfile:$main_break_line" "set breakpoint in main" mi_run_cmd mi_expect_stop "breakpoint-hit" "main" "" $srcfile $main_break_line \ diff --git a/gdb/testsuite/gdb.mi/mi-complete.exp b/gdb/testsuite/gdb.mi/mi-complete.exp index 22acda3..ad29b3f 100644 --- a/gdb/testsuite/gdb.mi/mi-complete.exp +++ b/gdb/testsuite/gdb.mi/mi-complete.exp @@ -26,7 +26,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debu return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile # Don't run to main to avoid increasing the search scope to include # debug info of shared libraries like glibc, libgcc, etc. diff --git a/gdb/testsuite/gdb.mi/mi-condbreak-call-thr-state.exp b/gdb/testsuite/gdb.mi/mi-condbreak-call-thr-state.exp index 02d02b2..7708a6d 100644 --- a/gdb/testsuite/gdb.mi/mi-condbreak-call-thr-state.exp +++ b/gdb/testsuite/gdb.mi/mi-condbreak-call-thr-state.exp @@ -59,7 +59,7 @@ proc test { variant } { return -1 } - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-condbreak-fail.exp b/gdb/testsuite/gdb.mi/mi-condbreak-fail.exp index 43b1e2f..5bd8993 100644 --- a/gdb/testsuite/gdb.mi/mi-condbreak-fail.exp +++ b/gdb/testsuite/gdb.mi/mi-condbreak-fail.exp @@ -35,7 +35,7 @@ if [build_executable ${testfile}.exp ${binfile} ${srcfile}] { proc run_test { unwind_on_signal } { - if {[mi_clean_restart $::binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp b/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp index 9897b2b..b4960a8 100644 --- a/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp +++ b/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp @@ -16,7 +16,7 @@ # Check that when GDB fails to evaluate the condition of a conditional # breakpoint we only get one *stopped notification. In this test case # the breakpoint condition fails due to throwing an uncaught C++ -# excpetion. +# exception. require allow_cplus_tests @@ -38,7 +38,7 @@ if [build_executable ${testfile}.exp ${binfile} ${srcfile} {debug c++}] { proc run_test { unwind_on_exception } { - if {[mi_clean_restart $::binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp index efb1ea9..861ef42 100644 --- a/gdb/testsuite/gdb.mi/mi-console.exp +++ b/gdb/testsuite/gdb.mi/mi-console.exp @@ -53,7 +53,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-corefile.exp b/gdb/testsuite/gdb.mi/mi-corefile.exp index 3f0e720..b491486 100644 --- a/gdb/testsuite/gdb.mi/mi-corefile.exp +++ b/gdb/testsuite/gdb.mi/mi-corefile.exp @@ -29,6 +29,7 @@ if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} { set corefile [core_find $binfile {}] if {$corefile == ""} { + untested "unable to create or find corefile" return 0 } diff --git a/gdb/testsuite/gdb.mi/mi-detach.exp b/gdb/testsuite/gdb.mi/mi-detach.exp index ff983c1..b485a9b 100644 --- a/gdb/testsuite/gdb.mi/mi-detach.exp +++ b/gdb/testsuite/gdb.mi/mi-detach.exp @@ -25,7 +25,7 @@ if {[build_executable $testfile.exp $testfile $srcfile {debug}] == -1} { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main mi_gdb_test "-target-detach" "=thread-exited,id=\"1\".*=thread-group-exited,id=\"i1\".*" "detach" diff --git a/gdb/testsuite/gdb.mi/mi-disassemble.exp b/gdb/testsuite/gdb.mi/mi-disassemble.exp index 15ead33..90f79e3 100644 --- a/gdb/testsuite/gdb.mi/mi-disassemble.exp +++ b/gdb/testsuite/gdb.mi/mi-disassemble.exp @@ -345,7 +345,7 @@ proc test_disassembly_opcode_format {} { "data-disassemble checking the opcodes bytes format" } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main test_disassembly_only test_disassembly_with_opcodes diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp index c0208eb..0e1d0bc 100644 --- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp +++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp @@ -65,9 +65,19 @@ if { $dyln_name eq "" } { set bp_main [gdb_get_line_number "bp.main" $srcfile] set bp_loaded [gdb_get_line_number "bp.loaded" $srcfile] +# If the dynamic linker path contains a symlink, some instances show the real +# path instead of the original path. Accept both. +lassign [remote_exec target realpath "$dyln_name"] realpath_ret dyln_realpath_name + +if { $realpath_ret == 0 } { + set dyln_realpath_name [string trim $dyln_realpath_name] +} else { + set dyln_realpath_name "not-a-valid-path" +} + # Return true if FILENAME is the dynamic linker. Otherwise return false. proc is_dyln { filename } { - return [expr {$filename eq $::dyln_name}] + return [expr {$filename eq $::dyln_name || $filename eq $::dyln_realpath_name}] } # Run 'info sharedlibrary' and count the number of mappings that look @@ -81,7 +91,7 @@ proc get_dyld_info {} { set dyld_count 0 set dyld_start_addr "" gdb_test_multiple "info sharedlibrary" "" { - -re "~\"From\\s+To(\\s+NS)?\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" { + -re "~\"From\\s+To(\\s+Linker NS)?\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" { exp_continue } -re "^~\"($::hex)\\s+${::hex}(\\s+$::decimal)?\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" { @@ -122,7 +132,7 @@ proc get_dyld_info {} { # number of unload events for the libraries created for this test, and # additionally, check for dynamic linker unload events. proc check_solib_unload_events {} { - mi_clean_restart $::binfile + mi_clean_restart $::testfile if {[mi_runto_main] == -1} { return diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp b/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp index c3e1bdf..0584a86 100644 --- a/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp +++ b/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp @@ -52,7 +52,7 @@ if { [build_executable "build exec" $binfile $srcfile $opts] == -1} { set bp_line [gdb_get_line_number "Break here" $srcfile] # Start the inferior. -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main # Place a breakpoint at the dlopen() line. diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-pending.exp b/gdb/testsuite/gdb.mi/mi-dprintf-pending.exp index 2df9ad4..3685e42 100644 --- a/gdb/testsuite/gdb.mi/mi-dprintf-pending.exp +++ b/gdb/testsuite/gdb.mi/mi-dprintf-pending.exp @@ -39,7 +39,7 @@ if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-dprintf.exp b/gdb/testsuite/gdb.mi/mi-dprintf.exp index 5d448e4..9d0b95a 100644 --- a/gdb/testsuite/gdb.mi/mi-dprintf.exp +++ b/gdb/testsuite/gdb.mi/mi-dprintf.exp @@ -31,7 +31,7 @@ if {[build_executable $testfile.exp $testfile $srcfile $flags] == -1} { set bp_location1 [gdb_get_line_number "set breakpoint 1 here"] set dp_location1 [gdb_get_line_number "set dprintf 1 here"] -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main set i 0 diff --git a/gdb/testsuite/gdb.mi/mi-eval.exp b/gdb/testsuite/gdb.mi/mi-eval.exp index 27c27f5..2b21895 100644 --- a/gdb/testsuite/gdb.mi/mi-eval.exp +++ b/gdb/testsuite/gdb.mi/mi-eval.exp @@ -32,7 +32,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-exec-run.exp b/gdb/testsuite/gdb.mi/mi-exec-run.exp index a7a61b8..43406cf 100644 --- a/gdb/testsuite/gdb.mi/mi-exec-run.exp +++ b/gdb/testsuite/gdb.mi/mi-exec-run.exp @@ -30,6 +30,8 @@ set MIFLAGS "-i=mi" # cannot use it, then there is no point in running this testcase. require !use_gdb_stub +set have_startup_shell [have_startup_shell] + standard_testfile mi-start.c if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { @@ -172,6 +174,9 @@ remote_exec target "chmod \"a-x\" $binfile.nox" foreach_with_prefix inferior-tty {"main" "separate"} { foreach_with_prefix mi {"main" "separate"} { foreach_with_prefix force-fail {0 1} { + if { ${force-fail} && $have_startup_shell == -1 } { + continue + } test ${inferior-tty} ${mi} ${force-fail} } } diff --git a/gdb/testsuite/gdb.mi/mi-exit-code.exp b/gdb/testsuite/gdb.mi/mi-exit-code.exp index 344d565..af2c6bd 100644 --- a/gdb/testsuite/gdb.mi/mi-exit-code.exp +++ b/gdb/testsuite/gdb.mi/mi-exit-code.exp @@ -36,7 +36,7 @@ proc test_list_thread_groups { } { "122\\^done,groups=\\\[\{id=\"i1\",type=\"process\"\}\]" \ "-list-thread-groups before run shows no exit-code" - mi_clean_restart $binfile + mi_clean_restart $::testfile with_test_prefix "first run" { mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-fill-memory.exp b/gdb/testsuite/gdb.mi/mi-fill-memory.exp index 0afc258..ab7e03a 100644 --- a/gdb/testsuite/gdb.mi/mi-fill-memory.exp +++ b/gdb/testsuite/gdb.mi/mi-fill-memory.exp @@ -27,7 +27,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}.c" "${binfile}" executable {d return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main mi_next_to "main" "" "mi-read-memory.c" "20" "next at main" diff --git a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp index 8886702..48391bc 100644 --- a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp +++ b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp @@ -28,7 +28,7 @@ if {[build_executable "failed to prepare" ${testfile} \ return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-frame-regs.exp b/gdb/testsuite/gdb.mi/mi-frame-regs.exp index f31e4a1..990abd5 100644 --- a/gdb/testsuite/gdb.mi/mi-frame-regs.exp +++ b/gdb/testsuite/gdb.mi/mi-frame-regs.exp @@ -62,7 +62,7 @@ proc_with_prefix do_floating_varobj_test {} { global hex global expect_out - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { fail "couldn't start gdb" return } @@ -113,7 +113,7 @@ proc_with_prefix do_fixed_varobj_test {} { global srcfile binfile global hex - if {[mi_clean_restart $binfile] != 0} { + if {[mi_clean_restart $::testfile] != 0} { fail "couldn't start gdb" return } diff --git a/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp index 130b5bf..6c1dbec 100644 --- a/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp +++ b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp @@ -58,7 +58,7 @@ if { [gdb_compile "$srcfileabs" "${binfile}" executable {debug}] != "" } { file delete -- $srcfileabs -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-info-os.exp b/gdb/testsuite/gdb.mi/mi-info-os.exp index 5d8d3ff..c70dac6 100644 --- a/gdb/testsuite/gdb.mi/mi-info-os.exp +++ b/gdb/testsuite/gdb.mi/mi-info-os.exp @@ -32,7 +32,7 @@ if [build_executable "Failed to build $testfile" $testfile $srcfile \ return -1; } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-info-sources.exp b/gdb/testsuite/gdb.mi/mi-info-sources.exp index f44fc29..80ca596 100644 --- a/gdb/testsuite/gdb.mi/mi-info-sources.exp +++ b/gdb/testsuite/gdb.mi/mi-info-sources.exp @@ -26,7 +26,7 @@ if {[build_executable $testfile.exp $testfile \ return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile set readnow_p [mi_readnow] diff --git a/gdb/testsuite/gdb.mi/mi-inheritance-syntax-error.exp b/gdb/testsuite/gdb.mi/mi-inheritance-syntax-error.exp index 0ab2de2..3092b692 100644 --- a/gdb/testsuite/gdb.mi/mi-inheritance-syntax-error.exp +++ b/gdb/testsuite/gdb.mi/mi-inheritance-syntax-error.exp @@ -25,7 +25,7 @@ if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != "" return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-linespec-err-cp.exp b/gdb/testsuite/gdb.mi/mi-linespec-err-cp.exp index 3314d5f..7eeb259 100644 --- a/gdb/testsuite/gdb.mi/mi-linespec-err-cp.exp +++ b/gdb/testsuite/gdb.mi/mi-linespec-err-cp.exp @@ -29,7 +29,7 @@ if {[build_executable "failed to prepare" $exefile $srcfile {debug c++}]} { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile # Turn off the pending breakpoint queries. mi_gdb_test "-interpreter-exec console \"set breakpoint pending off\"" \ diff --git a/gdb/testsuite/gdb.mi/mi-logging.exp b/gdb/testsuite/gdb.mi/mi-logging.exp index de76e02..8235591 100644 --- a/gdb/testsuite/gdb.mi/mi-logging.exp +++ b/gdb/testsuite/gdb.mi/mi-logging.exp @@ -24,7 +24,7 @@ if [build_executable $testfile.exp $testfile $srcfile $opts] { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return -1 diff --git a/gdb/testsuite/gdb.mi/mi-memory-changed.exp b/gdb/testsuite/gdb.mi/mi-memory-changed.exp index bc2b6c3..6d02c33 100644 --- a/gdb/testsuite/gdb.mi/mi-memory-changed.exp +++ b/gdb/testsuite/gdb.mi/mi-memory-changed.exp @@ -22,7 +22,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ load_lib mi-support.exp -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-multi-commands.exp b/gdb/testsuite/gdb.mi/mi-multi-commands.exp index 20b8d46..3bc63eb 100644 --- a/gdb/testsuite/gdb.mi/mi-multi-commands.exp +++ b/gdb/testsuite/gdb.mi/mi-multi-commands.exp @@ -90,7 +90,7 @@ proc run_test { args } { # looking for. However, due to the unpredictable # intermingling, it's much easier if we drop the ^ anchor. # However, with this gone dejagnu would sometimes match the - # second comand output before the first commands output. + # second command output before the first commands output. # # This approach just looks for the first command output, then, # once that has been found, we start looking for the second diff --git a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp index 599e460..4729033 100644 --- a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp +++ b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp @@ -30,7 +30,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-nonstop.exp b/gdb/testsuite/gdb.mi/mi-nonstop.exp index b8efef7..1ba37a3 100644 --- a/gdb/testsuite/gdb.mi/mi-nonstop.exp +++ b/gdb/testsuite/gdb.mi/mi-nonstop.exp @@ -41,7 +41,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp index 20d9e45..20936f1 100644 --- a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp +++ b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp @@ -43,7 +43,7 @@ if {[gdb_compile "$srcdir/$subdir/$srcfile" \ save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-nsintrall.exp b/gdb/testsuite/gdb.mi/mi-nsintrall.exp index 983c0fe..8c8aef8 100644 --- a/gdb/testsuite/gdb.mi/mi-nsintrall.exp +++ b/gdb/testsuite/gdb.mi/mi-nsintrall.exp @@ -30,7 +30,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp index da43a93..2307c2e 100644 --- a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp +++ b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp @@ -30,7 +30,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp index fd8aa54..1f9d1ae 100644 --- a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp +++ b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp @@ -35,7 +35,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-pending.exp b/gdb/testsuite/gdb.mi/mi-pending.exp index 49839cb..eb0719c 100644 --- a/gdb/testsuite/gdb.mi/mi-pending.exp +++ b/gdb/testsuite/gdb.mi/mi-pending.exp @@ -45,7 +45,7 @@ if { [gdb_compile_pthreads $srcdir/$subdir/$srcfile $binfile executable $exec_op } # Start with a fresh gdb. -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } mi_load_shlibs $lib_sl1 diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp index 93f0344..117b2de 100644 --- a/gdb/testsuite/gdb.mi/mi-pthreads.exp +++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp @@ -63,7 +63,7 @@ if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $option return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-py-modify-bp.exp b/gdb/testsuite/gdb.mi/mi-py-modify-bp.exp index 4193757..5175899 100644 --- a/gdb/testsuite/gdb.mi/mi-py-modify-bp.exp +++ b/gdb/testsuite/gdb.mi/mi-py-modify-bp.exp @@ -31,7 +31,7 @@ if {[build_executable $testfile.exp $testfile $srcfile] == -1} { set remote_python_file [gdb_remote_download host \ ${srcdir}/${subdir}/${testfile}.py] -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main # Delete all breakpoints, watchpoints, tracepoints, and catchpoints. diff --git a/gdb/testsuite/gdb.mi/mi-read-memory.exp b/gdb/testsuite/gdb.mi/mi-read-memory.exp index 8de8728..4469123 100644 --- a/gdb/testsuite/gdb.mi/mi-read-memory.exp +++ b/gdb/testsuite/gdb.mi/mi-read-memory.exp @@ -25,7 +25,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main mi_next_to "main" "" "mi-read-memory.c" "20" "next at main" diff --git a/gdb/testsuite/gdb.mi/mi-record-changed.exp b/gdb/testsuite/gdb.mi/mi-record-changed.exp index e37540b..986efd9 100644 --- a/gdb/testsuite/gdb.mi/mi-record-changed.exp +++ b/gdb/testsuite/gdb.mi/mi-record-changed.exp @@ -24,7 +24,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ load_lib mi-support.exp -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-reg-undefined.exp b/gdb/testsuite/gdb.mi/mi-reg-undefined.exp index c7e0564..ef102ce 100644 --- a/gdb/testsuite/gdb.mi/mi-reg-undefined.exp +++ b/gdb/testsuite/gdb.mi/mi-reg-undefined.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-regs.exp b/gdb/testsuite/gdb.mi/mi-regs.exp index 0bb305b..aae00a6 100644 --- a/gdb/testsuite/gdb.mi/mi-regs.exp +++ b/gdb/testsuite/gdb.mi/mi-regs.exp @@ -108,7 +108,7 @@ require {istarget "sparc-*-*"} mi_clean_restart sparc_register_tests_no_exec -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main sparc_register_tests diff --git a/gdb/testsuite/gdb.mi/mi-return.exp b/gdb/testsuite/gdb.mi/mi-return.exp index ba296d5..998a1ff 100644 --- a/gdb/testsuite/gdb.mi/mi-return.exp +++ b/gdb/testsuite/gdb.mi/mi-return.exp @@ -31,7 +31,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-reverse.exp b/gdb/testsuite/gdb.mi/mi-reverse.exp index d039240..aa25255 100644 --- a/gdb/testsuite/gdb.mi/mi-reverse.exp +++ b/gdb/testsuite/gdb.mi/mi-reverse.exp @@ -39,7 +39,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main if [supports_process_record] { diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp index e390f14..5ee7881 100644 --- a/gdb/testsuite/gdb.mi/mi-simplerun.exp +++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp @@ -34,7 +34,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp index c66d4b0..8ddca8d 100644 --- a/gdb/testsuite/gdb.mi/mi-solib.exp +++ b/gdb/testsuite/gdb.mi/mi-solib.exp @@ -34,7 +34,7 @@ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-stack.exp b/gdb/testsuite/gdb.mi/mi-stack.exp index a91b76e..89f58c8 100644 --- a/gdb/testsuite/gdb.mi/mi-stack.exp +++ b/gdb/testsuite/gdb.mi/mi-stack.exp @@ -32,7 +32,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-start.exp b/gdb/testsuite/gdb.mi/mi-start.exp index 745e5c9..d384230 100644 --- a/gdb/testsuite/gdb.mi/mi-start.exp +++ b/gdb/testsuite/gdb.mi/mi-start.exp @@ -28,7 +28,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-stepi.exp b/gdb/testsuite/gdb.mi/mi-stepi.exp index 8ba6399..7f53c8b 100644 --- a/gdb/testsuite/gdb.mi/mi-stepi.exp +++ b/gdb/testsuite/gdb.mi/mi-stepi.exp @@ -63,7 +63,7 @@ proc test_stepi_nexti {} { } } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main test_stepi_nexti diff --git a/gdb/testsuite/gdb.mi/mi-stepn.exp b/gdb/testsuite/gdb.mi/mi-stepn.exp index 489564a..f11e9c0 100644 --- a/gdb/testsuite/gdb.mi/mi-stepn.exp +++ b/gdb/testsuite/gdb.mi/mi-stepn.exp @@ -26,7 +26,7 @@ if [build_executable ${testfile}.exp ${testfile} ${srcfile} $opts] { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return -1 diff --git a/gdb/testsuite/gdb.mi/mi-sym-info.exp b/gdb/testsuite/gdb.mi/mi-sym-info.exp index ef8dd86..6b0bf2d 100644 --- a/gdb/testsuite/gdb.mi/mi-sym-info.exp +++ b/gdb/testsuite/gdb.mi/mi-sym-info.exp @@ -33,7 +33,7 @@ if {[build_executable "failed to prepare" ${testfile} \ return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile # Don't run to main to avoid increasing the search scope to include # debug info of shared libraries like libc, libgcc, etc. diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/mi-syn-frame.exp index 633f317..b3ec377 100644 --- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp +++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-thread-bp-deleted.exp b/gdb/testsuite/gdb.mi/mi-thread-bp-deleted.exp index 2a734c8..976b68d 100644 --- a/gdb/testsuite/gdb.mi/mi-thread-bp-deleted.exp +++ b/gdb/testsuite/gdb.mi/mi-thread-bp-deleted.exp @@ -47,7 +47,7 @@ foreach_mi_ui_mode mode { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop on\"" append GDBFLAGS " -ex \"set mi-async on\"" - mi_clean_restart $binfile $start_ops + mi_clean_restart $::testfile $start_ops } mi_runto_main diff --git a/gdb/testsuite/gdb.mi/mi-thread-specific-bp.exp b/gdb/testsuite/gdb.mi/mi-thread-specific-bp.exp index 86d050a..81ff274 100644 --- a/gdb/testsuite/gdb.mi/mi-thread-specific-bp.exp +++ b/gdb/testsuite/gdb.mi/mi-thread-specific-bp.exp @@ -90,7 +90,7 @@ foreach_mi_ui_mode mode { set start_ops "" } - if {[mi_clean_restart $binfile $start_ops]} { + if {[mi_clean_restart $::testfile $start_ops]} { break } diff --git a/gdb/testsuite/gdb.mi/mi-threads-interrupt.exp b/gdb/testsuite/gdb.mi/mi-threads-interrupt.exp index ff74e7b..8aab3b8 100644 --- a/gdb/testsuite/gdb.mi/mi-threads-interrupt.exp +++ b/gdb/testsuite/gdb.mi/mi-threads-interrupt.exp @@ -33,7 +33,7 @@ proc test_continue_interrupt { } { global binfile global async - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-until.exp b/gdb/testsuite/gdb.mi/mi-until.exp index ee50c4f..e8f24bc 100644 --- a/gdb/testsuite/gdb.mi/mi-until.exp +++ b/gdb/testsuite/gdb.mi/mi-until.exp @@ -31,7 +31,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp index bdba639..3914c3a 100644 --- a/gdb/testsuite/gdb.mi/mi-var-block.exp +++ b/gdb/testsuite/gdb.mi/mi-var-block.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-child-f.exp b/gdb/testsuite/gdb.mi/mi-var-child-f.exp index c424490..4856e3d 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child-f.exp +++ b/gdb/testsuite/gdb.mi/mi-var-child-f.exp @@ -28,7 +28,7 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp index 89ce9dd..4a3ba07 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi-var-child.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index 8c8c306..9e7b14c 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.exp b/gdb/testsuite/gdb.mi/mi-var-cp.exp index c1d70f1..eee1007 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cp.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cp.exp @@ -25,7 +25,7 @@ if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != "" return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-create-rtti.exp b/gdb/testsuite/gdb.mi/mi-var-create-rtti.exp index ad6ce5c..517449c 100644 --- a/gdb/testsuite/gdb.mi/mi-var-create-rtti.exp +++ b/gdb/testsuite/gdb.mi/mi-var-create-rtti.exp @@ -23,7 +23,7 @@ if [build_executable $testfile.exp $testfile $srcfile $opts] { return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile if {[mi_runto_main] < 0} { return -1 diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp index 61b3894..3ae593b 100644 --- a/gdb/testsuite/gdb.mi/mi-var-display.exp +++ b/gdb/testsuite/gdb.mi/mi-var-display.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } @@ -96,7 +96,7 @@ mi_gdb_test "-var-evaluate-expression bar" \ # Desc: change value of bar mi_gdb_test "-var-assign bar 3" \ "\\^done,value=\"0x3\"" \ - "assing to variable bar" + "assign to variable bar" mi_gdb_test "-var-set-format bar decimal" \ "\\^done,format=\"decimal\",value=\"3\"" \ @@ -152,7 +152,7 @@ mi_gdb_test "-var-evaluate-expression foo" \ # Desc: change value of foo mi_gdb_test "-var-assign foo 3" \ "\\^done,value=\"03\"" \ - "assing to variable foo" + "assign to variable foo" mi_gdb_test "-var-set-format foo decimal" \ "\\^done,format=\"decimal\",value=\"3\"" \ diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp index c1c52f2..800c22f 100644 --- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp +++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp @@ -44,7 +44,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {d return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-list-children-invalid-grandchild.exp b/gdb/testsuite/gdb.mi/mi-var-list-children-invalid-grandchild.exp index 0f20c50f..597e2e0 100644 --- a/gdb/testsuite/gdb.mi/mi-var-list-children-invalid-grandchild.exp +++ b/gdb/testsuite/gdb.mi/mi-var-list-children-invalid-grandchild.exp @@ -26,7 +26,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-var-rtti.exp b/gdb/testsuite/gdb.mi/mi-var-rtti.exp index fcf8404..c2768b6 100644 --- a/gdb/testsuite/gdb.mi/mi-var-rtti.exp +++ b/gdb/testsuite/gdb.mi/mi-var-rtti.exp @@ -25,7 +25,7 @@ if [build_executable $testfile.exp $testfile $srcfile $opts] { return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-vla-c99.exp b/gdb/testsuite/gdb.mi/mi-vla-c99.exp index ec12e6f..5f23d05 100644 --- a/gdb/testsuite/gdb.mi/mi-vla-c99.exp +++ b/gdb/testsuite/gdb.mi/mi-vla-c99.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" \ return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp index 5077089..81e2d89 100644 --- a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp +++ b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp @@ -34,7 +34,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \ # the type names can be printed differently. set real [fortran_real4] -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp index f9237c0..36d7410 100644 --- a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp +++ b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp @@ -38,7 +38,7 @@ if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug}] != "" } save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - mi_clean_restart $binfile + mi_clean_restart $::testfile } mi_gdb_test "-gdb-set mi-async 1" ".*" diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp index e318a2b..43f2378 100644 --- a/gdb/testsuite/gdb.mi/mi-watch.exp +++ b/gdb/testsuite/gdb.mi/mi-watch.exp @@ -155,7 +155,7 @@ proc test_watchpoint_all {mi_mode type} { } else { set start_ops "" } - if [mi_clean_restart ${binfile} $start_ops] { + if [mi_clean_restart ${::testfile} $start_ops] { return } diff --git a/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp b/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp index c7e21e9..0d51dc5 100644 --- a/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp +++ b/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp @@ -31,7 +31,7 @@ if [build_executable ${testfile}.exp ${binfile} ${srcfile} $opts] { return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi2-cli-display.exp b/gdb/testsuite/gdb.mi/mi2-cli-display.exp index 656c93e..993b87c 100644 --- a/gdb/testsuite/gdb.mi/mi2-cli-display.exp +++ b/gdb/testsuite/gdb.mi/mi2-cli-display.exp @@ -25,7 +25,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp index 9bd9054..3618d5a 100644 --- a/gdb/testsuite/gdb.mi/mi2-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp @@ -29,7 +29,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp index cb83329..7112248 100644 --- a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp +++ b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp @@ -102,7 +102,7 @@ proc do_test {sync_command} { } foreach_with_prefix sync-command {"run" "continue"} { - if {[mi_clean_restart $binfile "separate-mi-tty"] != 0} { + if {[mi_clean_restart $::testfile "separate-mi-tty"] != 0} { fail "could not start gdb" break } diff --git a/gdb/testsuite/gdb.mi/pr11022.exp b/gdb/testsuite/gdb.mi/pr11022.exp index ad8e3b2..1e01bf6 100644 --- a/gdb/testsuite/gdb.mi/pr11022.exp +++ b/gdb/testsuite/gdb.mi/pr11022.exp @@ -29,7 +29,7 @@ proc test_memory_changed_observer { mi_command } { with_test_prefix "${mi_command}" { global srcfile binfile - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_runto_main set line_number [gdb_get_line_number "break here"] diff --git a/gdb/testsuite/gdb.mi/print-simple-values.exp b/gdb/testsuite/gdb.mi/print-simple-values.exp index 1c56d68..23488e3 100644 --- a/gdb/testsuite/gdb.mi/print-simple-values.exp +++ b/gdb/testsuite/gdb.mi/print-simple-values.exp @@ -34,7 +34,7 @@ if [build_executable "failed to prepare" $testfile $srcfile $opts] { return -1 } -if [mi_clean_restart $binfile] { +if [mi_clean_restart $::testfile] { return } diff --git a/gdb/testsuite/gdb.mi/run-with-two-mi-uis.exp b/gdb/testsuite/gdb.mi/run-with-two-mi-uis.exp index df370c9..c9e352d 100644 --- a/gdb/testsuite/gdb.mi/run-with-two-mi-uis.exp +++ b/gdb/testsuite/gdb.mi/run-with-two-mi-uis.exp @@ -29,7 +29,7 @@ if {[build_executable $testfile.exp $testfile ${srcfile} "debug"] == -1} { # UI_TO_RUN is the UI that should issue the run command. proc do_test { ui_to_run } { - if {[mi_clean_restart $::binfile "separate-mi-tty"] != 0} { + if {[mi_clean_restart $::testfile "separate-mi-tty"] != 0} { fail "could not start gdb" return } diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp index 9198cfb..a0bf11f 100644 --- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp +++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp @@ -40,6 +40,8 @@ standard_testfile # gdbserver modes are supported. require !use_gdb_stub +require allow_multi_inferior_tests + set compile_options "debug pthreads" if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} { untested "failed to compile" @@ -985,7 +987,7 @@ proc_with_prefix test_mi_stack_select_frame { mode } { # Now use the '-stack-select-frame' command with the --frame # option, this verifies that even when the frame GDB would - # swith to is the same as the frame specified with --frame, an + # switch to is the same as the frame specified with --frame, an # event is still sent to the CLI. set cli_re [make_cli_re $mode -1 -1 0] @@ -1327,7 +1329,7 @@ foreach_with_prefix mode { "all-stop" "non-stop" } { set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop 1\""] } - if { [mi_clean_restart $binfile "separate-mi-tty"] != 0 } { + if { [mi_clean_restart $::testfile "separate-mi-tty"] != 0 } { break } } diff --git a/gdb/testsuite/gdb.multi/attach-no-multi-process.exp b/gdb/testsuite/gdb.multi/attach-no-multi-process.exp index 28aabaf..2813fa9 100644 --- a/gdb/testsuite/gdb.multi/attach-no-multi-process.exp +++ b/gdb/testsuite/gdb.multi/attach-no-multi-process.exp @@ -44,7 +44,7 @@ proc test {target_non_stop} { "${::GDBFLAGS} -ex \"set remote multiprocess-feature-packet off\"" set ::GDBFLAGS \ "${::GDBFLAGS} -ex \"maint set target-non-stop ${target_non_stop}\"" - clean_restart ${binfile} + clean_restart ${::testfile} } # Start the first inferior. @@ -59,7 +59,10 @@ proc test {target_non_stop} { "switch to inferior 2" set res [gdbserver_start "--multi" ""] set gdbserver_gdbport [lindex $res 1] - gdb_target_cmd "extended-remote" $gdbserver_gdbport + if { [gdb_target_cmd_ext "extended-remote" $gdbserver_gdbport] == 2 } { + unsupported "non-stop RSP" + return + } # Start a program, then attach to it. set spawn_id_list [spawn_wait_for_attach [list $binfile]] diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp index 5b63030..4eb500e 100644 --- a/gdb/testsuite/gdb.multi/attach-while-running.exp +++ b/gdb/testsuite/gdb.multi/attach-while-running.exp @@ -37,6 +37,7 @@ standard_testfile require can_spawn_for_attach +require allow_multi_inferior_tests if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } { return @@ -45,11 +46,11 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } { proc do_test {} { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart $::binfile + clean_restart $::testfile } gdb_test -no-prompt-anchor "run &" - gdb_test "add-inferior" "Added inferior 2 on connection 1 .*" + gdb_test -no-prompt-anchor "add-inferior" "Added inferior 2 on connection 1 .*" gdb_test "inferior 2" "Switching to inferior 2 .*" set spawn_id [spawn_wait_for_attach $::binfile] diff --git a/gdb/testsuite/gdb.multi/bp-thread-specific.exp b/gdb/testsuite/gdb.multi/bp-thread-specific.exp index 32b7602..3fe4c20 100644 --- a/gdb/testsuite/gdb.multi/bp-thread-specific.exp +++ b/gdb/testsuite/gdb.multi/bp-thread-specific.exp @@ -19,6 +19,8 @@ # Also check that the correct thread-ids are used in the saved # breakpoints file. +require allow_multi_inferior_tests + # The plain remote target can't do multiple inferiors. require !use_gdb_stub diff --git a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp index 1a9d413..4119e3f 100644 --- a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp +++ b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp @@ -19,6 +19,8 @@ set executable ${testfile} # The plain remote target can't do multiple inferiors. require !use_gdb_stub +require allow_multi_inferior_tests + if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { return -1 } diff --git a/gdb/testsuite/gdb.multi/gdb-settings.exp b/gdb/testsuite/gdb.multi/gdb-settings.exp index b1acca0..97961f5 100644 --- a/gdb/testsuite/gdb.multi/gdb-settings.exp +++ b/gdb/testsuite/gdb.multi/gdb-settings.exp @@ -44,7 +44,7 @@ set run [expr {![use_gdb_stub]}] set inferiors {1 2} # Start all the inferiors. -clean_restart $binfile +clean_restart $::testfile foreach_with_prefix inf $inferiors { if { $inf > 1 } { gdb_test "add-inferior -exec $binfile" "Added inferior 2.*" \ @@ -71,6 +71,7 @@ foreach_with_prefix inf $inferiors { gdb_test_no_output "set args inf${inf}-args" gdb_test_no_output "set cwd /inf${inf}-cwd" gdb_test_no_output "set inferior-tty /inf${inf}-tty" + gdb_test_no_output "set remote exec-file /inf${inf}-remote-exec" } # Check settings are still correct for each inferior. @@ -88,6 +89,9 @@ foreach_with_prefix inf $inferiors { gdb_test "with inferior-tty tmp-value -- print 1" " = 1" gdb_test "show inferior-tty" "/inf${inf}-tty.*" + gdb_test "with remote exec-file tmp-value -- print 1" " = 1" + gdb_test "show remote exec-file" "/inf${inf}-remote-exec.*" + # If the inferiors are running check $_gdb_setting_str and # $_gdb_setting return the correct values. if { $run } { @@ -101,6 +105,11 @@ foreach_with_prefix inf $inferiors { "\"/inf${inf}-tty\"" gdb_test {print $_gdb_setting("inferior-tty")} \ "\"/inf${inf}-tty\"" + + gdb_test {print $_gdb_setting_str("remote exec-file")} \ + "\"/inf${inf}-remote-exec\"" + gdb_test {print $_gdb_setting("remote exec-file")} \ + "\"/inf${inf}-remote-exec\"" } # Check the settings can be read from Python. @@ -109,6 +118,8 @@ foreach_with_prefix inf $inferiors { gdb_test "python print(gdb.parameter('cwd'))" "/inf${inf}-cwd" gdb_test "python print(gdb.parameter('inferior-tty'))" \ "/inf${inf}-tty" + gdb_test "python print(gdb.parameter('remote exec-file'))" \ + "/inf${inf}-remote-exec" } # Check the settings can be read from Guile. @@ -119,5 +130,7 @@ foreach_with_prefix inf $inferiors { "/inf${inf}-cwd" gdb_test "guile (print (parameter-value \"inferior-tty\"))" \ "/inf${inf}-tty" + gdb_test "guile (print (parameter-value \"remote exec-file\"))" \ + "/inf${inf}-remote-exec" } } diff --git a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp index db09095..6d2fc9e 100644 --- a/gdb/testsuite/gdb.multi/inferior-specific-bp.exp +++ b/gdb/testsuite/gdb.multi/inferior-specific-bp.exp @@ -22,8 +22,10 @@ if {[use_gdb_stub]} { } set srcfile1 ${srcfile} -set binfile1 ${binfile}-1 -set binfile2 ${binfile}-2 +set testfile1 $testfile-1 +set testfile2 $testfile-2 +set binfile1 [standard_output_file $testfile1] +set binfile2 [standard_output_file $testfile2] if {[build_executable ${testfile}.exp ${binfile1} "${srcfile1}"] != 0} { return -1 @@ -34,7 +36,7 @@ if {[build_executable ${testfile}.exp ${binfile2} "${srcfile2}"] != 0} { } # Start the first inferior. -clean_restart ${binfile1} +clean_restart $testfile1 if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.multi/interrupt-bg-exec.c b/gdb/testsuite/gdb.multi/interrupt-bg-exec.c new file mode 100644 index 0000000..b5fa568 --- /dev/null +++ b/gdb/testsuite/gdb.multi/interrupt-bg-exec.c @@ -0,0 +1,47 @@ +/* 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/>. */ + +#include <unistd.h> + +volatile int wait_for_gdb = 1; + +void +breakpt (void) +{ + /* Nothing. */ +} + +void +all_started (void) +{ + /* Nothing. */ +} + +int +main (void) +{ + alarm (360); + + all_started (); + + while (wait_for_gdb) + sleep (1); + + breakpt (); + + return 0; +} diff --git a/gdb/testsuite/gdb.multi/interrupt-bg-exec.exp b/gdb/testsuite/gdb.multi/interrupt-bg-exec.exp new file mode 100644 index 0000000..065a112 --- /dev/null +++ b/gdb/testsuite/gdb.multi/interrupt-bg-exec.exp @@ -0,0 +1,143 @@ +# 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/>. + +# In all-stop mode, set one inferior running in the background, then +# continue a second inferior. When the second inferior hits a breakpoint, +# both inferiors should be stopped. + +# This tests the use of native and remote targets. If we try to run +# it with a board that forces native targets to become remote, then +# this doesn't really make sense (for this test). +require {string equal [target_info gdb_protocol] ""} + +source $srcdir/$subdir/multi-target.exp.tcl + +load_lib gdbserver-support.exp + +require allow_gdbserver_tests + +# This overrides the call in multi-target.exp.tcl. +standard_testfile + +if { [build_executable "failed to build" $testfile $srcfile] } { + return +} + +# Start two inferiors, TARGET_TYPE_1 and TARGET_TYPE_2 are strings, either +# 'extended-remote' or 'native', and control the connection type of each +# inferior. +# +# Set the first inferior running in the background, then continue theA +# second inferior allowing it to hit a breakpoint. +# +# Once the breakpoint is hit, both inferiors should be stopped. +proc run_test { target_type_1 target_type_2 } { + cleanup_gdbservers + + clean_restart + + gdb_test "disconnect" ".*" + + gdb_test_no_output "set sysroot" + + # multi-target depends on target running in non-stop mode. Force it + # on for remote targets, until this is the default. + gdb_test_no_output "maint set target-non-stop on" + + # Run in all-stop mode. + gdb_test_no_output "set non-stop off" + + if {![add_inferior 2 $target_type_1 $::binfile]} { + return 0 + } + + if {![add_inferior 3 $target_type_2 $::binfile]} { + return 0 + } + + # Check we see all the expected threads. + gdb_test "info threads" \ + [multi_line \ + "\\s+Id\\s+Target Id\\s+Frame\\s*" \ + "\\s+2\\.1\\s+\[^\r\n\]+" \ + "\\*\\s+3\\.1\\s+\[^\r\n\]+"] \ + "check expected threads exist" + + # The breakpoint will be set in both inferiors, but only inferior 3 + # will hit it as 'wait_for_gdb' is cleared only in that inferior. + gdb_breakpoint breakpt + gdb_test "thread apply 3.1 set wait_for_gdb = 0" + + # Let inferior 2 run in the background. + gdb_test "thread 2.1" + gdb_test -no-prompt-anchor "continue&" + + # Run inferior 3 until it hits a breakpoint. + gdb_test "thread 3.1" + gdb_test "continue" \ + [multi_line \ + "Thread 3\\.1 \[^\r\n\]+ hit Breakpoint \[^\r\n\]+, breakpt \\(\\) \[^\r\n\]+" \ + "$::decimal\\s+\[^\r\n\]+"] \ + "continue to breakpt function" + + # Check the state of all threads. None should be running. + set saw_inferior_2 false + set saw_inferior_3 false + gdb_test_multiple "info threads" "check threads after stop" { + -re "^info threads\r\n" { + exp_continue + } + + -re "^\\s+Id\\s+Target Id\\s+Frame\\s*\r\n" { + exp_continue + } + + -re "^\\s+2\\.1\\s+\[^\r\n\]+\\s+\\(running\\)\\s*\r\n" { + # Don't count this as seeing inferior 2 as the thread is + # incorrectly still marked as running. By not setting the + # SAW_INFERIOR_2 flag this test will now fail. + exp_continue + } + + -re "^\\s+2\\.1\\s+\[^\r\n\]+\r\n" { + set saw_inferior_2 true + exp_continue + } + + -re "^\\*\\s+3\\.1\\s+\[^\r\n\]+\r\n" { + set saw_inferior_3 true + exp_continue + } + + -re "^$::gdb_prompt $" { + gdb_assert { $saw_inferior_2 && $saw_inferior_3 } \ + $gdb_test_name + } + + -re "^\[^\r\n\]*\r\n" { + exp_continue + } + } +} + +set all_target_types { extended-remote native } + +foreach_with_prefix target_type_1 $all_target_types { + foreach_with_prefix target_type_2 $all_target_types { + run_test $target_type_1 $target_type_2 + } +} + +multi_target_cleanup diff --git a/gdb/testsuite/gdb.multi/multi-arch-exec.exp b/gdb/testsuite/gdb.multi/multi-arch-exec.exp index 69c6b13..435efc5 100644 --- a/gdb/testsuite/gdb.multi/multi-arch-exec.exp +++ b/gdb/testsuite/gdb.multi/multi-arch-exec.exp @@ -23,7 +23,7 @@ require !use_gdb_stub # The 64-bit compile may succeed for i386-linux, but gdb won't be able # to load the file. -if [istarget "i?86-*linux*"] { +if {[istarget "i?86-*linux*"]} { return } @@ -69,9 +69,9 @@ proc append_arch2_options {options_var} { } } - if [istarget "powerpc64*-*-*"] { + if {[istarget "powerpc64*-*-*"]} { set march "-m64" - } elseif [istarget "s390*-*-*"] { + } elseif {[istarget "s390*-*-*"]} { set march "-m31" } else { set march "-m32" diff --git a/gdb/testsuite/gdb.multi/multi-arch.exp b/gdb/testsuite/gdb.multi/multi-arch.exp index d0ae511..b75009d 100644 --- a/gdb/testsuite/gdb.multi/multi-arch.exp +++ b/gdb/testsuite/gdb.multi/multi-arch.exp @@ -18,12 +18,14 @@ set testfile "multi-arch" +require allow_multi_inferior_tests + # The plain remote target can't do multiple inferiors. require !use_gdb_stub # The 64-bit compile may succeed for i386-linux, but gdb won't be able # to load the file. -if [istarget "i?86-*linux*"] { +if {[istarget "i?86-*linux*"]} { return } @@ -39,7 +41,7 @@ set binfile2 [standard_output_file ${exec2}] # Build two executables, one for each arch. -if [istarget "s390*-*-*"] { +if {[istarget "s390*-*-*"]} { set march1 "-m64" set march2 "-m31" } elseif { [istarget "aarch64*-*-*"] } { @@ -65,7 +67,7 @@ if { [build_executable "failed to prepare" ${exec1} "${srcfile1}" \ set options [list debug] -if [istarget "aarch64*-*-*"] { +if {[istarget "aarch64*-*-*"]} { if {[arm_cc_for_target] != ""} { lappend options "compiler=[arm_cc_for_target]" } else { diff --git a/gdb/testsuite/gdb.multi/multi-attach.exp b/gdb/testsuite/gdb.multi/multi-attach.exp index 2d702ee..210c8ca 100644 --- a/gdb/testsuite/gdb.multi/multi-attach.exp +++ b/gdb/testsuite/gdb.multi/multi-attach.exp @@ -17,6 +17,8 @@ # Test attaching to multiple threaded programs. +require allow_multi_inferior_tests + standard_testfile require can_spawn_for_attach diff --git a/gdb/testsuite/gdb.multi/multi-exit.exp b/gdb/testsuite/gdb.multi/multi-exit.exp index 71236c1..fcd7cd2 100644 --- a/gdb/testsuite/gdb.multi/multi-exit.exp +++ b/gdb/testsuite/gdb.multi/multi-exit.exp @@ -24,6 +24,8 @@ standard_testfile +require allow_multi_inferior_tests + require !use_gdb_stub if {[build_executable "failed to prepare" $testfile $srcfile]} { @@ -34,7 +36,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile]} { # Hence, go with the all-stop-on-top-of-non-stop mode. save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart ${binfile} + clean_restart ${::testfile} } # Start inferior NUM. diff --git a/gdb/testsuite/gdb.multi/multi-kill.exp b/gdb/testsuite/gdb.multi/multi-kill.exp index 48a2534..1473372 100644 --- a/gdb/testsuite/gdb.multi/multi-kill.exp +++ b/gdb/testsuite/gdb.multi/multi-kill.exp @@ -24,6 +24,8 @@ standard_testfile +require allow_multi_inferior_tests + require !use_gdb_stub if {[build_executable "failed to prepare" $testfile $srcfile {debug}]} { @@ -34,7 +36,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug}]} { # Hence, go with the all-stop-on-top-of-non-stop mode. save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart ${binfile} + clean_restart ${::testfile} } # Wrap the entire test in a namespace to avoid contaminating other tests. diff --git a/gdb/testsuite/gdb.multi/multi-re-run.exp b/gdb/testsuite/gdb.multi/multi-re-run.exp index 002de57..89d43a4 100644 --- a/gdb/testsuite/gdb.multi/multi-re-run.exp +++ b/gdb/testsuite/gdb.multi/multi-re-run.exp @@ -20,25 +20,27 @@ # misbehave, including failing to load libthread_db.so. See PR # gdb/25410. +require allow_multi_inferior_tests + # Build two executables, with different symbols. -set exec1 "multi-re-run-1" +set testfile1 "multi-re-run-1" set srcfile1 multi-re-run-1.c -set binfile1 [standard_output_file ${exec1}] +set binfile1 [standard_output_file $testfile1] -set exec2 "multi-re-run-2" +set testfile2 "multi-re-run-2" set srcfile2 multi-re-run-2.c -set binfile2 [standard_output_file ${exec2}] +set binfile2 [standard_output_file $testfile2] with_test_prefix "exec1" { - if { [build_executable "failed to prepare" ${exec1} "${srcfile1}" \ + if { [build_executable "failed to prepare" $testfile1 $srcfile1 \ [list pthreads debug]] } { return -1 } } with_test_prefix "exec2" { - if { [build_executable "failed to prepare" ${exec2} "${srcfile2}" \ + if { [build_executable "failed to prepare" $testfile2 $srcfile2 \ [list pthreads debug]] } { return -1 } @@ -53,7 +55,7 @@ proc test_re_run {re_run_inf} { global gdb_prompt global last_loaded_file - clean_restart ${binfile1} + clean_restart $::testfile1 delete_breakpoints diff --git a/gdb/testsuite/gdb.multi/multi-target.exp.tcl b/gdb/testsuite/gdb.multi/multi-target.exp.tcl index 8c24602..1963db5 100644 --- a/gdb/testsuite/gdb.multi/multi-target.exp.tcl +++ b/gdb/testsuite/gdb.multi/multi-target.exp.tcl @@ -53,7 +53,7 @@ proc add_inferior {num target binfile {gcorefile ""}} { return 0 } } - if ![runto "all_started"] then { + if { ![runto "all_started"] } { return 0 } delete_breakpoints @@ -65,9 +65,9 @@ proc prepare_core {} { global gcorefile gcore_created global binfile - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto all_started] then { + if { ![runto all_started] } { return -1 } @@ -114,7 +114,7 @@ proc setup {non-stop {multi_process ""}} { # Make GDB read files from the local file system, not through the # remote targets, to speed things up. set ::GDBFLAGS "${::GDBFLAGS} -ex \"set sysroot\"" - clean_restart ${binfile} + clean_restart ${::testfile} } # multi-target depends on target running in non-stop mode. Force @@ -123,13 +123,13 @@ proc setup {non-stop {multi_process ""}} { gdb_test_no_output "set non-stop ${non-stop}" - if {${multi_process} ne ""} then { + if {${multi_process} ne ""} { gdb_test \ "set remote multiprocess-feature-packet $multi_process" \ "Support for the 'multiprocess-feature' packet on future remote targets is set to \"${multi_process}\"." } - if ![runto all_started] then { + if { ![runto all_started] } { return 0 } @@ -175,12 +175,16 @@ proc multi_target_prepare {} { return 0 } + if {![allow_multi_inferior_tests]} { + return 0 + } + # The plain remote target can't do multiple inferiors. if {[target_info gdb_protocol] != ""} { return 0 } - if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \ + if { [prepare_for_testing "failed to prepare" $::testfile $srcfile \ {debug pthreads}] } { return 0 } diff --git a/gdb/testsuite/gdb.multi/multi-term-settings.exp b/gdb/testsuite/gdb.multi/multi-term-settings.exp index 2f8b3b8..2893d36 100644 --- a/gdb/testsuite/gdb.multi/multi-term-settings.exp +++ b/gdb/testsuite/gdb.multi/multi-term-settings.exp @@ -25,9 +25,11 @@ standard_testfile +require allow_multi_inferior_tests + require can_spawn_for_attach -if [build_executable "failed to prepare" $testfile $srcfile {debug}] { +if {[build_executable "failed to prepare" $testfile $srcfile {debug}]} { return -1 } @@ -54,7 +56,7 @@ proc create_inferior {which_inf inf_how} { # Run to main and delete breakpoints. proc my_runto_main {} { - if ![runto_main] { + if {![runto_main]} { return 0 } else { # Delete breakpoints otherwise GDB would try to step over @@ -67,7 +69,7 @@ proc create_inferior {which_inf inf_how} { } if {$inf_how == "run"} { - if [my_runto_main] { + if {[my_runto_main]} { global inferior_spawn_id return $inferior_spawn_id } @@ -78,7 +80,7 @@ proc create_inferior {which_inf inf_how} { set inf_tty_name $spawn_out(slave,name) gdb_test_no_output "tty $inf_tty_name" "tty TTY" - if [my_runto_main] { + if {[my_runto_main]} { return $inf_spawn_id } } elseif {$inf_how == "attach"} { @@ -136,7 +138,7 @@ proc coretest {inf1_how inf2_how} { global gdb_spawn_id global decimal - clean_restart $binfile + clean_restart $::testfile with_test_prefix "inf1" { set inf1_spawn_id [create_inferior 1 $inf1_how] diff --git a/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp b/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp index a7055d7..781937d 100644 --- a/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp +++ b/gdb/testsuite/gdb.multi/pending-bp-del-inferior.exp @@ -37,7 +37,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { # # Return true after a successful setup, otherwise, return false. proc test_setup {} { - clean_restart $::binfile + clean_restart $::testfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.multi/pending-bp.exp b/gdb/testsuite/gdb.multi/pending-bp.exp index 1cd1cfb..30a75b9 100644 --- a/gdb/testsuite/gdb.multi/pending-bp.exp +++ b/gdb/testsuite/gdb.multi/pending-bp.exp @@ -45,7 +45,7 @@ if { [build_executable "failed to prepare" $testfile $srcfile \ # 'breakpoint pending' flag is enabled, so pending breakpoints can be created # without GDB prompting the user. proc do_test_setup { inf_1_stop inf_2_stop } { - clean_restart ${::binfile} + clean_restart ${::testfile} gdb_locate_shlib $::binfile_lib @@ -328,5 +328,7 @@ proc_with_prefix py_test_clear_thread {} { # Run all the tests. test_no_inf_display test_pending_toggle -py_test_toggle_thread -py_test_clear_thread +if { [allow_python_tests] } { + py_test_toggle_thread + py_test_clear_thread +} diff --git a/gdb/testsuite/gdb.multi/remote-with-running-inferior.c b/gdb/testsuite/gdb.multi/remote-with-running-inferior.c new file mode 100644 index 0000000..a610eda --- /dev/null +++ b/gdb/testsuite/gdb.multi/remote-with-running-inferior.c @@ -0,0 +1,38 @@ +/* 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/>. */ + +#include <unistd.h> + +int global_var = 123; + +void +breakpt (void) +{ + /* Nothing. */ +} + +int +main (void) +{ + for (int i = 0; i < 30; ++i) + { + sleep (1); + breakpt (); + } + + return 0; +} diff --git a/gdb/testsuite/gdb.multi/remote-with-running-inferior.exp b/gdb/testsuite/gdb.multi/remote-with-running-inferior.exp new file mode 100644 index 0000000..43842ba --- /dev/null +++ b/gdb/testsuite/gdb.multi/remote-with-running-inferior.exp @@ -0,0 +1,171 @@ +# 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/>. + +# Set an inferior running in the background (using "run&"), then +# connect to gdbserver in a second inferior. When this test was added +# there were two bugs in GDB. First, just connecting to gdbserver +# while an inferior was running on a different connection type +# (e.g. inferior 1 was native, and inferior 2 was gdbserver) would +# trigger an assertion. +# +# Then, once the assertion was fixed, GDB would stop the thread from +# the first inferior, but would fail to update it's state in GDB core, +# this would leave the thread stopped, but GDB core thinking the +# thread was running. Check this is fixed by looking at the 'info +# threads' output after connecting to the remote target. + +# This tests the use of native and remote targets, and also depends on use +# of the 'run' command. If we try to run it with a board that forces native +# targets to become remote, then this test isn't going to work, especially +# for 'remote' targets where 'run' is not supported. +require {string equal [target_info gdb_protocol] ""} + +load_lib gdbserver-support.exp + +require allow_gdbserver_tests + +standard_testfile + +if { [build_executable "failed to build" $testfile $srcfile] } { + return +} + +# Set non-stop mode based on NON_STOP. Start a native inferior running in +# the background, then start a second, remote inferior. Based on the value +# of NON_STOP we might expect the inferior thread to have been stopped. +# Confirm inferior one is in the correct state, and that it can be +# interrupted and/or resumed. +proc run_test { target_non_stop non_stop } { + clean_restart $::testfile + + # Setup non-stop settings. + gdb_test_no_output "maint set target-non-stop $target_non_stop" + gdb_test_no_output "set non-stop $non_stop" + + # Start the first inferior running in the background. + gdb_test -no-prompt-anchor "run&" "Starting program: .*" "start background inferior" + + # Add a second inferior. + gdb_test "add-inferior" "Added inferior 2.*" + gdb_test "inferior 2" "Switching to inferior 2.*" + + # Setup the sysroot if possible. This will make connecting to + # gdbserver quicker. + if { ![is_remote host] && ![is_remote target] } { + gdb_test "set sysroot" + } + + # Setup, and connect to, a remote target. + set target_exec [gdbserver_download_current_prog] + set res [gdbserver_start "" $target_exec] + set gdbserver_protocol [lindex $res 0] + set gdbserver_gdbport [lindex $res 1] + set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] + gdb_assert {$res == 0} "connect to remote target" + + # Check the info threads output. We're checking that we see the two + # threads we expect, that the correct thread (inferior two's thread) + # is current, and that none of the threads are running. + set state_inferior_1 "" + set state_inferior_2 "" + gdb_test_multiple "info threads" "" { + -re "^info threads\r\n" { + exp_continue + } + + -re "^\\s+Id\\s+Target Id\\s+Frame\\s*\r\n" { + exp_continue + } + + -re "^\\s+1\\.1\\s+\[^\r\n\]+\\(running\\)\r\n" { + set state_inferior_1 "running" + exp_continue + } + + -re "^\\*\\s+2\\.1\\s+\[^\r\n\]+\\(running\\)\r\n" { + set state_inferior_2 "running" + exp_continue + } + + -re "^\\s+1\\.1\\s+\[^\r\n\]+\r\n" { + set state_inferior_1 "stopped" + exp_continue + } + + -re "^\\*\\s+2\\.1\\s+\[^\r\n\]+\r\n" { + set state_inferior_2 "stopped" + exp_continue + } + + -re "^$::gdb_prompt $" { + if { $non_stop } { + gdb_assert { $state_inferior_1 == "running" \ + && $state_inferior_2 == "stopped" } \ + $gdb_test_name + } else { + gdb_assert { $state_inferior_1 == "stopped" \ + && $state_inferior_2 == "stopped" } \ + $gdb_test_name + } + } + } + + # Allow inferior 2 to reach main. The confirms that inferior 2 can be + # set running again. + gdb_breakpoint main + gdb_continue_to_breakpoint "breakpoint in main" + gdb_test "bt 1" \ + "#0\\s+main \\(\\) at\[^\r\n\]+" \ + "check inferior 2 is in main" + + # Switch to inferior 1 and allow it to continue. This is a + # critical part of the test. When the test was added a bug (in + # all-stop mode) would leave inferior 1 stopped, but GDB code + # would think the thread was running. As such. the thread + # couldn't be resumed again. + gdb_test "inferior 1" "Switching to inferior 1.*" + + # In non-stop mode, thread 1.1 is correctly left running, so we + # need to stop it now. + if { $non_stop } { + gdb_test -no-prompt-anchor "interrupt" + gdb_test "p 1 + 1" " = 2" \ + "simple print to resync output" + } + + gdb_breakpoint breakpt + gdb_continue_to_breakpoint "continue to breakpoint in breakpt" + gdb_test "bt 1" \ + [multi_line \ + "#0\\s+breakpt \\(\\) at\[^\r\n\]+" \ + "\\(More stack frames follow\\.\\.\\.\\)"] \ + "check inferior 1 is in breakpt" + + # Switch back to inferior 2. The testing infrastructure will try to + # use 'monitor exit' to close gdbserver. It helps if we are in the + # gdbserver inferior when the script finishes. + gdb_test "inferior 2" "Switching to inferior 2.*" \ + "switch back to inferior 2" +} + +# Multi-inferior support requires non-stop targets. +foreach_with_prefix target_non_stop { auto on } { + # But it's OK if we're emulating all-stop mode on top of non-stop. + foreach_with_prefix non_stop { on off } { + run_test $target_non_stop $non_stop + } +} diff --git a/gdb/testsuite/gdb.multi/remove-inferiors.exp b/gdb/testsuite/gdb.multi/remove-inferiors.exp index 586d958..52e6cb0 100644 --- a/gdb/testsuite/gdb.multi/remove-inferiors.exp +++ b/gdb/testsuite/gdb.multi/remove-inferiors.exp @@ -32,7 +32,7 @@ proc add_inferior { expected_num message } { proc test_remove_inferiors { } { global binfile - clean_restart ${binfile} + clean_restart ${::testfile} # Add another inferior and switch to it. add_inferior 2 "add second inferior" diff --git a/gdb/testsuite/gdb.multi/run-only-second-inf.exp b/gdb/testsuite/gdb.multi/run-only-second-inf.exp index 7b6532c..3645962 100644 --- a/gdb/testsuite/gdb.multi/run-only-second-inf.exp +++ b/gdb/testsuite/gdb.multi/run-only-second-inf.exp @@ -31,7 +31,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug}]} { # So, start GDB with this setting. save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart ${binfile} + clean_restart ${::testfile} } # Add and start the second inferior. diff --git a/gdb/testsuite/gdb.multi/sched-multi-add-inferior.exp b/gdb/testsuite/gdb.multi/sched-multi-add-inferior.exp new file mode 100644 index 0000000..9344c80 --- /dev/null +++ b/gdb/testsuite/gdb.multi/sched-multi-add-inferior.exp @@ -0,0 +1,109 @@ +# 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/>. + +# Start multiple inferiors while schedule-multiple is on. Make use of +# the multi-target.exp.tcl support library for the helper procs, but +# don't use its 'setup' proc as that only turns on schedule-multiple +# after starting all the inferiors, and that is too late for this test. +# +# The specific bug that this test guards against was that, when a +# native target starts and runs upto a breakpoint, the thread would +# have its last signal recorded as SIGTRAP. +# +# When starting a gdbserver inferior (with schedule-multiple on) the +# native target would also be resumed. +# +# However, GDBs 'run' command was failing to clear out the old signal +# state from the native inferior, and so GDB would deliver a SIGTRAP +# to that inferior, killing it. + +source $srcdir/$subdir/multi-target.exp.tcl + +if {![multi_target_prepare]} { + return +} + +# Some breakpoint locations. +set line1 [gdb_get_line_number "set break 1 here"] +set line2 [gdb_get_line_number "set break 2 here"] + +# Start two inferiors using TARGET_TYPE_1 and TARGET_TYPE_2 (either +# 'extended-remote' or 'native'). Due to the way that inferior 1 is +# special (existing once GDB starts up), we just use the existing +# helper functions to create inferiors 2 and 3 using these types, and +# we leave inferior 1 unused. +proc run_test { target_type_1 target_type_2 } { + cleanup_gdbservers + + clean_restart + + gdb_test_no_output "set sysroot" + + # The schedule-multiple setting relies on all targets running in + # non-stop mode. Force it on for remote targets, until this is + # the default. + gdb_test_no_output "maint set target-non-stop on" + + # Run in all-stop mode. + gdb_test_no_output "set non-stop off" + + # Turn on schedule-multiple before starting any inferiors. + gdb_test_no_output "set schedule-multiple on" + + if {![add_inferior 2 $target_type_1 $::binfile]} { + return 0 + } + + if {![add_inferior 3 $target_type_2 $::binfile]} { + return 0 + } + + # Check we see all the expected threads. + gdb_test "info threads" \ + [multi_line \ + "\\s+Id\\s+Target Id\\s+Frame\\s*" \ + "\\s+2\\.1\\s+\[^\r\n\]+" \ + "\\s+2\\.2\\s+\[^\r\n\]+" \ + "\\*\\s+3\\.1\\s+\[^\r\n\]+" \ + "\\s+3\\.2\\s+\[^\r\n\]+"] + + # Ensure that all inferiors can be set running again. + gdb_test "break ${::srcfile}:${::line1} thread 3.1" + gdb_test "break ${::srcfile}:${::line2} thread 2.1" + gdb_test "continue" \ + [multi_line \ + "Thread 3\\.1 \[^\r\n\]+, main \\(\[^\r\n\]+\\) at \[^\r\n\]+" \ + "$::decimal\\s+function1 \\(\\); /\\* set break 1 here \\*/"] \ + "continue to function1" + + # Unblock thread 2.1 and continue again. This time, thread 2.1 + # will hit a breakpoint. + gdb_test "thread apply 2.1 set wait_for_gdb = 0" ".*" + gdb_test "continue" \ + [multi_line \ + "Thread 2\\.1 \[^\r\n\]+, main \\(\[^\r\n\]+\\) at \[^\r\n\]+" \ + "$::decimal\\s+function2 \\(\\); /\\* set break 2 here \\*/"] \ + "continue to function2" +} + +set all_target_types { extended-remote native } + +foreach_with_prefix target_type_1 $all_target_types { + foreach_with_prefix target_type_2 $all_target_types { + run_test $target_type_1 $target_type_2 + } +} + +multi_target_cleanup diff --git a/gdb/testsuite/gdb.multi/start-inferior-specific.exp b/gdb/testsuite/gdb.multi/start-inferior-specific.exp index 819c1c3..39621f0 100644 --- a/gdb/testsuite/gdb.multi/start-inferior-specific.exp +++ b/gdb/testsuite/gdb.multi/start-inferior-specific.exp @@ -25,10 +25,13 @@ standard_testfile .c -other.c +require allow_multi_inferior_tests + require !use_gdb_stub set srcfile_other ${srcfile2} -set binfile_other ${binfile}-other +set testfile_other $testfile-other +set binfile_other [standard_output_file $testfile_other] if { [build_executable ${testfile}.exp ${binfile} "${srcfile}" {debug}] != 0 } { return -1 @@ -46,7 +49,7 @@ proc do_test {} { append ::GDBFLAGS " -ex \"maintenance set target-non-stop on\"" } - clean_restart ${::binfile_other} + clean_restart $::testfile_other } gdb_test -no-prompt-anchor "run&" "Starting program: .*" "start background inferior" diff --git a/gdb/testsuite/gdb.multi/stop-all-on-exit.exp b/gdb/testsuite/gdb.multi/stop-all-on-exit.exp index b4ff09c..47071f3 100644 --- a/gdb/testsuite/gdb.multi/stop-all-on-exit.exp +++ b/gdb/testsuite/gdb.multi/stop-all-on-exit.exp @@ -18,6 +18,8 @@ # Test that in all-stop mode with multiple inferiors, GDB stops all # threads upon receiving an exit event from one of the inferiors. +require allow_multi_inferior_tests + # This is a test specific for a native target, where we use the # "-exec" argument to "add-inferior" and we explicitly don't do # "maint set target-non-stop on". diff --git a/gdb/testsuite/gdb.multi/tids-gid-reset.exp b/gdb/testsuite/gdb.multi/tids-gid-reset.exp index 6cc27eb..1785ac2 100644 --- a/gdb/testsuite/gdb.multi/tids-gid-reset.exp +++ b/gdb/testsuite/gdb.multi/tids-gid-reset.exp @@ -54,6 +54,8 @@ with_test_prefix "single-inferior" { # non-extended gdbserver is not supported. require !use_gdb_stub +require allow_multi_inferior_tests + # Test with multiple inferiors. This time, since we restart inferior # 1 while inferior 2 still has threads, then the new thread 1.1 should # end up with GID == 3, since we won't be able to reset the global diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp index b84f908..436a38a 100644 --- a/gdb/testsuite/gdb.multi/tids.exp +++ b/gdb/testsuite/gdb.multi/tids.exp @@ -124,6 +124,9 @@ with_test_prefix "single inferior" { gdb_test "print \$_inferior_thread_count" " = 1" } +# The rest of the tests require running multiple inferiors. +require allow_multi_inferior_tests + # "info threads" while there are multiple inferiors should show # qualified thread IDs. with_test_prefix "two inferiors" { @@ -290,7 +293,7 @@ with_test_prefix "two inferiors" { # Try both the convenience variable and the literal number. foreach thr {"\$thr" "20" "1.20" "\$inf.1" "30.1" } { set expected [string_to_regexp $thr] - gdb_test "info threads $thr" "No threads match '${expected}'." + gdb_test "info threads $thr" "No threads matched\\." # "info threads" works like a filter. If there's any other # valid thread in the list, there's no error. info_threads "$thr 1.1" "1.1" @@ -412,7 +415,7 @@ with_test_prefix "two inferiors" { # Check that we do parse the inferior number and don't confuse it. gdb_test "info threads 3.1" \ - "No threads match '3.1'\." + "No threads matched\\." } if { [allow_python_tests] } { diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp index 70c3da9..a149407 100644 --- a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp +++ b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp @@ -17,6 +17,8 @@ # watchpoints don't end up with stale locations, preventing resumption # of other inferiors. +require allow_fork_tests + standard_testfile if {[build_executable "failed to build" $testfile $srcfile {debug}]} { @@ -29,12 +31,12 @@ if {[build_executable "failed to build" $testfile $srcfile {debug}]} { proc do_test {dispose} { global binfile bkptno_numopt_re - clean_restart $binfile + clean_restart $::testfile gdb_test_no_output "set follow-fork child" gdb_test_no_output "set detach-on-fork off" - if ![runto "child_function"] { + if {![runto "child_function"]} { return } diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp index f448689..501f0a6 100644 --- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp +++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp @@ -16,6 +16,8 @@ standard_testfile set executable ${testfile} +require allow_multi_inferior_tests + # Multiple inferiors are needed, therefore both native and extended gdbserver # modes are supported. Only non-extended gdbserver is not supported. require !use_gdb_stub @@ -36,7 +38,7 @@ gdb_test_no_output "set breakpoint always-inserted on" # displaced-stepping is also needed as other GDB sometimes still removes the # breakpoints, even with always-inserted on. # Without the support this test just is not as thorough as it could be. -if [support_displaced_stepping] { +if {[support_displaced_stepping]} { gdb_test_no_output "set displaced-stepping on" } diff --git a/gdb/testsuite/gdb.objc/basicclass.exp b/gdb/testsuite/gdb.objc/basicclass.exp index 7f29aff..9e40c71 100644 --- a/gdb/testsuite/gdb.objc/basicclass.exp +++ b/gdb/testsuite/gdb.objc/basicclass.exp @@ -72,7 +72,7 @@ proc deduce_language_of_main {} { proc do_objc_tests {} { global binfile - clean_restart $binfile + clean_restart $::testfile deduce_language_of_main } diff --git a/gdb/testsuite/gdb.objc/nondebug.exp b/gdb/testsuite/gdb.objc/nondebug.exp index dfdd9bc..9ca86ff 100644 --- a/gdb/testsuite/gdb.objc/nondebug.exp +++ b/gdb/testsuite/gdb.objc/nondebug.exp @@ -29,7 +29,7 @@ if {[gdb_compile_objc "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [ proc do_objc_tests {} { global binfile - clean_restart $binfile + clean_restart $::testfile } do_objc_tests diff --git a/gdb/testsuite/gdb.objc/objcdecode.exp b/gdb/testsuite/gdb.objc/objcdecode.exp index b7c38db..5414f0f 100644 --- a/gdb/testsuite/gdb.objc/objcdecode.exp +++ b/gdb/testsuite/gdb.objc/objcdecode.exp @@ -29,7 +29,7 @@ if {[gdb_compile_objc "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [ proc do_objc_tests {} { global binfile - clean_restart $binfile + clean_restart $::testfile } do_objc_tests diff --git a/gdb/testsuite/gdb.objc/print.exp b/gdb/testsuite/gdb.objc/print.exp index c18bf29..e3f4177 100644 --- a/gdb/testsuite/gdb.objc/print.exp +++ b/gdb/testsuite/gdb.objc/print.exp @@ -59,7 +59,7 @@ proc test_float_rejected {} { clean_restart -if [set_lang_objc] { +if { [set_lang_objc] } { test_float_accepted test_float_rejected } else { diff --git a/gdb/testsuite/gdb.opencl/callfuncs.exp b/gdb/testsuite/gdb.opencl/callfuncs.exp index 8ab8db7..6982461 100644 --- a/gdb/testsuite/gdb.opencl/callfuncs.exp +++ b/gdb/testsuite/gdb.opencl/callfuncs.exp @@ -21,8 +21,9 @@ load_lib opencl.exp require allow_opencl_tests -set testfile "callfuncs" -set clprogram [remote_download target ${srcdir}/${subdir}/${testfile}.cl] +standard_testfile .cl + +set clprogram [remote_download target $srcdir/$subdir/$srcfile] # Compile the generic OpenCL host app if { [gdb_compile_opencl_hostapp "${clprogram}" "${testfile}" "" ] != "" } { @@ -30,7 +31,7 @@ if { [gdb_compile_opencl_hostapp "${clprogram}" "${testfile}" "" ] != "" } { return -1 } -clean_restart [standard_testfile $testfile] +clean_restart $testfile # Set breakpoint at the OpenCL kernel gdb_test "tbreak testkernel" \ diff --git a/gdb/testsuite/gdb.opencl/vec_comps.exp b/gdb/testsuite/gdb.opencl/vec_comps.exp index 3485a34..09c12ec 100644 --- a/gdb/testsuite/gdb.opencl/vec_comps.exp +++ b/gdb/testsuite/gdb.opencl/vec_comps.exp @@ -58,7 +58,7 @@ set have_cl_khr_fp16 [get_integer_valueof "have_cl_khr_fp16" 0] # Sanity checks proc check_basic { name type size } { gdb_test "ptype ${name}" "type = ${type}16" - gdb_test "p sizeof(${name})" " = [expr ${size} * 16]" + gdb_test "p sizeof(${name})" " = [expr {${size} * 16}]" gdb_test "print/d ${name}" " = \\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\\}" } @@ -227,40 +227,40 @@ proc check_type { name type alttype } { } proc check_sizeof { name size } { - gdb_test "print sizeof (${name}.lo)" " = [expr $size * 8]" - gdb_test "print sizeof (${name}.hi)" " = [expr $size * 8]" - gdb_test "print sizeof (${name}.even)" " = [expr $size * 8]" - gdb_test "print sizeof (${name}.odd)" " = [expr $size * 8]" + gdb_test "print sizeof (${name}.lo)" " = [expr {$size * 8}]" + gdb_test "print sizeof (${name}.hi)" " = [expr {$size * 8}]" + gdb_test "print sizeof (${name}.even)" " = [expr {$size * 8}]" + gdb_test "print sizeof (${name}.odd)" " = [expr {$size * 8}]" - gdb_test "print sizeof (${name}.hi.even)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.odd.odd.lo)" " = [expr $size * 2]" + gdb_test "print sizeof (${name}.hi.even)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.odd.odd.lo)" " = [expr {$size * 2}]" gdb_test "print sizeof (${name}.even.hi.lo.odd)" " = $size" gdb_test "print sizeof (${name}.x)" " = $size" - gdb_test "print sizeof (${name}.xy)" " = [expr $size * 2]" - gdb_test "print sizeof (${name}.xyz)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.xyzw)" " = [expr $size * 4]" + gdb_test "print sizeof (${name}.xy)" " = [expr {$size * 2}]" + gdb_test "print sizeof (${name}.xyz)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.xyzw)" " = [expr {$size * 4}]" gdb_test "print sizeof (${name}.xy.x)" " = $size" - gdb_test "print sizeof (${name}.wzyx.yy)" " = [expr $size * 2]" + gdb_test "print sizeof (${name}.wzyx.yy)" " = [expr {$size * 2}]" gdb_test "print sizeof (${name}.wzyx.yx.x)" " = $size" gdb_test "print sizeof (${name}.xyzw.w)" " = $size" gdb_test "print sizeof (${name}.s0)" " = $size" - gdb_test "print sizeof (${name}.s01)" " = [expr $size * 2]" - gdb_test "print sizeof (${name}.s012)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.s0123)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.s01234567)" " = [expr $size * 8]" - gdb_test "print sizeof (${name}.s0123456789abcdef)" " = [expr $size * 16]" - - gdb_test "print sizeof (${name}.sfedcba98.S0246)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.sfedcba98.S0246.s13)" " = [expr $size * 2]" + gdb_test "print sizeof (${name}.s01)" " = [expr {$size * 2}]" + gdb_test "print sizeof (${name}.s012)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.s0123)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.s01234567)" " = [expr {$size * 8}]" + gdb_test "print sizeof (${name}.s0123456789abcdef)" " = [expr {$size * 16}]" + + gdb_test "print sizeof (${name}.sfedcba98.S0246)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.sfedcba98.S0246.s13)" " = [expr {$size * 2}]" gdb_test "print sizeof (${name}.sfedcba98.S0246.s13.s0)" " = $size" - gdb_test "print sizeof (${name}.s0123456789abcdef.s22)" " = [expr $size * 2]" + gdb_test "print sizeof (${name}.s0123456789abcdef.s22)" " = [expr {$size * 2}]" - gdb_test "print sizeof (${name}.hi.s7654.wx)" " = [expr $size * 2]" - gdb_test "print sizeof (${name}.s0123456789abcdef.even.lo)" " = [expr $size * 4]" - gdb_test "print sizeof (${name}.odd.xyzw.s23)" " = [expr $size * 2]" + gdb_test "print sizeof (${name}.hi.s7654.wx)" " = [expr {$size * 2}]" + gdb_test "print sizeof (${name}.s0123456789abcdef.even.lo)" " = [expr {$size * 4}]" + gdb_test "print sizeof (${name}.odd.xyzw.s23)" " = [expr {$size * 2}]" gdb_test "print sizeof (${name}.xyzw.hi.odd)" " = $size" } @@ -343,8 +343,8 @@ proc check_access { name } { # lvalue tests for {set i 0} {$i < 16} {incr i} { - gdb_test_no_output "set variable ${name}.s[format "%x" $i] = [expr 15 - $i]" - gdb_test "print/d ${name}.s[format "%x" $i]" " = [expr 15 - $i]" + gdb_test_no_output "set variable ${name}.s[format "%x" $i] = [expr {15 - $i}]" + gdb_test "print/d ${name}.s[format "%x" $i]" " = [expr {15 - $i}]" } gdb_test "print/d ${name}" " = \\{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0\\}" diff --git a/gdb/testsuite/gdb.opt/break-on-_exit.exp b/gdb/testsuite/gdb.opt/break-on-_exit.exp index 2b94be8..9295fea 100644 --- a/gdb/testsuite/gdb.opt/break-on-_exit.exp +++ b/gdb/testsuite/gdb.opt/break-on-_exit.exp @@ -25,7 +25,7 @@ # for libc, then the breakpoint is set on the exec-local _exit@plt instead, # and that functionality will also not be used. # -# We may get the required setup in case of a libc with misssing separate +# We may get the required setup in case of a libc with missing separate # debuginfo, but we want the same effect if that debuginfo is installed. # # So, we use -readnever to read minimal symbols, but not non-miminal symbols. diff --git a/gdb/testsuite/gdb.opt/inline-break.exp b/gdb/testsuite/gdb.opt/inline-break.exp index d83ff75..0805f69 100644 --- a/gdb/testsuite/gdb.opt/inline-break.exp +++ b/gdb/testsuite/gdb.opt/inline-break.exp @@ -209,7 +209,7 @@ foreach_with_prefix cmd [list "break" "tbreak"] { # that we actually stop where we think we should. for {set i 1} {$i < 4} {incr i} { foreach inline {"not_inline" "inline"} { - eval gdb_breakpoint "${inline}_func$i" $break_flags + gdb_breakpoint "${inline}_func$i" {*}$break_flags } } @@ -247,7 +247,7 @@ foreach_with_prefix func { "func_inline_caller" "func_inline_callee" } { - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { continue @@ -264,7 +264,7 @@ foreach_with_prefix func { set line [gdb_get_line_number "break here"] with_test_prefix "line number" { - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { continue @@ -288,7 +288,7 @@ with_test_prefix "line number" { with_test_prefix "address" { - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { continue @@ -308,7 +308,7 @@ with_test_prefix "address" { with_test_prefix "check alignment" { - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { continue diff --git a/gdb/testsuite/gdb.opt/inline-cmds.exp b/gdb/testsuite/gdb.opt/inline-cmds.exp index eca897c..e80d6f7 100644 --- a/gdb/testsuite/gdb.opt/inline-cmds.exp +++ b/gdb/testsuite/gdb.opt/inline-cmds.exp @@ -241,7 +241,7 @@ gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker" # Some architectures will have one or more instructions after # the call instruction which still are part of the call sequence, -# so it should be expected to return to the caller line after issue +# so it should be expected to return to the caller line after issue # a 'finish' command. gdb_test_multiple "finish" "finish from marker to func1" { -re -wrap "func1 \\(\\);" { diff --git a/gdb/testsuite/gdb.opt/inline-entry.exp b/gdb/testsuite/gdb.opt/inline-entry.exp index f185f10..0c6b0fb 100644 --- a/gdb/testsuite/gdb.opt/inline-entry.exp +++ b/gdb/testsuite/gdb.opt/inline-entry.exp @@ -43,11 +43,11 @@ if { [supports_statement_frontiers] } { lappend options additional_flags=-gstatement-frontiers } -if { [prepare_for_testing "failed to prepare" $binfile $srcfile $options] } { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile $options] } { return } -if ![runto_main] { +if { ![runto_main] } { return } diff --git a/gdb/testsuite/gdb.opt/inline-small-func.exp b/gdb/testsuite/gdb.opt/inline-small-func.exp index d77a10e..b04f957 100644 --- a/gdb/testsuite/gdb.opt/inline-small-func.exp +++ b/gdb/testsuite/gdb.opt/inline-small-func.exp @@ -41,7 +41,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -if ![runto_main] { +if { ![runto_main] } { return -1 } diff --git a/gdb/testsuite/gdb.opt/solib-intra-step.exp b/gdb/testsuite/gdb.opt/solib-intra-step.exp index 4b7ab3a..9c6d6c5 100644 --- a/gdb/testsuite/gdb.opt/solib-intra-step.exp +++ b/gdb/testsuite/gdb.opt/solib-intra-step.exp @@ -34,7 +34,7 @@ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_load_shlib $binfile_lib if {![runto_main]} { diff --git a/gdb/testsuite/gdb.pascal/floats.exp b/gdb/testsuite/gdb.pascal/floats.exp index a0c37ad..926c0c3 100644 --- a/gdb/testsuite/gdb.pascal/floats.exp +++ b/gdb/testsuite/gdb.pascal/floats.exp @@ -48,9 +48,9 @@ gdb_test "next" "u := 78\\.3;" "next to 'u := 78.3' line" gdb_test "next" "l := 1;" "next to 'l := 1' line" gdb_test "next" "i := 1;" "next to 'i := 1' line" -# At that point, +# At that point, # r should be equal to 1.25 -gdb_test "print r" " = 1\\.25" +gdb_test "print r" " = 1\\.25" # s should be equal to 2.2 gdb_test "print s" " = 2\\.(199.*|2|200.*)" # t should be equal to -3.2 @@ -120,7 +120,7 @@ gdb_test "next" "s := sin\\(u\\);" "advance to 's := sin(u)' line" gdb_test "print r" " = -1" "test cos(pi) is equal to -1" gdb_test "next" "" "go past 's := sin(u)' line" -set msg "Test sin(pi) is equal to 0" +set msg "Test sin(pi) is equal to 0" gdb_test_multiple "print s" $msg { -re ".* = (0|-?\[0-9\]\\.\[0-9\]*\[eE\](-?\[0-9\]*))\[\r\n\]+$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.pascal/gdb11492.exp b/gdb/testsuite/gdb.pascal/gdb11492.exp index e39f522..67764c5 100644 --- a/gdb/testsuite/gdb.pascal/gdb11492.exp +++ b/gdb/testsuite/gdb.pascal/gdb11492.exp @@ -37,9 +37,9 @@ if { [gdb_breakpoint ${srcfile}:${bp_location1}] } { gdb_test "continue" "" gdb_test "print integer_array" { = \{50, 51, 52, 53, 54, 55, 56, 57\}} -gdb_test "print /s integer_array" " = '23456789'" +gdb_test "print /s integer_array" " = '23456789'" -gdb_test "print char_array" " = '23456789'" +gdb_test "print char_array" " = '23456789'" gdb_test "print /d char_array" { = \{50, 51, 52, 53, 54, 55, 56, 57\}} gdb_test "print /x char_array" { = \{0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39\}} # Use next two times to avoid GPC line numbering problem diff --git a/gdb/testsuite/gdb.pascal/hello.exp b/gdb/testsuite/gdb.pascal/hello.exp index 904f2a9..ac10280 100644 --- a/gdb/testsuite/gdb.pascal/hello.exp +++ b/gdb/testsuite/gdb.pascal/hello.exp @@ -46,7 +46,7 @@ gdb_test "print st" \ # This test also fails for gpc because the program # stops after the string has been written -# while it should stop before writing it +# while it should stop before writing it if { $pascal_compiler_is_gpc } { setup_xfail *-*-* } diff --git a/gdb/testsuite/gdb.pascal/integers.exp b/gdb/testsuite/gdb.pascal/integers.exp index 5c878c5..12d15c8 100644 --- a/gdb/testsuite/gdb.pascal/integers.exp +++ b/gdb/testsuite/gdb.pascal/integers.exp @@ -43,9 +43,9 @@ gdb_test "print i" ".* = 0" "print i before assigned to 1" gdb_test "next" "i := 1;" "next to 'i := 1' line" gdb_test "next" "j := 2;" "next to 'j := 2' line" -# At that point, +# At that point, # i should be equal to 1 -gdb_test "print i" " = 1" +gdb_test "print i" " = 1" # but j should still be equal to zero if { $pascal_compiler_is_gpc } { setup_xfail *-*-* @@ -59,7 +59,7 @@ gdb_test "next" "l := k;" "next to 'l := k' line" gdb_test "print j" " = 2" # k should be equal to 3 gdb_test "print k" " = 3" -# But l shoud still be zero +# But l should still be zero if { $pascal_compiler_is_gpc } { setup_xfail *-*-* } diff --git a/gdb/testsuite/gdb.pascal/print.exp b/gdb/testsuite/gdb.pascal/print.exp index 98b0879..18dff4b 100644 --- a/gdb/testsuite/gdb.pascal/print.exp +++ b/gdb/testsuite/gdb.pascal/print.exp @@ -59,7 +59,7 @@ proc test_float_rejected {} { clean_restart -if [set_lang_pascal] { +if { [set_lang_pascal] } { test_float_accepted test_float_rejected } else { diff --git a/gdb/testsuite/gdb.pascal/types.exp b/gdb/testsuite/gdb.pascal/types.exp index c234c28..b4949f5 100644 --- a/gdb/testsuite/gdb.pascal/types.exp +++ b/gdb/testsuite/gdb.pascal/types.exp @@ -25,7 +25,7 @@ proc test_integer_literal_types_accepted {} { # Test various decimal values. # Should be integer*4 probably. - gdb_test "pt 123" "type = int" + gdb_test "pt 123" "type = int" } proc test_character_literal_types_accepted {} { global gdb_prompt diff --git a/gdb/testsuite/gdb.perf/backtrace.exp b/gdb/testsuite/gdb.perf/backtrace.exp index 9ec099f..aea1e01 100644 --- a/gdb/testsuite/gdb.perf/backtrace.exp +++ b/gdb/testsuite/gdb.perf/backtrace.exp @@ -28,7 +28,7 @@ set executable $testfile set expfile $testfile.exp # make check-perf RUNTESTFLAGS='backtrace.exp BACKTRACE_DEPTH=1024' -if ![info exists BACKTRACE_DEPTH] { +if {![info exists BACKTRACE_DEPTH]} { set BACKTRACE_DEPTH 64 } @@ -47,7 +47,7 @@ PerfTest::assemble { } { global binfile - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.perf/gmonster1.exp b/gdb/testsuite/gdb.perf/gmonster1.exp index f752062..8bb748d 100644 --- a/gdb/testsuite/gdb.perf/gmonster1.exp +++ b/gdb/testsuite/gdb.perf/gmonster1.exp @@ -38,7 +38,7 @@ load_lib gen-perf-test.exp require allow_perf_tests -if ![info exists MONSTER] { +if {![info exists MONSTER]} { set MONSTER "n" } diff --git a/gdb/testsuite/gdb.perf/gmonster2.exp b/gdb/testsuite/gdb.perf/gmonster2.exp index ba4e46b..7049bce 100644 --- a/gdb/testsuite/gdb.perf/gmonster2.exp +++ b/gdb/testsuite/gdb.perf/gmonster2.exp @@ -38,7 +38,7 @@ load_lib gen-perf-test.exp require allow_perf_tests -if ![info exists MONSTER] { +if {![info exists MONSTER]} { set MONSTER "n" } diff --git a/gdb/testsuite/gdb.perf/single-step.exp b/gdb/testsuite/gdb.perf/single-step.exp index 920cf9d..8ec32d1 100644 --- a/gdb/testsuite/gdb.perf/single-step.exp +++ b/gdb/testsuite/gdb.perf/single-step.exp @@ -26,7 +26,7 @@ set executable $testfile set expfile $testfile.exp # make check-perf RUNTESTFLAGS='single-step.exp SINGLE_STEP_COUNT=300' -if ![info exists SINGLE_STEP_COUNT] { +if {![info exists SINGLE_STEP_COUNT]} { set SINGLE_STEP_COUNT 1000 } @@ -39,7 +39,7 @@ PerfTest::assemble { return 0 } { global binfile - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.perf/skip-command.exp b/gdb/testsuite/gdb.perf/skip-command.exp index b82d318..e59cb07 100644 --- a/gdb/testsuite/gdb.perf/skip-command.exp +++ b/gdb/testsuite/gdb.perf/skip-command.exp @@ -33,10 +33,10 @@ set skip_func_file [standard_output_file $srcfile2] set expfile $testfile.exp # make check-perf RUNTESTFLAGS='skip-command.exp SKIP_STEP_COUNT=1000 ...' -if ![info exists SKIP_STEP_COUNT] { +if {![info exists SKIP_STEP_COUNT]} { set SKIP_STEP_COUNT 1000 } -if ![info exists SKIP_DIRECTIVE_COUNT] { +if {![info exists SKIP_DIRECTIVE_COUNT]} { set SKIP_DIRECTIVE_COUNT 1000 } @@ -91,7 +91,7 @@ proc write_skip_func_source { file_name func_name_prefix nr_funcs } { proc run_skip_bench { kind text } { global SKIP_STEP_COUNT SKIP_DIRECTIVE_COUNT - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -120,7 +120,7 @@ PerfTest::assemble { return 0 } { global binfile - clean_restart $binfile + clean_restart $::testfile return 0 } { global SKIP_STEP_COUNT SKIP_DIRECTIVE_COUNT diff --git a/gdb/testsuite/gdb.perf/skip-prologue.exp b/gdb/testsuite/gdb.perf/skip-prologue.exp index 50df93a..880a0f4 100644 --- a/gdb/testsuite/gdb.perf/skip-prologue.exp +++ b/gdb/testsuite/gdb.perf/skip-prologue.exp @@ -28,7 +28,7 @@ set executable $testfile set expfile $testfile.exp # make check-perf RUNTESTFLAGS='skip-prologue.exp SKIP_PROLOGUE_COUNT=500' -if ![info exists SKIP_PROLOGUE_COUNT] { +if {![info exists SKIP_PROLOGUE_COUNT]} { set SKIP_PROLOGUE_COUNT 500 } @@ -51,7 +51,7 @@ PerfTest::assemble { global binfile global gdb_prompt - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.perf/solib.exp b/gdb/testsuite/gdb.perf/solib.exp index 45f9330..e7870f6 100644 --- a/gdb/testsuite/gdb.perf/solib.exp +++ b/gdb/testsuite/gdb.perf/solib.exp @@ -31,7 +31,7 @@ set executable $testfile set expfile $testfile.exp # make check-perf RUNTESTFLAGS='solib.exp SOLIB_COUNT=1024' -if ![info exists SOLIB_COUNT] { +if {![info exists SOLIB_COUNT]} { set SOLIB_COUNT 128 } @@ -72,7 +72,7 @@ PerfTest::assemble { } { global binfile - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.perf/template-breakpoints.exp b/gdb/testsuite/gdb.perf/template-breakpoints.exp index 7d66e0f..e5d21b2 100644 --- a/gdb/testsuite/gdb.perf/template-breakpoints.exp +++ b/gdb/testsuite/gdb.perf/template-breakpoints.exp @@ -28,7 +28,7 @@ set executable $testfile set expfile $testfile.exp # make check-perf RUNTESTFLAGS='template-breakpoints.exp EXPANSION_DEPTH=40' -if ![info exists EXPANSION_DEPTH] { +if {![info exists EXPANSION_DEPTH]} { set EXPANSION_DEPTH 40 } @@ -47,7 +47,7 @@ PerfTest::assemble { } { global binfile - clean_restart $binfile + clean_restart $::testfile if ![runto_main] { return -1 diff --git a/gdb/testsuite/gdb.python/gdb_leak_detector.py b/gdb/testsuite/gdb.python/gdb_leak_detector.py new file mode 100644 index 0000000..8f74b67 --- /dev/null +++ b/gdb/testsuite/gdb.python/gdb_leak_detector.py @@ -0,0 +1,121 @@ +# Copyright (C) 2021-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/>. + +# Defines a base class, which can be sub-classed, in order to run +# memory leak tests on some aspects of GDB's Python API. See the +# comments on the gdb_leak_detector class for more details. + +import os +import tracemalloc + +import gdb + + +# This class must be sub-classed to create a memory leak test. The +# sub-classes __init__ method should call the parent classes __init__ +# method, and the sub-class should override allocate() and +# deallocate(). See the comments on the various methods below for +# more details of required arguments and expected usage. +class gdb_leak_detector: + + # Class initialisation. FILENAME is the file in which the + # sub-class is defined, usually passed as just '__file__'. This + # is used when looking for memory allocations; only allocations in + # FILENAME are considered. + def __init__(self, filename): + self.filters = [tracemalloc.Filter(True, "*" + os.path.basename(filename))] + + # Internal helper function to actually run the test. Calls the + # allocate() method to allocate an object from GDB's Python API. + # When CLEAR is True the object will then be deallocated by + # calling deallocate(), otherwise, deallocate() is not called. + # + # Finally, this function checks for any memory allocatios + # originating from 'self.filename' that have not been freed, and + # returns the total (in bytes) of the memory that has been + # allocated, but not freed. + def _do_test(self, clear): + # Start tracing, and take a snapshot of the current allocations. + tracemalloc.start() + snapshot1 = tracemalloc.take_snapshot() + + # Generate the GDB Python API object by calling the allocate + # method. + self.allocate() + + # Possibly clear the reference to the allocated object. + if clear: + self.deallocate() + + # Now grab a second snapshot of memory allocations, and stop + # tracing memory allocations. + snapshot2 = tracemalloc.take_snapshot() + tracemalloc.stop() + + # Filter the snapshots; we only care about allocations originating + # from this file. + snapshot1 = snapshot1.filter_traces(self.filters) + snapshot2 = snapshot2.filter_traces(self.filters) + + # Compare the snapshots, this leaves only things that were + # allocated, but not deallocated since the first snapshot. + stats = snapshot2.compare_to(snapshot1, "traceback") + + # Total up all the allocated things. + total = 0 + for stat in stats: + total += stat.size_diff + return total + + # Run the memory leak test. Prints 'PASS' if successful, + # otherwise, raises an exception (of type GdbError). + def run(self): + # The first time we run this some global state will be allocated which + # shows up as memory that is allocated, but not released. So, run the + # test once and discard the result. + self._do_test(True) + + # Now run the test twice, the first time we clear our global reference + # to the allocated object, which should allow Python to deallocate the + # object. The second time we hold onto the global reference, preventing + # Python from performing the deallocation. + bytes_with_clear = self._do_test(True) + bytes_without_clear = self._do_test(False) + + # If there are any allocations left over when we cleared the reference + # (and expected deallocation) then this indicates a leak. + if bytes_with_clear > 0: + raise gdb.GdbError("memory leak when object reference was released") + + # If there are no allocations showing when we hold onto a reference, + # then this likely indicates that the testing infrastructure is broken, + # and we're no longer spotting the allocations at all. + if bytes_without_clear == 0: + raise gdb.GdbError("object is unexpectedly not showing as allocated") + + # Print a PASS message that the TCL script can see. + print("PASS") + + # Sub-classes must override this method. Allocate an object (or + # multiple objects) from GDB's Python API. Store references to + # these objects within SELF. + def allocate(self): + raise NotImplementedError("allocate() not implemented") + + # Sub-classes must override this method. Deallocate the object(s) + # allocated by the allocate() method. All that is required is for + # the references created in allocate() to be set to None. + def deallocate(self): + raise NotImplementedError("allocate() not implemented") diff --git a/gdb/testsuite/gdb.python/make-visualizer.exp b/gdb/testsuite/gdb.python/make-visualizer.exp new file mode 100644 index 0000000..5794bbd --- /dev/null +++ b/gdb/testsuite/gdb.python/make-visualizer.exp @@ -0,0 +1,176 @@ +# Copyright (C) 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/>. + +# Tests for gdb.printing.make_visualizer; specifically that the +# optimized-out and synthetic pointer cases work properly. + +load_lib dwarf.exp +load_lib gdb-python.exp + +require dwarf2_support +require allow_python_tests + +# Use a simple plain-"main" source file. +standard_testfile py-progspace.c -dw.S + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { + return +} + +if {![runto_main]} { + return +} + +# Get size to create fake DWARF for the test. +set ptr_size [get_sizeof "void *" 96] + +set asm_file [standard_output_file ${srcfile2}] +Dwarf::assemble $asm_file { + cu {} { + compile_unit {} { + declare_labels i32_type i32_array \ + struct_label variable_label pointer_label + + i32_type: DW_TAG_base_type { + DW_AT_name "int32_t" + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata + } + + i32_array: DW_TAG_array_type { + DW_AT_name array_type + DW_AT_type :$i32_type + } { + DW_TAG_subrange_type { + DW_AT_type :$i32_type + DW_AT_lower_bound 0 DW_FORM_data1 + DW_AT_upper_bound 3 DW_FORM_data1 + } + } + + # Used for testing optimized-out elements of an array. + DW_TAG_variable { + DW_AT_name i32_noptr + DW_AT_type :$i32_array + DW_AT_location { + DW_OP_constu 1779823878 + DW_OP_stack_value + DW_OP_piece 4 + } SPECIAL_expr + } + + struct_label: DW_TAG_structure_type { + DW_AT_name i32_noptr + DW_AT_byte_size 4 DW_FORM_sdata + } { + DW_TAG_member { + DW_AT_name f + DW_AT_type :$i32_type + DW_AT_data_member_location 0 DW_FORM_data1 + } + } + + pointer_label: DW_TAG_pointer_type { + DW_AT_byte_size $::ptr_size DW_FORM_sdata + DW_AT_type :$struct_label + } + + variable_label: DW_TAG_variable { + DW_AT_name v + DW_AT_location { + DW_OP_implicit_value 0x1 0x1 0x1 0x1 + } SPECIAL_expr + DW_AT_type :$struct_label + } + + # Used for testing synthetic pointers. + DW_TAG_variable { + DW_AT_name synthptr + DW_AT_location [subst { + GNU_implicit_pointer $variable_label 0 + }] SPECIAL_expr + DW_AT_type :$pointer_label + } + + # Optimized-out pointer. + DW_TAG_variable { + DW_AT_name optoutptr + DW_AT_location { } SPECIAL_expr + DW_AT_type :$pointer_label + } + } + } +} + +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}]} { + return +} + +# Need a frame to evaluate a synthetic pointer. +if {![runto_main]} { + return +} + +gdb_test_no_output "python import gdb" +gdb_test_no_output "python import gdb.printing" + +gdb_test_no_output "python val = gdb.parse_and_eval('i32_noptr')" \ + "fetch i32_noptr" +gdb_test_no_output "python vz = gdb.printing.make_visualizer(val)" \ + "create i32_noptr visualizer" +gdb_test "python print(isinstance(vz, gdb.printing.NoOpArrayPrinter))" \ + True \ + "i32_noptr uses array printer" + +gdb_test_no_output "python vz1 = gdb.printing.make_visualizer(val\[0\])" \ + "create visualizer for valid element" +gdb_test "python print(isinstance(vz1, gdb.printing.NoOpScalarPrinter))" \ + True \ + "valid element uses scalar printer" +gdb_test "python print(vz1.to_string())" \ + 1779823878 \ + "string form of valid element" + +gdb_test_no_output "python vz2 = gdb.printing.make_visualizer(val\[1\])" \ + "create visualizer for optimized-out element" +gdb_test "python print(isinstance(vz2, gdb.printing.NoOpScalarPrinter))" \ + True \ + "optimized-out element uses scalar printer" +gdb_test "python print(vz2.to_string())" \ + "<optimized out>" \ + "string form of optimized-out element" + +gdb_test_no_output "python val2 = gdb.parse_and_eval('synthptr')" \ + "fetch synthetic pointer" +gdb_test_no_output "python vzv2 = gdb.printing.make_visualizer(val2)" \ + "create synthetic pointer visualizer" +gdb_test "python print(isinstance(vzv2, gdb.printing.NoOpPointerReferencePrinter))" \ + True \ + "synthetic pointer uses pointer printer" +gdb_test "python print(vzv2.child(0)\[1\])" \ + "{f = 16843009}" \ + "child of synthetic pointer" + +gdb_test_no_output "python val3 = gdb.parse_and_eval('optoutptr')" \ + "fetch optimized-out pointer" +gdb_test_no_output "python vzv3 = gdb.printing.make_visualizer(val3)" \ + "create optimized-out pointer visualizer" +gdb_test "python print(isinstance(vzv3, gdb.printing.NoOpScalarPrinter))" \ + True \ + "optimized-out pointer uses scalar printer" +gdb_test "python print(vzv3.to_string())" \ + "<optimized out>" \ + "string representation of optimized-out pointer" diff --git a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp index dd6cb59..17b8afe 100644 --- a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp +++ b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp @@ -39,7 +39,7 @@ proc start_test { breakpoint_comment } { # Start with a fresh gdb. # This is important because the test can crash GDB. - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { untested "couldn't run to breakpoint" diff --git a/gdb/testsuite/gdb.python/py-arch-reg-groups.exp b/gdb/testsuite/gdb.python/py-arch-reg-groups.exp index 855af27..2b0ac3e 100644 --- a/gdb/testsuite/gdb.python/py-arch-reg-groups.exp +++ b/gdb/testsuite/gdb.python/py-arch-reg-groups.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-arch-reg-names.exp b/gdb/testsuite/gdb.python/py-arch-reg-names.exp index 7093674..99fb8ce 100644 --- a/gdb/testsuite/gdb.python/py-arch-reg-names.exp +++ b/gdb/testsuite/gdb.python/py-arch-reg-names.exp @@ -23,7 +23,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp index 79e5939..531ae50 100644 --- a/gdb/testsuite/gdb.python/py-arch.exp +++ b/gdb/testsuite/gdb.python/py-arch.exp @@ -20,7 +20,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -78,7 +78,7 @@ foreach size {0 1 2 3 4 8 16} { } else { set sign_result [lindex $sign_data 1] } - set fullsize [expr 8 * $size] + set fullsize [expr {8 * $size}] gdb_test_no_output "python t = arch.integer_type($fullsize$sign)" \ "get integer type for $size$sign" gdb_test "python print(t.sizeof)" "$size" \ diff --git a/gdb/testsuite/gdb.python/py-as-string.exp b/gdb/testsuite/gdb.python/py-as-string.exp index 05d55df..2ad179d 100644 --- a/gdb/testsuite/gdb.python/py-as-string.exp +++ b/gdb/testsuite/gdb.python/py-as-string.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.python/py-auto-load-chaining.exp b/gdb/testsuite/gdb.python/py-auto-load-chaining.exp index 451dca6..fbb95d9 100644 --- a/gdb/testsuite/gdb.python/py-auto-load-chaining.exp +++ b/gdb/testsuite/gdb.python/py-auto-load-chaining.exp @@ -49,7 +49,7 @@ if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-bp-locations.exp b/gdb/testsuite/gdb.python/py-bp-locations.exp index 61e4e38..b09a401 100644 --- a/gdb/testsuite/gdb.python/py-bp-locations.exp +++ b/gdb/testsuite/gdb.python/py-bp-locations.exp @@ -27,7 +27,7 @@ save_vars { GDBFLAGS } { clean_restart $testfile } -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -79,7 +79,7 @@ gdb_test "python print(gdb.breakpoints()\[1\].locations\[0\])" \ "check repr of disabled breakpoint location" gdb_continue_to_breakpoint "" ".*25.*" -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-breakpoint-create-fail.exp b/gdb/testsuite/gdb.python/py-breakpoint-create-fail.exp index 391744e..4098a7a 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint-create-fail.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint-create-fail.exp @@ -27,7 +27,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { } clean_restart "${testfile}" -if ![runto_main] { +if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 1b9c05f..9a901a3 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -707,7 +707,7 @@ proc_with_prefix test_bkpt_explicit_loc {} { delete_breakpoints gdb_test "python bp1 = gdb.Breakpoint (line=bp1)" \ - "RuntimeError.*: Line keyword should be an integer or a string.*" \ + "RuntimeError.*: Line keyword should be an integer or a string\\.\r\n.*" \ "set explicit breakpoint by invalid line type" delete_breakpoints diff --git a/gdb/testsuite/gdb.python/py-caller-is.exp b/gdb/testsuite/gdb.python/py-caller-is.exp index 8e54c3b..0fdb80e 100644 --- a/gdb/testsuite/gdb.python/py-caller-is.exp +++ b/gdb/testsuite/gdb.python/py-caller-is.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp index f76c176..1fa3c73 100644 --- a/gdb/testsuite/gdb.python/py-cmd.exp +++ b/gdb/testsuite/gdb.python/py-cmd.exp @@ -278,13 +278,7 @@ gdb_test_multiline "input multi-line-output command" \ set test "verify pagination from test_multiline" gdb_test_multiple "test_multiline" $test { - -re "--Type <RET>" { - exp_continue - } - -re " for more, q to quit" { - exp_continue - } - -re ", c to continue without paging--$" { + -re "$pagination_prompt$" { pass $test } } @@ -328,4 +322,89 @@ proc_with_prefix test_command_redefining_itself {} { "call command redefining itself 2" } +# Try to create commands using unknown prefixes and check GDB gives an +# error. There's also a test in here for an ambiguous prefix, which +# gives the same error. +proc_with_prefix test_unknown_prefix {} { + clean_restart + + gdb_test_no_output "python gdb.Command('foo1', gdb.COMMAND_NONE, prefix=True)" + gdb_test_no_output "python gdb.Command('foo cmd', gdb.COMMAND_NONE)" + + foreach prefix { "xxx" "foo xxx" "foo1 xxx" } { + gdb_test "python gdb.Command('$prefix cmd', gdb.COMMAND_NONE)" \ + [multi_line \ + "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \ + "Error occurred in Python: Could not find command prefix $prefix\\."] + } + + gdb_test_no_output "python gdb.Command('foo2', gdb.COMMAND_NONE, prefix=True)" + + foreach prefix { "foo" "foo xxx" "foo1 xxx" "foo2 xxx" } { + gdb_test "python gdb.Command('$prefix cmd2', gdb.COMMAND_NONE)" \ + [multi_line \ + "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \ + "Error occurred in Python: Could not find command prefix $prefix\\."] + } +} + +# Check what happens if a command object is called without an 'invoke' +# method. +proc_with_prefix test_deleting_invoke_methods {} { + clean_restart + + gdb_test_multiline "create 'foo' prefix command" \ + "python" "" \ + "class test_prefix(gdb.Command):" "" \ + " def __init__ (self):" "" \ + " super().__init__ (\"foo\", gdb.COMMAND_USER, prefix=True)" "" \ + " def invoke (self, arg, from_tty):" "" \ + " print(\"In 'foo' invoke: %s\" % arg)" "" \ + "foo = test_prefix()" "" \ + "end" "" + + gdb_test_multiline "create 'foo bar' command" \ + "python" "" \ + "class test_cmd(gdb.Command):" "" \ + " def __init__ (self):" "" \ + " super().__init__ (\"foo bar\", gdb.COMMAND_USER)" "" \ + " def invoke (self, arg, from_tty):" "" \ + " print(\"In 'foo bar' invoke: %s\" % arg)" "" \ + "foo_bar = test_cmd()" "" \ + "end" "" + + gdb_test "foo def" "In 'foo' invoke: def" \ + "call 'foo' with an unknown sub-command" + + gdb_test "foo bar def" "In 'foo bar' invoke: def" \ + "call 'foo bar' with arguments" + + gdb_test_no_output "python del(foo_bar.__class__.invoke)" \ + "delete invoke from test_cmd class" + + with_test_prefix "after deleting test_cmd.invoke" { + gdb_test "foo def" "In 'foo' invoke: def" \ + "call 'foo' with an unknown sub-command" + + gdb_test "foo bar def" \ + "^Python command object missing 'invoke' method\\." \ + "call 'foo bar' with arguments" + } + + gdb_test_no_output "python del(foo.__class__.invoke)" \ + "delete invoke from test_prefix class" + + with_test_prefix "after deleting test_prefix.invoke" { + gdb_test "foo def" \ + "^Python command object missing 'invoke' method\\." \ + "call 'foo' with an unknown sub-command" + + gdb_test "foo bar def" \ + "^Python command object missing 'invoke' method\\." \ + "call 'foo bar' with arguments" + } +} + test_command_redefining_itself +test_unknown_prefix +test_deleting_invoke_methods diff --git a/gdb/testsuite/gdb.python/py-color-leak.exp b/gdb/testsuite/gdb.python/py-color-leak.exp new file mode 100644 index 0000000..6d7fa7c --- /dev/null +++ b/gdb/testsuite/gdb.python/py-color-leak.exp @@ -0,0 +1,28 @@ +# Copyright (C) 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/>. + +# This file is part of the GDB testsuite. It checks for memory leaks +# associated with allocating gdb.Color objects. + +load_lib gdb-python.exp + +require allow_python_tests + +standard_testfile + +clean_restart + +gdb_py_run_memory_leak_test ${srcdir}/${subdir}/${testfile}.py \ + "gdb.Color object deallocates correctly" diff --git a/gdb/testsuite/gdb.python/py-color-leak.py b/gdb/testsuite/gdb.python/py-color-leak.py new file mode 100644 index 0000000..28afd59 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-color-leak.py @@ -0,0 +1,37 @@ +# Copyright (C) 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/>. + +import sys + +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True + +import gdb_leak_detector + + +class color_leak_detector(gdb_leak_detector.gdb_leak_detector): + def __init__(self): + super().__init__(__file__) + self.color = None + + def allocate(self): + self.color = gdb.Color("red") + + def deallocate(self): + self.color = None + + +color_leak_detector().run() diff --git a/gdb/testsuite/gdb.python/py-color-pagination.exp b/gdb/testsuite/gdb.python/py-color-pagination.exp new file mode 100644 index 0000000..e7a9e4f --- /dev/null +++ b/gdb/testsuite/gdb.python/py-color-pagination.exp @@ -0,0 +1,137 @@ +# Copyright (C) 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/>. + +# This file is part of the GDB testsuite. It tests gdb.Color and how this +# interacts with GDB's pagination system. + +load_lib gdb-python.exp + +require allow_python_tests +require {!is_remote host} + +standard_testfile + +set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] + +set str "<[string repeat - 78]>" + +# These define all the default attributes for a style: background +# color, intensity, italics, and underlined. +set other_attr ";49;22;23;24;27" + +# These colors set the foreground color only. Everything else is the +# default. +set black "(?:\033\\\[30${other_attr}m)" +set red "(?:\033\\\[31${other_attr}m)" +set green "(?:\033\\\[32${other_attr}m)" +set yellow "(?:\033\\\[33${other_attr}m)" +set blue "(?:\033\\\[34${other_attr}m)" +set magenta "(?:\033\\\[35${other_attr}m)" +set cyan "(?:\033\\\[36${other_attr}m)" +set white "(?:\033\\\[37${other_attr}m)" + +set any_color "(?:${black}|${red}|${green}|${yellow}|${blue}|${magenta}|${cyan}|${white})" + +# Run the command 'TYPE-fill MODE' which fills the screen with output and +# triggers the pagination prompt. Check that styling is applied correctly +# to the output. +proc test_pagination { type mode } { + + # Start with a fresh GDB, but enable color support. + with_ansi_styling_terminal { + clean_restart + } + + gdb_test_no_output "source $::pyfile" "source the script" + + gdb_test_no_output "set width 80" + gdb_test_no_output "set height 15" + + set saw_bad_color_handling false + set expected_restore_color "" + set last_color "" + gdb_test_multiple "$type-fill $mode" "" { + -re "^$type-fill $mode\r\n" { + exp_continue + } + + -re "^(${::any_color})(${::any_color})$::str" { + # After a continuation prompt GDB will restore the previous + # color, and then we immediately switch to a new color. + set restored_color $expect_out(1,string) + if { $restored_color ne $expected_restore_color } { + set saw_bad_color_handling true + } + set last_color $expect_out(2,string) + exp_continue + } + + -re "^(${::any_color})$::str" { + # This pattern matches printing STR in all cases that are not + # immediately after a pagination prompt. In this case there is + # a single escape sequence to set the color. + set last_color $expect_out(1,string) + exp_continue + } + + -re "^\033\\\[${::decimal}m$::str" { + # This catches the case where the color's escape sequence has + # not been converted back into a full style. This indicates + # something went wrong in the pager_file::puts function. + set saw_bad_color_handling true + exp_continue + } + + -re "^\033\\\[m$::pagination_prompt$" { + # After a pagination prompt we expect GDB to restore the last + # color. + set expected_restore_color $last_color + + # Send '\n' to view more output. + send_gdb "\n" + exp_continue + } + + -re "^$::pagination_prompt$" { + # After a pagination prompt we expect GDB to restore the last + # color. + set expected_restore_color $last_color + + # If we didn't see a color reset sequence before the pagination + # prompt, then the prompt will have been printed in the wrong + # color, this is a GDB bug. + set saw_bad_color_handling true + + # Send '\n' to view more output. + send_gdb "\n" + exp_continue + } + + -re "^\r\n" { + # The matches the newline sent to the continuation prompt. + exp_continue + } + + -re "^\033\\\[m\r\n$::gdb_prompt $" { + gdb_assert { !$saw_bad_color_handling } $gdb_test_name + } + } +} + +foreach_with_prefix type { color } { + foreach_with_prefix mode { write print } { + test_pagination $type $mode + } +} diff --git a/gdb/testsuite/gdb.python/py-color-pagination.py b/gdb/testsuite/gdb.python/py-color-pagination.py new file mode 100644 index 0000000..efd501e --- /dev/null +++ b/gdb/testsuite/gdb.python/py-color-pagination.py @@ -0,0 +1,46 @@ +# Copyright (C) 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/>. + +import gdb + +basic_colors = ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"] + + +def write(mode, text): + if mode == "write": + gdb.write(text) + else: + print(text, end="") + + +class ColorTester(gdb.Command): + def __init__(self): + super().__init__("color-fill", gdb.COMMAND_USER) + + def invoke(self, args, from_tty): + mode = args + str = "<" + "-" * 78 + ">" + for i in range(0, 20): + for color_name in basic_colors: + c = gdb.Color(color_name) + write(mode, c.escape_sequence(True)) + write(mode, str) + + default = gdb.Color("none") + write(mode, default.escape_sequence(True)) + write(mode, "\n") + + +ColorTester() diff --git a/gdb/testsuite/gdb.python/py-color.exp b/gdb/testsuite/gdb.python/py-color.exp index c6f1041..08089e5 100644 --- a/gdb/testsuite/gdb.python/py-color.exp +++ b/gdb/testsuite/gdb.python/py-color.exp @@ -13,17 +13,22 @@ # 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 gdb.parameter and gdb.Parameter. +# This file is part of the GDB testsuite. It tests gdb.Color. load_lib gdb-python.exp require allow_python_tests +require {!is_remote host} -# Start with a fresh gdb. -clean_restart +# Start with a fresh GDB, but enable color support. +with_ansi_styling_terminal { + clean_restart +} -gdb_test_no_output "python print_color_attrs = lambda c: print (c, c.colorspace, c.is_none, c.is_indexed, c.is_direct)" \ +gdb_test_no_output "python get_color_attrs = lambda c: \"%s %s %s %s %s\" % (str(c), c.colorspace, c.is_none, c.is_indexed, c.is_direct)" \ + "get_color_attrs helper" + +gdb_test_no_output "python print_color_attrs = lambda c: print (get_color_attrs (c))" \ "print_color_attrs helper" gdb_test_no_output "python c = gdb.Color ()" \ @@ -59,6 +64,15 @@ gdb_test "python print_color_attrs (c)" "green 1 False True False" \ gdb_test "python print (c.index)" "2" \ "print index of a basic color with ansi colorspace" +# Create a color using keyword arguments, and check it matches the +# non-keyword color. +gdb_test_no_output "python c2 = gdb.Color (color_space = gdb.COLORSPACE_ANSI_8COLOR, value = 2)" \ + "create color from basic index and ansi colorspace using keywords" +gdb_test "python print(get_color_attrs (c) == get_color_attrs (c2))" "True" \ + "check attributes match" +gdb_test "python print(c.index == c2.index)" "True" \ + "check index matches" + gdb_test_no_output "python c = gdb.Color (2, gdb.COLORSPACE_XTERM_256COLOR)" \ "create color from basic index and xterm256 colorspace" gdb_test "python print_color_attrs (c)" "2 3 False True False" \ @@ -97,4 +111,54 @@ gdb_test [concat "python print (c_red.escape_sequence (True) + " \ "c_none.escape_sequence (True))"] \ "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ "escape sequences" - +gdb_test [concat "python print (c_red.escape_sequence (is_foreground = True) + " \ + "c_green.escape_sequence (is_foreground = False) + 'red on green' + " \ + "c_none.escape_sequence (is_foreground = False) + ' red on default' + " \ + "c_none.escape_sequence (is_foreground = True))"] \ + "\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \ + "escape sequences using keyword arguments" + +# Ensure that turning styling off means no escape sequences. +gdb_test_no_output "set style enabled off" +gdb_test_no_output "python print (c_red.escape_sequence (True), end='')" +gdb_test_no_output "python print (c_red.escape_sequence (False), end='')" +gdb_test_no_output "set style enabled on" + +gdb_test_multiline "Try to sub-class gdb.Color" \ + "python" "" \ + "class my_color(gdb.Color):" "" \ + " def __init__(self):" "" \ + " super().__init__('red')" "" \ + "end" \ + [multi_line \ + "Python Exception <class 'TypeError'>: type 'gdb\\.Color' is not an acceptable base type" \ + "Error occurred in Python: type 'gdb\\.Color' is not an acceptable base type"] + +gdb_test_multiline "Setup a color parameter and non gdb.Color object" \ + "python" "" \ + "class my_param(gdb.Parameter):" "" \ + " def __init__(self):" "" \ + " super().__init__('color-param', gdb.COMMAND_NONE, gdb.PARAM_COLOR)" "" \ + " self.value = gdb.Color('red')" "" \ + "color_param = my_param()" "" \ + " " "" \ + "class bad_type:" "" \ + " @property" "" \ + " def __class__(self):" "" \ + " raise RuntimeError('__class__ error for bad_type')" "" \ + "bad_obj = bad_type()" "" \ + "end" "" + +gdb_test_no_output "python color_param.value = gdb.Color('blue')" \ + "set color parameter to blue" + +gdb_test "python color_param.value = bad_obj" \ + [multi_line \ + "Python Exception <class 'RuntimeError'>: color argument must be a gdb\\.Color object\\." \ + "Error occurred in Python: color argument must be a gdb\\.Color object\\."] \ + "set color parameter to a non-color type" + +gdb_test "python c_none.escape_sequence(c_red)" \ + [multi_line \ + "Python Exception <class 'TypeError'>: argument 1 must be bool, not gdb.Color" \ + "Error occurred in Python: argument 1 must be bool, not gdb.Color"] diff --git a/gdb/testsuite/gdb.python/py-disasm.exp.tcl b/gdb/testsuite/gdb.python/py-disasm.exp.tcl index 938326d..5f45747 100644 --- a/gdb/testsuite/gdb.python/py-disasm.exp.tcl +++ b/gdb/testsuite/gdb.python/py-disasm.exp.tcl @@ -24,14 +24,16 @@ standard_testfile py-disasm.c if { $kind == "obj" } { - set obj [standard_output_file ${gdb_test_file_name}.o] + set testfile $testfile.o + set binfile [standard_output_file $testfile] - if { [gdb_compile "$srcdir/$subdir/$srcfile" $obj object "debug"] != "" } { - untested "failed to compile object file [file tail $obj]" + if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile object \ + "debug"] != "" } { + untested "failed to compile object file $testfile" return -1 } - clean_restart $obj + clean_restart $testfile } else { @@ -152,7 +154,10 @@ set test_plans \ "Buffer returned from read_memory is sized $decimal instead of the expected $decimal"]] \ [list "ResultOfWrongType" \ [make_exception_pattern "TypeError" \ - "Result is not a DisassemblerResult."]] \ + "Result from Disassembler must be gdb.DisassemblerResult, not Blah."]] \ + [list "ResultOfVeryWrongType" \ + [make_exception_pattern "TypeError" \ + "Result from Disassembler must be gdb.DisassemblerResult, not Blah."]] \ [list "ErrorCreatingTextPart_NoArgs" \ [make_exception_pattern "TypeError" \ [missing_arg_pattern "style" 1]]] \ diff --git a/gdb/testsuite/gdb.python/py-disasm.py b/gdb/testsuite/gdb.python/py-disasm.py index 32d6aa7..9761337 100644 --- a/gdb/testsuite/gdb.python/py-disasm.py +++ b/gdb/testsuite/gdb.python/py-disasm.py @@ -294,6 +294,24 @@ class ResultOfWrongType(TestDisassembler): return self.Blah(1, "ABC") +class ResultOfVeryWrongType(TestDisassembler): + """Return something that is not a DisassemblerResult from disassemble + method. The thing returned will raise an exception if used in an + isinstance() call, or in PyObject_IsInstance from C++. + """ + + class Blah: + def __init__(self): + pass + + @property + def __class__(self): + raise RuntimeError("error from __class__ in Blah") + + def disassemble(self, info): + return self.Blah() + + class TaggingDisassembler(TestDisassembler): """A simple disassembler that just tags the output.""" diff --git a/gdb/testsuite/gdb.python/py-event-load.exp b/gdb/testsuite/gdb.python/py-event-load.exp index a09a946..dbb225f 100644 --- a/gdb/testsuite/gdb.python/py-event-load.exp +++ b/gdb/testsuite/gdb.python/py-event-load.exp @@ -20,12 +20,6 @@ load_lib gdb-python.exp require allow_shlib_tests allow_python_tests -if {[get_compiler_info]} { - warning "Could not get compiler info" - untested "no compiler info" - return -1 -} - standard_testfile .c if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ executable {debug shlib_load}] != ""} { diff --git a/gdb/testsuite/gdb.python/py-exec-file.exp b/gdb/testsuite/gdb.python/py-exec-file.exp index b3418a5..139ce83 100644 --- a/gdb/testsuite/gdb.python/py-exec-file.exp +++ b/gdb/testsuite/gdb.python/py-exec-file.exp @@ -19,8 +19,10 @@ load_lib gdb-python.exp standard_testfile -set binfile1 ${binfile}-a -set binfile2 ${binfile}-b +set testfile1 $testfile-a +set binfile1 [standard_output_file $testfile1] +set testfile2 $testfile-b +set binfile2 [standard_output_file $testfile2] if {[build_executable "failed to prepare first executable" \ $binfile1 $srcfile]} { @@ -176,7 +178,7 @@ with_test_prefix "using 'symbol-file' command" { # Check the executable_changed event when the executable changes on disk. with_test_prefix "exec changes on disk" { - clean_restart $binfile1 + clean_restart $::testfile1 setup_exec_change_handler diff --git a/gdb/testsuite/gdb.python/py-explore-cc.exp b/gdb/testsuite/gdb.python/py-explore-cc.exp index 0be7019..8c28d87 100644 --- a/gdb/testsuite/gdb.python/py-explore-cc.exp +++ b/gdb/testsuite/gdb.python/py-explore-cc.exp @@ -36,7 +36,7 @@ A = <Enter 0 to explore this base class of type 'A'>.*\ i = <Enter 1 to explore this field of type 'int'>.*\ c = <Enter 2 to explore this field of type 'char'>.*" -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-explore.exp b/gdb/testsuite/gdb.python/py-explore.exp index a68c110..df0f465 100644 --- a/gdb/testsuite/gdb.python/py-explore.exp +++ b/gdb/testsuite/gdb.python/py-explore.exp @@ -47,7 +47,7 @@ proc array_description { value_name type } { proc pointer_description { value_name type_name } { set type_description "'$value_name' is a pointer to a value of type '$type_name'\.\[\r\n\]+" - set prompt "Continue exploring it as a pointer to a single value \[\[\]y/n\[\]\]: " + set prompt "Continue exploring it as a pointer to a single value \[\[\]y/n\[\]\]: " return "$type_description$prompt" } @@ -75,7 +75,7 @@ proc scalar_value { value_name value } { set SS_fields [field_values {a = 10} {d = 100[.].*}] -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -125,7 +125,7 @@ gdb_test_multiple "explore darray_ref" "" { } } } - } + } } } } diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp index c7d31f0..bec22ee 100644 --- a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp @@ -112,7 +112,7 @@ with_test_prefix "return to inlined function" { } # -# Test FinishBreakpoint with no debug symbol +# Test FinishBreakpoint with no debug symbol # with_test_prefix "no debug symbol" { @@ -140,7 +140,7 @@ with_test_prefix "no debug symbol" { } # -# Test FinishBreakpoint in function returned by longjmp +# Test FinishBreakpoint in function returned by longjmp # with_test_prefix "function returned by longjump" { @@ -166,7 +166,7 @@ with_test_prefix "function returned by longjump" { } # -# Test FinishBreakpoint in BP condition evaluation +# Test FinishBreakpoint in BP condition evaluation # (finish in dummy frame) # @@ -194,7 +194,7 @@ with_test_prefix "finish in dummy frame" { } # -# Test FinishBreakpoint in BP condition evaluation +# Test FinishBreakpoint in BP condition evaluation # (finish in normal frame) # diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp index 922426f..be81576 100644 --- a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp @@ -42,7 +42,7 @@ gdb_breakpoint [gdb_get_line_number "Break after exception 2"] gdb_test "source $pyfile" ".*Python script imported.*" \ "import python scripts" - + gdb_breakpoint "throw_exception_1" # diff --git a/gdb/testsuite/gdb.python/py-format-address.exp b/gdb/testsuite/gdb.python/py-format-address.exp index 173297c..2946314 100644 --- a/gdb/testsuite/gdb.python/py-format-address.exp +++ b/gdb/testsuite/gdb.python/py-format-address.exp @@ -27,12 +27,14 @@ foreach func_name { foo bar } { } } -set binary_foo [standard_output_file "${testfile}-foo"] -set binary_bar [standard_output_file "${testfile}-bar"] +set testfile_foo $testfile-foo +set testfile_bar $testfile-bar +set binary_foo [standard_output_file $testfile_foo] +set binary_bar [standard_output_file $testfile_bar] -clean_restart $binary_foo +clean_restart $testfile_foo -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -51,7 +53,7 @@ gdb_test_multiple "info break 1" "" { } } if { $next_addr == "UNKNOWN" || $next_addr == $main_addr } { - set next_addr [format 0x%x [expr $main_addr + 1]] + set next_addr [format 0x%x [expr {$main_addr + 1}]] } verbose -log "main_addr: $main_addr" diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp index 114a606..f34108d 100644 --- a/gdb/testsuite/gdb.python/py-format-string.exp +++ b/gdb/testsuite/gdb.python/py-format-string.exp @@ -47,7 +47,8 @@ proc build_inferior {exefile lang} { proc prepare_gdb {exefile} { global srcdir subdir srcfile testfile hex - clean_restart $exefile + clean_restart + gdb_load $exefile if {![runto_main]} { return @@ -109,7 +110,7 @@ proc get_cut_big_string { max } { return "\"${whole_big_string}\"" } - set cut_string [string range $whole_big_string 0 [expr $max - 1]] + set cut_string [string range $whole_big_string 0 [expr {$max - 1}]] return "\"${cut_string}\"..." } @@ -1202,7 +1203,9 @@ with_test_prefix "format_string" { set current_lang "c" prepare_gdb "${binfile}" test_all_common - test_styling + if { ![is_remote host] } { + test_styling + } } } } diff --git a/gdb/testsuite/gdb.python/py-frame-args.exp b/gdb/testsuite/gdb.python/py-frame-args.exp index 1dbd30e..12f1651 100644 --- a/gdb/testsuite/gdb.python/py-frame-args.exp +++ b/gdb/testsuite/gdb.python/py-frame-args.exp @@ -21,7 +21,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index 5668807..c1e3e33 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -188,6 +188,21 @@ gdb_test "python print(gdb.selected_frame().read_register(list()))" \ ".*Invalid type for register.*" \ "test Frame.read_register with list" +gdb_test_multiline "setup a bad object" \ + "python" "" \ + "class bad_type:" "" \ + " def __init__ (self):" "" \ + " pass" "" \ + " @property" "" \ + " def __class__(self):" "" \ + " raise RuntimeError('error from __class in bad_type')" "" \ + "bad_object = bad_type()" "" \ + "end" "" + +gdb_test "python print(gdb.selected_frame().read_register(bad_object))" \ + ".*Invalid type for register.*" \ + "test Frame.read_register with bad_type object" + # Compile again without debug info. gdb_exit if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {}] } { diff --git a/gdb/testsuite/gdb.python/py-framefilter-addr.exp b/gdb/testsuite/gdb.python/py-framefilter-addr.exp index 14eebc2..27c1de3 100644 --- a/gdb/testsuite/gdb.python/py-framefilter-addr.exp +++ b/gdb/testsuite/gdb.python/py-framefilter-addr.exp @@ -27,7 +27,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-framefilter-mi.exp b/gdb/testsuite/gdb.python/py-framefilter-mi.exp index de04236..03e5f90 100644 --- a/gdb/testsuite/gdb.python/py-framefilter-mi.exp +++ b/gdb/testsuite/gdb.python/py-framefilter-mi.exp @@ -28,7 +28,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.python/py-inferior-leak.exp b/gdb/testsuite/gdb.python/py-inferior-leak.exp index 6710f59..15216ee 100644 --- a/gdb/testsuite/gdb.python/py-inferior-leak.exp +++ b/gdb/testsuite/gdb.python/py-inferior-leak.exp @@ -24,15 +24,5 @@ standard_testfile clean_restart -# Skip this test if the tracemalloc module is not available. -if { ![gdb_py_module_available "tracemalloc"] } { - unsupported "tracemalloc module not available" - return -} - -set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] - -# Source the Python script, this runs the test (which is written -# completely in Python), and either prints PASS, or throws an -# exception. -gdb_test "source ${pyfile}" "PASS" "source python script" +gdb_py_run_memory_leak_test ${srcdir}/${subdir}/${testfile}.py \ + "gdb.Inferior object deallocates correctly" diff --git a/gdb/testsuite/gdb.python/py-inferior-leak.py b/gdb/testsuite/gdb.python/py-inferior-leak.py index 97837dc..bf61668 100644 --- a/gdb/testsuite/gdb.python/py-inferior-leak.py +++ b/gdb/testsuite/gdb.python/py-inferior-leak.py @@ -13,100 +13,39 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import re -import tracemalloc - -import gdb - -# A global variable in which we store a reference to the gdb.Inferior -# object sent to us in the new_inferior event. -inf = None - - -# Register the new_inferior event handler. -def new_inferior_handler(event): - global inf - inf = event.inferior - - -gdb.events.new_inferior.connect(new_inferior_handler) +import sys -# A global filters list, we only care about memory allocations -# originating from this script. -filters = [tracemalloc.Filter(True, "*py-inferior-leak.py")] +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True +import re -# Add a new inferior, and return the number of the new inferior. -def add_inferior(): - output = gdb.execute("add-inferior", False, True) - m = re.search(r"Added inferior (\d+)", output) - if m: - num = int(m.group(1)) - else: - raise RuntimeError("no match") - return num - - -# Run the test. When CLEAR is True we clear the global INF variable -# before comparing the before and after memory allocation traces. -# When CLEAR is False we leave INF set to reference the gdb.Inferior -# object, thus preventing the gdb.Inferior from being deallocated. -def test(clear): - global filters, inf - - # Start tracing, and take a snapshot of the current allocations. - tracemalloc.start() - snapshot1 = tracemalloc.take_snapshot() - - # Create an inferior, this triggers the new_inferior event, which - # in turn holds a reference to the new gdb.Inferior object in the - # global INF variable. - num = add_inferior() - gdb.execute("remove-inferiors %s" % num) - - # Possibly clear the global INF variable. - if clear: - inf = None - - # Now grab a second snapshot of memory allocations, and stop - # tracing memory allocations. - snapshot2 = tracemalloc.take_snapshot() - tracemalloc.stop() +import gdb_leak_detector - # Filter the snapshots; we only care about allocations originating - # from this file. - snapshot1 = snapshot1.filter_traces(filters) - snapshot2 = snapshot2.filter_traces(filters) - # Compare the snapshots, this leaves only things that were - # allocated, but not deallocated since the first snapshot. - stats = snapshot2.compare_to(snapshot1, "traceback") +class inferior_leak_detector(gdb_leak_detector.gdb_leak_detector): + def __init__(self): + super().__init__(__file__) + self.inferior = None + self.__handler = lambda event: setattr(self, "inferior", event.inferior) + gdb.events.new_inferior.connect(self.__handler) - # Total up all the deallocated things. - total = 0 - for stat in stats: - total += stat.size_diff - return total + def __del__(self): + gdb.events.new_inferior.disconnect(self.__handler) + def allocate(self): + output = gdb.execute("add-inferior", False, True) + m = re.search(r"Added inferior (\d+)", output) + if m: + num = int(m.group(1)) + else: + raise RuntimeError("no match") -# The first time we run this some global state will be allocated which -# shows up as memory that is allocated, but not released. So, run the -# test once and discard the result. -test(True) + gdb.execute("remove-inferiors %s" % num) -# Now run the test twice, the first time we clear our global reference -# to the gdb.Inferior object, which should allow Python to deallocate -# the object. The second time we hold onto the global reference, -# preventing Python from performing the deallocation. -bytes_with_clear = test(True) -bytes_without_clear = test(False) + def deallocate(self): + self.inferior = None -# The bug that used to exist in GDB was that even when we released the -# global reference the gdb.Inferior object would not be deallocated. -if bytes_with_clear > 0: - raise gdb.GdbError("memory leak when gdb.Inferior should be released") -if bytes_without_clear == 0: - raise gdb.GdbError("gdb.Inferior object is no longer allocated") -# Print a PASS message that the test script can see. -print("PASS") +inferior_leak_detector().run() diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp index 62af1a4..58632f0 100644 --- a/gdb/testsuite/gdb.python/py-inferior.exp +++ b/gdb/testsuite/gdb.python/py-inferior.exp @@ -318,7 +318,7 @@ with_test_prefix "large range" { # For native targets, test a pattern straddling a chunk boundary. -if [isnative] { +if {[isnative]} { with_test_prefix "straddling" { gdb_test_no_output "set *(int32_t*) &search_buf\[${CHUNK_SIZE}-1\] = 0xfdb97531" gdb_test_no_output "py pattern = pack('${python_pack_char}I', 0xfdb97531)" diff --git a/gdb/testsuite/gdb.python/py-label-symbol-value.exp b/gdb/testsuite/gdb.python/py-label-symbol-value.exp index ca534d4..07bc870 100644 --- a/gdb/testsuite/gdb.python/py-label-symbol-value.exp +++ b/gdb/testsuite/gdb.python/py-label-symbol-value.exp @@ -24,7 +24,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-lazy-string.exp b/gdb/testsuite/gdb.python/py-lazy-string.exp index 7e7272e..a6fdd77 100644 --- a/gdb/testsuite/gdb.python/py-lazy-string.exp +++ b/gdb/testsuite/gdb.python/py-lazy-string.exp @@ -26,7 +26,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { return -1 } -if ![runto_main ] { +if {![runto_main ]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-linetable-empty.exp b/gdb/testsuite/gdb.python/py-linetable-empty.exp index 1e737e1..f742d70 100644 --- a/gdb/testsuite/gdb.python/py-linetable-empty.exp +++ b/gdb/testsuite/gdb.python/py-linetable-empty.exp @@ -27,11 +27,11 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name py-linetable-empty.c} + DW_AT_language @DW_LANG_C + DW_AT_name py-linetable-empty.c } { subprogram { - {MACRO_AT_func {main}} + MACRO_AT_func {main} } } } @@ -42,7 +42,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-linetable.exp b/gdb/testsuite/gdb.python/py-linetable.exp index d27d16e..453ee7a 100644 --- a/gdb/testsuite/gdb.python/py-linetable.exp +++ b/gdb/testsuite/gdb.python/py-linetable.exp @@ -18,7 +18,7 @@ require allow_python_tests set opts {} standard_testfile .S -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.python/py-linetable.exp COMPILE=1" standard_testfile lappend opts debug optimize=-O2 @@ -30,7 +30,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $opts] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-mi-events.exp b/gdb/testsuite/gdb.python/py-mi-events.exp index ecdb74a..a15ba0b 100644 --- a/gdb/testsuite/gdb.python/py-mi-events.exp +++ b/gdb/testsuite/gdb.python/py-mi-events.exp @@ -39,7 +39,7 @@ mi_gdb_test "set auto-load safe-path ${remote_python_file}" \ {.*\^done} \ "set safe-path" -if [is_remote host] { +if {[is_remote host]} { set filename ${testfile} remote_download host ${binfile} ${filename} } else { diff --git a/gdb/testsuite/gdb.python/py-mi-objfile.exp b/gdb/testsuite/gdb.python/py-mi-objfile.exp index 58ecbc5..c1edffe 100644 --- a/gdb/testsuite/gdb.python/py-mi-objfile.exp +++ b/gdb/testsuite/gdb.python/py-mi-objfile.exp @@ -33,7 +33,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb # gdb will find it. set remote_python_file [gdb_remote_download host ${srcdir}/${subdir}/${pyfile}] -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } @@ -41,7 +41,7 @@ mi_gdb_test "set auto-load safe-path ${remote_python_file}" \ {.*\^done} \ "set safe-path" -if [is_remote host] { +if {[is_remote host]} { set filename ${testfile} remote_download host ${binfile} ${filename} } else { diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp index 07cd40f..7a9124b 100644 --- a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp +++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp @@ -29,7 +29,7 @@ if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug}] != "" } return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] mi_gdb_test "source ${pyfile}" \ diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp index 7f1dffc..28d63c1 100644 --- a/gdb/testsuite/gdb.python/py-mi.exp +++ b/gdb/testsuite/gdb.python/py-mi.exp @@ -26,7 +26,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } -if {[mi_clean_restart $binfile]} { +if {[mi_clean_restart $::testfile]} { return } @@ -345,7 +345,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" \ return -1 } -if {[mi_clean_restart ${binfile}-cxx]} { +if {[mi_clean_restart ${::testfile}-cxx]} { return } diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.exp b/gdb/testsuite/gdb.python/py-missing-objfile.exp index e4a1b3f..ce4dc76 100644 --- a/gdb/testsuite/gdb.python/py-missing-objfile.exp +++ b/gdb/testsuite/gdb.python/py-missing-objfile.exp @@ -79,6 +79,16 @@ proc setup_debugdir { dirname files } { # executable (when EXEC_LOADED is true) and/or the library (when LIB_LOADED # is true). proc check_loaded_debug { exec_loaded lib_loaded } { + set re_warn \ + [string_to_regexp \ + "Warning: the current language does not match this frame."] + set cmd "set lang c" + gdb_test_multiple $cmd "" { + -re -wrap "${cmd}(\r\n$re_warn)?" { + pass $gdb_test_name + } + } + if { $exec_loaded } { gdb_test "whatis global_exec_var" "^type = volatile struct exec_type" @@ -124,7 +134,7 @@ proc clean_restart_load_python {} { # For sanity, lets check that we can load the specify the executable # and then load the core-file the easy way. with_test_prefix "initial sanity check" { - clean_restart $binfile + clean_restart $::testfile load_core_file check_loaded_debug true true } diff --git a/gdb/testsuite/gdb.python/py-objfile-script.exp b/gdb/testsuite/gdb.python/py-objfile-script.exp index 1a3d394..4e6f5b6 100644 --- a/gdb/testsuite/gdb.python/py-objfile-script.exp +++ b/gdb/testsuite/gdb.python/py-objfile-script.exp @@ -41,7 +41,7 @@ gdb_load ${binfile} # Verify gdb loaded the script. gdb_test "info auto-load python-scripts" "Yes.*${testfile}-gdb.py.*" -if ![runto_main] { +if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.python/py-objfile.c b/gdb/testsuite/gdb.python/py-objfile.c index fe68671..d721e0c 100644 --- a/gdb/testsuite/gdb.python/py-objfile.c +++ b/gdb/testsuite/gdb.python/py-objfile.c @@ -19,7 +19,7 @@ int global_var = 42; static int __attribute__ ((used)) static_var = 50; int -main () +main (void) { int some_var = 0; return 0; diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp index d14eec6..ce4e37a 100644 --- a/gdb/testsuite/gdb.python/py-objfile.exp +++ b/gdb/testsuite/gdb.python/py-objfile.exp @@ -68,7 +68,7 @@ gdb_test "python print (gdb.lookup_objfile (\"${testfile}\").lookup_static_symbo "None" "lookup_static_symbol can handle nonexistent symbol" set binfile_build_id [get_build_id $binfile] -if [string compare $binfile_build_id ""] { +if {[string compare $binfile_build_id ""]} { verbose -log "binfile_build_id = $binfile_build_id" gdb_test "python print (objfile.build_id)" "$binfile_build_id" \ "Get objfile build id" @@ -119,7 +119,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile}2 ${srcfile} {nodebug l return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } @@ -144,7 +144,8 @@ gdb_test "python print (sep_objfile.owner.filename)" "${testfile}2" \ gdb_test "python print (sep_objfile.owner.username)" "${testfile}2" \ "Test user-name of owner of separate debug file" -gdb_test "p main" "= {int \\(\\)} $hex <main>" \ +set re_prototype [string_to_regexp "int (void)"] +gdb_test "p main" "= {$re_prototype} $hex <main>" \ "print main with debug info" # Separate debug files are not findable. @@ -157,12 +158,13 @@ if { [get_python_valueof "sep_objfile.build_id" "None"] != "None" } { # An objfile that was a symlink to a differently named file is still # findable with its original name. # On Windows we don't have proper symlinks, so skip this. -if ![ishost *-*-mingw*] { +if {![ishost *-*-mingw*]} { set symlink_binary [standard_output_file "symlink-binary"] remote_exec host "rm -f ${symlink_binary}" remote_exec host "ln -sf ${testfile} ${symlink_binary}" - if [remote_file host exists "${symlink_binary}"] { - clean_restart "${symlink_binary}" + if {[remote_file host exists "${symlink_binary}"]} { + clean_restart + gdb_load "${symlink_binary}" gdb_test "python print (gdb.lookup_objfile (\"${symlink_binary}\").filename)" \ "${testfile}" "gdb.lookup_objfile of symlinked binary" } diff --git a/gdb/testsuite/gdb.python/py-parameter-prefix.exp b/gdb/testsuite/gdb.python/py-parameter-prefix.exp new file mode 100644 index 0000000..eb09fe7 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-parameter-prefix.exp @@ -0,0 +1,382 @@ +# Copyright (C) 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/>. + +# This file is part of the GDB testsuite. It tests +# gdb.ParameterPrefix. See each of the test procs for a full +# description of what is being tested. + +load_lib gdb-python.exp + +require allow_python_tests + +clean_restart + +# Helper proc to generate the output of 'show PREFIX' commands for the +# case where the prefix command doesn't handle unknown sub-commands. +# In this case GDB will list the value of every sub-command under +# PREFIX. +proc make_show_prefix_re { prefix } { + return "$prefix param-1:\\s+The current value of '$prefix param-1' is \"off\"\\." +} + +# Helper proc to generate the help text that describes all of the sub +# commands under PREFIX. The MODE is either 'set' or 'show'. This +# output will appear for 'help MODE PREFIX' and also for 'set PREFIX'. +proc make_sub_cmd_help_re { mode prefix } { + if { $mode == "set" } { + set word "Set" + } else { + set word "Show" + } + + return \ + [multi_line \ + "List of \"$mode $prefix\" subcommands:" \ + "" \ + "$mode $prefix param-1 -- $word the current value of '$prefix param-1'\\." \ + "" \ + "Type \"help $mode $prefix\" followed by subcommand name for full documentation\\." \ + "Type \"apropos word\" to search for commands related to \"word\"\\." \ + "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \ + "Command name abbreviations are allowed if unambiguous\\."] +} + +# Helper proc to generate the output of 'help MODE PREFIX', where MODE +# will be either 'set' or 'show'. The HELP_TEXT is the expected help +# text for this prefix command, this should not be a regexp, as this +# proc converts the text to a regexp. +# +# Return a single regexp which should match the output. +proc make_help_re { mode prefix help_text } { + set help_re [string_to_regexp $help_text] + + return \ + [multi_line \ + "$help_re" \ + "" \ + [make_sub_cmd_help_re $mode $prefix]] +} + +# Create gdb.ParameterPrefix without using a sub-class, both with, and +# without a doc string. For the doc string case, test single line, +# and multi-line doc strings. +proc_with_prefix test_basic_usage {} { + gdb_test_multiline "some basic ParameterPrefix usage" \ + "python" "" \ + "gdb.ParameterPrefix('prefix-1', gdb.COMMAND_NONE)" "" \ + "gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.ParameterPrefix('prefix-2', gdb.COMMAND_NONE," "" \ + " \"\"\"This is prefix-2 help string.\"\"\")" "" \ + "gdb.Parameter('prefix-2 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.ParameterPrefix('prefix-3', gdb.COMMAND_NONE," "" \ + " \"\"\"This is prefix-3 help string." "" \ + " " "" \ + " This help text spans multiple lines.\"\"\")" "" \ + "gdb.Parameter('prefix-3 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" + + foreach mode { "set" "show" } { + gdb_test "help $mode prefix-1" \ + [make_help_re $mode "prefix-1" \ + "This command is not documented."] + + gdb_test "help $mode prefix-2" \ + [make_help_re $mode "prefix-2" \ + "This is prefix-2 help string."] + + gdb_test "help $mode prefix-3" \ + [make_help_re $mode "prefix-3" \ + [multi_line \ + "This is prefix-3 help string." \ + "" \ + "This help text spans multiple lines."]] + + foreach prefix { prefix-1 prefix-2 prefix-3 } { + gdb_test "$mode $prefix xxx" \ + "^Undefined $mode $prefix command: \"xxx\"\\. Try \"help $mode $prefix\"\\." + } + } + + foreach prefix { prefix-1 prefix-2 prefix-3 } { + gdb_test "set $prefix" \ + [make_sub_cmd_help_re "set" $prefix] + + gdb_test "show $prefix" \ + [make_show_prefix_re $prefix] + } +} + +# Create a sub-class of gdb.ParameterPrefix, but don't do anything +# particularly interesting. Again test the with and without +# documentation string cases. +proc_with_prefix test_simple_sub_class {} { + gdb_test_multiline "some basic ParameterPrefix usage" \ + "python" "" \ + "class BasicParamPrefix(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + "BasicParamPrefix('prefix-4')" "" \ + "gdb.Parameter('prefix-4 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class BasicParamPrefixWithSingleLineDoc(gdb.ParameterPrefix):" "" \ + " \"\"\"This is a single line doc string.\"\"\"" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + "BasicParamPrefixWithSingleLineDoc('prefix-5')" "" \ + "gdb.Parameter('prefix-5 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class BasicParamPrefixWithMultiLineDoc(gdb.ParameterPrefix):" "" \ + " \"\"\"This is a multi line doc string." "" \ + " " "" \ + " The rest of the doc string is here.\"\"\"" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + "BasicParamPrefixWithMultiLineDoc('prefix-6')" "" \ + "gdb.Parameter('prefix-6 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class BasicParamPrefixWithDocParameter(gdb.ParameterPrefix):" "" \ + " \"\"\"This is an unsused doc string.\"\"\"" "" \ + " def __init__(self, name, doc):" "" \ + " super().__init__(name, gdb.COMMAND_NONE, doc)" "" \ + "BasicParamPrefixWithDocParameter('prefix-7'," "" \ + " \"\"\"The doc string text is here.\"\"\")" "" \ + "gdb.Parameter('prefix-7 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" + + foreach mode { "set" "show" } { + gdb_test "help $mode prefix-4" \ + [make_help_re $mode "prefix-4" \ + "This command is not documented."] + + gdb_test "help $mode prefix-5" \ + [make_help_re $mode "prefix-5" \ + "This is a single line doc string."] + + gdb_test "help $mode prefix-6" \ + [make_help_re $mode "prefix-6" \ + [multi_line \ + "This is a multi line doc string." \ + "" \ + "The rest of the doc string is here."]] + + gdb_test "help $mode prefix-7" \ + [make_help_re $mode "prefix-7" \ + "The doc string text is here."] + + foreach prefix { prefix-4 prefix-5 prefix-6 prefix-7 } { + gdb_test "$mode $prefix xxx" \ + "^Undefined $mode $prefix command: \"xxx\"\\. Try \"help $mode $prefix\"\\." + } + } + + foreach prefix { prefix-4 prefix-5 prefix-6 prefix-7 } { + gdb_test "set $prefix" \ + [make_sub_cmd_help_re "set" $prefix] + + gdb_test "show $prefix" \ + [make_show_prefix_re $prefix] + } +} + +# Create a sub-class of gdb.ParameterPrefix, and make use of +# 'invoke_set' and 'invoke_show'. Test that the invoke method is +# executed when expected, and that, by default, these invoke methods +# repeat when the user issues an empty command. +proc_with_prefix test_prefix_with_invoke {} { + gdb_test_multiline "ParameterPrefix with invoke_set" \ + "python" "" \ + "class PrefixWithInvokeSet(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + " def invoke_set(self, args, from_tty):" "" \ + " print(f\"invoke_set (a): \\\"{args}\\\" {from_tty}\")" "" \ + "PrefixWithInvokeSet('prefix-8')" "" \ + "gdb.Parameter('prefix-8 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class PrefixWithInvokeShow(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + " def invoke_show(self, args, from_tty):" "" \ + " print(f\"invoke_show (b): \\\"{args}\\\" {from_tty}\")" "" \ + "PrefixWithInvokeShow('prefix-9')" "" \ + "gdb.Parameter('prefix-9 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class PrefixWithBothInvoke(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + " def invoke_set(self, args, from_tty):" "" \ + " print(f\"invoke_set (c): \\\"{args}\\\" {from_tty}\")" "" \ + " def invoke_show(self, args, from_tty):" "" \ + " print(f\"invoke_show (d): \\\"{args}\\\" {from_tty}\")" "" \ + "PrefixWithBothInvoke('prefix-10')" "" \ + "gdb.Parameter('prefix-10 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" + + gdb_test "set prefix-8 xxx yyy" \ + "^invoke_set \\(a\\): \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^\r\ninvoke_set \\(a\\): \"xxx yyy\" True" \ + "repeat set prefix-8 xxx yyy" + + gdb_test "show prefix-8 xxx yyy" \ + "^Undefined show prefix-8 command: \"xxx yyy\"\\. Try \"help show prefix-8\"\\." + + gdb_test "set prefix-9 xxx yyy" \ + "^Undefined set prefix-9 command: \"xxx yyy\"\\. Try \"help set prefix-9\"\\." + + gdb_test "show prefix-9 xxx yyy" \ + "^invoke_show \\(b\\): \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^\r\ninvoke_show \\(b\\): \"xxx yyy\" True" \ + "repeat show prefix-9 xxx yyy" + + gdb_test "set prefix-10 xxx yyy" \ + "^invoke_set \\(c\\): \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^\r\ninvoke_set \\(c\\): \"xxx yyy\" True" \ + "repeat set prefix-10 xxx yyy" + + gdb_test "show prefix-10 xxx yyy" \ + "^invoke_show \\(d\\): \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^\r\ninvoke_show \\(d\\): \"xxx yyy\" True" \ + "repeat show prefix-10 xxx yyy" + + gdb_test "set prefix-8" \ + "^invoke_set \\(a\\): \"\" True" + + gdb_test "show prefix-8" \ + [make_show_prefix_re "prefix-8"] + + gdb_test "set prefix-9" \ + [make_sub_cmd_help_re "set" "prefix-9"] + + gdb_test "show prefix-9" \ + "^invoke_show \\(b\\): \"\" True" + + gdb_test "set prefix-10" \ + "^invoke_set \\(c\\): \"\" True" + + gdb_test "show prefix-10" \ + "^invoke_show \\(d\\): \"\" True" +} + +# Create ParameterPrefix sub-classes that make use of the +# dont_repeat() method. Check that the relevant set/show invoke +# callback doesn't repeat when an empty command is used. +proc_with_prefix test_dont_repeat {} { + gdb_test_multiline "ParameterPrefix with invoke_set and dont_repeat" \ + "python" "" \ + "class PrefixWithInvokeAndDoNotRepeatSet(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + " def invoke_set(self, args, from_tty):" "" \ + " self.dont_repeat()" "" \ + " print(f\"invoke_set: \\\"{args}\\\" {from_tty}\")" "" \ + " def invoke_show(self, args, from_tty):" "" \ + " print(f\"invoke_show: \\\"{args}\\\" {from_tty}\")" "" \ + "PrefixWithInvokeAndDoNotRepeatSet('prefix-11')" "" \ + "gdb.Parameter('prefix-11 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "class PrefixWithInvokeAndDoNotRepeatShow(gdb.ParameterPrefix):" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE)" "" \ + " def invoke_set(self, args, from_tty):" "" \ + " print(f\"invoke_set: \\\"{args}\\\" {from_tty}\")" "" \ + " def invoke_show(self, args, from_tty):" "" \ + " self.dont_repeat()" "" \ + " print(f\"invoke_show: \\\"{args}\\\" {from_tty}\")" "" \ + "PrefixWithInvokeAndDoNotRepeatShow('prefix-12')" "" \ + "gdb.Parameter('prefix-12 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" + + gdb_test "set prefix-11 xxx yyy" \ + "^invoke_set: \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^" \ + "repeat set prefix-11 xxx yyy" + + gdb_test "show prefix-11 xxx yyy" \ + "^invoke_show: \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "invoke_show: \"xxx yyy\" True" \ + "repeat show prefix-11 xxx yyy" + + gdb_test "set prefix-12 xxx yyy" \ + "^invoke_set: \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^\r\ninvoke_set: \"xxx yyy\" True" \ + "repeat set prefix-12 xxx yyy" + + gdb_test "show prefix-12 xxx yyy" \ + "^invoke_show: \"xxx yyy\" True" + + send_gdb "\n" + gdb_test "" "^" \ + "repeat show prefix-12 xxx yyy" +} + +# Create a parameter prefixm, and immediately add another prefix under +# the first. The important thing here is that the second prefix is +# created into an otherwise empty prefix as this triggered a bug at +# one point. +proc_with_prefix test_nested {} { + gdb_test_multiline "Create nested parameter prefixes" \ + "python" "" \ + "gdb.ParameterPrefix('prefix-13', gdb.COMMAND_NONE)" "" \ + "gdb.ParameterPrefix('prefix-13 prefix-14', gdb.COMMAND_NONE)" "" \ + "gdb.Parameter('prefix-13 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 param-2', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 prefix-14 param-3', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('prefix-13 prefix-14 param-4', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "end" "" + + gdb_test "show prefix-13 prefix-14" \ + [multi_line \ + "^prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \ + "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."] + + gdb_test "show prefix-13" \ + [multi_line \ + "^prefix-13 param-1: The current value of 'prefix-13 param-1' is \"off\"\\." \ + "prefix-13 param-2: The current value of 'prefix-13 param-2' is \"off\"\\." \ + "prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \ + "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."] + + gdb_test "set prefix-13 prefix-14" \ + [multi_line \ + "" \ + "set prefix-13 prefix-14 param-3 -- Set the current value of 'prefix-13 prefix-14 param-3'\\." \ + "set prefix-13 prefix-14 param-4 -- Set the current value of 'prefix-13 prefix-14 param-4'\\." \ + "" \ + ".*"] + + gdb_test "set prefix-13" \ + [multi_line \ + "" \ + "set prefix-13 param-1 -- Set the current value of 'prefix-13 param-1'\\." \ + "set prefix-13 param-2 -- Set the current value of 'prefix-13 param-2'\\." \ + "set prefix-13 prefix-14 -- This command is not documented\\." \ + "" \ + ".*"] +} + +test_basic_usage +test_simple_sub_class +test_prefix_with_invoke +test_dont_repeat +test_nested diff --git a/gdb/testsuite/gdb.python/py-parameter.exp b/gdb/testsuite/gdb.python/py-parameter.exp index c15bef1..1d7f22b 100644 --- a/gdb/testsuite/gdb.python/py-parameter.exp +++ b/gdb/testsuite/gdb.python/py-parameter.exp @@ -24,7 +24,7 @@ require allow_python_tests clean_restart proc py_param_test_maybe_no_output { command pattern args } { - if [string length $pattern] { + if {[string length $pattern]} { gdb_test $command $pattern $args } else { gdb_test_no_output $command $args @@ -38,13 +38,17 @@ proc_with_prefix test_directories { } { # doesn't set search directories on remote host. set directories ".*\\\$cdir.\\\$cwd" } else { - set escaped_directory [string_to_regexp "$::srcdir/$::subdir"] + set directory [host_file_normalize "$::srcdir/$::subdir"] + set escaped_directory [string_to_regexp $directory] set directories "$escaped_directory.\\\$cdir.\\\$cwd" } gdb_test "python print (gdb.parameter ('directories'))" $directories } proc_with_prefix test_data_directory { } { + # Proc assumes local host. + require {!is_remote host} + clean_restart # Check we can correctly read the data-directory parameter. First, @@ -187,6 +191,8 @@ proc_with_prefix test_enum_parameter { } { # Test an color parameter. proc_with_prefix test_color_parameter { } { + require {!is_remote host} + global env with_ansi_styling_terminal { # This enables 256 colors support and disables colors approximation. @@ -346,6 +352,91 @@ proc_with_prefix test_really_undocumented_parameter { } { "test general help" } +# Test a parameter in which the __doc__ string is empty or None. +proc_with_prefix test_empty_doc_parameter {} { + gdb_test_multiline "empty __doc__ parameter" \ + "python" "" \ + "class EmptyDocParam(gdb.Parameter):" "" \ + " __doc__ = \"\"" "" \ + " def __init__(self, name):" "" \ + " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + " self.value = True" "" \ + "test_empty_doc_param = EmptyDocParam('print test-empty-doc-param')" ""\ + "end" + + # Setting the __doc__ string to empty means GDB will completely + # elide it from the output. + gdb_test "help set print test-empty-doc-param" \ + "^Set the current value of 'print test-empty-doc-param'\\." + + gdb_test_multiline "None __doc__ parameter" \ + "python" "" \ + "class NoneDocParam(gdb.Parameter):" "" \ + " __doc__ = None" "" \ + " def __init__(self, name):" "" \ + " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + " self.value = True" "" \ + "test_none_doc_param = NoneDocParam('print test-none-doc-param')" ""\ + "end" + + # Setting the __doc__ string to None, or anything else that isn't + # a string, causes GDB to use a default string instead. + gdb_test "help set print test-none-doc-param" \ + [multi_line \ + "^Set the current value of 'print test-none-doc-param'\\." \ + "This command is not documented\\."] +} + +# Test a parameter in which the set_doc/show_doc strings are either +# empty, or None. +proc_with_prefix test_empty_set_show_doc_parameter {} { + gdb_test_multiline "empty set/show doc parameter" \ + "python" "" \ + "class EmptySetShowParam(gdb.Parameter):" "" \ + " set_doc = \"\"" "" \ + " show_doc = \"\"" "" \ + " def __init__(self, name):" "" \ + " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + " self.value = True" "" \ + "test_empty_set_show_param = EmptySetShowParam('print test-empty-set-show-param')" ""\ + "end" + + # Setting the set_doc/show_doc string to empty means GDB will use + # a suitable default string. + gdb_test "help set print test-empty-set-show-param" \ + [multi_line \ + "^Set the current value of 'print test-empty-set-show-param'\\." \ + "This command is not documented\\."] + + gdb_test "help show print test-empty-set-show-param" \ + [multi_line \ + "^Show the current value of 'print test-empty-set-show-param'\\." \ + "This command is not documented\\."] + + gdb_test_multiline "None set/show doc parameter" \ + "python" "" \ + "class NoneSetShowParam(gdb.Parameter):" "" \ + " set_doc = None" "" \ + " show_doc = None" "" \ + " def __init__(self, name):" "" \ + " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + " self.value = True" "" \ + "test_none_set_show_param = NoneSetShowParam('print test-none-set-show-param')" ""\ + "end" + + # Setting the set_doc/show_doc string to None (or any non-string + # value) means GDB will use a suitable default string. + gdb_test "help set print test-none-set-show-param" \ + [multi_line \ + "^Set the current value of 'print test-none-set-show-param'\\." \ + "This command is not documented\\."] + + gdb_test "help show print test-none-set-show-param" \ + [multi_line \ + "^Show the current value of 'print test-none-set-show-param'\\." \ + "This command is not documented\\."] +} + # Test deprecated API. Do not use in your own implementations. proc_with_prefix test_deprecated_api_parameter { } { clean_restart @@ -669,6 +760,104 @@ proc_with_prefix test_ambiguous_parameter {} { "Parameter .* is ambiguous.*Error occurred in Python.*" gdb_test "python print(gdb.parameter('test-ambiguous-value-1a'))" \ "Could not find parameter.*Error occurred in Python.*" + + # Create command prefixs 'set foo1' and 'show foo1'. + gdb_test_no_output "python gdb.Command('set foo1', gdb.COMMAND_NONE, prefix=True)" + gdb_test_no_output "python gdb.Command('show foo1', gdb.COMMAND_NONE, prefix=True)" + + # Create a parameter under 'foo1', but use a truncated prefix. At + # this point though, the prefix is not ambiguous. + gdb_test_no_output "python gdb.Parameter('foo bar', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" + gdb_test "python print(gdb.parameter('foo1 bar'))" "False" + + # Create another prefix command, similar in name to the first. + gdb_test_no_output "python gdb.Command('set foo2', gdb.COMMAND_NONE, prefix=True)" + gdb_test_no_output "python gdb.Command('show foo2', gdb.COMMAND_NONE, prefix=True)" + + # An attempt to create a parameter using an ambiguous prefix will give an error. + gdb_test "python gdb.Parameter('foo baz', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" \ + [multi_line \ + "Python Exception <class 'RuntimeError'>: Could not find command prefix foo\\." \ + "Error occurred in Python: Could not find command prefix foo\\."] +} + +# Check that creating a gdb.Parameter with an unknown command prefix results in an error. +proc_with_prefix test_unknown_prefix {} { + gdb_test_multiline "create parameter" \ + "python" "" \ + "class UnknownPrefixParam(gdb.Parameter):" "" \ + " def __init__ (self, name):" "" \ + " super().__init__ (name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + " self.value = True" "" \ + "end" + + foreach prefix { "unknown-prefix" "style unknown-prefix" "style disassembler unknown-prefix"} { + gdb_test "python UnknownPrefixParam('$prefix new-param')" \ + [multi_line \ + "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \ + "Error occurred in Python: Could not find command prefix $prefix\\."] + } +} + +# Test the default behaviour of a set/show parameter prefix command. +proc_with_prefix test_set_show_parameters {} { + # This first set/show prefix command doesn't have an invoke + # method. As such, GDB installs the default invoke behaviour; set + # prints the full list of sub-commands, and show prints all the + # sub-command values. + gdb_test_multiline "Setup set/show parameter prefix with no invoke" \ + "python" "" \ + "class TestParamPrefix(gdb.Command):" "" \ + " \"\"\"TestParamPrefix documentation string.\"\"\"" "" \ + " def __init__(self, name):" "" \ + " super().__init__(name, gdb.COMMAND_NONE, prefix = True)" "" \ + "TestParamPrefix('set test-prefix')" "" \ + "TestParamPrefix('show test-prefix')" "" \ + "gdb.Parameter('test-prefix param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('test-prefix param-2', gdb.COMMAND_NONE, gdb.PARAM_INTEGER)" "" \ + "gdb.Parameter('test-prefix param-3', gdb.COMMAND_NONE, gdb.PARAM_STRING)" "" \ + "end" + + gdb_test "set test-prefix" \ + [multi_line \ + "List of \"set test-prefix\" subcommands:" \ + "" \ + "set test-prefix param-1 -- Set the current value of 'test-prefix param-1'." \ + "set test-prefix param-2 -- Set the current value of 'test-prefix param-2'." \ + "set test-prefix param-3 -- Set the current value of 'test-prefix param-3'." \ + "" \ + "Type \"help set test-prefix\" followed by subcommand name for full documentation\\." \ + "Type \"apropos word\" to search for commands related to \"word\"\\." \ + "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \ + "Command name abbreviations are allowed if unambiguous\\."] + + gdb_test "show test-prefix" \ + [multi_line \ + "test-prefix param-1: The current value of 'test-prefix param-1' is \"off\"\\." \ + "test-prefix param-2: The current value of 'test-prefix param-2' is \"0\"\\." \ + "test-prefix param-3: The current value of 'test-prefix param-3' is \"\"\\."] + + # This next set/show prefix has an invoke method, which will be + # called instead of the default behaviour tested above. + gdb_test_multiline "Setup set/show parameter prefix with invoke" \ + "python" "" \ + "class TestParamPrefix(gdb.Command):" "" \ + " \"\"\"TestParamPrefix documentation string.\"\"\"" "" \ + " def __init__(self, name, mode):" "" \ + " self._mode = mode" "" \ + " super().__init__(self._mode + ' ' + name, gdb.COMMAND_NONE, prefix = True)" "" \ + " def invoke(self, args, from_tty):" "" \ + " print('invoke -- ' + self._mode)" "" \ + "TestParamPrefix('test-prefix-2', 'set')" "" \ + "TestParamPrefix('test-prefix-2', 'show')" "" \ + "gdb.Parameter('test-prefix-2 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \ + "gdb.Parameter('test-prefix-2 param-2', gdb.COMMAND_NONE, gdb.PARAM_INTEGER)" "" \ + "gdb.Parameter('test-prefix-2 param-3', gdb.COMMAND_NONE, gdb.PARAM_STRING)" "" \ + "end" + + gdb_test "set test-prefix-2" "^invoke -- set" + + gdb_test "show test-prefix-2" "^invoke -- show" } test_directories @@ -679,11 +868,15 @@ test_color_parameter test_file_parameter test_undocumented_parameter test_really_undocumented_parameter +test_empty_doc_parameter +test_empty_set_show_doc_parameter test_deprecated_api_parameter test_gdb_parameter test_integer_parameter test_throwing_parameter test_language test_ambiguous_parameter +test_unknown_prefix +test_set_show_parameters rename py_param_test_maybe_no_output "" diff --git a/gdb/testsuite/gdb.python/py-pp-cast.exp b/gdb/testsuite/gdb.python/py-pp-cast.exp index 7e20756..917547c 100644 --- a/gdb/testsuite/gdb.python/py-pp-cast.exp +++ b/gdb/testsuite/gdb.python/py-pp-cast.exp @@ -25,7 +25,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto break_function] { +if {![runto break_function]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-pp-integral.exp b/gdb/testsuite/gdb.python/py-pp-integral.exp index 8111d75..45645f9 100644 --- a/gdb/testsuite/gdb.python/py-pp-integral.exp +++ b/gdb/testsuite/gdb.python/py-pp-integral.exp @@ -21,7 +21,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto tick_tock] { +if {![runto tick_tock]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-pp-maint.exp b/gdb/testsuite/gdb.python/py-pp-maint.exp index 74d8e76..bd26b91 100644 --- a/gdb/testsuite/gdb.python/py-pp-maint.exp +++ b/gdb/testsuite/gdb.python/py-pp-maint.exp @@ -72,10 +72,10 @@ gdb_test "enable pretty-printer" \ "second enable of all pretty printers" gdb_test "disable pretty-printer global lookup_function_lookup_test" \ - "1 printer disabled.*[expr $num_pp - 1] of $num_pp printers enabled" + "1 printer disabled.*[expr {$num_pp - 1}] of $num_pp printers enabled" gdb_test "disable pretty-printer global pp-test;.*" \ - "[expr 5] printers disabled.*0 of $num_pp printers enabled" + "[expr {$num_pp - 1}] printers disabled.*0 of $num_pp printers enabled" gdb_test "info pretty-printer global .*function" \ {.*function_lookup_test \[disabled\].*} \ @@ -101,10 +101,10 @@ gdb_test "enable pretty-printer global pp-test" \ "0 printers enabled.*1 of $num_pp printers enabled" gdb_test "enable pretty-printer global pp-test;.*ss.*" \ - "2 printers enabled.*[expr $num_pp - 3] of $num_pp printers enabled" + "2 printers enabled.*[expr {$num_pp - 3}] of $num_pp printers enabled" gdb_test "enable pretty-printer global pp-test;.*s.*" \ - "2 printers enabled.*[expr $num_pp - 1] of $num_pp printers enabled" + "2 printers enabled.*[expr {$num_pp - 1}] of $num_pp printers enabled" gdb_test "enable pretty-printer global pp-test;.*" \ "1 printer enabled.*$num_pp of $num_pp printers enabled" diff --git a/gdb/testsuite/gdb.python/py-pp-re-notag.exp b/gdb/testsuite/gdb.python/py-pp-re-notag.exp index 8111d75..45645f9 100644 --- a/gdb/testsuite/gdb.python/py-pp-re-notag.exp +++ b/gdb/testsuite/gdb.python/py-pp-re-notag.exp @@ -21,7 +21,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto tick_tock] { +if {![runto tick_tock]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-pp-registration.exp b/gdb/testsuite/gdb.python/py-pp-registration.exp index c5e7f9a..d0d1fda 100644 --- a/gdb/testsuite/gdb.python/py-pp-registration.exp +++ b/gdb/testsuite/gdb.python/py-pp-registration.exp @@ -29,7 +29,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { set remote_python_file [gdb_remote_download host \ ${srcdir}/${subdir}/${testfile}.py] -if ![runto_main ] { +if {![runto_main ]} { return -1 } @@ -40,7 +40,7 @@ proc prepare_test { } { clean_restart ${testfile} set run_to_here [gdb_get_line_number {break to inspect} ${testfile}.c ] - if ![runto ${testfile}.c:$run_to_here] { + if {![runto ${testfile}.c:$run_to_here]} { return 0 } @@ -63,7 +63,7 @@ proc test_printers { s_prefix } { # Test registration with verbose off. with_test_prefix "verbose off" { - if ![prepare_test] { + if {![prepare_test]} { return -1 } @@ -78,7 +78,7 @@ with_test_prefix "verbose off" { # Test registration with verbose on. with_test_prefix "verbose on" { - if ![prepare_test] { + if {![prepare_test]} { return -1 } @@ -95,7 +95,7 @@ with_test_prefix "verbose on" { # Exercise the "replace" argument to register_pretty_printer. with_test_prefix "replace" { - if ![prepare_test] { + if {![prepare_test]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp index 0b5ca9a..be2cecd 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.exp +++ b/gdb/testsuite/gdb.python/py-prettyprint.exp @@ -36,7 +36,8 @@ proc run_lang_tests {exefile lang} { set nl "\[\r\n\]+" # Start with a fresh gdb. - clean_restart $exefile + clean_restart + gdb_load $exefile if {![runto_main]} { return @@ -52,11 +53,11 @@ proc run_lang_tests {exefile lang} { ${srcdir}/${subdir}/${testfile}.py] gdb_test_no_output "source ${remote_python_file}" "load python file" - + gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" gdb_test "print ssa\[1\]" " = a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>" gdb_test "print ssa" " = {a=< a=<3> b=<$hex>> b=< a=<4> b=<$hex>>, a=< a=<5> b=<$hex>> b=< a=<6> b=<$hex>>}" - + gdb_test "print arraystruct" " = {$nl *y = 7, *$nl *x = { a=<23> b=<$hex>, a=<24> b=<$hex>} *$nl *}" # Test that when a pretty-printer returns a gdb.Value in its to_string, we @@ -192,7 +193,7 @@ with_test_prefix c++ { # Run various other tests. -clean_restart $binfile +clean_restart $::testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.python/py-progspace.exp b/gdb/testsuite/gdb.python/py-progspace.exp index 1d271d4..822c079 100644 --- a/gdb/testsuite/gdb.python/py-progspace.exp +++ b/gdb/testsuite/gdb.python/py-progspace.exp @@ -76,7 +76,7 @@ gdb_test "python print (blk.end >= ${pc_val})" "True" \ "block end is after \$pc" # Check what happens when we ask for a block of an invalid address. -if ![is_address_zero_readable] { +if {![is_address_zero_readable]} { gdb_test "python print (gdb.current_progspace ().block_for_pc (0))" "None" } diff --git a/gdb/testsuite/gdb.python/py-read-memory-leak.exp b/gdb/testsuite/gdb.python/py-read-memory-leak.exp index 0015a57..0b663d7 100644 --- a/gdb/testsuite/gdb.python/py-read-memory-leak.exp +++ b/gdb/testsuite/gdb.python/py-read-memory-leak.exp @@ -26,19 +26,9 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } -# Skip this test if the tracemalloc module is not available. -if { ![gdb_py_module_available "tracemalloc"] } { - unsupported "tracemalloc module not available" - return -} - -set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] - -# Source the Python script, this runs the test (which is written -# completely in Python), and either prints PASS, or throws an -# exception. -gdb_test "source ${pyfile}" "PASS" "source python script" +gdb_py_run_memory_leak_test ${srcdir}/${subdir}/${testfile}.py \ + "buffers returned by read_memory() deallocates correctly" diff --git a/gdb/testsuite/gdb.python/py-read-memory-leak.py b/gdb/testsuite/gdb.python/py-read-memory-leak.py index 348403d..89647cf 100644 --- a/gdb/testsuite/gdb.python/py-read-memory-leak.py +++ b/gdb/testsuite/gdb.python/py-read-memory-leak.py @@ -13,81 +13,27 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import os -import tracemalloc +import sys -import gdb +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True -# A global variable in which we store a reference to the memory buffer -# returned from gdb.Inferior.read_memory(). -mem_buf = None +import gdb_leak_detector -# A global filters list, we only care about memory allocations -# originating from this script. -filters = [tracemalloc.Filter(True, "*" + os.path.basename(__file__))] +class read_leak_detector(gdb_leak_detector.gdb_leak_detector): + def __init__(self): + super().__init__(__file__) + self.mem_buf = None + self.addr = gdb.parse_and_eval("px") + self.inf = gdb.inferiors()[0] + def allocate(self): + self.mem_buf = self.inf.read_memory(self.addr, 4096) -# Run the test. When CLEAR is True we clear the global INF variable -# before comparing the before and after memory allocation traces. -# When CLEAR is False we leave INF set to reference the gdb.Inferior -# object, thus preventing the gdb.Inferior from being deallocated. -def test(clear): - global filters, mem_buf + def deallocate(self): + self.mem_buf = None - addr = gdb.parse_and_eval("px") - inf = gdb.inferiors()[0] - # Start tracing, and take a snapshot of the current allocations. - tracemalloc.start() - snapshot1 = tracemalloc.take_snapshot() - - # Read from the inferior, this allocate a memory buffer object. - mem_buf = inf.read_memory(addr, 4096) - - # Possibly clear the global INF variable. - if clear: - mem_buf = None - - # Now grab a second snapshot of memory allocations, and stop - # tracing memory allocations. - snapshot2 = tracemalloc.take_snapshot() - tracemalloc.stop() - - # Filter the snapshots; we only care about allocations originating - # from this file. - snapshot1 = snapshot1.filter_traces(filters) - snapshot2 = snapshot2.filter_traces(filters) - - # Compare the snapshots, this leaves only things that were - # allocated, but not deallocated since the first snapshot. - stats = snapshot2.compare_to(snapshot1, "traceback") - - # Total up all the allocated things. - total = 0 - for stat in stats: - total += stat.size_diff - return total - - -# The first time we run this some global state will be allocated which -# shows up as memory that is allocated, but not released. So, run the -# test once and discard the result. -test(True) - -# Now run the test twice, the first time we clear our global reference -# to the memory buffer object, which should allow Python to deallocate -# the object. The second time we hold onto the global reference, -# preventing Python from performing the deallocation. -bytes_with_clear = test(True) -bytes_without_clear = test(False) - -# The bug that used to exist in GDB was that even when we released the -# global reference the gdb.Inferior object would not be deallocated. -if bytes_with_clear > 0: - raise gdb.GdbError("memory leak when memory buffer should be released") -if bytes_without_clear == 0: - raise gdb.GdbError("memory buffer object is no longer allocated") - -# Print a PASS message that the test script can see. -print("PASS") +read_leak_detector().run() diff --git a/gdb/testsuite/gdb.python/py-record-btrace.exp b/gdb/testsuite/gdb.python/py-record-btrace.exp index aff7c6c..6dd3ae1 100644 --- a/gdb/testsuite/gdb.python/py-record-btrace.exp +++ b/gdb/testsuite/gdb.python/py-record-btrace.exp @@ -23,7 +23,7 @@ load_lib gdb-python.exp standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { return -1 } +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.python/py-record-full.exp b/gdb/testsuite/gdb.python/py-record-full.exp index 97d21ce..790e5b3 100644 --- a/gdb/testsuite/gdb.python/py-record-full.exp +++ b/gdb/testsuite/gdb.python/py-record-full.exp @@ -23,7 +23,7 @@ load_lib gdb-python.exp standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile] { return -1 } +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { return -1 } if {![runto_main]} { return -1 diff --git a/gdb/testsuite/gdb.python/py-section-script.exp b/gdb/testsuite/gdb.python/py-section-script.exp index cc4425c..9d4e48c 100644 --- a/gdb/testsuite/gdb.python/py-section-script.exp +++ b/gdb/testsuite/gdb.python/py-section-script.exp @@ -71,13 +71,13 @@ 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] { +if {[is_remote host]} { set remote_binfile [file tail ${binfile}] } else { set remote_binfile ${binfile} } -if [ishost *-*-mingw*] { +if {[ishost *-*-mingw*]} { set remote_pathsep ";" } else { set remote_pathsep ":" @@ -107,7 +107,7 @@ gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*" gdb_test "info auto-load python-scripts no-script-matches-this" \ "No auto-load scripts matching no-script-matches-this." -if ![runto_main] { +if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.python/py-source-styling-2.exp b/gdb/testsuite/gdb.python/py-source-styling-2.exp index b13ee1f..ebf7f32 100644 --- a/gdb/testsuite/gdb.python/py-source-styling-2.exp +++ b/gdb/testsuite/gdb.python/py-source-styling-2.exp @@ -32,7 +32,9 @@ if { [build_executable "failed to build" $testfile $srcfile $opts] == -1 } { return } -clean_restart +with_ansi_styling_terminal { + clean_restart +} gdb_test_no_output "maint set gnu-source-highlight enabled off" @@ -40,16 +42,14 @@ gdb_load $binfile require {gdb_py_module_available pygments} -with_ansi_styling_terminal { - gdb_test_no_output "set style enabled on" - - gdb_test_multiple "list $line_number" "Styling of c++ keyword try" { - -re -wrap " try\r\n.*" { - # Unstyled. - fail $gdb_test_name - } - -re -wrap "" { - pass $gdb_test_name - } +gdb_test_no_output "set style enabled on" + +gdb_test_multiple "list $line_number" "Styling of c++ keyword try" { + -re -wrap " try\r\n.*" { + # Unstyled. + fail $gdb_test_name + } + -re -wrap "" { + pass $gdb_test_name } } diff --git a/gdb/testsuite/gdb.python/py-source-styling.exp b/gdb/testsuite/gdb.python/py-source-styling.exp index 308053c..e030768 100644 --- a/gdb/testsuite/gdb.python/py-source-styling.exp +++ b/gdb/testsuite/gdb.python/py-source-styling.exp @@ -62,7 +62,7 @@ proc check_source_listing_styling { cmd expect_styled { testname "" } } { # highlighting when GNU source highlight is not available (or is # disabled, as is done in this test). proc test_pygments_styling {} { - clean_restart $::binfile + clean_restart $::testfile # Remote host boards disable styling via GDB's command line. Turn # it back on now. @@ -75,7 +75,7 @@ proc test_pygments_styling {} { return } - if ![runto_main] { + if {![runto_main]} { return } @@ -91,7 +91,7 @@ proc test_pygments_styling {} { # string, then set the correct host encoding, and try again. This # time the conversion should succeed. proc test_gdb_execute_non_utf8_source {} { - clean_restart $::binfile + clean_restart $::testfile # The default host charset is utf-8, the source code contains a # non-utf-8 character, so this will fail. @@ -117,7 +117,7 @@ proc test_gdb_execute_non_utf8_source {} { # output to be returned via a string, and in other cases we ask for # the output to be sent straight to stdout. proc_with_prefix test_source_cache_style_tracking {} { - clean_restart $::binfile + clean_restart $::testfile # Remote host boards disable styling via GDB's command line. Turn # it back on now. diff --git a/gdb/testsuite/gdb.python/py-startup-opt.exp b/gdb/testsuite/gdb.python/py-startup-opt.exp index 7410706..929c64d 100644 --- a/gdb/testsuite/gdb.python/py-startup-opt.exp +++ b/gdb/testsuite/gdb.python/py-startup-opt.exp @@ -17,6 +17,7 @@ # initialized. require allow_python_tests +require {!is_remote host} # Return a list containing two directory paths for newly created home # directories. diff --git a/gdb/testsuite/gdb.python/py-strfns.exp b/gdb/testsuite/gdb.python/py-strfns.exp index 2b5dff19..13b8d2e 100644 --- a/gdb/testsuite/gdb.python/py-strfns.exp +++ b/gdb/testsuite/gdb.python/py-strfns.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.python/py-styled-execute.exp b/gdb/testsuite/gdb.python/py-styled-execute.exp index 0b27c63..198dab5 100644 --- a/gdb/testsuite/gdb.python/py-styled-execute.exp +++ b/gdb/testsuite/gdb.python/py-styled-execute.exp @@ -17,6 +17,7 @@ # on the value of the third argument passed to gdb.execute. require allow_python_tests +require {!is_remote host} load_lib gdb-python.exp diff --git a/gdb/testsuite/gdb.python/py-sym-artificial.exp b/gdb/testsuite/gdb.python/py-sym-artificial.exp index e26e9d2..831ebd2 100644 --- a/gdb/testsuite/gdb.python/py-sym-artificial.exp +++ b/gdb/testsuite/gdb.python/py-sym-artificial.exp @@ -27,21 +27,21 @@ set asm_file [standard_output_file ${srcfile2}] Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name py-sym-artificial.c} + DW_AT_language @DW_LANG_C + DW_AT_name py-sym-artificial.c } { declare_labels signed signed: DW_TAG_base_type { - {DW_AT_byte_size 1 DW_FORM_sdata} - {DW_AT_encoding @DW_ATE_signed} - {DW_AT_name bool} + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_signed + DW_AT_name bool } DW_TAG_variable { - {name the_variable} - {DW_AT_type :$signed} - {artificial 1 DW_FORM_flag_present} + DW_AT_name the_variable + DW_AT_type :$signed + DW_AT_artificial 1 DW_FORM_flag_present } } } diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp index 55cdebe..2029c28 100644 --- a/gdb/testsuite/gdb.python/py-symbol.exp +++ b/gdb/testsuite/gdb.python/py-symbol.exp @@ -44,7 +44,7 @@ if {!$readnow_p} { } # Restart so we don't have expanded symtabs after the previous test. -clean_restart ${binfile} +clean_restart ${::testfile} # Test looking up a global symbol before we runto_main as this is the # point where we don't have a current frame, and we don't want to @@ -100,7 +100,6 @@ gdb_test_multiple $cmd "print value of rr" { fail $gdb_test_name } } - gdb_test "python print (gdb.lookup_static_symbol ('rr').needs_frame)" \ "False" \ @@ -215,8 +214,10 @@ gdb_test "python print (t\[0\].symtab)" "${py_symbol_c}" "get symtab" # C++ tests # Recompile binary. lappend opts c++ -if {[prepare_for_testing "failed to prepare" "${binfile}-cxx" \ - [list $srcfile $srcfile2] $opts]} { +set testfile $testfile-cxx +set binfile [standard_output_file $testfile] +if { [prepare_for_testing "failed to prepare" $testfile \ + [list $srcfile $srcfile2] $opts] } { return -1 } @@ -252,7 +253,7 @@ gdb_test "python print (cplusfunc.addr_class == gdb.SYMBOL_LOC_BLOCK)" "True" "t # Test is_valid when the objfile is unloaded. This must be the last # test as it unloads the object file in GDB. # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.python/py-thread-exited.exp b/gdb/testsuite/gdb.python/py-thread-exited.exp index dcacb11..0f47ce0 100644 --- a/gdb/testsuite/gdb.python/py-thread-exited.exp +++ b/gdb/testsuite/gdb.python/py-thread-exited.exp @@ -32,7 +32,7 @@ gdb_test_no_output "source ${pyfile}" "load python file" gdb_test "test-events" "Event testers registered." -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-thread-exited.py b/gdb/testsuite/gdb.python/py-thread-exited.py index ef5a244..f725bd5 100644 --- a/gdb/testsuite/gdb.python/py-thread-exited.py +++ b/gdb/testsuite/gdb.python/py-thread-exited.py @@ -26,6 +26,8 @@ def thread_exited_handler(event): global threadOneExit, threadTwoExit, mainThreadExit print("{}".format(event)) assert isinstance(event, gdb.ThreadExitedEvent) + # Also check the inheritance. + assert isinstance(event, gdb.ThreadEvent) if threadOneExit == "": threadOneExit = "event type: thread-exited. global num: {}".format( event.inferior_thread.global_num diff --git a/gdb/testsuite/gdb.python/py-thrhandle.exp b/gdb/testsuite/gdb.python/py-thrhandle.exp index 343bf4b..a959044 100644 --- a/gdb/testsuite/gdb.python/py-thrhandle.exp +++ b/gdb/testsuite/gdb.python/py-thrhandle.exp @@ -29,7 +29,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index 0bc4556..c32a5bd 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -33,8 +33,9 @@ proc build_inferior {exefile lang} { } # Restart GDB. -proc restart_gdb {exefile} { - clean_restart $exefile +proc restart_gdb {exefile} { + clean_restart + gdb_load $exefile if {![runto_main]} { return @@ -134,7 +135,7 @@ proc test_fields {lang} { # Test conversion to bool on scalar types gdb_test "python print (not not st.type\['a'\].type)" "True" - + # Test regression PR python/10805 gdb_py_test_silent_cmd "print (ar)" "print value(ar)" 1 gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1 @@ -253,9 +254,9 @@ proc test_template {} { || [test_compiler_info {gcc-4-[0-4]-*}]} { set have_older_gcc 1 } - if $have_older_gcc { setup_xfail *-*-* } + if {$have_older_gcc} { setup_xfail *-*-* } gdb_test "python print (ttype.template_argument(1))" "23" - if $have_older_gcc { setup_xfail *-*-* } + if {$have_older_gcc} { setup_xfail *-*-* } gdb_test "python print (isinstance(ttype.template_argument(1), gdb.Value))" \ "True" diff --git a/gdb/testsuite/gdb.python/py-unwind.exp b/gdb/testsuite/gdb.python/py-unwind.exp index 80eac28..b416c2f 100644 --- a/gdb/testsuite/gdb.python/py-unwind.exp +++ b/gdb/testsuite/gdb.python/py-unwind.exp @@ -245,6 +245,13 @@ with_test_prefix "frame-id 'pc' is invalid" { "Python Exception <class 'ValueError'>: invalid literal for int\\(\\) with base 10: 'xyz'\r\n.*" } +with_test_prefix "bad object unwinder" { + gdb_test_no_output "python obj = bad_object_unwinder(\"bad-object\")" + gdb_test_no_output "python gdb.unwinder.register_unwinder(None, obj, replace=True)" + gdb_test "backtrace" \ + "Python Exception <class 'gdb.error'>: an Unwinder should return gdb.UnwindInfo, not Blah\\.\r\n.*" +} + # Gather information about every frame. gdb_test_no_output "python capture_all_frame_information()" gdb_test_no_output "python gdb.newest_frame().select()" diff --git a/gdb/testsuite/gdb.python/py-unwind.py b/gdb/testsuite/gdb.python/py-unwind.py index 8e65a1a..0faccf2 100644 --- a/gdb/testsuite/gdb.python/py-unwind.py +++ b/gdb/testsuite/gdb.python/py-unwind.py @@ -267,4 +267,24 @@ class validating_unwinder(Unwinder): return None +class bad_object_unwinder(Unwinder): + def __init__(self, name): + super().__init__(name) + + def __call__(self, pending_frame): + + if pending_frame.level() != 1: + return None + + class Blah: + def __init__(self): + pass + + @property + def __class__(self): + raise RuntimeError("error in Blah.__class__") + + return Blah() + + print("Python script imported") diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp index 3d371bc..6d261fb 100644 --- a/gdb/testsuite/gdb.python/py-value-cc.exp +++ b/gdb/testsuite/gdb.python/py-value-cc.exp @@ -24,7 +24,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c index a822346..f6dbf55 100644 --- a/gdb/testsuite/gdb.python/py-value.c +++ b/gdb/testsuite/gdb.python/py-value.c @@ -19,6 +19,14 @@ #include <stdlib.h> #include <string.h> +int long_array[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49 +}; + struct s { int a; @@ -60,6 +68,7 @@ struct Derived : public Base { Base *base = new Derived (); Derived derived; Base &base_ref = derived; +struct str pod; void ptr_ref(int*& rptr_int) { diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp index 93985a9..087c8c2 100644 --- a/gdb/testsuite/gdb.python/py-value.exp +++ b/gdb/testsuite/gdb.python/py-value.exp @@ -297,9 +297,9 @@ proc test_value_in_inferior {} { gdb_test "print argc" " = $argc_value" "sanity check argc" gdb_test "python print (argc_lazy.is_lazy)" "\r\nTrue" \ "python print (argc_lazy.is_lazy) the second time" - gdb_test_no_output "set argc=[expr $argc_value + 1]" "change argc" + gdb_test_no_output "set argc=[expr {$argc_value + 1}]" "change argc" gdb_test "python print (argc_notlazy)" "\r\n$argc_value" - gdb_test "python print (argc_lazy)" "\r\n[expr $argc_value + 1]" + gdb_test "python print (argc_lazy)" "\r\n[expr {$argc_value + 1}]" gdb_test "python print (argc_lazy.is_lazy)" "False" # Test string fetches, both partial and whole. @@ -431,7 +431,8 @@ proc test_value_after_death {} { proc test_subscript_regression {exefile lang} { # Start with a fresh gdb. - clean_restart ${exefile} + clean_restart + gdb_load $exefile if {![runto_main]} { return @@ -457,6 +458,8 @@ proc test_subscript_regression {exefile lang} { "Derived \[*\]" gdb_test "python print (gdb.parse_and_eval('base_ref').dynamic_type)" \ "Derived \[&\]" + gdb_test "python print (gdb.parse_and_eval('pod').dynamic_type)" \ + "str" # A static type case. gdb_test "python print (gdb.parse_and_eval('5').dynamic_type)" \ "int" @@ -595,7 +598,7 @@ proc test_value_from_buffer {} { gdb_py_test_silent_cmd "python atpbig=tp.array(3)" "make bigger array type" 0 gdb_test "python vabig=gdb.Value(b,atpbig)" \ "ValueError.*: Size of type is larger than that of buffer object\..*" \ - "attempt to construct large value with small buffer" + "attempt to construct large value with small buffer" gdb_test "python v=gdb.Value(2048,tp)" \ "TypeError.*: Object must support the python buffer protocol\..*" \ "attempt to construct value from buffer with non-buffer object" @@ -680,6 +683,7 @@ proc_with_prefix test_value_bytes { } { "python" "" \ "def check_value_bytes(var_name):" "" \ " val = gdb.parse_and_eval(var_name)" "" \ + " assert not val.is_unavailable" "" \ " addr = val.address" "" \ " len = val.type.sizeof" "" \ " mem = gdb.selected_inferior().read_memory(addr, len)" "" \ @@ -762,13 +766,45 @@ proc test_assign {} { "cannot assign to integer" } +# Test Value.is_unavailable +proc test_unavailable {} { + set elem_size [get_valueof "/d" "sizeof(long_array\[0\])" "UNKNOWN" \ + "get size of long_array element"] + set max [expr {$elem_size * 10}] + + with_set "print elements" 5 { + with_max_value_size $max { + gdb_test "p long_array" + + gdb_test_no_output "set print elements 15" + + gdb_test_no_output "python v = gdb.history(0)" + + gdb_test "python print(v.is_unavailable)" "^True" \ + "overall object shows as unavailable" + for { set i 0 } { $i < 10 } { incr i } { + gdb_test "python print(v\[$i\].is_unavailable)" "^False" \ + "array element $i is available" + gdb_test "python print(v\[$i\])" "^$i" \ + "array element $i has correct value" + } + for { set i 10 } { $i < 15 } { incr i } { + gdb_test "python print(v\[$i\].is_unavailable)" "^True" \ + "array element $i is unavailable" + gdb_test "python print(v\[$i\])" "^<unavailable>" \ + "array element $i shows as unavailable" + } + } + } +} + # Build C version of executable. C++ is built later. if { [build_inferior "${binfile}" "c"] < 0 } { return -1 } # Start with a fresh gdb. -clean_restart ${binfile} +clean_restart ${::testfile} test_history_count test_value_creation @@ -788,6 +824,7 @@ if {![runto_main]} { return 0 } +test_unavailable test_value_in_inferior test_value_from_buffer test_value_sub_classes @@ -797,7 +834,7 @@ test_assign test_value_bytes test_value_after_death -# Test either C or C++ values. +# Test either C or C++ values. test_subscript_regression "${binfile}" "c" @@ -809,3 +846,15 @@ if {[allow_cplus_tests]} { test_subscript_regression "${binfile}-cxx" "c++" } } + +if {[allow_rust_tests]} { + gdb_test "set lang rust" + + set cst 0x80000000000000000000000000000000 + gdb_test "python print(int(gdb.parse_and_eval('${cst}u128')))" \ + "170141183460469231731687303715884105728" \ + "convert 128 bit unsigned constant to python int" + gdb_test "python print(int(gdb.parse_and_eval('${cst}i128')))" \ + "-170141183460469231731687303715884105728" \ + "convert 128 bit signed constant to python int" +} diff --git a/gdb/testsuite/gdb.python/py-varobj.exp b/gdb/testsuite/gdb.python/py-varobj.exp index 7fb45f9..cf6a662 100644 --- a/gdb/testsuite/gdb.python/py-varobj.exp +++ b/gdb/testsuite/gdb.python/py-varobj.exp @@ -25,7 +25,7 @@ if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug}] != ""} return -1 } -mi_clean_restart $binfile +mi_clean_restart $::testfile set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] mi_gdb_test "source ${pyfile}" \ diff --git a/gdb/testsuite/gdb.python/py-warning.exp b/gdb/testsuite/gdb.python/py-warning.exp new file mode 100644 index 0000000..6b26a4e --- /dev/null +++ b/gdb/testsuite/gdb.python/py-warning.exp @@ -0,0 +1,63 @@ +# Copyright (C) 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 the gdb.warning() function. + +load_lib gdb-python.exp + +require allow_python_tests + +clean_restart + +# Basic usage. +gdb_test "python gdb.warning(\"some text\")" \ + "warning: some text" + +# Basic usage with named argument. +gdb_test "python gdb.warning(text=\"a warning message\")" \ + "warning: a warning message" + +# Make sure GDB prints format specifiers correctly. +gdb_test "python gdb.warning(\"%s %d %p\")" \ + "warning: %s %d %p" + +# Empty string gives an error. +gdb_test "python gdb.warning(\"\")" \ + [multi_line \ + "Python Exception <class 'ValueError'>: Empty text string passed to gdb\\.warning" \ + "Error occurred in Python: Empty text string passed to gdb\\.warning"] + +# Missing argument gives an error. +set re1 \ + [multi_line \ + [string_to_regexp \ + [concat \ + "Python Exception <class 'TypeError'>:" \ + "function missing required argument 'text' (pos 1)"]] \ + [string_to_regexp \ + [concat \ + "Error occurred in Python:" \ + "function missing required argument 'text' (pos 1)"]]] +set re2 \ + [multi_line \ + [string_to_regexp \ + [concat \ + "Python Exception <class 'TypeError'>:" \ + "Required argument 'text' (pos 1) not found"]] \ + [string_to_regexp \ + [concat \ + "Error occurred in Python:" \ + "Required argument 'text' (pos 1) not found"]]] +gdb_test "python gdb.warning()" $re1|$re2 diff --git a/gdb/testsuite/gdb.python/py-xmethods.exp b/gdb/testsuite/gdb.python/py-xmethods.exp index 3dafe0e..5863ec5 100644 --- a/gdb/testsuite/gdb.python/py-xmethods.exp +++ b/gdb/testsuite/gdb.python/py-xmethods.exp @@ -26,7 +26,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp index 6b2f671..020fc66 100644 --- a/gdb/testsuite/gdb.python/python.exp +++ b/gdb/testsuite/gdb.python/python.exp @@ -152,29 +152,17 @@ gdb_test_no_output "set height $lines" set test "verify pagination beforehand" gdb_test_multiple "python print (\"\\n\" * $lines)" $test { - -re "--Type <RET>" { - exp_continue - } - -re " for more, q to quit" { - exp_continue - } - -re ", c to continue without paging--$" { + -re "$pagination_prompt$" { pass $test } } gdb_test "q" "Quit.*" "verify pagination beforehand: q" -gdb_test "python if gdb.execute('python print (\"\\\\n\" * $lines)', to_string=True) == \"\\n\" * [expr $lines + 1]: print (\"yes\")" "yes" "gdb.execute does not page" +gdb_test "python if gdb.execute('python print (\"\\\\n\" * $lines)', to_string=True) == \"\\n\" * [expr {$lines + 1}]: print (\"yes\")" "yes" "gdb.execute does not page" set test "verify pagination afterwards" gdb_test_multiple "python print (\"\\n\" * $lines)" $test { - -re "--Type <RET>" { - exp_continue - } - -re " for more, q to quit" { - exp_continue - } - -re ", c to continue without paging--$" { + -re "$pagination_prompt$" { pass $test } } @@ -300,7 +288,7 @@ gdb_test "python gdb.write(\"Foo\\n\")" "Foo" "test default write" gdb_test "python gdb.write(\"Error stream\\n\", stream=gdb.STDERR)" "Error stream" "test stderr write" gdb_test "python gdb.write(\"Normal stream\\n\", stream=gdb.STDOUT)" "Normal stream" "test stdout write" -if ![gdb_debug_enabled] { +if {![gdb_debug_enabled]} { gdb_test "python gdb.write(\"Log stream\\n\", stream=gdb.STDLOG)" "Log stream" "test stdlog write" } diff --git a/gdb/testsuite/gdb.replay/connect.exp b/gdb/testsuite/gdb.replay/connect.exp index 5790d38..b25c372 100644 --- a/gdb/testsuite/gdb.replay/connect.exp +++ b/gdb/testsuite/gdb.replay/connect.exp @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. */ # -# Starts a communication with gdbsever setting the remotelog file. +# Starts a communication with gdbserver setting the remotelog file. # Modifies the remotelog with update_log proc, injects an error message # instead of the expected replay to the vMustReplyEmpty packet in order # to test GDB reacts to the error response properly. After the remotelog @@ -70,9 +70,8 @@ proc_with_prefix record_initial_logfile {} { # Connect to gdbreply using the global REMOTELOG. Runs to a breakpoint # in main. proc_with_prefix replay_without_error {} { - global binfile global remotelog - clean_restart $binfile + clean_restart $::testfile # Make sure we're disconnected, in case we're testing with an # extended-remote board, therefore already connected. gdb_test "disconnect" ".*" @@ -97,7 +96,6 @@ proc_with_prefix replay_without_error {} { # copy of REMOTELOG. Attempt to connect to the remote and expect to see # the error reported by GDB. proc_with_prefix replay_with_mustreplyempty_error {} { - global binfile global remotelog global testfile set newline E.errtext @@ -107,7 +105,7 @@ proc_with_prefix replay_with_mustreplyempty_error {} { # the vMustReplayEmty packet to an error. update_log $remotelog $output_file "vMustReplyEmpty" $newline - clean_restart $binfile + clean_restart $::testfile # Make sure we're disconnected, in case we're testing with an # extended-remote board, therefore already connected. gdb_test "disconnect" ".*" diff --git a/gdb/testsuite/gdb.replay/missing-thread.c b/gdb/testsuite/gdb.replay/missing-thread.c new file mode 100644 index 0000000..8edb240 --- /dev/null +++ b/gdb/testsuite/gdb.replay/missing-thread.c @@ -0,0 +1,61 @@ +/* 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/>. */ + +#include <pthread.h> +#include <assert.h> +#include <signal.h> +#include <stdio.h> +#include <unistd.h> +#include <stdbool.h> + +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t g_condvar = PTHREAD_COND_INITIALIZER; + +void * +worker_function (void *arg) +{ + printf ("In worker, about to notify\n"); + pthread_cond_signal (&g_condvar); + + while (true) + sleep(1); + + return NULL; +} + +int +main() +{ + pthread_t my_thread; + + int result = pthread_create (&my_thread, NULL, worker_function, NULL); + assert (result == 0); + + pthread_mutex_lock (&g_mutex); + pthread_cond_wait (&g_condvar, &g_mutex); + + printf ("In main, have been woken.\n"); + pthread_mutex_unlock (&g_mutex); + + result = pthread_kill (my_thread, SIGTRAP); + assert (result == 0); + + result = pthread_join (my_thread, NULL); + assert (result == 0); + + return 0; +} diff --git a/gdb/testsuite/gdb.replay/missing-thread.exp b/gdb/testsuite/gdb.replay/missing-thread.exp new file mode 100644 index 0000000..6ee2e4c --- /dev/null +++ b/gdb/testsuite/gdb.replay/missing-thread.exp @@ -0,0 +1,237 @@ +# 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/>. */ + +# This test confirms how GDB handles a badly behaving remote target. The +# remote target reports a stop event (signal delivery), then, as GDB is +# processing the stop it syncs the thread list with the remote. +# +# The badly behaving remote target was dropping the signaled thread from the +# thread list at this point, that is, the thread appeared to exit before an +# exit event had been sent to (and seen by) GDB. +# +# At one point this was causing an assertion failed. GDB would try to +# process the signal stop event, and to do this would try to read some +# registers. Reading registers requires a regcache, and GDB will only +# create a regcache for a non-exited thread. + +load_lib gdbserver-support.exp +load_lib gdbreplay-support.exp + +require allow_gdbserver_tests +require has_gdbreplay + +standard_testfile + +if { [build_executable "failed to build exec" $testfile $srcfile {debug pthreads}] } { + return -1 +} + +# Start the inferior and record a remote log for our interaction with it. +# All we do is start the inferior and wait for thread 2 to receive a signal. +# Check that GDB correctly shows the signal as received. LOG_FILENAME is +# where we should write the remote log. +proc_with_prefix record_initial_logfile { log_filename } { + clean_restart $::testfile + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + gdb_test_no_output "set sysroot" \ + "setting sysroot before starting gdbserver" + + # Start gdbserver like: + # gdbserver :PORT .... + set res [gdbserver_start "" $::binfile] + set gdbserver_protocol [lindex $res 0] + set gdbserver_gdbport [lindex $res 1] + + gdb_test_no_output "set remotelogfile $log_filename" \ + "setup remotelogfile" + + # Connect to gdbserver. + if {![gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] == 0} { + unsupported "$testfile (couldn't start gdbserver)" + return + } + + gdb_breakpoint main + gdb_continue_to_breakpoint "continuing to main" + + gdb_test "continue" \ + "Thread $::decimal \[^\r\n\]+ received signal SIGTRAP, .*" + + gdb_test "disconnect" ".*" \ + "disconnect after seeing signal" +} + +# Copy the remote log from IN_FILENAME to OUT_FILENAME, but modify one +# particular line. +# +# The line to be modified is the last <threads>...</threads> line, this is +# the reply from the remote that indicates the thread list. It is expected +# that the thread list will contain two threads. +# +# When DROP_BOTH is true then both threads will be removed from the modified +# line. Otherwise, only the second thread is removed. +proc update_replay_log { in_filename out_filename drop_both } { + # Read IN_FILENAME into a list. + set fd [open $in_filename] + set data [read $fd] + close $fd + set lines [split $data "\n"] + + # Find the last line in LINES that contains the <threads> list. + set idx -1 + for { set i 0 } { $i < [llength $lines] } { incr i } { + if { [regexp "^r.*<threads>.*</threads>" [lindex $lines $i]] } { + set idx $i + } + } + + # Modify the line by dropping the second thread. This does assume + # the thread order as seen in the <threads>...</threads> list, but + # this seems stable for now. + set line [lindex $lines $idx] + set fixed_log false + if {[regexp "^(r .*<threads>\\\\n)(<thread id.*/>\\\\n)(<thread id.*/>\\\\n)(</threads>.*)$" $line \ + match part1 part2 part3 part4]} { + if { $drop_both } { + set line $part1$part4 + } else { + set line $part1$part2$part4 + } + set lines [lreplace $lines $idx $idx $line] + set fixed_log true + } + + # Write all the lines to OUT_FILENAME + set fd [open $out_filename "w"] + foreach l $lines { + puts $fd $l + } + close $fd + + # Did we manage to update the log file? + return $fixed_log +} + +# Replay the test process using REMOTE_LOG as the logfile to replay. If +# EXPECT_ERROR is true then after the final 'continue' we expect GDB to give +# an error as the required thread is missing. When EXPECT_ERROR is false +# then we expect the test to complete as normal. NON_STOP is eithe 'on' or +# 'off' and indicates GDBs non-stop mode. +proc_with_prefix replay_with_log { remote_log expect_error non_stop } { + clean_restart $::testfile + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + gdb_test_no_output "set sysroot" + + set res [gdbreplay_start $remote_log] + set gdbserver_protocol [lindex $res 0] + set gdbserver_gdbport [lindex $res 1] + + # Connect to gdbserver. + if {![gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] == 0} { + fail "couldn't connect to gdbreplay" + return + } + + gdb_breakpoint main + gdb_continue_to_breakpoint "continuing to main" + + if { $expect_error } { + set expected_output \ + [list \ + "\\\[Thread \[^\r\n\]+ exited\\\]" \ + "warning: command aborted, Thread \[^\r\n\]+ unexpectedly exited after signal stop event"] + + if { !$non_stop } { + lappend expected_output "\\\[Switching to Thread \[^\r\n\]+\\\]" + } + + gdb_test "continue" [multi_line {*}$expected_output] + } else { + # This is the original behaviour, we see this when running + # with the unmodified log. + gdb_test "continue" \ + "Thread ${::decimal}(?: \[^\r\n\]+)? received signal SIGTRAP, .*" + } + + gdb_test "disconnect" ".*" \ + "disconnect after seeing signal" +} + +# Run the complete test cycle; generate an initial log file, modify the log +# file, then check that GDB correctly handles replaying the modified log +# file. +# +# NON_STOP is either 'on' or 'off' and indicates GDB's non-stop mode. +proc run_test { non_stop } { + if { $non_stop } { + set suffix "-ns" + } else { + set suffix "" + } + + # The replay log is placed in 'replay.log'. + set remote_log [standard_output_file replay${suffix}.log] + set missing_1_log [standard_output_file replay-missing-1${suffix}.log] + set missing_2_log [standard_output_file replay-missing-2${suffix}.log] + + record_initial_logfile $remote_log + + if { ![update_replay_log $remote_log $missing_1_log false] } { + fail "couldn't update remote replay log (drop 1 case)" + } + + if { ![update_replay_log $remote_log $missing_2_log true] } { + fail "couldn't update remote replay log (drop 2 case)" + } + + with_test_prefix "with unmodified log" { + # Replay with the unmodified log. This confirms that we can replay this + # scenario correctly. + replay_with_log $remote_log false $non_stop + } + + with_test_prefix "missing 1 thread log" { + # Now replay with the modified log, this time the thread that receives + # the event should be missing from the thread list, GDB will give an + # error when the inferior stops. + replay_with_log $missing_1_log true $non_stop + } + + with_test_prefix "missing 2 threads log" { + # When we drop both threads from the <threads> reply, GDB doesn't + # actually remove both threads from the inferior; an inferior must + # always have at least one thread. So in this case, as the primary + # thread is first, GDB drops this, then retains the second thread, which + # is the one we're stopping in, and so, we don't expect to see the error + # in this case. + replay_with_log $missing_2_log false $non_stop + } +} + +# Run the test twice, with non-stop on and off. +foreach_with_prefix non_stop { on off } { + save_vars { ::GDBFLAGS } { + append ::GDBFLAGS " -ex \"set non-stop $non_stop\"" + run_test $non_stop + } +} diff --git a/gdb/testsuite/gdb.reverse/aarch64-mops.exp b/gdb/testsuite/gdb.reverse/aarch64-mops.exp index 0f447a6..797a0c2 100644 --- a/gdb/testsuite/gdb.reverse/aarch64-mops.exp +++ b/gdb/testsuite/gdb.reverse/aarch64-mops.exp @@ -40,7 +40,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp b/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp index 56ebb92..b5878f0 100644 --- a/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp +++ b/gdb/testsuite/gdb.reverse/amd64-tailcall-reverse.exp @@ -18,7 +18,7 @@ require supports_reverse set opts {} standard_testfile .S -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.reverse/amd64-tailcall-reverse.exp COMPILE=1" standard_testfile lappend opts debug optimize=-O2 @@ -30,11 +30,11 @@ if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $opts] } { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } -if [supports_process_record] { +if {[supports_process_record]} { gdb_test_no_output "record" } diff --git a/gdb/testsuite/gdb.reverse/break-reverse.exp b/gdb/testsuite/gdb.reverse/break-reverse.exp index 02c38ac..6db7ce1 100644 --- a/gdb/testsuite/gdb.reverse/break-reverse.exp +++ b/gdb/testsuite/gdb.reverse/break-reverse.exp @@ -31,7 +31,7 @@ set end_location [gdb_get_line_number "end of main" ] runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/consecutive-precsave.exp b/gdb/testsuite/gdb.reverse/consecutive-precsave.exp index 2cb139d..3ccff48 100644 --- a/gdb/testsuite/gdb.reverse/consecutive-precsave.exp +++ b/gdb/testsuite/gdb.reverse/consecutive-precsave.exp @@ -79,7 +79,7 @@ set testmsg "stopped at bp, 2nd instr" gdb_test_multiple "step" $testmsg { -re -wrap "Breakpoint $decimal, ($hex) in foo.*" { set stop_addr $expect_out(1,string) - if {[eval expr "$foo2_addr == $stop_addr"]} { + if {$foo2_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" @@ -90,7 +90,7 @@ gdb_test_multiple "step" $testmsg { set stop_addr_is_stmt [hex_in_list $stop_addr $is_stmt] if { ! $stop_addr_is_stmt } { fail "stopped at bp, 2nd instr (missing hex prefix)" - } elseif {[eval expr "$foo2_addr == $stop_addr"]} { + } elseif {$foo2_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" @@ -112,7 +112,7 @@ set test_msg "stopped at bp in reverse, 1st instr" gdb_test_multiple "step" "$test_msg" { -re "Breakpoint $decimal, ($hex) in foo.*$gdb_prompt $" { set stop_addr $expect_out(1,string) - if {[eval expr "$foo1_addr == $stop_addr"]} { + if {$foo1_addr == $stop_addr} { pass "$test_msg" } else { fail "$test_msg (wrong address)" diff --git a/gdb/testsuite/gdb.reverse/consecutive-reverse.exp b/gdb/testsuite/gdb.reverse/consecutive-reverse.exp index 27f2b72..7434efb 100644 --- a/gdb/testsuite/gdb.reverse/consecutive-reverse.exp +++ b/gdb/testsuite/gdb.reverse/consecutive-reverse.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } @@ -61,7 +61,7 @@ set testmsg "stopped at bp, 2nd instr" gdb_test_multiple "step" $testmsg { -re -wrap "Breakpoint $decimal, ($hex) in foo.*" { set stop_addr $expect_out(1,string) - if {[eval expr "$foo2_addr == $stop_addr"]} { + if {$foo2_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" @@ -72,7 +72,7 @@ gdb_test_multiple "step" $testmsg { set stop_addr_is_stmt [hex_in_list $stop_addr $is_stmt] if { ! $stop_addr_is_stmt } { fail "stopped at bp, 2nd instr (missing hex prefix)" - } elseif {[eval expr "$foo2_addr == $stop_addr"]} { + } elseif {$foo2_addr == $stop_addr} { pass "stopped at bp, 2nd instr" } else { fail "stopped at bp, 2nd instr (wrong address)" @@ -94,7 +94,7 @@ set test_msg "stopped at bp in reverse, 1st instr" gdb_test_multiple "step" "$test_msg" { -re "Breakpoint $decimal, ($hex) in foo.*$gdb_prompt $" { set stop_addr $expect_out(1,string) - if {[eval expr "$foo1_addr == $stop_addr"]} { + if {$foo1_addr == $stop_addr} { pass "$test_msg" } else { fail "$test_msg (wrong address)" diff --git a/gdb/testsuite/gdb.reverse/finish-precsave.exp b/gdb/testsuite/gdb.reverse/finish-precsave.exp index 596b40d..2e76a46 100644 --- a/gdb/testsuite/gdb.reverse/finish-precsave.exp +++ b/gdb/testsuite/gdb.reverse/finish-precsave.exp @@ -27,12 +27,12 @@ if { [prepare_for_testing "failed to prepare" "$testfile" $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } -# Run until end, then save execution log. +# Run until end, then save execution log. set breakloc [gdb_get_line_number "end of main" "$srcfile"] gdb_test "break $breakloc" \ diff --git a/gdb/testsuite/gdb.reverse/finish-reverse-bkpt.exp b/gdb/testsuite/gdb.reverse/finish-reverse-bkpt.exp index 1e92252..586d236 100644 --- a/gdb/testsuite/gdb.reverse/finish-reverse-bkpt.exp +++ b/gdb/testsuite/gdb.reverse/finish-reverse-bkpt.exp @@ -52,7 +52,7 @@ if {![runto_main]} { return 0 } -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/finish-reverse-next.exp b/gdb/testsuite/gdb.reverse/finish-reverse-next.exp index f744e9c..07ba30c 100644 --- a/gdb/testsuite/gdb.reverse/finish-reverse-next.exp +++ b/gdb/testsuite/gdb.reverse/finish-reverse-next.exp @@ -41,7 +41,7 @@ # test only verified the reverse-finish command for a normal call that used # the LEP. -if ![supports_reverse] { +if {![supports_reverse]} { return } @@ -53,7 +53,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay. gdb_test_no_output "record" "turn on process record for test1" } diff --git a/gdb/testsuite/gdb.reverse/finish-reverse.exp b/gdb/testsuite/gdb.reverse/finish-reverse.exp index f90a79f..ff28bd8 100644 --- a/gdb/testsuite/gdb.reverse/finish-reverse.exp +++ b/gdb/testsuite/gdb.reverse/finish-reverse.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" "$testfile" $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/fstatat-reverse.exp b/gdb/testsuite/gdb.reverse/fstatat-reverse.exp index 76bd8a2..db2f5dc 100644 --- a/gdb/testsuite/gdb.reverse/fstatat-reverse.exp +++ b/gdb/testsuite/gdb.reverse/fstatat-reverse.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/getrandom.exp b/gdb/testsuite/gdb.reverse/getrandom.exp index 62640af..2756fa3 100644 --- a/gdb/testsuite/gdb.reverse/getrandom.exp +++ b/gdb/testsuite/gdb.reverse/getrandom.exp @@ -30,7 +30,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/getresuid-reverse.exp b/gdb/testsuite/gdb.reverse/getresuid-reverse.exp index 5ff0f2b..37d070d 100644 --- a/gdb/testsuite/gdb.reverse/getresuid-reverse.exp +++ b/gdb/testsuite/gdb.reverse/getresuid-reverse.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index a37b65a..bf6cb77 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -30,6 +30,18 @@ char global_buf1[] = {0, 0, 0, 0, 0, 0, 0, 0, char *dyn_buf0; char *dyn_buf1; + /* Zero memory regions again, so that future tests can update them + without worry. */ +void +reset_buffers () +{ + for (int i = 0; i < 32; i++) + { + global_buf1[i] = 0; + dyn_buf1[i] = 0; + } +} + int vmov_test () { @@ -168,6 +180,22 @@ vmov_test () asm volatile ("vmovapd %%xmm0, %0" : : "m"(*dyn_buf1)); asm volatile ("vmovaps %%ymm15, %0" : : "m"(*dyn_buf1)); + /* Testing vmov[hl|lh]ps and vmov[h|l]pd. */ + asm volatile ("vmovhlps %xmm1, %xmm8, %xmm0"); + asm volatile ("vmovhlps %xmm1, %xmm2, %xmm15"); + asm volatile ("vmovlhps %xmm1, %xmm8, %xmm0"); + asm volatile ("vmovlhps %xmm1, %xmm2, %xmm15"); + + asm volatile ("vmovhps %0, %%xmm1, %%xmm0" : : "m"(buf0)); + asm volatile ("vmovhps %%xmm0, %0" : "=m" (buf1)); + asm volatile ("vmovhpd %0, %%xmm1, %%xmm15" : : "m"(global_buf0)); + asm volatile ("vmovhpd %%xmm15, %0" : "=m" (global_buf1)); + asm volatile ("vmovlpd %0, %%xmm1, %%xmm15" : : "m"(*dyn_buf0)); + asm volatile ("vmovlpd %%xmm15, %0" : "=m" (*dyn_buf1)); + + asm volatile ("vmovddup %xmm1, %xmm15"); + asm volatile ("vmovddup %ymm2, %ymm0"); + /* We have a return statement to deal with epilogue in different compilers. */ return 0; /* end vmov_test */ @@ -245,7 +273,7 @@ vpunpck_test () return 0; /* end vpunpck_test */ } -/* Test if we can record vpbroadcast instructions. */ +/* Test if we can record vpbroadcast and vbroadcast instructions. */ int vpbroadcast_test () { @@ -268,6 +296,14 @@ vpbroadcast_test () asm volatile ("vpbroadcastq %xmm1, %ymm0"); asm volatile ("vpbroadcastq %xmm1, %ymm15"); + asm volatile ("vbroadcastss %xmm1, %xmm0"); + asm volatile ("vbroadcastss %xmm1, %ymm15"); + asm volatile ("vbroadcastss %0, %%ymm0" : : "m" (global_buf0)); + asm volatile ("vbroadcastss %0, %%xmm15": : "m" (*dyn_buf0)); + asm volatile ("vbroadcastsd %xmm1, %ymm0"); + asm volatile ("vbroadcastsd %0, %%ymm15": : "m" (global_buf0)); + asm volatile ("vbroadcastf128 %0, %%ymm0" : : "m" (*dyn_buf0)); + /* We have a return statement to deal with epilogue in different compilers. */ return 0; /* end vpbroadcast_test */ @@ -372,6 +408,7 @@ arith_test () /* Using GDB, load these values onto registers for testing. ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5} ymm1.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5} + ymm2.v2_int128 = {0x0, 0x0} ymm15.v2_int128 = {0x0, 0x0} this way it's easy to confirm we're undoing things correctly. */ asm volatile ("vaddps %xmm0, %xmm1, %xmm15"); @@ -416,9 +453,318 @@ arith_test () asm volatile ("vmaxss %xmm0, %xmm1, %xmm15"); asm volatile ("vmaxsd %xmm0, %xmm1, %xmm15"); + /* Some sanity checks for other arithmetic instructions. */ + asm volatile ("vpaddb %xmm0, %xmm1, %xmm2"); + asm volatile ("vpaddw %xmm0, %xmm1, %xmm15"); + asm volatile ("vpaddd %ymm0, %ymm1, %ymm2"); + asm volatile ("vpaddq %ymm0, %ymm1, %ymm15"); + + asm volatile ("vpmullw %xmm0, %xmm1, %xmm2"); + asm volatile ("vpmulld %xmm0, %xmm1, %xmm15"); + asm volatile ("vpmulhw %ymm0, %ymm1, %ymm2"); + asm volatile ("vpmulhuw %ymm0, %ymm1, %ymm15"); + asm volatile ("vpmuludq %ymm0, %ymm1, %ymm15"); + + asm volatile ("vxorps %xmm0, %xmm1, %xmm2"); + asm volatile ("vxorpd %ymm0, %ymm1, %ymm2"); + asm volatile ("vpand %xmm0, %xmm1, %xmm15"); + asm volatile ("vpandn %ymm0, %ymm1, %ymm15"); + + asm volatile ("vpsadbw %xmm0, %xmm1, %xmm2"); + asm volatile ("vpsadbw %ymm0, %ymm1, %ymm15"); + return 0; /* end arith_test */ } +int +vaddsubpd_test () +{ + /* start vaddsubpd_test */ + /* YMM test. */ + asm volatile ("vaddsubpd %ymm15,%ymm1,%ymm0"); + asm volatile ("vaddsubpd %ymm0,%ymm1,%ymm15"); + asm volatile ("vaddsubpd %ymm2,%ymm3,%ymm4"); + + /* XMM test. */ + asm volatile ("vaddsubpd %xmm15,%xmm1,%xmm2"); + asm volatile ("vaddsubpd %xmm0,%xmm1,%xmm10"); + return 0; /* end vaddsubpd_test */ +} + +int +vaddsubps_test () +{ + /* start vaddsubps_test */ + /* YMM test. */ + asm volatile ("vaddsubps %ymm15,%ymm1,%ymm2"); + asm volatile ("vaddsubps %ymm0,%ymm1,%ymm10"); + asm volatile ("vaddsubps %ymm2,%ymm3,%ymm4"); + + /* XMM test. */ + asm volatile ("vaddsubps %xmm0,%xmm1,%xmm15"); + asm volatile ("vaddsubps %xmm15,%xmm1,%xmm0"); + return 0; /* end vaddsubps_test */ +} + + +/* Test record shifting instructions. */ +int +shift_test () +{ + /* start shift_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v2_int128 = {0, 0} + ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16} + xmm2.uint128 = 1 + ymm15.v2_int128 = {0x0, 0x0} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vpsllw $1, %xmm1, %xmm0"); + asm volatile ("vpsllw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpslld $3, %ymm1, %ymm15"); + asm volatile ("vpslld %xmm2, %xmm1, %xmm15"); + asm volatile ("vpsllq $5, %xmm1, %xmm15"); + asm volatile ("vpsllq %xmm2, %ymm1, %ymm15"); + + asm volatile ("vpsraw $1, %xmm1, %xmm0"); + asm volatile ("vpsraw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpsrad $3, %ymm1, %ymm15"); + asm volatile ("vpsrad %xmm2, %xmm1, %xmm15"); + + asm volatile ("vpsrlw $1, %xmm1, %xmm0"); + asm volatile ("vpsrlw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpsrld $3, %ymm1, %ymm15"); + asm volatile ("vpsrld %xmm2, %xmm1, %xmm15"); + asm volatile ("vpsrlq $5, %xmm1, %xmm15"); + asm volatile ("vpsrlq %xmm2, %ymm1, %ymm15"); + + /* The dq version is treated separately in the manual, so + we test it separately just to be sure. */ + asm volatile ("vpslldq $1, %xmm1, %xmm0"); + asm volatile ("vpslldq $2, %ymm1, %ymm0"); + asm volatile ("vpslldq $3, %xmm1, %xmm15"); + asm volatile ("vpslldq $4, %ymm1, %ymm15"); + + asm volatile ("vpsrldq $1, %xmm1, %xmm0"); + asm volatile ("vpsrldq $2, %ymm1, %ymm0"); + asm volatile ("vpsrldq $3, %xmm1, %xmm15"); + asm volatile ("vpsrldq $4, %ymm1, %ymm15"); + + return 0; /* end shift_test */ +} + +int +shuffle_test () +{ + /* start shuffle_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v2_int128 = {0, 0} + ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16} + ymm2.v16_int15 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32} + ymm15.v2_int128 = {0x0, 0x0} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vpshufb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpshufb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpshufd $1, %ymm2, %ymm0"); + asm volatile ("vpshufd $2, %xmm2, %xmm15"); + + asm volatile ("vpshufhw $3, %xmm2, %xmm0"); + asm volatile ("vpshufhw $4, %ymm2, %ymm15"); + asm volatile ("vpshuflw $5, %ymm2, %ymm0"); + asm volatile ("vpshuflw $6, %xmm2, %xmm15"); + + asm volatile ("vshufps $1, %xmm1, %xmm2, %xmm0"); + asm volatile ("vshufps $2, %ymm1, %ymm2, %ymm15"); + asm volatile ("vshufpd $4, %ymm1, %ymm2, %ymm0"); + asm volatile ("vshufpd $8, %xmm1, %xmm2, %xmm15"); + + return 0; /* end shuffle_test */ +} + +int +permute_test () +{ + /* start permute_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v2_int128 = {0, 0} + ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16} + ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32} + ymm15.v2_int128 = {0x0, 0x0} + eax = 0 + this way it's easy to confirm we're undoing things correctly. */ + asm volatile ("vperm2f128 $1, %ymm1, %ymm2, %ymm0"); + asm volatile ("vperm2f128 $0, %ymm1, %ymm2, %ymm15"); + asm volatile ("vperm2i128 $1, %ymm2, %ymm1, %ymm0"); + asm volatile ("vperm2i128 $0, %ymm2, %ymm1, %ymm15"); + + asm volatile ("vpermd %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermd %ymm1, %ymm2, %ymm15"); + asm volatile ("vpermq $1, %ymm1, %ymm0"); + asm volatile ("vpermq $0, %ymm2, %ymm15"); + + asm volatile ("vpermilpd %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermilpd %xmm1, %xmm2, %xmm15"); + asm volatile ("vpermilpd $1, %ymm2, %ymm15"); + asm volatile ("vpermilpd $0, %xmm2, %xmm0"); + asm volatile ("vpermilps %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermilps %xmm1, %xmm2, %xmm15"); + asm volatile ("vpermilps $1, %ymm2, %ymm15"); + asm volatile ("vpermilps $0, %xmm2, %xmm0"); + + asm volatile ("vpermpd $0, %ymm1, %ymm15"); + asm volatile ("vpermpd $0, %ymm2, %ymm0"); + asm volatile ("vpermps %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermps %ymm1, %ymm2, %ymm15"); + + return 0; /* end permute_test */ +} + +int +extract_insert_test () +{ + /* start extract_insert_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v2_int128 = {0, 0} + ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16} + xmm2.uint128 = 0xcafe + ymm15.v2_int128 = {0x0, 0x0} + eax = 0 + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vinserti128 $1, %xmm2, %ymm1, %ymm0"); + asm volatile ("vinsertf128 $0, %xmm2, %ymm1, %ymm15"); + asm volatile ("vextracti128 $1, %ymm1, %xmm0"); + asm volatile ("vextractf128 $0, %ymm1, %xmm15"); + asm volatile ("vinsertps $16, %xmm2, %xmm1, %xmm0"); + asm volatile ("vextractps $0, %xmm2, %rax"); + + asm volatile ("vpextrb $5, %xmm1, %rax"); + asm volatile ("vpextrb $4, %%xmm1, %0" : "=m" (global_buf1)); + asm volatile ("vpextrd $3, %xmm1, %eax"); + asm volatile ("vpextrd $2, %%xmm1, %0" : "=m" (global_buf1)); + asm volatile ("vpextrq $1, %xmm1, %rax"); + asm volatile ("vpextrq $0, %%xmm1, %0" : "=m" (global_buf1)); + + asm volatile ("vpinsrb $3, %rax, %xmm2, %xmm0"); + asm volatile ("vpinsrw $2, %eax, %xmm2, %xmm15"); + asm volatile ("vpinsrd $1, %eax, %xmm2, %xmm0"); + asm volatile ("vpinsrq $0, %rax, %xmm2, %xmm15"); + + /* vpextrw has completely different mechanics to other vpextr + instructions, so separate them for ease of testing later. */ + asm volatile ("vpextrw $1, %xmm1, %eax"); + asm volatile ("vpextrw $1, %%xmm1, %0" : "=m" (global_buf1)); + + return 0; /* end extract_insert_test */ +} + +int +blend_test () +{ + /* start blend_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v2_int128 = {0, 0} + ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16} + ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32} + ymm15.v2_int128 = {0x0, 0x0} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vblendps $5, %xmm1, %xmm2, %xmm0"); + asm volatile ("vblendpd $10, %ymm1, %ymm2, %ymm15"); + asm volatile ("vblendvps %ymm15, %ymm1, %ymm2, %ymm0"); + asm volatile ("vblendvpd %xmm0, %xmm1, %xmm2, %xmm15"); + + asm volatile ("vpblendw $94, %ymm1, %ymm2, %ymm15"); + asm volatile ("vpblendw $47, %xmm1, %xmm2, %xmm0"); + asm volatile ("vpblendd $22, %ymm1, %ymm2, %ymm0"); + asm volatile ("vpblendd $11, %xmm1, %xmm2, %xmm15"); + asm volatile ("vpblendvb %xmm0, %xmm1, %xmm2, %xmm15"); + asm volatile ("vpblendvb %ymm0, %ymm1, %ymm2, %ymm0"); + + return 0; /* end blend_test */ +} + +int +compare_test () +{ + /* start compare_test. */ + /* Using GDB, load these values onto registers for testing. + xmm0.v4_float = {0, 1.5, 2, 0} + xmm1.v4_float = {0, 1, 2.5, -1} + xmm15.v4_float = {-1, -2, 10, 100} + eflags = 2 + eflags can't be set to some values, if we set it to 0, it'll + be reset to 2, so set it to that directly to make results less + confusing. + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vcomisd %xmm0, %xmm1"); + asm volatile ("vcomiss %xmm15, %xmm1"); + asm volatile ("vucomiss %xmm1, %xmm15"); + asm volatile ("vucomisd %xmm15, %xmm0"); + + return 0; /* end compare_test */ +} + +int +pack_test () +{ + /* start pack_test. */ + /* Using GDB, load these values onto registers for testing. + xmm0.v4_float = {0, 1.5, 2, 0} + xmm1.v4_float = {0, 1, 2.5, -1} + xmm2.v4_float = {0, 1, 2.5, -1} + xmm15.v4_float = {-1, -2, 10, 100} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vpacksswb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpacksswb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpackssdw %xmm1, %xmm2, %xmm15"); + asm volatile ("vpackssdw %ymm1, %ymm2, %ymm0"); + asm volatile ("vpackuswb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpackuswb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpackusdw %xmm1, %xmm2, %xmm15"); + asm volatile ("vpackusdw %ymm1, %ymm2, %ymm0"); + + return 0; /* end pack_test */ +} + +int +convert_test () +{ + /* start convert_test. */ + /* Using GDB, load these values onto registers for testing. + xmm0.v2_int128 = {0, 0} + xmm1.v4_float = {0, 1, 2.5, 10} + xmm15.v2_int128 = {0, 0} + ecx = -1 + ebx = 0 + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vcvtdq2ps %xmm1, %xmm0"); + asm volatile ("vcvtdq2pd %xmm1, %xmm15"); + + asm volatile ("vcvtps2dq %xmm1, %xmm15"); + asm volatile ("vcvtps2pd %xmm1, %xmm0"); + asm volatile ("vcvtpd2ps %xmm1, %xmm15"); + asm volatile ("vcvtpd2dq %xmm1, %xmm0"); + + asm volatile ("vcvtsd2si %xmm1, %rbx"); + asm volatile ("vcvtsd2ss %xmm0, %xmm1, %xmm15"); + asm volatile ("vcvtsi2sd %rcx, %xmm1, %xmm0"); + asm volatile ("vcvtsi2ss %rcx, %xmm1, %xmm15"); + asm volatile ("vcvtss2sd %xmm15, %xmm1, %xmm0"); + asm volatile ("vcvtss2si %xmm1, %rbx"); + + asm volatile ("vcvttpd2dq %xmm1, %xmm0"); + asm volatile ("vcvttps2dq %xmm1, %xmm15"); + asm volatile ("vcvttsd2si %xmm0, %rbx"); + asm volatile ("vcvttss2si %xmm1, %ecx"); + + return 0; /* end convert_test */ +} + /* This include is used to allocate the dynamic buffer and have the pointers aligned to a 32-bit boundary, so we can test instructions that require aligned memory. */ @@ -442,6 +788,7 @@ main () asm volatile ("vmovq %0, %%xmm15": : "m" (global_buf1)); vmov_test (); + reset_buffers (); vpunpck_test (); vpbroadcast_test (); vzeroupper_test (); @@ -449,5 +796,15 @@ main () vpcmpeq_test (); vpmovmskb_test (); arith_test (); + vaddsubpd_test (); + vaddsubps_test (); + shift_test (); + shuffle_test (); + permute_test (); + extract_insert_test (); + blend_test (); + compare_test (); + pack_test (); + convert_test (); return 0; /* end of main */ } diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp index 0ff56dd..b3550e2 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -109,7 +109,7 @@ proc record_full_function {function} { gdb_breakpoint $end temporary gdb_continue_to_breakpoint "start ${function}_test" - if [supports_process_record] { + if {[supports_process_record]} { # Activate process record/replay. gdb_test_no_output "record" "${function}: turn on process record" } @@ -149,6 +149,33 @@ global decimal if {[record_full_function "vmov"] == true} { # Now execute backwards, checking all instructions. + test_one_register "vmovddup" "ymm0" \ + "0x3736353433323130c004000000000000, 0x0" + test_one_register "vmovddup" "ymm15" \ + "0x2726252423222120, 0x0" + test_one_memory "vmovlpd" "dyn_buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28" \ + true + test_one_register "vmovlpd" "ymm15" \ + "0x1716151413121110c004000000000000, 0x0" + test_one_memory "vmovhpd" "global_buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18" + test_one_register "vmovhpd" "ymm15" \ + "0xc004000000000000c004000000000000, 0x0" + test_one_memory "vmovhps" "buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38" + test_one_register "vmovhps" "ymm0" \ + "0xc004000000000000c004000000000000, 0x0" + + test_one_register "vmovlhps" "ymm15" \ + "0x0, 0x0" + test_one_register "vmovlhps" "ymm0" \ + "0x0, 0x0" + test_one_register "vmovhlps" "ymm15" \ + "0x2f2e2d2c2b2a29280000000000000000, 0x2f2e2d2c2b2a29282726252423222120" + test_one_register "vmovhlps" "ymm0" \ + "0x2f2e2d2c2b2a29282726252423222120, 0x0" + # Explicitly test for the start of the array, since the value repeats. test_one_memory "vmovaps" "dyn_buf1" \ "\\\{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28" true @@ -365,6 +392,24 @@ gdb_test_no_output "set \$xmm1.v2_int64 = {0x1716151413121110, 0x1f1e1d1c1b1a191 "set xmm1 for vpbroadcast" gdb_test_no_output "set \$ymm15.v2_int128 = {0x0, 0x0}" "set xmm15 for vpbroadcast" if {[record_full_function "vpbroadcast"] == true} { + test_one_register "vbroadcastf128" "ymm0" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vbroadcastsd" "ymm15" \ + "0x23222120232221202322212023222120, 0x0" + test_one_register "vbroadcastsd" "ymm0" \ + "0x13121110131211101312111013121110, 0x13121110131211101312111013121110" + + test_one_register "vbroadcastss" "ymm15" \ + "0x13121110131211101312111013121110, 0x13121110131211101312111013121110" \ + "broadcast from memory" + test_one_register "vbroadcastss" "ymm0" \ + "0x13121110131211101312111013121110, 0x0" \ + "broadcast from memory" + test_one_register "vbroadcastss" "ymm15" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vbroadcastss" "ymm0" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vpbroadcastq" "ymm15" "0x13121110131211101312111013121110, 0x0" test_one_register "vpbroadcastq" "ymm0" "0x13121110131211101312111013121110, 0x0" @@ -397,7 +442,7 @@ gdb_test_no_output "set \$ymm15.v2_int128 = {0x0, 0xcafeface}" "set ymm15 for vp if {[record_full_function "vzeroupper"] == true} { # Since vzeroupper needs to save 8 or 16 registers, let's check what was # actually recorded, instead of just undoing an instruction. Only - # really check the values of egisters 0, 1, 2 and 15 because those are + # really check the values of registers 0, 1, 2 and 15 because those are # the only ones we're setting. gdb_test "maint print record-instruction" \ [multi_line "Register ymm0h changed: 74565" \ @@ -527,9 +572,43 @@ gdb_test_no_output \ "set \$ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5}" gdb_test_no_output \ "set \$ymm1.v8_float = {0, 1, 2, 3, 4, 5, 6, 7}" +gdb_test_no_output "set \$ymm2.v2_int128 = {0,0}" gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" if {[record_full_function "arith"] == true} { + test_one_register "vpsadbw" "ymm15" \ + "0x20000000200000004000003f000000, 0x100000001000000010000000100000" + test_one_register "vpsadbw" "ymm2" \ + "0x20000000200000004000003f000000, 0x100000001000000010000000100000" + test_one_register "vpandn" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" + test_one_register "vpand" "ymm15" \ + "0x10080000000000000000000000000000, 0x10649c00000000001044480000000000" + test_one_register "vxorpd" "ymm2" \ + "0x20000000200000004000003f000000, 0x0" + test_one_register "vxorps" "ymm2" \ + "0x10280000100800000fd0000000000000, 0x10740000106400001054000010440000" + + test_one_register "vpmuludq" "ymm15" \ + "0x10280000100800000fd0000000000000, 0x10740000106400001054000010440000" + test_one_register "vpmulhuw" "ymm15" \ + "0x0, 0x0" + test_one_register "vpmulhw" "ymm2" \ + "0x18000000000000002000000000000000, 0x0" + test_one_register "vpmulld" "ymm15" \ + "0x80a00000802000007f4000003f000000, 0x81d00000819000008150000081100000" + test_one_register "vpmullw" "ymm2" \ + "0x80a00000802000007f4000003f000000, 0x81d00000819000008150000081100000" + + test_one_register "vpaddq" "ymm15" \ + "0x80a00000802000007f4000003f000000, 0x0" + test_one_register "vpaddd" "ymm2" \ + "0x80a00000802000007e4000003f000000, 0x0" + test_one_register "vpaddw" "ymm15" \ + "0x40400000400000003fc000003f000000, 0x0" + test_one_register "vpaddb" "ymm2" \ + "0x0, 0x0" + test_one_register "vmaxsd" "ymm15" \ "0x40400000400000003f8000003f000000, 0x0" "ymm operation: " test_one_register "vmaxss" "ymm15" \ @@ -626,3 +705,493 @@ if {[record_full_function "arith"] == true} { } gdb_test "finish" "Run till exit from.*arith_test.*" \ "leaving arith" + +# Preparation and testing vaddsubpd instructions + +gdb_test_no_output "set \$ymm15.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm15 for vaddsubpd" +gdb_test_no_output "set \$ymm0.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm0 for vaddsubpd" +gdb_test_no_output "set \$xmm2.uint128 = 0xbeef" \ + "set xmm2 for vaddsubpd" +gdb_test_no_output "set \$xmm10.uint128 = 0xbeef" \ + "set xmm10 for vaddsubpd" +gdb_test_no_output "set \$ymm3.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm3 for vaddsubpd" +gdb_test_no_output "set \$ymm4.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm4 for vaddsubpd" + +if {[record_full_function "vaddsubpd"] == true} { + test_one_register "vaddsubpd" "xmm10" \ + "0xbeef" "xmm10:" + test_one_register "vaddsubpd" "xmm2" \ + "0xbeef" "xmm2:" + test_one_register "vaddsubpd" "ymm4" \ + "0xcafeface, 0xcafeface" "ymm4: " + test_one_register "vaddsubpd" "ymm15" \ + "0xcafeface, 0xcafeface" "ymm15: " + test_one_register "vaddsubpd" "ymm0" \ + "0xcafeface, 0xcafeface" "ymm0: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for vaddsubpd_test" +} else { + untested "couldn't run vaddsubpd tests" +} +gdb_test "finish" "Run till exit from.*vaddsubpd_test.*" \ + "leaving vaddsubpd" + +# Preparation and testing vaddsubps instruction + +gdb_test_no_output "set \$ymm10.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm10 for vaddsubps" +gdb_test_no_output "set \$ymm2.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm2 for vaddsubps" +gdb_test_no_output "set \$xmm15.uint128 = 0xbeef" \ + "set xmm15 for vaddsubps" +gdb_test_no_output "set \$xmm0.uint128 = 0xbeef" \ + "set xmm0 for vaddsubps" +gdb_test_no_output "set \$ymm3.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm3 for vaddsubps" +gdb_test_no_output "set \$ymm4.v2_int128 = {0xcafeface, 0xcafeface}" \ + "set ymm4 for vaddsubps" + +if {[record_full_function "vaddsubps"] == true} { + test_one_register "vaddsubps" "xmm0" \ + "0xbeef" "xmm0: " + test_one_register "vaddsubps" "xmm15" \ + "0xbeef" "xmm15: " + test_one_register "vaddsubps" "ymm4" \ + "0xcafeface, 0xcafeface" "ymm4: " + test_one_register "vaddsubps" "ymm10" \ + "0xcafeface, 0xcafeface" "ymm10: " + test_one_register "vaddsubps" "ymm2" \ + "0xcafeface, 0xcafeface" "ymm2: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for vaddsubps_test" +} else { + untested "couldn't run vaddsubps tests" +} +gdb_test "finish" "Run till exit from.*vaddsubps_test.*" \ + "leaving vaddsubps" + +# Preparation and testing shifting instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for shift" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \ + "set ymm1 for shift" +gdb_test_no_output "set \$xmm2.uint128 = 1" "set ymm2 for shift" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for shift" + +if {[record_full_function "shift"] == true} { + test_one_register "vpsrldq" "ymm15" \ + "0x80007000600050004000300, 0x0" \ + "High ymm register: " + test_one_register "vpsrldq" "ymm15" \ + "0x60005000400030002000100000000, 0xe000d000c000b000a000900000000" \ + "High xmm register: " + test_one_register "vpsrldq" "ymm0" \ + "0x800070006000500040003000200, 0x0" \ + "Low ymm register: " + test_one_register "vpsrldq" "ymm0" \ + "0x70006000500040003000200010000, 0xf000e000d000c000b000a00090000" \ + "Low xmm register: " + + test_one_register "vpslldq" "ymm15" \ + "0x7000600050004000300020001000000, 0x0" \ + "High ymm register: " + test_one_register "vpslldq" "ymm15" \ + "0x40003800300020002000180010000, 0x80007800700060006000580050004" \ + "High xmm register: " + test_one_register "vpslldq" "ymm0" \ + "0x8000700060005000400030002000100, 0x0" \ + "Low ymm register: " + test_one_register "vpslldq" "ymm0" \ + "0x40003000300020002000100010000, 0x80007000700060006000500050004" \ + "Low xmm register: " + + test_one_register "vpsrlq" "ymm15" \ + "0x4000380030000000200018001000, 0x0" \ + "from register: " + test_one_register "vpsrlq" "ymm15" \ + "0x40003000300020002000100010000, 0x0" \ + "from constant: " + test_one_register "vpsrld" "ymm15" \ + "0x100000000c0000000800000004000, 0x200010001c0010001800100014001" \ + "from register: " + test_one_register "vpsrld" "ymm15" \ + "0x40003000300020002000100010000, 0x0" \ + "from constant: " + test_one_register "vpsrlw" "ymm0" \ + "0x40003000300020002000100010000, 0x0" \ + "from register: " + test_one_register "vpsrlw" "ymm0" \ + "0x40003000300020002000100010000, 0x80007000700060006000500050004" \ + "from constant: " + + test_one_register "vpsrad" "ymm15" \ + "0x100000000c0000000800000004000, 0x200010001c0010001800100014001" \ + "from register: " + test_one_register "vpsrad" "ymm15" \ + "0x10000e000c000a0008000600040002, 0x20001e001c001a0018001600140012" \ + "from constant: " + test_one_register "vpsraw" "ymm0" \ + "0x40003000300020002000100010000, 0x0" \ + "from register: " + test_one_register "vpsraw" "ymm0" \ + "0x10000e000c000a0008000600040002, 0x20001e001c001a0018001600140012" \ + "from constant: " + + test_one_register "vpsllq" "ymm15" \ + "0x10000e000c000a00080006000400020, 0x0" \ + "from register: " + test_one_register "vpsllq" "ymm15" \ + "0x10000e000c000a0008000600040002, 0x0" \ + "from constant: " + test_one_register "vpslld" "ymm15" \ + "0x400038003000280020001800100008, 0x800078007000680060005800500048" \ + "from register: " + test_one_register "vpslld" "ymm15" "0x0, 0x0" "from constant: " + test_one_register "vpsllw" "ymm0" \ + "0x10000e000c000a0008000600040002, 0x0" \ + "from register: " + test_one_register "vpsllw" "ymm0" "0x0, 0x0" "from constant: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for shift_test" +} else { + untested "couldn't run shift tests" +} +gdb_test "finish" "Run till exit from.*shift_test.*" \ + "leaving shift" + +# Preparation and testing shuffling instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for shuffle" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \ + "set ymm1 for shuffle" +gdb_test_no_output "set \$ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}" \ + "set ymm2 for shuffle" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for shuffle" + +if {[record_full_function "shuffle"] == true} { + test_one_register "vshufpd" "ymm15" \ + "0x20001000200010012001100160015, 0xa0009000a0009001a0019001e001d" \ + "high register: " + test_one_register "vshufpd" "ymm0" \ + "0x20001000200010012001100140013, 0x0" \ + "low register: " + test_one_register "vshufps" "ymm15" \ + "0x180017001600150011001100120013, 0x0" \ + "high register: " + test_one_register "vshufps" "ymm0" \ + "0x180017001600150011001100120012, 0x20001f001e001d00190019001a001a" \ + "low register: " + + test_one_register "vpshuflw" "ymm15" \ + "0x150015001600150014001300120011, 0x1d001d001e001d001c001b001a0019" \ + "high register: " + test_one_register "vpshuflw" "ymm0" \ + "0x150015001500180014001300120011, 0x0" \ + "low register: " + test_one_register "vpshufhw" "ymm15" \ + "0x120011001200110012001100160015, 0x0" \ + "high register: " + test_one_register "vpshufhw" "ymm0" \ + "0x120011001200110012001100140013, 0x1a0019001a0019001a0019001c001b" \ + "low register: " + + test_one_register "vpshufd" "ymm15" \ + "0x11151100111411001113110011121100, 0x1919190019201900191f1900191e1900" \ + "high register: " + test_one_register "vpshufd" "ymm0" \ + "0x11151100111411001113110011121100, 0x0" \ + "low register: " + test_one_register "vpshufb" "ymm15" "0x0, 0x0" "high register: " + test_one_register "vpshufb" "ymm0" "0x0, 0x0" "low register: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for shuffle_test" +} else { + untested "couldn't run shuffle tests" +} +gdb_test "finish" "Run till exit from.*shuffle_test.*" \ + "leaving shuffle" + +# Preparation and testing permute instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for permute" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \ + "set ymm1 for permute" +gdb_test_no_output "set \$ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}" \ + "set ymm2 for permute" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for permute" + +if {[record_full_function "permute"] == true} { + test_one_register "vpermps" "ymm15" \ + "0x40003000200010004000300020001, 0x40003000200010004000300020001" + test_one_register "vpermps" "ymm0" \ + "0x140013001200110014001300120011, 0x140013001200110014001300120011" + test_one_register "vpermpd" "ymm0" \ + "0x120011001200110012001100120011, 0x0" + test_one_register "vpermpd" "ymm15" \ + "0x120011001200110012001100140013, 0x1a0019001a0019001a0019001c001b" + + test_one_register "vpermilps" "ymm0" \ + "0x180017001400130018001700140013, 0x20001f001c001b0020001f001c001b" \ + "register version" + test_one_register "vpermilps" "ymm15" \ + "0x180017001400130018001700140013, 0x0" \ + "register version" + test_one_register "vpermilps" "ymm15" \ + "0x140013001200110018001700160015, 0x1c001b001a0019001c001b001a0019" \ + "immediate version" + test_one_register "vpermilps" "ymm0" \ + "0x140013001200110014001300120011, 0x0" \ + "immediate version" + + test_one_register "vpermilpd" "ymm0" \ + "0x140013001200110014001300120011, 0x1c001b001a0019001c001b001a0019" \ + "register version" + test_one_register "vpermilpd" "ymm15" \ + "0x140013001200110014001300120011, 0x0" \ + "register version" + test_one_register "vpermilpd" "ymm15" \ + "0x140013001200110014001300120011, 0x140013001200110014001300120011" \ + "immediate version" + test_one_register "vpermilpd" "ymm0" \ + "0x40003000200010008000700060005, 0x40003000200010004000300020001" \ + "immediate version" + + test_one_register "vpermq" "ymm15" \ + "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003" + test_one_register "vpermq" "ymm0" \ + "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003" + test_one_register "vpermd" "ymm15" \ + "0x80007000600050004000300020001, 0x80007000600050004000300020001" + test_one_register "vpermd" "ymm0" \ + "0x10000f000e000d000c000b000a0009, 0x80007000600050004000300020001" + + test_one_register "vperm2i128" "ymm15" \ + "0x180017001600150014001300120011, 0x180017001600150014001300120011" + test_one_register "vperm2i128" "ymm0" \ + "0x20001f001e001d001c001b001a0019, 0x180017001600150014001300120011" + test_one_register "vperm2f128" "ymm15" "0x0, 0x0" + test_one_register "vperm2f128" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for permute_test" +} else { + untested "couldn't run permute tests" +} +gdb_test "finish" "Run till exit from.*permute_test.*" \ + "leaving permute" + +# Preparation and testing extract_insert instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for extract_insert" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \ + "set ymm1 for extract_insert" +gdb_test_no_output "set \$xmm2.uint128 = 0xcafe" \ + "set ymm2 for extract_insert" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for extract_insert" +gdb_test_no_output "set \$rax = 0" "set eax for extract_insert" + +if {[record_full_function "extract_insert"] == true} { + test_one_memory "vpextrw" "global_buf1" \ + "\\\{0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0 <repeats 25 times>" + test_one_general_register "vpextrw" "rax" "0x8000700060005" + + test_one_register "vpinsrq" "ymm15" \ + "0x50000cafe, 0x0" + test_one_register "vpinsrd" "ymm0" \ + "0x500cafe, 0x0" + test_one_register "vpinsrw" "ymm15" \ + "0x80007000600050004000300020001, 0x0" + test_one_register "vpinsrb" "ymm0" \ + "0x80007000600050000cafe00020001, 0x0" + + test_one_memory "vpextrq" "global_buf1" \ + "\\\{0x5, 0x0, 0x6, 0x0 <repeats 29 times>" + test_one_general_register "vpextrq" "rax" "0x80007" + test_one_memory "vpextrd" "global_buf1" \ + "\\\{0x3, 0x0 <repeats 31 times>" + test_one_general_register "vpextrd" "rax" "0x0" + test_one_memory "vpextrb" "global_buf1" \ + "\\\{0x0 <repeats 32 times>" + test_one_general_register "vpextrb" "rax" "0xcafe" + + test_one_general_register "vextractps" "eax" "0x0" + test_one_register "vinsertps" "ymm0" \ + "0x10000f000e000d000c000b000a0009, 0x0" + test_one_register "vextractf128" "ymm15" \ + "0xcafe, 0x10000f000e000d000c000b000a0009" + test_one_register "vextracti128" "ymm0" \ + "0x80007000600050004000300020001, 0xcafe" + test_one_register "vinsertf128" "ymm15" \ + "0x0, 0x0" + test_one_register "vinserti128" "ymm0" \ + "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for extract_insert_test" +} else { + untested "couldn't run extract_insert tests" +} +gdb_test "finish" "Run till exit from.*extract_insert_test.*" \ + "leaving extract_insert" + +# Preparation and testing blend instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for blend" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \ + "set ymm1 for blend" +gdb_test_no_output \ + "set \$ymm2.v16_int16 = {17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}" \ + "set ymm2 for blend" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for blend" + +if {[record_full_function "blend"] == true} { + test_one_register "vpblendvb" "ymm0" \ + "0x180017000600050004000300120011, 0x20001f001e001d001c001b000a0009" + test_one_register "vpblendvb" "ymm15" \ + "0x80007001600150004000300020001, 0x0" + test_one_register "vpblendd" "ymm15" \ + "0x180007001600050004000300020011, 0x20000f001e000d000c000b000a0019" + test_one_register "vpblendd" "ymm0" \ + "0x180017000600150004000300020001, 0x0" + test_one_register "vpblendw" "ymm0" \ + "0x180017001600150014001300120011, 0x20001f001e001d001c001b001a0019" + test_one_register "vpblendw" "ymm15" \ + "0x180017001600150014001300120011, 0x0" + + test_one_register "vblendvpd" "ymm15" \ + "0x80007000600050014001300120011, 0x10000f000e000d001c001b001a0019" + test_one_register "vblendvps" "ymm0" \ + "0x180017000600050014001300020001, 0x0" + test_one_register "vblendpd" "ymm15" "0x0, 0x0" + test_one_register "vblendps" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for blend_test" +} else { + untested "couldn't run blend tests" +} +gdb_test "finish" "Run till exit from.*blend_test.*" \ + "leaving blend" + +# Preparation and testing compare instructions. +gdb_test_no_output \ + "set \$xmm0.v4_float = {0, 1.5, 2, 0}" "set ymm0 for compare" +gdb_test_no_output \ + "set \$xmm1.v4_float = {0, 1, 2.5, -1}" "set ymm1 for compare" +gdb_test_no_output \ + "set \$xmm15.v4_float = {-1, -2, 10, 100}" "set ymm15 for compare" +gdb_test_no_output "set \$eflags = 2" + +if {[record_full_function "compare"] == true} { + test_one_general_register "vucomisd" "eflags" "0x203" + test_one_general_register "vucomiss" "eflags" "0x202" + test_one_general_register "vcomiss" "eflags" "0x203" + test_one_general_register "vcomisd" "eflags" "0x202" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for compare_test" +} else { + untested "couldn't run compare tests" +} +gdb_test "finish" "Run till exit from.*compare_test.*" \ + "leaving compare" + +# Preparation and testing pack instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for pack" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {0x1020, 0x1121, 0x1222, 0x1323, 0x1424, 0x1525, 0x1626, 0x1727, 0x1828, 0x1929, 0x1a2a, 0x1b2b, 0x1c2c, 0x1d2d, 0x1e2e, 0x1f2f}" \ + "set ymm1 for pack" +gdb_test_no_output \ + "set \$ymm2.v16_int16 = {0x3040, 0x3141, 0x3242, 0x3343, 0x3444, 0x3545, 0x3646, 0x3747, 0x3848, 0x3949, 0x3a4a, 0x3b4b, 0x3c4c, 0x3d4d, 0x3e4e, 0x3f4f}" \ + "set ymm2 for pack" +gdb_test_no_output \ + "set \$ymm15.v2_int128 = {0, 0}" "set ymm15 for pack" + +if {[record_full_function "pack"] == true} { + test_one_register "vpackusdw" "ymm0" \ + "0xffffffffffffffffffffffffffffffff, 0x0" + test_one_register "vpackusdw" "ymm15" \ + "0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff" + test_one_register "vpackuswb" "ymm15" \ + "0x7fff7fff7fff7fff7fff7fff7fff7fff, 0x0" + test_one_register "vpackuswb" "ymm0" \ + "0x7fff7fff7fff7fff7fff7fff7fff7fff, 0x7fff7fff7fff7fff7fff7fff7fff7fff" + test_one_register "vpackssdw" "ymm0" \ + "0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f, 0x0" + test_one_register "vpackssdw" "ymm15" \ + "0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f, 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" + test_one_register "vpacksswb" "ymm15" "0x0, 0x0" + test_one_register "vpacksswb" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for pack_test" +} else { + untested "couldn't run pack tests" +} +gdb_test "finish" "Run till exit from.*pack_test.*" \ + "leaving pack" + +# Preparation and testing converting instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0,0}" \ + "set ymm0 for convert test" +gdb_test_no_output \ + "set \$ymm1.v8_float = {0, 1, 2.5, 10, -1, -2.5, 0}" \ + "set ymm1 for convert test" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" \ + "set ymm15 for convert test" +gdb_test_no_output "set \$ecx = -1" "set ecx for convert test" +gdb_test_no_output "set \$ebx = 1" "set ebx for convert test" + +if {[record_full_function "convert"] == true} { + gdb_test "maint print record-instruction" ".*" + test_one_general_register "vcvttss2si" "ecx" "0xffffffff" + test_one_general_register "vcvttsd2si" "ebx" "0x0" + test_one_register "vcvttps2dq" "ymm15" \ + "0x41200000402000003f8000004f800000, 0x0" + test_one_register "vcvttpd2dq" "ymm0" \ + "0x412000004020000041f0000000000000, 0x0" + test_one_general_register "vcvtss2si" "ebx" "0x0" + + test_one_register "vcvtss2sd" "ymm0" \ + "0x412000004020000041efffffffe00000, 0x0" + test_one_register "vcvtsi2ss" "ymm15" \ + "0x41200000402000003f80000000000000, 0x0" + test_one_register "vcvtsi2sd" "ymm0" \ + "0x8000000000000, 0x0" + test_one_register "vcvtsd2ss" "ymm15" \ + "0x490000023c000000, 0x0" + test_one_general_register "vcvtsd2si" "ebx" "0x1" + + test_one_register "vcvtpd2dq" "ymm0" \ + "0x3ff00000000000000000000000000000, 0x0" + test_one_register "vcvtpd2ps" "ymm15" \ + "0xa000000020000000100000000, 0x0" + test_one_register "vcvtps2pd" "ymm0" \ + "0x4e8240004e8040004e7e000000000000, 0x0" + test_one_register "vcvtps2dq" "ymm15" \ + "0x41cfc000000000000000000000000000, 0x0" + test_one_register "vcvtdq2pd" "ymm15" "0x0, 0x0" + test_one_register "vcvtdq2ps" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for convert_test" +} else { + untested "couldn't run convert tests" +} +gdb_test "finish" "Run till exit from.*convert_test.*" \ + "leaving convert" diff --git a/gdb/testsuite/gdb.reverse/i386-reverse.exp b/gdb/testsuite/gdb.reverse/i386-reverse.exp index 8c22363..9aee9a4 100644 --- a/gdb/testsuite/gdb.reverse/i386-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-reverse.exp @@ -36,7 +36,7 @@ set end_of_inc_dec_tests [gdb_get_line_number " end inc_dec_tests "] runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp b/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp index 0c99480..aa4cfce 100644 --- a/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp @@ -43,7 +43,7 @@ set end_sse4_test [gdb_get_line_number " end sse4_test "] runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/i387-env-reverse.exp b/gdb/testsuite/gdb.reverse/i387-env-reverse.exp index 4b6a3f7..f3350fc 100644 --- a/gdb/testsuite/gdb.reverse/i387-env-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i387-env-reverse.exp @@ -36,7 +36,7 @@ set location [gdb_get_line_number "END I387-FLOAT-REVERSE"] gdb_test_no_output "record" "Turn on process record" # This can take awhile. set oldtimeout $timeout -set timeout [expr $oldtimeout + 120] +set timeout [expr {$oldtimeout + 120}] gdb_test "until $location" ".*$srcfile:$location.*" \ "record to end of main" set timeout $oldtimeout diff --git a/gdb/testsuite/gdb.reverse/insn-reverse.exp b/gdb/testsuite/gdb.reverse/insn-reverse.exp index 5b3a2cd..9e238f0 100644 --- a/gdb/testsuite/gdb.reverse/insn-reverse.exp +++ b/gdb/testsuite/gdb.reverse/insn-reverse.exp @@ -106,7 +106,7 @@ proc test { func testcase_nr } { } # Registers contents after each backward single step. - for {set i [expr $count - 1]} {$i >= 0} {incr i -1} { + for {set i [expr {$count - 1}]} {$i >= 0} {incr i -1} { gdb_test -nopass "reverse-stepi" set post_regs($i) [capture_command_output "info all-registers" ""] } diff --git a/gdb/testsuite/gdb.reverse/machinestate-precsave.exp b/gdb/testsuite/gdb.reverse/machinestate-precsave.exp index 53b958d..94d9723 100644 --- a/gdb/testsuite/gdb.reverse/machinestate-precsave.exp +++ b/gdb/testsuite/gdb.reverse/machinestate-precsave.exp @@ -13,7 +13,7 @@ # 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. +# This file is part of the GDB testsuite. # This test tests the restoration of various kinds of machine state # to their original values with a process record log. We will execute # the program forward while it changes various types of data, and diff --git a/gdb/testsuite/gdb.reverse/machinestate.exp b/gdb/testsuite/gdb.reverse/machinestate.exp index 9177029..7edf517 100644 --- a/gdb/testsuite/gdb.reverse/machinestate.exp +++ b/gdb/testsuite/gdb.reverse/machinestate.exp @@ -13,7 +13,7 @@ # 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. +# This file is part of the GDB testsuite. # This test tests the restoration of various kinds of machine state # to their original values by reverse execution. We will execute # the program forward while it changes various types of data, and @@ -53,7 +53,7 @@ set endmain [gdb_get_line_number " end main " $srcfile] runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/maint-print-instruction.exp b/gdb/testsuite/gdb.reverse/maint-print-instruction.exp index 6599345..151c117 100644 --- a/gdb/testsuite/gdb.reverse/maint-print-instruction.exp +++ b/gdb/testsuite/gdb.reverse/maint-print-instruction.exp @@ -23,7 +23,7 @@ # change is printed, since any instruction must have at least a change # to the PC. -if ![supports_reverse] { +if {![supports_reverse]} { return } @@ -52,7 +52,7 @@ if { ![runto_main] } { #confirm that GDB doesn't go crazy if recording isn't enabled test_print false "" "print before starting to record" -if ![supports_process_record] { +if {![supports_process_record]} { # No point in testing the rest if we can't record anything return } diff --git a/gdb/testsuite/gdb.reverse/map-to-same-line.exp b/gdb/testsuite/gdb.reverse/map-to-same-line.exp index 410394c..e31eef0 100644 --- a/gdb/testsuite/gdb.reverse/map-to-same-line.exp +++ b/gdb/testsuite/gdb.reverse/map-to-same-line.exp @@ -48,16 +48,16 @@ Dwarf::assemble $asm_file { cu {} { compile_unit { - {language @DW_LANG_C} - {name map-to-same-line.c} - {stmt_list $L DW_FORM_sec_offset} - {low_pc 0 addr} + DW_AT_language @DW_LANG_C + DW_AT_name map-to-same-line.c + DW_AT_stmt_list $L DW_FORM_sec_offset + DW_AT_low_pc 0 addr } { subprogram { - {external 1 flag} - {name main} - {low_pc $main_start addr} - {high_pc $main_len DW_FORM_data4} + DW_AT_external 1 flag + DW_AT_name main + DW_AT_low_pc $main_start addr + DW_AT_high_pc $main_len DW_FORM_data4 } } } diff --git a/gdb/testsuite/gdb.reverse/next-reverse-bkpt-over-sr.exp b/gdb/testsuite/gdb.reverse/next-reverse-bkpt-over-sr.exp index 454808d..574ab5e 100644 --- a/gdb/testsuite/gdb.reverse/next-reverse-bkpt-over-sr.exp +++ b/gdb/testsuite/gdb.reverse/next-reverse-bkpt-over-sr.exp @@ -52,7 +52,7 @@ if {![runto_main]} { return 0 } -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/pipe-reverse.exp b/gdb/testsuite/gdb.reverse/pipe-reverse.exp index eb4f8eb..93ba3d1 100644 --- a/gdb/testsuite/gdb.reverse/pipe-reverse.exp +++ b/gdb/testsuite/gdb.reverse/pipe-reverse.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/readv-reverse.exp b/gdb/testsuite/gdb.reverse/readv-reverse.exp index 47149f2..4456340 100644 --- a/gdb/testsuite/gdb.reverse/readv-reverse.exp +++ b/gdb/testsuite/gdb.reverse/readv-reverse.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/recursion.exp b/gdb/testsuite/gdb.reverse/recursion.exp index bfe1770..ca08930 100644 --- a/gdb/testsuite/gdb.reverse/recursion.exp +++ b/gdb/testsuite/gdb.reverse/recursion.exp @@ -26,7 +26,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/recvmsg-reverse.exp b/gdb/testsuite/gdb.reverse/recvmsg-reverse.exp index 89cac87..af6f73f 100644 --- a/gdb/testsuite/gdb.reverse/recvmsg-reverse.exp +++ b/gdb/testsuite/gdb.reverse/recvmsg-reverse.exp @@ -29,7 +29,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/s390-mvcle.exp b/gdb/testsuite/gdb.reverse/s390-mvcle.exp index 36cd611..642be8f 100644 --- a/gdb/testsuite/gdb.reverse/s390-mvcle.exp +++ b/gdb/testsuite/gdb.reverse/s390-mvcle.exp @@ -27,7 +27,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/sigall-precsave.exp b/gdb/testsuite/gdb.reverse/sigall-precsave.exp index 64869c5..552be4b 100644 --- a/gdb/testsuite/gdb.reverse/sigall-precsave.exp +++ b/gdb/testsuite/gdb.reverse/sigall-precsave.exp @@ -134,20 +134,20 @@ proc test_one_sig_reverse {prevsig} { } else { xfail "$testmsg (handled)" } - } + } } } -clean_restart $binfile +clean_restart $::testfile runto gen_ABRT -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } -# Run until end, then save execution log. +# Run until end, then save execution log. set breakloc [gdb_get_line_number "end of main" "$srcfile"] gdb_test "break $breakloc" \ @@ -299,7 +299,7 @@ gdb_test "continue" \ "get signal TERM" gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM" -gdb_test "continue" " end of main .*" "continue to sigall exit" +gdb_test "continue" " end of main .*" "continue to sigall exit" foreach sig [lreverse $signals] { test_one_sig_reverse $sig diff --git a/gdb/testsuite/gdb.reverse/sigall-reverse.exp b/gdb/testsuite/gdb.reverse/sigall-reverse.exp index b72e098..f9259a1 100644 --- a/gdb/testsuite/gdb.reverse/sigall-reverse.exp +++ b/gdb/testsuite/gdb.reverse/sigall-reverse.exp @@ -140,15 +140,15 @@ proc test_one_sig_reverse {prevsig} { } else { xfail "$testmsg (handled)" } - } + } } } -clean_restart $binfile +clean_restart $::testfile runto gen_ABRT -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp b/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp index 7c1cf0b..8b9cb20 100644 --- a/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp +++ b/gdb/testsuite/gdb.reverse/singlejmp-reverse.exp @@ -18,7 +18,7 @@ require supports_reverse standard_testfile ".S" "${gdb_test_file_name}-nodebug.S" set executable ${testfile} -if [info exists COMPILE] { +if {[info exists COMPILE]} { # make check RUNTESTFLAGS="gdb.reverse/singlejmp-reverse.exp COMPILE=1" if { [build_executable_from_specs ${testfile}.exp $executable {} \ ${testfile}.c {debug optimize=-O2} \ @@ -36,11 +36,11 @@ if [info exists COMPILE] { clean_restart $executable -if ![runto_main] { +if {![runto_main]} { return -1 } -if [supports_process_record] { +if {[supports_process_record]} { gdb_test_no_output "record" } diff --git a/gdb/testsuite/gdb.reverse/solib-precsave.exp b/gdb/testsuite/gdb.reverse/solib-precsave.exp index 277e33c..0b93501 100644 --- a/gdb/testsuite/gdb.reverse/solib-precsave.exp +++ b/gdb/testsuite/gdb.reverse/solib-precsave.exp @@ -52,7 +52,7 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable \ untested "failed to compile" return -1 } - + # Note: The test previously did "set debug-file-directory" to (try to) # ensure the debug info for the dynamic loader and libc weren't found. # This doesn't work if the debug info is in the .debug subdirectory. @@ -60,7 +60,7 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable \ # and is no longer attempted. Instead, the test does not make assumptions # about whether the debug info is present or not. -clean_restart $binfile +clean_restart $::testfile gdb_load_shlib $library1 gdb_load_shlib $library2 @@ -140,7 +140,7 @@ gdb_test_multiple "reverse-step" "reverse-step into solib function one" { pass $gdb_test_name } } -# Depending on wether the closing } has a line associated, we might have +# Depending on whether the closing } has a line associated, we might have # different acceptable results here gdb_test_multiple "reverse-step" "reverse-step within solib function one" { -re -wrap "return y;.*" { diff --git a/gdb/testsuite/gdb.reverse/solib-reverse.exp b/gdb/testsuite/gdb.reverse/solib-reverse.exp index 1e22e91..8991177 100644 --- a/gdb/testsuite/gdb.reverse/solib-reverse.exp +++ b/gdb/testsuite/gdb.reverse/solib-reverse.exp @@ -44,7 +44,7 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $exec_opt untested "failed to compile" return -1 } - + # Note: The test previously did "set debug-file-directory" to (try to) # ensure the debug info for the dynamic loader and libc weren't found. # This doesn't work if the debug info is in the .debug subdirectory. @@ -52,13 +52,13 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $exec_opt # and is no longer attempted. Instead, the test does not make assumptions # about whether the debug info is present or not. -clean_restart $binfile +clean_restart $::testfile gdb_load_shlib $library1 gdb_load_shlib $library2 runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } @@ -116,7 +116,7 @@ gdb_test_multiple "reverse-step" "reverse-step into solib function one" { pass $gdb_test_name } } -# Depending on wether the closing } has a line associated, we might have +# Depending on whether the closing } has a line associated, we might have # different acceptable results here gdb_test_multiple "reverse-step" "reverse-step within solib function one" { -re -wrap "return y;.*" { diff --git a/gdb/testsuite/gdb.reverse/step-precsave.exp b/gdb/testsuite/gdb.reverse/step-precsave.exp index b49c21b..d152454 100644 --- a/gdb/testsuite/gdb.reverse/step-precsave.exp +++ b/gdb/testsuite/gdb.reverse/step-precsave.exp @@ -69,7 +69,7 @@ with_timeout_factor 10 { gdb_test "kill" "" "kill process, prepare to debug log file" \ "Kill the program being debugged\\? \\(y or n\\) " "y" -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test "record restore $precsave" \ "Restored records from core file .*" \ @@ -229,7 +229,7 @@ gdb_test_multiple "stepi" "$test_message" { } } -re "ENTER CALLEE.*$gdb_prompt $" { - send_gdb "stepi\n" + send_gdb "stepi\n" exp_continue } -re "$pic_thunk_re.*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.reverse/step-reverse.exp b/gdb/testsuite/gdb.reverse/step-reverse.exp index 6ecf1cd..78a11bf 100644 --- a/gdb/testsuite/gdb.reverse/step-reverse.exp +++ b/gdb/testsuite/gdb.reverse/step-reverse.exp @@ -30,7 +30,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } @@ -191,7 +191,7 @@ gdb_test_multiple "stepi" "$test_message" { } } -re "ENTER CALLEE.*$gdb_prompt $" { - send_gdb "stepi\n" + send_gdb "stepi\n" exp_continue } -re "$pic_thunk_re.*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.reverse/time-reverse.exp b/gdb/testsuite/gdb.reverse/time-reverse.exp index fe191a0..58dcdde 100644 --- a/gdb/testsuite/gdb.reverse/time-reverse.exp +++ b/gdb/testsuite/gdb.reverse/time-reverse.exp @@ -20,6 +20,7 @@ # require supports_reverse +require supports_process_record standard_testfile @@ -38,23 +39,49 @@ proc test {mode} { return } - runto marker1 - - if [supports_process_record] { - # Activate process record/replay - gdb_test_no_output "record" "turn on process record" + if { ![runto marker1] } { + return } + # Activate process record/replay + gdb_test_no_output "record" "turn on process record" + gdb_test_no_output "set record full stop-at-limit on" + gdb_test_no_output "set record full insn-number-max 2000" + + set re_srcfile [string_to_regexp $::srcfile] + gdb_test "break marker2" \ - "Breakpoint $::decimal at $::hex: file .*$::srcfile, line $::decimal.*" \ + "Breakpoint $::decimal at $::hex: file .*$re_srcfile, line $::decimal.*" \ "set breakpoint at marker2" - gdb_continue_to_breakpoint "marker2" ".*$::srcfile:.*" + set re_question \ + [string_list_to_regexp \ + "Do you want to auto delete previous execution log entries when" \ + " record/replay buffer becomes full" \ + { (record full stop-at-limit)?([y] or n)}] + set re_program_stopped \ + [multi_line \ + [string_to_regexp "Process record: stopped by user."] \ + "" \ + [string_to_regexp "Program stopped."]] + set re_marker2 [string_to_regexp "marker2 ()"] + gdb_test_multiple "continue" "continue to breakpoint: marker2" { + -re "$re_question " { + send_gdb "n\n" + exp_continue + } + -re -wrap "Breakpoint $::decimal, $re_marker2 .*" { + pass $gdb_test_name + } + -re -wrap "\r\n$re_program_stopped\r\n.*" { + unsupported $gdb_test_name + } + } # Show how many instructions we've recorded. gdb_test "info record" "Active record target: .*" - gdb_test "reverse-continue" ".*$::srcfile:$::decimal.*" "reverse to marker1" + gdb_test "reverse-continue" ".*$re_srcfile:$::decimal.*" "reverse to marker1" # If the variable was recorded properly, the old contents (-1) # will be remembered. If not, new contents (current time) will be diff --git a/gdb/testsuite/gdb.reverse/until-precsave.exp b/gdb/testsuite/gdb.reverse/until-precsave.exp index 1f25a3a..325e4a8 100644 --- a/gdb/testsuite/gdb.reverse/until-precsave.exp +++ b/gdb/testsuite/gdb.reverse/until-precsave.exp @@ -13,7 +13,7 @@ # 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 'until' and +# This file is part of the GDB testsuite. It tests 'until' and # 'advance' in precord logfile. # This test suitable only for process record-replay @@ -147,7 +147,7 @@ gdb_test "advance $bp_location19" \ "factorial .value=720.*${srcfile}:$bp_location19.*" \ "reverse-advance to final return of factorial" -# Now do "until" across the recursive calls, +# Now do "until" across the recursive calls, # ending up in the same frame where we are now. gdb_test "until $bp_location7" \ diff --git a/gdb/testsuite/gdb.reverse/until-reverse.exp b/gdb/testsuite/gdb.reverse/until-reverse.exp index 240f6da..de138f5 100644 --- a/gdb/testsuite/gdb.reverse/until-reverse.exp +++ b/gdb/testsuite/gdb.reverse/until-reverse.exp @@ -13,7 +13,7 @@ # 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 'until' and +# This file is part of the GDB testsuite. It tests 'until' and # 'advance' in reverse debugging. require supports_reverse @@ -34,7 +34,7 @@ set bp_location21 [gdb_get_line_number "set breakpoint 21 here"] runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } @@ -120,7 +120,7 @@ gdb_test "advance $bp_location19" \ "factorial .value=720.*${srcfile}:$bp_location19.*" \ "reverse-advance to final return of factorial" -# Now do "until" across the recursive calls, +# Now do "until" across the recursive calls, # ending up in the same frame where we are now. gdb_test "until $bp_location7" \ diff --git a/gdb/testsuite/gdb.reverse/waitpid-reverse.exp b/gdb/testsuite/gdb.reverse/waitpid-reverse.exp index c1cb402..26c3c99 100644 --- a/gdb/testsuite/gdb.reverse/waitpid-reverse.exp +++ b/gdb/testsuite/gdb.reverse/waitpid-reverse.exp @@ -31,7 +31,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.reverse/watch-reverse.exp b/gdb/testsuite/gdb.reverse/watch-reverse.exp index 6a694be..567ae4a 100644 --- a/gdb/testsuite/gdb.reverse/watch-reverse.exp +++ b/gdb/testsuite/gdb.reverse/watch-reverse.exp @@ -28,7 +28,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { runto_main -if [supports_process_record] { +if {[supports_process_record]} { # Activate process record/replay gdb_test_no_output "record" "turn on process record" } diff --git a/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp new file mode 100644 index 0000000..d75bc76 --- /dev/null +++ b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp @@ -0,0 +1,86 @@ +/* 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/>. */ + +#ifdef DEVICE + +#include <hip/hip_runtime.h> + +constexpr unsigned int NUM_BREAKPOINT_HITS = 5; + +static __device__ void +break_here () +{ +} + +extern "C" __global__ void +kernel () +{ + for (int n = 0; n < NUM_BREAKPOINT_HITS; ++n) + break_here (); +} + +#else + +#include <hip/hip_runtime.h> +#include <unistd.h> + +constexpr unsigned int NUM_ITEMS_PER_BLOCK = 256; +constexpr unsigned int NUM_BLOCKS = 128; +constexpr unsigned int NUM_ITEMS = NUM_ITEMS_PER_BLOCK * NUM_BLOCKS; +constexpr unsigned int NUM_LOAD_UNLOADS = 5; + +#define CHECK(cmd) \ + { \ + hipError_t error = cmd; \ + if (error != hipSuccess) \ + { \ + fprintf (stderr, "error: '%s'(%d) at %s:%d\n", \ + hipGetErrorString (error), error, __FILE__, __LINE__); \ + exit (EXIT_FAILURE); \ + } \ + } + +int +main (int argc, const char **argv) +{ + if (argc != 2) + { + fprintf (stderr, "Usage: %s <hip_module_path>\n", argv[0]); + return 1; + } + + const auto module_path = argv[1]; + hipModule_t module; + CHECK (hipModuleLoad (&module, module_path)); + + /* Launch the kernel. */ + hipFunction_t function; + CHECK (hipModuleGetFunction (&function, module, "kernel")); + CHECK (hipModuleLaunchKernel (function, NUM_BLOCKS, 1, 1, + NUM_ITEMS_PER_BLOCK, 1, 1, 0, nullptr, nullptr, + nullptr)); + + /* Load and unload the module many times. */ + for (int i = 0; i < NUM_LOAD_UNLOADS; ++i) + { + hipModule_t dummy_module; + CHECK (hipModuleLoad (&dummy_module, module_path)); + CHECK (hipModuleUnload (dummy_module)); + } +} + +#endif diff --git a/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp new file mode 100644 index 0000000..e994884 --- /dev/null +++ b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp @@ -0,0 +1,69 @@ +# Copyright 2025 Free Software Foundation, Inc. + +# This file is part of GDB. + +# 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 test verifies what happens when a code object list update happens at the +# same time as some wave stop events are reported. It was added following a +# performance bug fix, where forward progress requirement disabled when +# pulling events from amd-dbgapi in amd_dbgapi_target_breakpoint::check_status. +# +# The test launches a kernel that hits a breakpoint with an always false +# condition a certain number of times. Meanwhile, the host loads and unloads +# a code object in a loop, causing check_status to be called. The hope is that +# check_status, when calling process_event_queue, will pull many WAVE_STOP +# events from the kernel hitting the breakpoint. +# +# Without the appropriate fix (of disabling forward progress requirement in +# check_status), GDB would hit the newly-added assert in process_event_queue, +# which verifies that forward progress requirement is disabled. Even without +# this assert, the test would likely time out (depending on the actual timeout +# value). + +load_lib rocm.exp +standard_testfile .cpp +require allow_hipcc_tests + +# Build the host executable. +if { [build_executable "failed to prepare" \ + $testfile $srcfile {debug hip}] == -1 } { + return -1 +} + +set hipmodule_path [standard_output_file ${testfile}.co] + +# Build the kernel object file. +if { [gdb_compile $srcdir/$subdir/$srcfile \ + $hipmodule_path object \ + { debug hip additional_flags=--genco additional_flags=-DDEVICE } ] != "" } { + return -1 +} + +proc do_test { } { + with_rocm_gpu_lock { + clean_restart + gdb_load $::binfile + gdb_test_no_output "set args $::hipmodule_path" "set args" + + if { ![runto_main] } { + return + } + + gdb_test "with breakpoint pending on -- break break_here if 0" + gdb_continue_to_end "continue to end" "continue" 1 + } +} + +do_test diff --git a/gdb/testsuite/gdb.rocm/displaced-stepping.exp b/gdb/testsuite/gdb.rocm/displaced-stepping.exp index cd50fec..9e8abd4 100644 --- a/gdb/testsuite/gdb.rocm/displaced-stepping.exp +++ b/gdb/testsuite/gdb.rocm/displaced-stepping.exp @@ -28,7 +28,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile {hip}]} { } proc do_test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile with_rocm_gpu_lock { if ![runto_main] { diff --git a/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp b/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp index 7588525..dfd1092 100644 --- a/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp +++ b/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp @@ -21,6 +21,7 @@ load_lib rocm.exp require allow_hipcc_tests +require allow_fork_tests standard_testfile -execer.cpp -execee.cpp @@ -53,7 +54,8 @@ proc do_test { detach-on-fork follow-fork-mode fork_func } { } with_rocm_gpu_lock { - clean_restart ${::binfile}-execer-${fork_func} + clean_restart + gdb_load ${::binfile}-execer-${fork_func} gdb_test_no_output "set detach-on-fork ${detach-on-fork}" gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" diff --git a/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp b/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp index a6bcf69..b14e2c7 100644 --- a/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp +++ b/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp @@ -20,6 +20,7 @@ load_lib rocm.exp require allow_hipcc_tests +require allow_fork_tests standard_testfile -execer.cpp -execee.cpp @@ -52,7 +53,8 @@ proc do_test { detach-on-fork follow-fork-mode fork_func } { } with_rocm_gpu_lock { - clean_restart ${::binfile}-execer-${fork_func} + clean_restart + gdb_load ${::binfile}-execer-${fork_func} gdb_test_no_output "set detach-on-fork ${detach-on-fork}" gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" diff --git a/gdb/testsuite/gdb.rocm/mi-attach.cpp b/gdb/testsuite/gdb.rocm/mi-attach.cpp index da7659d..441d460 100644 --- a/gdb/testsuite/gdb.rocm/mi-attach.cpp +++ b/gdb/testsuite/gdb.rocm/mi-attach.cpp @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <unistd.h> #include <hip/hip_runtime.h> +#include "gdb_watchdog.h" __global__ void kern () @@ -30,7 +30,7 @@ main () { /* This program will run outside of GDB, make sure that if anything goes wrong it eventually gets killed. */ - alarm (30); + gdb_watchdog (30); kern<<<1, 1>>> (); return hipDeviceSynchronize () != hipSuccess; diff --git a/gdb/testsuite/gdb.rocm/mi-attach.exp b/gdb/testsuite/gdb.rocm/mi-attach.exp index 2ca610c..37ce92a 100644 --- a/gdb/testsuite/gdb.rocm/mi-attach.exp +++ b/gdb/testsuite/gdb.rocm/mi-attach.exp @@ -13,10 +13,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +load_lib rocm.exp load_lib mi-support.exp set MIFLAGS "-i=mi" -require can_spawn_for_attach +require can_spawn_for_attach allow_hipcc_tests standard_testfile .cpp diff --git a/gdb/testsuite/gdb.rocm/multi-inferior-gpu.exp b/gdb/testsuite/gdb.rocm/multi-inferior-gpu.exp index 4f55432..0ed11e8 100644 --- a/gdb/testsuite/gdb.rocm/multi-inferior-gpu.exp +++ b/gdb/testsuite/gdb.rocm/multi-inferior-gpu.exp @@ -28,7 +28,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug hip}]} { } proc do_test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile gdb_test_no_output "set non-stop on" gdb_test_no_output "set detach-on-fork off" gdb_test_no_output "set follow-fork parent" diff --git a/gdb/testsuite/gdb.rocm/precise-memory-exec.exp b/gdb/testsuite/gdb.rocm/precise-memory-exec.exp index 506488c..76be078 100644 --- a/gdb/testsuite/gdb.rocm/precise-memory-exec.exp +++ b/gdb/testsuite/gdb.rocm/precise-memory-exec.exp @@ -29,7 +29,8 @@ if {[build_executable "failed to prepare $testfile" $testfile $srcfile {debug}]} } proc do_test { follow-exec-mode } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile with_rocm_gpu_lock { if ![runto_main] { diff --git a/gdb/testsuite/gdb.rocm/precise-memory-fork.exp b/gdb/testsuite/gdb.rocm/precise-memory-fork.exp index d326c2e..23c1ebe 100644 --- a/gdb/testsuite/gdb.rocm/precise-memory-fork.exp +++ b/gdb/testsuite/gdb.rocm/precise-memory-fork.exp @@ -21,6 +21,7 @@ load_lib rocm.exp require allow_hipcc_tests +require allow_fork_tests standard_testfile .c diff --git a/gdb/testsuite/gdb.rocm/precise-memory-multi-inferiors.exp b/gdb/testsuite/gdb.rocm/precise-memory-multi-inferiors.exp index c7a78b8..058b085 100644 --- a/gdb/testsuite/gdb.rocm/precise-memory-multi-inferiors.exp +++ b/gdb/testsuite/gdb.rocm/precise-memory-multi-inferiors.exp @@ -30,7 +30,7 @@ proc test_per_inferior { } { gdb_test "show amdgpu precise-memory" \ "AMDGPU precise memory access reporting is off \\(currently disabled\\)." \ "show initial value, inferior 1" - if $::test_python { + if { $::test_python } { gdb_test "python print(gdb.parameter(\"amdgpu precise-memory\"))" \ "False" \ "show initial value using Python, inferior 1" @@ -40,7 +40,7 @@ proc test_per_inferior { } { gdb_test "show amdgpu precise-memory" \ "AMDGPU precise memory access reporting is on \\(currently disabled\\)." \ "show new value, inferior 1" - if $::test_python { + if { $::test_python } { gdb_test "python print(gdb.parameter(\"amdgpu precise-memory\"))" \ "True" \ "show new value using Python, inferior 1" @@ -52,7 +52,7 @@ proc test_per_inferior { } { gdb_test "show amdgpu precise-memory" \ "AMDGPU precise memory access reporting is off \\(currently disabled\\)." \ "show initial value, inferior 2" - if $::test_python { + if { $::test_python } { gdb_test "python print(gdb.parameter(\"amdgpu precise-memory\"))" \ "False" \ "show initial value using Python, inferior 2" diff --git a/gdb/testsuite/gdb.rocm/precise-memory-warning-sigsegv.exp b/gdb/testsuite/gdb.rocm/precise-memory-warning-sigsegv.exp index f855719..da0a95a 100644 --- a/gdb/testsuite/gdb.rocm/precise-memory-warning-sigsegv.exp +++ b/gdb/testsuite/gdb.rocm/precise-memory-warning-sigsegv.exp @@ -29,7 +29,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug hip}]} { } proc do_test { } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile with_rocm_gpu_lock { if ![runto_main] { diff --git a/gdb/testsuite/gdb.rocm/precise-memory.exp b/gdb/testsuite/gdb.rocm/precise-memory.exp index fbcb451..8f00559 100644 --- a/gdb/testsuite/gdb.rocm/precise-memory.exp +++ b/gdb/testsuite/gdb.rocm/precise-memory.exp @@ -28,7 +28,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug hip}]} { } proc do_test { } { - clean_restart $::binfile + clean_restart + gdb_load $::binfile with_rocm_gpu_lock { if ![runto_main] { @@ -59,7 +60,7 @@ proc do_test { } { return } - # Get to the begining of the GPU kernel without precise memory enabled. + # Get to the beginning of the GPU kernel without precise memory enabled. with_test_prefix "goto gpu code" { gdb_test_no_output "set amdgpu precise-memory off" gdb_breakpoint "kernel" allow-pending diff --git a/gdb/testsuite/gdb.rocm/simple.exp b/gdb/testsuite/gdb.rocm/simple.exp index bc90a0a..8f6ff3e 100644 --- a/gdb/testsuite/gdb.rocm/simple.exp +++ b/gdb/testsuite/gdb.rocm/simple.exp @@ -27,7 +27,8 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug hip}]} { } proc do_test {} { - clean_restart $::binfile + clean_restart + gdb_load $::binfile with_rocm_gpu_lock { if ![runto_main] { diff --git a/gdb/testsuite/gdb.rust/modules.exp b/gdb/testsuite/gdb.rust/modules.exp index 5b2e998..0874db3 100644 --- a/gdb/testsuite/gdb.rust/modules.exp +++ b/gdb/testsuite/gdb.rust/modules.exp @@ -34,7 +34,7 @@ if {![runto ${srcfile}:$line]} { # https://github.com/rust-lang/rust/issues/33121 # gdb_test "call f2()" "lambda f2" -if ![target_info exists gdb,noinferiorio] { +if { ![target_info exists gdb,noinferiorio] } { gdb_test_stdio "call f3()" "mod1::inner::innest::f3" gdb_test_stdio "call self::f2()" "mod1::inner::innest::f2" gdb_test_stdio "call self::super::f2()" "mod1::inner::f2" diff --git a/gdb/testsuite/gdb.rust/traits.exp b/gdb/testsuite/gdb.rust/traits.exp index e5ef015..82fc894 100644 --- a/gdb/testsuite/gdb.rust/traits.exp +++ b/gdb/testsuite/gdb.rust/traits.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} { } set readelf_program [gdb_find_readelf] -set result [catch "exec $readelf_program --debug-dump=info $binfile" output] +set result [catch {exec $readelf_program --debug-dump=info $binfile} output] if {$result != 0} { untested "could not read [file tail ${binfile}] with readelf" return diff --git a/gdb/testsuite/gdb.server/argument-errors.exp b/gdb/testsuite/gdb.server/argument-errors.exp new file mode 100644 index 0000000..45037bf --- /dev/null +++ b/gdb/testsuite/gdb.server/argument-errors.exp @@ -0,0 +1,81 @@ +# 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 gdbserver prints a suitable message when argument values are +# missing. + +load_lib gdbserver-support.exp + +standard_testfile + +require allow_gdbserver_tests + +set gdbserver [find_gdbserver] +if { $gdbserver == "" } { + unsupported "could not find gdbserver" + return +} + +# Start gdbserver using CMD_ARGS and a non-existent program name. We +# expect to see an error message matching ERROR_RE from gdbserver. +proc test_argument_error { cmd_args error_re } { + # Fire off gdbserver. gdbserver should give an error because + # --debug-file is missing its argument. + set spawn_id [remote_spawn target "$::gdbserver $cmd_args non-existing-program"] + + set saw_expected_error false + set test "check gdbserver error: $cmd_args" + expect { + -i $spawn_id + -re $error_re { + set saw_expected_error true + exp_continue + } + eof { + gdb_assert $saw_expected_error $test + wait + } + timeout { + fail "$test (timeout)" + } + } + + # expect defaults to spawn_id in many places. Avoid confusing any + # following code. + unset spawn_id +} + +# Check that an argument that expects a value will not use a port, or +# another argument, as its value. +foreach arg { --debug-format --debug-file } { + test_argument_error "$arg stdio" \ + "Missing argument value for: $arg" + test_argument_error "$arg :54321" \ + "Missing argument value for: $arg" + test_argument_error "$arg -" \ + "Missing argument value for: $arg" + test_argument_error "$arg --once -" \ + "Missing argument value for: $arg" +} + +# Test unknown argument handling. +test_argument_error "--unknown -" \ + "Unknown argument: --unknown" +test_argument_error "-unknown -" \ + "Unknown argument: -unknown" +test_argument_error "--unknown=blah -" \ + "Unknown argument: --unknown" diff --git a/gdb/testsuite/gdb.server/bkpt-other-inferior.exp b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp index 893bd72..453be14 100644 --- a/gdb/testsuite/gdb.server/bkpt-other-inferior.exp +++ b/gdb/testsuite/gdb.server/bkpt-other-inferior.exp @@ -23,7 +23,7 @@ standard_testfile server.c require allow_gdbserver_tests -if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \ +if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ {debug pthreads}] } { return } diff --git a/gdb/testsuite/gdb.server/build-id-seqno.exp b/gdb/testsuite/gdb.server/build-id-seqno.exp index a508a44..8475ccc 100644 --- a/gdb/testsuite/gdb.server/build-id-seqno.exp +++ b/gdb/testsuite/gdb.server/build-id-seqno.exp @@ -90,13 +90,13 @@ proc load_binfile_check_debug_is_found { debuginfo_file testname } { with_test_prefix "$testname" { with_timeout_factor 5 { # Probing for .build-id based debug files on remote - # targets uses the vFile:stat packet by default, though + # targets uses the vFile:lstat packet by default, though # there is a work around that avoids this which can be # used if GDB is connected to an older gdbserver without # 'stat' support. # # Check the work around works by disabling use of the - # vFile:stat packet. + # vFile:lstat packet. foreach_with_prefix stat_pkt {auto off} { clean_restart @@ -105,7 +105,7 @@ proc load_binfile_check_debug_is_found { debuginfo_file testname } { gdb_test_no_output "set sysroot target:" - gdb_test "set remote hostio-stat-packet $stat_pkt" + gdb_test "set remote hostio-lstat-packet $stat_pkt" # Make sure we're disconnected, in case we're testing with an # extended-remote board, therefore already connected. diff --git a/gdb/testsuite/gdb.server/connect-stopped-target.exp b/gdb/testsuite/gdb.server/connect-stopped-target.exp index 021f063..603782c 100644 --- a/gdb/testsuite/gdb.server/connect-stopped-target.exp +++ b/gdb/testsuite/gdb.server/connect-stopped-target.exp @@ -34,7 +34,7 @@ proc do_test {nonstop} { global gdb_prompt global hex - clean_restart $binfile + clean_restart $::testfile # Make sure we're disconnected, in case we're testing with an # extended-remote board, therefore already connected. diff --git a/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp b/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp index 4e5ee98..01d7e46 100644 --- a/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp +++ b/gdb/testsuite/gdb.server/connect-with-no-symbol-file.exp @@ -69,7 +69,7 @@ proc connect_no_symbol_file { sysroot action } { } elseif { $action == "permission" } { remote_exec target "chmod 000 $target_exec" } - + # Connect to GDBserver. gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport } diff --git a/gdb/testsuite/gdb.server/connect-without-multi-process.exp b/gdb/testsuite/gdb.server/connect-without-multi-process.exp index 1a7246c..f47e57e 100644 --- a/gdb/testsuite/gdb.server/connect-without-multi-process.exp +++ b/gdb/testsuite/gdb.server/connect-without-multi-process.exp @@ -38,7 +38,7 @@ proc do_test {multiprocess} { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart $binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an diff --git a/gdb/testsuite/gdb.server/exit-multiple-threads.exp b/gdb/testsuite/gdb.server/exit-multiple-threads.exp index 73e4c32..be29f9e 100644 --- a/gdb/testsuite/gdb.server/exit-multiple-threads.exp +++ b/gdb/testsuite/gdb.server/exit-multiple-threads.exp @@ -45,7 +45,8 @@ proc prepare_for_test { executable target_executable disable_multi_process } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart ${executable} + clean_restart + gdb_load $executable } # Make sure we're disconnected, in case we're testing with an @@ -69,7 +70,7 @@ proc prepare_for_test { executable target_executable disable_multi_process } { set gdbserver_protocol [lindex $res 0] set gdbserver_gdbport [lindex $res 1] set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] - if ![gdb_assert {$res == 0} "connect"] { + if { ![gdb_assert {$res == 0} "connect"] } { return } diff --git a/gdb/testsuite/gdb.server/ext-attach.exp b/gdb/testsuite/gdb.server/ext-attach.exp index bda3ae9..6af2ede 100644 --- a/gdb/testsuite/gdb.server/ext-attach.exp +++ b/gdb/testsuite/gdb.server/ext-attach.exp @@ -45,7 +45,7 @@ proc run_test { target_async target_non_stop to_disable } { set ::GDBFLAGS "$::GDBFLAGS -ex \"set sysroot\"" } - clean_restart $::binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an diff --git a/gdb/testsuite/gdb.server/ext-run.exp b/gdb/testsuite/gdb.server/ext-run.exp index 2286454..f4ff546 100644 --- a/gdb/testsuite/gdb.server/ext-run.exp +++ b/gdb/testsuite/gdb.server/ext-run.exp @@ -37,7 +37,7 @@ save_vars { GDBFLAGS } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart $binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an diff --git a/gdb/testsuite/gdb.server/extended-remote-restart.exp b/gdb/testsuite/gdb.server/extended-remote-restart.exp index df722a1..a5ba53c 100644 --- a/gdb/testsuite/gdb.server/extended-remote-restart.exp +++ b/gdb/testsuite/gdb.server/extended-remote-restart.exp @@ -58,7 +58,7 @@ proc test_reload { do_kill_p follow_child_p } { global decimal global binfile - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 @@ -70,7 +70,7 @@ proc test_reload { do_kill_p follow_child_p } { set live_inf_ptn "process $decimal" set dead_inf_ptn "<null>" - if ${follow_child_p} { + if { $follow_child_p } { gdb_test_no_output "set follow-fork child" set parent_prefix " " set child_prefix "\\*" diff --git a/gdb/testsuite/gdb.server/fileio-packets.exp b/gdb/testsuite/gdb.server/fileio-packets.exp new file mode 100644 index 0000000..9435efd --- /dev/null +++ b/gdb/testsuite/gdb.server/fileio-packets.exp @@ -0,0 +1,66 @@ +# 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 some remote file I/O. The associated Python script uses the +# Python API to create and send vFile:* packets to gdbserver to +# perform actions like 'stat'. The same action is then performed +# directly from Python (e.g. a 'stat' is performed), and the results, +# from gdbserver, and from the local syscall, are compared. + +load_lib gdb-python.exp +load_lib gdbserver-support.exp + +require allow_python_tests +require allow_gdbserver_tests +require {!is_remote host} +require {!is_remote target} + +standard_testfile + +clean_restart + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] +gdb_test_no_output "source $pyfile" "source the script" + +# Start gdbserver, but always in extended-remote mode, and then +# connect to it from GDB. +set res [gdbserver_start "--multi --once" ""] +set gdbserver_protocol "extended-remote" +set gdbserver_gdbport [lindex $res 1] +gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport + +gdb_test_no_output "set python print-stack full" + +set test_file_1 [standard_output_file "test_file_1"] +remote_exec host "touch $test_file_1" + +set test_file_2 [standard_output_file "test_file_2"] +remote_exec host "ln -s $test_file_1 $test_file_2" + +gdb_test "python check_lstat(\"$test_file_1\")" "PASS" \ + "check remote lstat works on a normal file" + +gdb_test "python check_lstat(\"$test_file_2\")" "PASS" \ + "check remote lstat works on a symbolic link" + +gdb_test "python check_stat(\"$test_file_1\")" "PASS" \ + "check remote stat works on a normal file" + +gdb_test "python check_stat(\"$test_file_2\")" "PASS" \ + "check remote stat works on a symbolic link" diff --git a/gdb/testsuite/gdb.server/fileio-packets.py b/gdb/testsuite/gdb.server/fileio-packets.py new file mode 100644 index 0000000..f132e91 --- /dev/null +++ b/gdb/testsuite/gdb.server/fileio-packets.py @@ -0,0 +1,208 @@ +# Copyright (C) 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/>. + +import os +import stat + + +# Hex encode INPUT_STRING in the same way that GDB does. Each +# character in INPUT_STRING is expanded to its two digit hex +# representation in the returned string. +# +# Only ASCII characters may appear in INPUT_STRING, this is more +# restrictive than GDB, but is good enough for testing. +def hex_encode(input_string): + byte_string = input_string.encode("ascii") + hex_string = byte_string.hex() + return hex_string + + +# Binary remote data packets can contain some escaped bytes. Decode +# the packet now. +def unescape_remote_data(buf): + escaped = False + res = bytearray() + for b in buf: + if escaped: + res.append(b ^ 0x20) + escaped = False + elif b == ord("}"): + escaped = True + else: + res.append(b) + res = bytes(res) + return res + + +# Decode the results of a remote stat like command from BUF. Returns +# None if BUF is not a valid stat result (e.g. if it indicates an +# error, or the buffer is too short). If BUF is valid then the fields +# are decoded according to the GDB remote protocol and placed into a +# dictionary, this dictionary is then returned. +def decode_stat_reply(buf, byteorder="big"): + + buf = unescape_remote_data(buf) + + if ( + buf[0] != ord("F") + or buf[1] != ord("4") + or buf[2] != ord("0") + or buf[3] != ord(";") + or len(buf) != 68 + ): + l = len(buf) + print(f"decode_stat_reply failed: {buf}\t(length = {l})") + return None + + # Discard the 'F40;' prefix. The rest is the 64 bytes of data to + # be decoded. + buf = buf[4:] + + st_dev = int.from_bytes(buf[0:4], byteorder=byteorder) + st_ino = int.from_bytes(buf[4:8], byteorder=byteorder) + st_mode = int.from_bytes(buf[8:12], byteorder=byteorder) + st_nlink = int.from_bytes(buf[12:16], byteorder=byteorder) + st_uid = int.from_bytes(buf[16:20], byteorder=byteorder) + st_gid = int.from_bytes(buf[20:24], byteorder=byteorder) + st_rdev = int.from_bytes(buf[24:28], byteorder=byteorder) + st_size = int.from_bytes(buf[28:36], byteorder=byteorder) + st_blksize = int.from_bytes(buf[36:44], byteorder=byteorder) + st_blocks = int.from_bytes(buf[44:52], byteorder=byteorder) + st_atime = int.from_bytes(buf[52:56], byteorder=byteorder) + st_mtime = int.from_bytes(buf[56:60], byteorder=byteorder) + st_ctime = int.from_bytes(buf[60:64], byteorder=byteorder) + + return { + "st_dev": st_dev, + "st_ino": st_ino, + "st_mode": st_mode, + "st_nlink": st_nlink, + "st_uid": st_uid, + "st_gid": st_gid, + "st_rdev": st_rdev, + "st_size": st_size, + "st_blksize": st_blksize, + "st_blocks": st_blocks, + "st_atime": st_atime, + "st_mtime": st_mtime, + "st_ctime": st_ctime, + } + + +# Perform an lstat of remote file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def remote_lstat(filename): + conn = gdb.selected_inferior().connection + if not isinstance(conn, gdb.RemoteTargetConnection): + raise gdb.GdbError("connection is the wrong type") + + filename_hex = hex_encode(filename) + reply = conn.send_packet("vFile:lstat:%s" % filename_hex) + + stat = decode_stat_reply(reply) + return stat + + +# Perform a stat of remote file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def remote_stat(filename): + conn = gdb.selected_inferior().connection + if not isinstance(conn, gdb.RemoteTargetConnection): + raise gdb.GdbError("connection is the wrong type") + + filename_hex = hex_encode(filename) + reply = conn.send_packet("vFile:stat:%s" % filename_hex) + + stat = decode_stat_reply(reply) + return stat + + +# Convert a stat_result object to a dictionary that should match the +# dictionary built from the remote protocol reply. +def stat_result_to_dict(res): + # GDB doesn't support the S_IFLNK flag for the remote protocol, so + # clear that flag in the local results. + if stat.S_ISLNK(res.st_mode): + st_mode = stat.S_IMODE(res.st_mode) + else: + st_mode = res.st_mode + + # GDB returns an integer for these fields, while Python returns a + # floating point value. Convert back to an integer to match GDB. + st_atime = int(res.st_atime) + st_mtime = int(res.st_mtime) + st_ctime = int(res.st_ctime) + + return { + "st_dev": res.st_dev, + "st_ino": res.st_ino, + "st_mode": st_mode, + "st_nlink": res.st_nlink, + "st_uid": res.st_uid, + "st_gid": res.st_gid, + "st_rdev": res.st_rdev, + "st_size": res.st_size, + "st_blksize": res.st_blksize, + "st_blocks": res.st_blocks, + "st_atime": st_atime, + "st_mtime": st_mtime, + "st_ctime": st_ctime, + } + + +# Perform an lstat of local file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def local_lstat(filename): + res = os.lstat(filename) + return stat_result_to_dict(res) + + +# Perform an lstat of local file FILENAME, and create a dictionary of +# the results, the keys are the fields of the stat structure. +def local_stat(filename): + res = os.stat(filename) + return stat_result_to_dict(res) + + +# Perform a remote lstat using GDB, and a local lstat using os.lstat. +# Compare the results to check they are the same. +# +# For this test to work correctly, gdbserver, and GDB (where this +# Python script is running), must see the same filesystem. +def check_lstat(filename): + s1 = remote_lstat(filename) + s2 = local_lstat(filename) + + print(f"remote = {s1}") + print(f"local = {s2}") + + assert s1 == s2 + print("PASS") + + +# Perform a remote stat using GDB, and a local stat using os.stat. +# Compare the results to check they are the same. +# +# For this test to work correctly, gdbserver, and GDB (where this +# Python script is running), must see the same filesystem. +def check_stat(filename): + s1 = remote_stat(filename) + s2 = local_stat(filename) + + print(f"remote = {s1}") + print(f"local = {s2}") + + assert s1 == s2 + print("PASS") diff --git a/gdb/testsuite/gdb.server/inferior-args.c b/gdb/testsuite/gdb.server/inferior-args.c new file mode 100644 index 0000000..3bc3ff7 --- /dev/null +++ b/gdb/testsuite/gdb.server/inferior-args.c @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023-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/>. */ + +#include <stdio.h> + +int +main (int argc, char **argv) +{ + for (int i = 0; i < argc; i++) + printf ("[%d] %s\n", i, argv[i]); + + return 0; +} diff --git a/gdb/testsuite/gdb.server/inferior-args.exp b/gdb/testsuite/gdb.server/inferior-args.exp new file mode 100644 index 0000000..18ac5a3 --- /dev/null +++ b/gdb/testsuite/gdb.server/inferior-args.exp @@ -0,0 +1,156 @@ +# Copyright 2023-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 passing inferior arguments on the gdbserver command line. Tests the +# flags --no-startup-with-shell and --no-escape-args that change how GDB +# interprets the arguments being passed. + +# This test relies on starting gdbserver using the pipe syntax. Not sure +# how well this will run if part of this test is being run elsewhere. +require {!is_remote target} {!is_remote host} + +load_lib gdbserver-support.exp + +standard_testfile + +require allow_gdbserver_tests + +set gdbserver [find_gdbserver] +if { $gdbserver == "" } { + unsupported "could not find gdbserver" + return +} + +standard_testfile +if {[build_executable "failed to prepare" $testfile $srcfile]} { + return -1 +} + +# EXTENDED_P is a boolean, when true gdbserver is started with --multi, and +# GDB connects using extended-remote protocol. Otherwise, no --multi flag +# is passed, and GDB connects with the remote protocol. +# +# WITH_SHELL_P is a boolean, when true gdbserver starts the inferior using a +# shell, when false gdbserver is passed the --no-startup-with-shell command +# line option, and should not start the inferior through a shell. +# +# ESCAPE_P is a boolean, when true gdbserver applies escapes to the inferior +# arguments, when false gdbserver is passed the --no-escape-args command +# line option, and should not apply escaping to the inferior arguments. +# +# ARGLIST is a list of inferior arguments to add to the gdbserver command +# line. +# +# RE_LIST is a list of patterns to match, one for each of ARGLIST. Once the +# inferior is started we check that each argument matches its corresponding +# entry in RE_LIST. +proc do_test_inner { extended_p with_shell_p escape_p arglist re_list } { + + clean_restart ${::testfile} + + gdb_test_no_output "set sysroot" + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + if { $extended_p } { + set protocol "extended-remote" + } else { + set protocol "remote" + } + + if { $escape_p } { + set esc_opt "" + } else { + set esc_opt "--no-escape-args" + } + + if { $with_shell_p } { + set shell_opt "" + } else { + set shell_opt "--no-startup-with-shell" + } + + gdb_test "target ${protocol} | ${::gdbserver} --once ${esc_opt} ${shell_opt} - ${::binfile} ${arglist}" \ + ".*" \ + "start gdbserver over stdin" + + gdb_breakpoint main + gdb_continue_to_breakpoint main + + set expected_len [expr {1 + [llength $re_list]}] + gdb_test "print argc" \ + "\\\$$::decimal = $expected_len" "check argc" + + set i 1 + foreach arg $re_list { + gdb_test "print argv\[$i\]" \ + "\\\$$::decimal = $::hex \"$arg\"" \ + "check argv\[$i\]" + incr i + } +} + +# Wrapper around do_test_inner. NAME is the name of this test, used to make +# the test names unique. ARGLIST is the list of inferior arguments to add +# to the gdbserver command line. +# +# The optional RE_ESC_LIST is a list of patterns to match against the +# inferior arguments once the inferior is started, one pattern for each +# argument. If RE_ESC_LIST is not given then ARGLIST is reused, which +# implies the arguments appear unmodified in the test output. +# +# The optional RE_NO_ESC_LIST is a list of patterns to match against the +# inferior arguments when gdbserver is started with --no-escape-args or +# --no-startup-with-shell. There should be one pattern for each argument. +# If RE_NO_ESC_LIST is not given then RE_ESC_LIST is reused, which implies +# there's no difference in how the arguments are printed. +proc args_test { name arglist {re_esc_list {}} {re_no_esc_list {}} } { + if {[llength $re_esc_list] == 0} { + set re_esc_list $arglist + } + + if {[llength $re_no_esc_list] == 0} { + set re_no_esc_list $re_esc_list + } + + foreach_with_prefix extended_p { yes no } { + foreach_with_prefix startup_with_shell { on off } { + foreach_with_prefix escape_p { yes no } { + if { $escape_p || !$startup_with_shell } { + set re_list $re_esc_list + } else { + set re_list $re_no_esc_list + } + + with_test_prefix "$name" { + do_test_inner $extended_p $startup_with_shell \ + $escape_p $arglist $re_list + } + } + } + } +} + +args_test "basic" {a b c} +args_test "one empty" {1 "" 3} +args_test "two empty" {1 "" "" 3} +args_test "one with single quotes" {1 "''" 3} +args_test "lone double quote" {"1" \" 3} {1 \\\\\" 3} +save_vars { env(TEST) } { + set env(TEST) "ABCD" + args_test "shell variable" {\$TEST} {\\$TEST} {ABCD} +} diff --git a/gdb/testsuite/gdb.server/monitor-exit-quit.exp b/gdb/testsuite/gdb.server/monitor-exit-quit.exp index ce63560..74842a0 100644 --- a/gdb/testsuite/gdb.server/monitor-exit-quit.exp +++ b/gdb/testsuite/gdb.server/monitor-exit-quit.exp @@ -34,7 +34,7 @@ save_vars { GDBFLAGS } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart $binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an @@ -70,7 +70,7 @@ gdb_test_multiple "quit" "" { # Cleanup, as in default_gdb_exit. if { $do_cleanup } { - if ![is_remote host] { + if { ![is_remote host] } { remote_close host } unset gdb_spawn_id diff --git a/gdb/testsuite/gdb.server/no-thread-db.exp b/gdb/testsuite/gdb.server/no-thread-db.exp index cc24708..9fd2090 100644 --- a/gdb/testsuite/gdb.server/no-thread-db.exp +++ b/gdb/testsuite/gdb.server/no-thread-db.exp @@ -57,6 +57,8 @@ gdb_breakpoint ${srcfile}:[gdb_get_line_number "after tls assignment"] gdb_continue_to_breakpoint "after tls assignment" # Printing a tls variable should fail gracefully without a libthread_db. +# Alternately, the correct answer might be printed due GDB's internal +# TLS support for some targets. set re_exec "\[^\r\n\]*[file tail $binfile]" gdb_test "print foo" \ - "Cannot find thread-local storage for Thread \[^,\]+, executable file $re_exec:\[\r\n\]+Remote target failed to process qGetTLSAddr request" + "= 1|(?:Cannot find thread-local storage for Thread \[^,\]+, executable file $re_exec:\[\r\n\]+Remote target failed to process qGetTLSAddr request)" diff --git a/gdb/testsuite/gdb.server/non-existing-program.exp b/gdb/testsuite/gdb.server/non-existing-program.exp index 7119723..ec9c044 100644 --- a/gdb/testsuite/gdb.server/non-existing-program.exp +++ b/gdb/testsuite/gdb.server/non-existing-program.exp @@ -34,6 +34,8 @@ if { $gdbserver == "" } { # to spawn the program before opening the connection. set spawn_id [remote_spawn target "$gdbserver stdio non-existing-program"] +set eol {[\r\n]} + set msg "gdbserver exits cleanly" set saw_exiting 0 expect { @@ -51,7 +53,7 @@ expect { exp_continue } # This is what we get on Windows. - -re "Error creating process\r\n\r\nExiting\r\n" { + -re "Error creating process.*$eol+Exiting$eol+" { set saw_exiting 1 exp_continue } diff --git a/gdb/testsuite/gdb.server/pread-offset-size.S b/gdb/testsuite/gdb.server/pread-offset-size.S new file mode 100644 index 0000000..6ca8cf0 --- /dev/null +++ b/gdb/testsuite/gdb.server/pread-offset-size.S @@ -0,0 +1,29 @@ +/* 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/>. */ + +/* Here we are trying to create a large binary (> 2 GB), + 3742415472 bytes is about 3.5 gigabytes. */ + + .text + .globl _start +_start: + .skip 3742415472 + ret + .globl f + .type f, @function +f: + ret diff --git a/gdb/testsuite/gdb.server/pread-offset-size.exp b/gdb/testsuite/gdb.server/pread-offset-size.exp new file mode 100644 index 0000000..54e67c5 --- /dev/null +++ b/gdb/testsuite/gdb.server/pread-offset-size.exp @@ -0,0 +1,49 @@ +# Copyright (C) 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/>. +# +# Check that GDBserver's vFile::pread implementation is able to access +# large files (> 2GB). + +load_lib gdbserver-support.exp + +require allow_gdbserver_tests + +standard_testfile .S + +if { [prepare_for_testing ${testfile}.exp $testfile \ + $srcfile {debug additional_flags=-nostdlib} ] } { + return -1 +} + +clean_restart + +gdb_test_no_output "set remote exec-file $binfile" \ + "set remote exec-file" + +# Make sure we're disconnected, in case we're testing with an +# extended-remote board, therefore already connected. +gdb_test "disconnect" ".*" + +set res [gdbserver_spawn ""] +set gdbserver_protocol [lindex $res 0] +set gdbserver_gdbport [lindex $res 1] + +gdb_test "target $gdbserver_protocol $gdbserver_gdbport" \ + "Remote debugging using .*" \ + "target $gdbserver_protocol" + +# If loading the large binary was successful, we should be able to +# place a breakpoint on f. +gdb_test "break f" "Breakpoint 1.*" diff --git a/gdb/testsuite/gdb.server/reconnect-ctrl-c.exp b/gdb/testsuite/gdb.server/reconnect-ctrl-c.exp index 83869a3..bcab2de 100644 --- a/gdb/testsuite/gdb.server/reconnect-ctrl-c.exp +++ b/gdb/testsuite/gdb.server/reconnect-ctrl-c.exp @@ -51,7 +51,7 @@ proc connect_continue_ctrl_c {} { global gdbserver_protocol gdbserver_gdbport set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] - if ![gdb_assert {$res == 0} "connect"] { + if { ![gdb_assert {$res == 0} "connect"] } { return } diff --git a/gdb/testsuite/gdb.server/server-exec-info.exp b/gdb/testsuite/gdb.server/server-exec-info.exp index fccf075..007290a 100644 --- a/gdb/testsuite/gdb.server/server-exec-info.exp +++ b/gdb/testsuite/gdb.server/server-exec-info.exp @@ -21,7 +21,7 @@ load_lib gdbserver-support.exp require allow_gdbserver_tests allow_shlib_tests standard_testfile server.c -if [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] { +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { return -1 } diff --git a/gdb/testsuite/gdb.server/server-kill.exp b/gdb/testsuite/gdb.server/server-kill.exp index 0a759ae..a9fcabb 100644 --- a/gdb/testsuite/gdb.server/server-kill.exp +++ b/gdb/testsuite/gdb.server/server-kill.exp @@ -43,7 +43,7 @@ proc prepare {} { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart $binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an diff --git a/gdb/testsuite/gdb.server/server-pipe.exp b/gdb/testsuite/gdb.server/server-pipe.exp index d786946..20ca0b0 100644 --- a/gdb/testsuite/gdb.server/server-pipe.exp +++ b/gdb/testsuite/gdb.server/server-pipe.exp @@ -50,7 +50,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile debug]} { # the contents of the gdb.TargetConnection.details string. proc do_test { target } { global timeout - clean_restart ${::binfile} + clean_restart ${::testfile} # Make sure we're disconnected, in case we're testing with an # extended-remote board, therefore already connected. diff --git a/gdb/testsuite/gdb.server/server-run.exp b/gdb/testsuite/gdb.server/server-run.exp index 6c9db98..53b3278 100644 --- a/gdb/testsuite/gdb.server/server-run.exp +++ b/gdb/testsuite/gdb.server/server-run.exp @@ -34,7 +34,7 @@ save_vars { GDBFLAGS } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart $binfile + clean_restart $::testfile } # Make sure we're disconnected, in case we're testing with an diff --git a/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp b/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp index 42608c4..f1c68a5 100644 --- a/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp +++ b/gdb/testsuite/gdb.server/stop-reply-no-thread-multi.exp @@ -54,7 +54,7 @@ proc run_test { target_non_stop disable_feature } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart ${binfile} + clean_restart ${::testfile} } # Make sure we're disconnected, in case we're testing with an @@ -78,7 +78,7 @@ proc run_test { target_non_stop disable_feature } { "Support for the 'multiprocess-feature' packet on future remote targets is set to \"off\"." set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] - if ![gdb_assert {$res == 0} "connect"] { + if { ![gdb_assert {$res == 0} "connect"] } { return } diff --git a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp index 38402e8..aa77095 100644 --- a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp +++ b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp @@ -42,7 +42,7 @@ proc run_test { disable_feature target_nonstop } { set GDBFLAGS "$GDBFLAGS -ex \"set sysroot\"" } - clean_restart ${binfile} + clean_restart ${::testfile} } # Make sure we're disconnected, in case we're testing with an @@ -70,7 +70,7 @@ proc run_test { disable_feature target_nonstop } { gdb_test_no_output "maint set target-non-stop ${target_nonstop}" set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] - if ![gdb_assert {$res == 0} "connect"] { + if { ![gdb_assert {$res == 0} "connect"] } { return } diff --git a/gdb/testsuite/gdb.stabs/weird.def b/gdb/testsuite/gdb.stabs/weird.def index 179b126..f809963 100644 --- a/gdb/testsuite/gdb.stabs/weird.def +++ b/gdb/testsuite/gdb.stabs/weird.def @@ -294,7 +294,7 @@ attr69: # Using double quotes requires an escaping, as the stabs string # is a double quote delimited string. .stabs "constString2:c=s\"Double quote String2\"", N_LSYM,0,0, 0 -# Escaping sinlge quote with is easy +# Escaping single quote with is easy .stabs "constString3:c=s'String3 with embedded quote \' in the middle'", N_LSYM,0,0, 0 # Esaping double quotes is less clear... .stabs "constString4:c=s\"String4 with embedded quote \\" in the middle\"", N_LSYM,0,0, 0 diff --git a/gdb/testsuite/gdb.testsuite/board-sanity.exp b/gdb/testsuite/gdb.testsuite/board-sanity.exp index 9c80282..7b9a19e 100644 --- a/gdb/testsuite/gdb.testsuite/board-sanity.exp +++ b/gdb/testsuite/gdb.testsuite/board-sanity.exp @@ -44,7 +44,7 @@ proc test_remote { remote host_is_target } { if { $host_is_target } { set res [remote_file $other_remote exists $file] gdb_assert { $res != $exists_ok } \ - "$other_remote copy does not exist" + "$other_remote copy does not exist" } } @@ -80,7 +80,7 @@ proc test_remote { remote host_is_target } { set build_file [remote_upload $remote $file] gdb_assert { [string equal [file tail $build_file] $file] == 1 } \ "remote_upload returns valid value" - + set res [remote_file $remote delete $file] gdb_assert { [string equal $res $delete_ok] == 1 } \ "remove $remote copy" @@ -92,7 +92,7 @@ proc test_remote { remote host_is_target } { if { $host_is_target } { set res [remote_file $other_remote exists $file] gdb_assert { $res != $exists_ok } \ - "$other_remote copy does not exist" + "$other_remote copy does not exist" } set res [remote_file build exists $file] diff --git a/gdb/testsuite/gdb.testsuite/gdb-caching-proc-consistency.exp b/gdb/testsuite/gdb.testsuite/gdb-caching-proc-consistency.exp index 0957dbd..27f905e 100644 --- a/gdb/testsuite/gdb.testsuite/gdb-caching-proc-consistency.exp +++ b/gdb/testsuite/gdb.testsuite/gdb-caching-proc-consistency.exp @@ -63,8 +63,8 @@ proc test_file { file } { set fp [open $file] while { [gets $fp line] >= 0 } { - if [regexp -- "^gdb_caching_proc \[ \t\]*(\[^ \t\]*)" $line \ - match procname] { + if { [regexp -- "^gdb_caching_proc \[ \t\]*(\[^ \t\]*)" $line \ + match procname] } { lappend procnames $procname } } @@ -95,7 +95,8 @@ proc test_file { file } { } if { $setup_gdb } { - clean_restart $obj + clean_restart + gdb_load $obj } test_proc $procname @@ -113,7 +114,7 @@ if { ![gdb_simple_compile $me $src executable] } { } # Test gdb_caching_procs in gdb/testsuite/lib/*.exp -set files [eval glob -types f $srcdir/lib/*.exp] +set files [glob -types f $srcdir/lib/*.exp] set files [lsort $files] foreach file $files { test_file $file diff --git a/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp b/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp index f9610af..6b46b1c 100644 --- a/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp +++ b/gdb/testsuite/gdb.testsuite/gdb-caching-proc.exp @@ -22,23 +22,32 @@ gdb_caching_proc gdb_testsuite_gdb_caching_proc_exp_arg { arg } { return $arg } +gdb_caching_proc gdb_testsuite_gdb_caching_proc_exp_arg_nested { arg } { + incr ::count + return [gdb_testsuite_gdb_caching_proc_exp_arg $arg] +} + +# List of "expected $::count after running expression" and +# "expression". set assertions { - { [gdb_testsuite_gdb_caching_proc_exp_noarg] == 1 } - { [gdb_testsuite_gdb_caching_proc_exp_arg 1] == 1 } - { [gdb_testsuite_gdb_caching_proc_exp_arg "foo foo"] == "foo foo" } + 1 { [gdb_testsuite_gdb_caching_proc_exp_noarg] == 1 } + 1 { [gdb_testsuite_gdb_caching_proc_exp_arg 1] == 1 } + 1 { [gdb_testsuite_gdb_caching_proc_exp_arg "foo foo"] == "foo foo" } + 1 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "foo foo"] == "foo foo" } + 2 { [gdb_testsuite_gdb_caching_proc_exp_arg_nested "bar bar"] == "bar bar" } } set assertion_nr 0 -foreach assertion $assertions { +foreach {expected_count assertion} $assertions { with_test_prefix $assertion_nr { set ::count 0 gdb_assert $assertion - gdb_assert { $::count == 1 } + gdb_assert { $::count == $expected_count } with_test_prefix cached { gdb_assert $assertion - gdb_assert { $::count == 1 } + gdb_assert { $::count == $expected_count } } } incr assertion_nr diff --git a/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp new file mode 100644 index 0000000..a05ce61 --- /dev/null +++ b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp @@ -0,0 +1,84 @@ +# 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 gdb_test_multiple -lbl, particularly with patterns that share a +# common prefix. + +standard_testfile + +clean_restart + +gdb_test_no_output "source ${srcdir}/${subdir}/$testfile.gdb" \ + "source gdb test script" + +set saw_prompt 0 +set saw_prefix 0 +set saw_command 0 +set saw_prefix_foo 0 +set saw_prefix_bar 0 + +# #1 - We need anchors so that the "prefix foo" pattern below does not +# match when the expect output buffer contains: +# +# "\r\nprefix xxx\r\n\prefix foo\r\n" +# +# #2 - We need an anchor on the prompt match as otherwise the prompt +# regexp would match: +# +# "\r\nmeant-to-be-matched-by-lbl-2\r\nprefix xxx\r\n(gdb) " +# +# This test would fail if -lbl did not force the built-in prompt match +# regexp to have an anchor as well, as without it, the built-in prompt +# regexp would have the exact same issue as #2 above. + +gdb_test_multiple "command" "" -lbl { + -re "^command(?=\r\n)" { + verbose -log <COMMAND> + incr saw_command + exp_continue + } + -re "^\r\nprefix foo(?=\r\n)" { + verbose -log <PREFIX-FOO> + incr saw_prefix_foo + exp_continue + } + -re "^\r\nprefix bar(?=\r\n)" { + verbose -log <PREFIX-BAR> + incr saw_prefix_bar + exp_continue + } + -re "^\r\nprefix \[^\r\n\]*(?=\r\n)" { + verbose -log <PREFIX> + incr saw_prefix + exp_continue + } + -re "^\r\n$gdb_prompt $" { + verbose -log <PROMPT> + incr saw_prompt + pass $gdb_test_name + } +} + +verbose -log "saw_command: $saw_command" +verbose -log "saw_prefix_foo: $saw_prefix_foo" +verbose -log "saw_prefix_bar: $saw_prefix_bar" +verbose -log "saw_prefix: $saw_prefix" +verbose -log "saw_prompt: $saw_prompt" + +gdb_assert {$saw_command == 1} +gdb_assert {$saw_prefix_foo == 1} +gdb_assert {$saw_prefix_bar == 1} +gdb_assert {$saw_prefix == 3} +gdb_assert {$saw_prompt == 1} diff --git a/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb new file mode 100755 index 0000000..8c94dfa --- /dev/null +++ b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb @@ -0,0 +1,25 @@ +# 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/>. + +define command + echo prefix xxx\n + echo meant-to-be-matched-by-lbl-1\n + echo prefix foo\n + echo prefix bar\n + echo meant-to-be-matched-by-lbl-2\n + echo prefix xxx\n + echo prefix xxx\n + echo meant-to-be-matched-by-lbl-3\n +end diff --git a/gdb/testsuite/gdb.testsuite/mount-point-map.exp b/gdb/testsuite/gdb.testsuite/mount-point-map.exp new file mode 100644 index 0000000..9e462bb --- /dev/null +++ b/gdb/testsuite/gdb.testsuite/mount-point-map.exp @@ -0,0 +1,49 @@ +# 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/>. + +set unix_to_win { + /bin C:/msys64/usr/bin + /c C: + / C:/msys64 +} + +# Test that FROM is normalized to TO. + +proc test {from to} { + set got [host_file_normalize_mingw $from $::unix_to_win] + verbose -log "input: $from" + verbose -log "expected: $to" + verbose -log "got: $got" + gdb_assert {$got == $to} $from +} + +# Drive letters always get a '/' suffix, other Windows file names do +# not. +test "/" "C:/msys64" +test "/c" "C:/" +test "/bin" "C:/msys64/usr/bin" + +# A file name that already starts with a drive letter. +test "C:/msys64" "C:/msys64" + +# A subdir/subfile under each mount. +test "/foo" "C:/msys64/foo" +test "/c/foo" "C:/foo" +test "/bin/foo" "C:/msys64/usr/bin/foo" + +# Test slash normalization. +test "//" "C:/msys64" +test "/c///foo//bar//" "C:/foo/bar" +# We don't currently handle UNC paths. +test "//server///" "C:/msys64/server" diff --git a/gdb/testsuite/gdb.testsuite/with-override.exp b/gdb/testsuite/gdb.testsuite/with-override.exp index 9180150..2a316f9 100644 --- a/gdb/testsuite/gdb.testsuite/with-override.exp +++ b/gdb/testsuite/gdb.testsuite/with-override.exp @@ -42,6 +42,10 @@ with_test_prefix no-args { gdb_assert { [foo] == 2 } } } + + with_test_prefix "foo1 again" { + gdb_assert { [foo] == 1 } + } } with_test_prefix after { @@ -50,11 +54,11 @@ with_test_prefix no-args { } proc foo { {a 0} } { - return [expr $a + 1] + return [expr {$a + 1}] } proc foo_plus_1 { {a 0} } { - return [expr $a + 2] + return [expr {$a + 2}] } with_test_prefix default-arg { diff --git a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp index b41e3b2..64d2f53 100644 --- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp +++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp @@ -51,10 +51,10 @@ proc test { non_stop } { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop $non_stop\"" - clean_restart ${binfile} + clean_restart ${::testfile} } - if ![runto setup_done] { + if {![runto setup_done]} { return -1 } @@ -74,42 +74,45 @@ proc test { non_stop } { delete_breakpoints # Start the second inferior. - with_test_prefix "second inferior" { - # With stub targets that do reload on run, if we let the new - # inferior share inferior 1's connection, runto would - # fail because GDB is already connected to something, like - # e.g. with --target_board=native-gdbserver: - # - # (gdb) kill - # ... - # (gdb) target remote localhost:2348 - # Already connected to a remote target. Disconnect? (y or n) - # - # Instead, start the inferior with no connection, and let - # gdb_load/runto spawn a new remote connection/gdbserver. - # - # OTOH, with extended-remote, we must let the new inferior - # reuse the current connection, so that runto below can - # issue the "run" command, and have the inferior run on the - # remote target. If we forced no connection, then "run" would - # either fail if "set auto-connect-native-target" is on, like - # the native-extended-gdbserver board enforces, or it would - # run the inferior on the native target, which isn't what is - # being tested. - # - # Since it's reload_on_run targets that need special care, we - # default to reusing the connection on most targets. - if [target_info exists gdb,do_reload_on_run] { - gdb_test "add-inferior -no-connection" "New inferior 2.*" - } else { - gdb_test "add-inferior" "New inferior 2.*" - } - gdb_test "inferior 2" "Switching to inferior 2 .*" - - gdb_load $binfile - - if ![runto setup_done] { - return -1 + if {[allow_multi_inferior_tests]} { + with_test_prefix "second inferior" { + # With stub targets that do reload on run, if we let the + # new inferior share inferior 1's connection, runto would + # fail because GDB is already connected to something, like + # e.g. with --target_board=native-gdbserver: + # + # (gdb) kill + # ... + # (gdb) target remote localhost:2348 + # Already connected to a remote target. Disconnect? (y or n) + # + # Instead, start the inferior with no connection, and let + # gdb_load/runto spawn a new remote connection/gdbserver. + # + # OTOH, with extended-remote, we must let the new inferior + # reuse the current connection, so that runto below can + # issue the "run" command, and have the inferior run on + # the remote target. If we forced no connection, then + # "run" would either fail if "set + # auto-connect-native-target" is on, like the + # native-extended-gdbserver board enforces, or it would + # run the inferior on the native target, which isn't what + # is being tested. + # + # Since it's reload_on_run targets that need special care, + # we default to reusing the connection on most targets. + if {[target_info exists gdb,do_reload_on_run]} { + gdb_test "add-inferior -no-connection" "New inferior 2.*" + } else { + gdb_test "add-inferior" "New inferior 2.*" + } + gdb_test "inferior 2" "Switching to inferior 2 .*" + + gdb_load $binfile + + if {![runto setup_done]} { + return -1 + } } } @@ -158,13 +161,15 @@ proc test { non_stop } { verbose -log "xxxxx: iteration $iter" gdb_test -nopass "info threads" - if {$inf == 1} { - set inf 2 - } else { - set inf 1 - } + if {[allow_multi_inferior_tests]} { + if {$inf == 1} { + set inf 2 + } else { + set inf 1 + } - my_gdb_test "inferior $inf" ".*" "inferior $inf" + my_gdb_test "inferior $inf" ".*" "inferior $inf" + } my_gdb_test "print global_var = 555" " = 555" \ "write to global_var" @@ -182,7 +187,7 @@ proc test { non_stop } { } foreach non_stop { "off" "on" } { - set stop_mode [expr ($non_stop=="off")?"all-stop":"non-stop"] + set stop_mode [expr {($non_stop=="off")?"all-stop":"non-stop"}] with_test_prefix "$stop_mode" { test $non_stop } diff --git a/gdb/testsuite/gdb.threads/async.exp b/gdb/testsuite/gdb.threads/async.exp index b1e562a..6347333 100644 --- a/gdb/testsuite/gdb.threads/async.exp +++ b/gdb/testsuite/gdb.threads/async.exp @@ -32,7 +32,7 @@ proc test_current_thread {expected_thr} { global gdb_prompt global binfile - clean_restart $binfile + clean_restart $::testfile if {![runto "all_started"]} { return diff --git a/gdb/testsuite/gdb.threads/attach-into-signal.exp b/gdb/testsuite/gdb.threads/attach-into-signal.exp index 0629736..ca452c1 100644 --- a/gdb/testsuite/gdb.threads/attach-into-signal.exp +++ b/gdb/testsuite/gdb.threads/attach-into-signal.exp @@ -58,7 +58,7 @@ proc corefunc { threadtype executable } { # nonthreaded: pass $test verbose -log "$test succeeded on the attempt # $attempt of $attempts" - set passes [expr $passes + 1] + set passes [expr {$passes + 1}] } -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { set ok 0 @@ -84,11 +84,11 @@ proc corefunc { threadtype executable } { if { $ok == 0} { # We just lack the luck, we should try it again. - set attempt [expr $attempt + 1] + set attempt [expr {$attempt + 1}] } else { pass $test verbose -log "$test succeeded on the attempt # $attempt of $attempts" - set passes [expr $passes + 1] + set passes [expr {$passes + 1}] } } }] != 0 } { diff --git a/gdb/testsuite/gdb.threads/attach-non-stop.exp b/gdb/testsuite/gdb.threads/attach-non-stop.exp index 9404edd..b8da5b1 100644 --- a/gdb/testsuite/gdb.threads/attach-non-stop.exp +++ b/gdb/testsuite/gdb.threads/attach-non-stop.exp @@ -37,7 +37,7 @@ proc test {target_non_stop non_stop cmd} { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\"" append GDBFLAGS " -ex \"set non-stop $non_stop\"" - clean_restart $binfile + clean_restart $::testfile } set test_spawn_id [spawn_wait_for_attach $binfile] diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp index e628adf..0391914 100644 --- a/gdb/testsuite/gdb.threads/attach-stopped.exp +++ b/gdb/testsuite/gdb.threads/attach-stopped.exp @@ -40,13 +40,13 @@ proc corefunc { threadtype } { set test_spawn_id [spawn_wait_for_attach $binfile] set testpid [spawn_id_get_pid $test_spawn_id] - # Stop the program + # Stop the program remote_exec build "kill -s STOP ${testpid}" - clean_restart $binfile + clean_restart $::testfile # Verify that we can attach to the stopped process. - + set test "$threadtype: attach2 to stopped, after setting file" gdb_test_multiple "attach $testpid" "$test" { -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.threads/bp_in_thread.exp b/gdb/testsuite/gdb.threads/bp_in_thread.exp index c63f179..5180c18 100644 --- a/gdb/testsuite/gdb.threads/bp_in_thread.exp +++ b/gdb/testsuite/gdb.threads/bp_in_thread.exp @@ -24,7 +24,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart $binfile +clean_restart $::testfile runto_main diff --git a/gdb/testsuite/gdb.threads/break-while-running.exp b/gdb/testsuite/gdb.threads/break-while-running.exp index fbc2b59..c1e1051 100644 --- a/gdb/testsuite/gdb.threads/break-while-running.exp +++ b/gdb/testsuite/gdb.threads/break-while-running.exp @@ -39,12 +39,12 @@ proc test { update_thread_list always_inserted non_stop } { global gdb_prompt global decimal - clean_restart $binfile + clean_restart $::testfile gdb_test_no_output "set non-stop $non_stop" gdb_test_no_output "set breakpoint always-inserted $always_inserted" - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -152,8 +152,8 @@ proc test { update_thread_list always_inserted non_stop } { foreach update_thread_list { true false } { foreach always_inserted { "off" "on" } { foreach non_stop { "off" "on" } { - set stop_mode [expr ($non_stop=="off")?"all-stop":"non-stop"] - set update_list_mode [expr ($update_thread_list)?"w/ithr":"wo/ithr"] + set stop_mode [expr {($non_stop=="off")?"all-stop":"non-stop"}] + set update_list_mode [expr {($update_thread_list)?"w/ithr":"wo/ithr"}] with_test_prefix "$update_list_mode: always-inserted $always_inserted: $stop_mode" { test $update_thread_list $always_inserted $non_stop } diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.exp b/gdb/testsuite/gdb.threads/check-libthread-db.exp index b97ab49..6d63185 100644 --- a/gdb/testsuite/gdb.threads/check-libthread-db.exp +++ b/gdb/testsuite/gdb.threads/check-libthread-db.exp @@ -40,7 +40,7 @@ set initial_thread_re "($thread_re1|$thread_re2)" with_test_prefix "user-initiated check" { # User-initiated check with libthread_db not loaded. - clean_restart ${binfile} + clean_restart ${::testfile} gdb_test "maint show check-libthread-db" \ "Whether to check libthread_db at load time is off." @@ -85,7 +85,7 @@ with_test_prefix "automated load-time check" { # Automated load-time check with NPTL possibly uninitialized. with_test_prefix "libpthread.so possibly not initialized" { - clean_restart ${binfile} + clean_restart ${::testfile} gdb_test_no_output "maint set check-libthread-db 1" gdb_test_no_output "set debug libthread-db 1" @@ -104,7 +104,7 @@ with_test_prefix "automated load-time check" { # Automated load-time check with NPTL fully operational. if { [can_spawn_for_attach] } { with_test_prefix "libpthread.so fully initialized" { - clean_restart ${binfile} + clean_restart ${::testfile} gdb_test_no_output "maint set check-libthread-db 1" gdb_test_no_output "set debug libthread-db 1" diff --git a/gdb/testsuite/gdb.threads/clone-attach-detach.exp b/gdb/testsuite/gdb.threads/clone-attach-detach.exp index 3da2c3e..b0f5e52 100644 --- a/gdb/testsuite/gdb.threads/clone-attach-detach.exp +++ b/gdb/testsuite/gdb.threads/clone-attach-detach.exp @@ -19,7 +19,7 @@ # clone as proxy for when libthread_db is not available. # This only works on targets with the Linux kernel. -if ![istarget *-*-linux*] { +if {![istarget *-*-linux*]} { return } @@ -27,7 +27,7 @@ require can_spawn_for_attach standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/clone-thread_db.exp b/gdb/testsuite/gdb.threads/clone-thread_db.exp index 7ee233d..12349e2 100644 --- a/gdb/testsuite/gdb.threads/clone-thread_db.exp +++ b/gdb/testsuite/gdb.threads/clone-thread_db.exp @@ -16,17 +16,17 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # This only works on targets with the Linux kernel. -if ![istarget *-*-linux*] { +if {![istarget *-*-linux*]} { return } standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/continue-pending-after-query.exp b/gdb/testsuite/gdb.threads/continue-pending-after-query.exp index 5069cd2..1da2e23 100644 --- a/gdb/testsuite/gdb.threads/continue-pending-after-query.exp +++ b/gdb/testsuite/gdb.threads/continue-pending-after-query.exp @@ -51,7 +51,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads} proc test {} { global srcfile gdb_prompt - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/continue-pending-status.exp b/gdb/testsuite/gdb.threads/continue-pending-status.exp index 9cde85a..447b683 100644 --- a/gdb/testsuite/gdb.threads/continue-pending-status.exp +++ b/gdb/testsuite/gdb.threads/continue-pending-status.exp @@ -21,11 +21,11 @@ require {!target_info exists gdb,nointerrupts} standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/corethreads.exp b/gdb/testsuite/gdb.threads/corethreads.exp index 3b50ae3..0011dc3 100644 --- a/gdb/testsuite/gdb.threads/corethreads.exp +++ b/gdb/testsuite/gdb.threads/corethreads.exp @@ -29,6 +29,7 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa set corefile [core_find $binfile] if {$corefile == ""} { + untested "unable to create or find corefile" return 0 } diff --git a/gdb/testsuite/gdb.threads/create-fail.exp b/gdb/testsuite/gdb.threads/create-fail.exp index 14f3f4b..5d633f9 100644 --- a/gdb/testsuite/gdb.threads/create-fail.exp +++ b/gdb/testsuite/gdb.threads/create-fail.exp @@ -33,7 +33,7 @@ for {set i 1} {$i <= $iterations} {incr i} { clean_restart ${executable} - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/current-lwp-dead.exp b/gdb/testsuite/gdb.threads/current-lwp-dead.exp index 7aa7ab9..c8364df 100644 --- a/gdb/testsuite/gdb.threads/current-lwp-dead.exp +++ b/gdb/testsuite/gdb.threads/current-lwp-dead.exp @@ -47,6 +47,6 @@ gdb_breakpoint $line gdb_continue_to_breakpoint "fn_return" ".*at-fn_return.*" # Confirm thread 2 is really gone. -gdb_test "info threads 2" "No threads match '2'\\." +gdb_test "info threads 2" "No threads matched\\." gdb_continue_to_end "" continue 1 diff --git a/gdb/testsuite/gdb.threads/del-pending-thread-bp.exp b/gdb/testsuite/gdb.threads/del-pending-thread-bp.exp index 1fbfc40..bdc519f 100644 --- a/gdb/testsuite/gdb.threads/del-pending-thread-bp.exp +++ b/gdb/testsuite/gdb.threads/del-pending-thread-bp.exp @@ -44,7 +44,7 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ gdb_locate_shlib $binfile_lib -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp index e48b83c..98b412c 100644 --- a/gdb/testsuite/gdb.threads/detach-step-over.exp +++ b/gdb/testsuite/gdb.threads/detach-step-over.exp @@ -50,6 +50,8 @@ require can_spawn_for_attach +require allow_multi_inferior_tests + standard_testfile set bp_lineno [gdb_get_line_number "Set breakpoint here"] @@ -64,7 +66,7 @@ proc start_gdb_for_test {condition_eval target_non_stop non_stop displaced} { append ::GDBFLAGS " -ex \"set non-stop $non_stop\"" append ::GDBFLAGS " -ex \"set displaced $displaced\"" append ::GDBFLAGS " -ex \"set schedule-multiple on\"" - clean_restart $::binfile + clean_restart $::testfile } gdb_test_no_output "set breakpoint condition-evaluation $condition_eval" @@ -227,7 +229,7 @@ proc_with_prefix test_detach_command {condition_eval target_non_stop non_stop di set running_count 0 set interrupted 0 - set running_expected [expr ($::n_threads + 1) * 2] + set running_expected [expr {($::n_threads + 1) * 2}] gdb_test_multiple "info threads" "threads running" { -re "\\(running\\)" { incr running_count @@ -355,7 +357,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options] == -1} return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/execl.exp b/gdb/testsuite/gdb.threads/execl.exp index 502d387..a42dce9 100644 --- a/gdb/testsuite/gdb.threads/execl.exp +++ b/gdb/testsuite/gdb.threads/execl.exp @@ -31,7 +31,7 @@ if {[gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {deb return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if { [is_remote target] } { gdb_remote_download target $binfile1 } diff --git a/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp b/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp index 5245988..29ec34c 100644 --- a/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp +++ b/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp @@ -17,6 +17,8 @@ # another thread, in different combinations of "set follow-fork # parent/child", and other execution modes. +require allow_fork_tests + standard_testfile # Line where to stop the main thread. @@ -44,7 +46,7 @@ proc do_test { fork_func follow target-non-stop non-stop displaced-stepping } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart ${::binfile}-${fork_func} + clean_restart ${::testfile}-${fork_func} } gdb_test_no_output "set displaced-stepping ${displaced-stepping}" diff --git a/gdb/testsuite/gdb.threads/fork-child-threads.exp b/gdb/testsuite/gdb.threads/fork-child-threads.exp index abe9769..d1b413c 100644 --- a/gdb/testsuite/gdb.threads/fork-child-threads.exp +++ b/gdb/testsuite/gdb.threads/fork-child-threads.exp @@ -13,10 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# Only GNU/Linux is known to support `set follow-fork-mode child'. -if { ! [istarget "*-*-linux*"] } { - return 0 -} +require allow_fork_tests standard_testfile @@ -24,7 +21,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/fork-plus-threads.exp b/gdb/testsuite/gdb.threads/fork-plus-threads.exp index 3a5e66a..c41b164 100644 --- a/gdb/testsuite/gdb.threads/fork-plus-threads.exp +++ b/gdb/testsuite/gdb.threads/fork-plus-threads.exp @@ -20,6 +20,8 @@ # # See https://sourceware.org/bugzilla/show_bug.cgi?id=18600 +require allow_fork_tests + # In remote mode, we cannot continue debugging after all # inferiors have terminated, and this test requires that. if { [target_info exists gdb_protocol] @@ -74,7 +76,7 @@ proc do_test { detach-on-fork } { set saw_cannot_remove_breakpoints 0 set saw_thread_stopped 0 - set expected_num_inferior_exits [expr ${detach-on-fork} == "off" ? 11 : 1] + set expected_num_inferior_exits [expr {${detach-on-fork} == "off" ? 11 : 1}] # Flags indicating if we have see the exit for each inferior. for {set i 1} {$i <= $expected_num_inferior_exits} {incr i} { diff --git a/gdb/testsuite/gdb.threads/fork-thread-pending.exp b/gdb/testsuite/gdb.threads/fork-thread-pending.exp index d0a1ca1..e0e3625 100644 --- a/gdb/testsuite/gdb.threads/fork-thread-pending.exp +++ b/gdb/testsuite/gdb.threads/fork-thread-pending.exp @@ -13,11 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# Only GNU/Linux is known to support `set follow-fork-mode child'. -# -if { ! [istarget "*-*-linux*"] } { - return 0 -} +require allow_fork_tests standard_testfile @@ -25,7 +21,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 @@ -79,7 +75,7 @@ gdb_test_multiple "info threads" "$test" { # Start over, but this time, don't switch away from the fork event thread. -clean_restart $binfile +clean_restart $::testfile if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp index 1f76898..d65fe83d 100644 --- a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp +++ b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp @@ -16,6 +16,8 @@ # This test verifies that several threads forking while another thread # is constantly stepping over a breakpoint is properly handled. +require allow_fork_tests + standard_testfile set linenum [gdb_get_line_number "set break here"] @@ -35,7 +37,7 @@ proc probe_displaced_stepping_support {} { global binfile gdb_prompt with_test_prefix "probe displaced-stepping support" { - clean_restart $binfile + clean_restart $::testfile gdb_test_no_output "set displaced on" if {![runto_main]} { @@ -74,7 +76,7 @@ proc do_test { cond_bp_target detach_on_fork displaced } { save_vars { GDBFLAGS } { set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop on\""] - clean_restart $binfile + clean_restart $::testfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.threads/gcore-thread.exp b/gdb/testsuite/gdb.threads/gcore-thread.exp index 4e00f80..f32e9b4 100644 --- a/gdb/testsuite/gdb.threads/gcore-thread.exp +++ b/gdb/testsuite/gdb.threads/gcore-thread.exp @@ -123,7 +123,7 @@ proc load_core { filename } { } # FIXME: now what can we test about the thread state? - # We do not know for certain that there should be at least + # We do not know for certain that there should be at least # three threads, because who knows what kind of many-to-one # mapping various OS's may do? Let's assume that there must # be at least two threads: diff --git a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp index d1be1d0..f9c9e87 100644 --- a/gdb/testsuite/gdb.threads/hand-call-in-threads.exp +++ b/gdb/testsuite/gdb.threads/hand-call-in-threads.exp @@ -44,7 +44,7 @@ proc get_dummy_frame_number { } { return "" } -clean_restart ${binfile} +clean_restart ${::testfile} if { ![runto_main] } { return 0 @@ -74,7 +74,7 @@ gdb_test "show scheduler-locking" ".* locking scheduler .* is \"on\"." "show sch # stop without returning. # Add one for the main thread. -set total_nr_threads [expr $NR_THREADS + 1] +set total_nr_threads [expr {$NR_THREADS + 1}] # Thread numbering in gdb is origin-1, so begin numbering at 1. for { set i 1 } { $i <= $total_nr_threads } { incr i } { diff --git a/gdb/testsuite/gdb.threads/hand-call-new-thread.exp b/gdb/testsuite/gdb.threads/hand-call-new-thread.exp index 6b859ff..479c2ff 100644 --- a/gdb/testsuite/gdb.threads/hand-call-new-thread.exp +++ b/gdb/testsuite/gdb.threads/hand-call-new-thread.exp @@ -18,11 +18,11 @@ standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}]} { return -1 } -if ![runto_main] { +if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.threads/ia64-sigill.exp b/gdb/testsuite/gdb.threads/ia64-sigill.exp index ac6ff20..46954de 100644 --- a/gdb/testsuite/gdb.threads/ia64-sigill.exp +++ b/gdb/testsuite/gdb.threads/ia64-sigill.exp @@ -27,7 +27,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable clean_restart $testfile -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/inf-thr-count.exp b/gdb/testsuite/gdb.threads/inf-thr-count.exp index d7a7687..4508be2 100644 --- a/gdb/testsuite/gdb.threads/inf-thr-count.exp +++ b/gdb/testsuite/gdb.threads/inf-thr-count.exp @@ -43,33 +43,31 @@ if {[build_executable "failed to prepare" $testfile $srcfile \ # Start GDB. Ensure we are in non-stop mode as we need to read from # the inferior while it is running. save_vars {GDBFLAGS} { - append GDBFLAGS " -ex \"set non-stop on\"" - clean_restart $binfile + append GDBFLAGS { -ex "set non-stop on"} + clean_restart $::testfile } -if ![runto_main] { +if {![runto_main]} { return -1 } gdb_breakpoint breakpt gdb_continue_to_breakpoint "first breakpt call" +set re_var [string_to_regexp "$"]$decimal + # Check we can see a single thread to begin with. -gdb_test "p \$_inferior_thread_count" \ - "^\\\$$::decimal = 1" \ - "only one thread in \$_inferior_thread_count" +gdb_test {p $_inferior_thread_count} \ + "^$re_var = 1" \ + {only one thread in $_inferior_thread_count} # We don't want thread events, it makes it harder to match GDB's # output. gdb_test_no_output "set print thread-events off" # Continue the program in the background. -set test "continue&" -gdb_test_multiple "continue&" $test { - -re "Continuing\\.\r\n$gdb_prompt " { - pass $test - } -} +gdb_test -no-prompt-anchor "continue&" \ + [string_to_regexp "Continuing."] # Read the 'stage' flag from the inferior. This is initially 0, but # will be set to 1 once the extra thread has been created, and then 2 @@ -88,8 +86,17 @@ proc wait_for_stage { num } { set failure_count 0 set cmd "print /d stage" set stage_flag 0 + + set re_int -?$::decimal + + set re_msg \ + [multi_line \ + "Cannot execute this command while the target is running" \ + {Use the "interrupt" command to stop the target} \ + [string_to_regexp "and then try again."]] + gdb_test_multiple "$cmd" "wait for 'stage' flag to be $num" { - -re -wrap "^Cannot execute this command while the target is running\\.\r\nUse the \"interrupt\" command to stop the target\r\nand then try again\\." { + -re -wrap ^$re_msg { fail "$gdb_test_name (can't read asynchronously)" gdb_test_no_output "interrupt" @@ -101,7 +108,7 @@ proc wait_for_stage { num } { } } - -re -wrap "^\\$\[0-9\]* = (\[-\]*\[0-9\]*).*" { + -re -wrap "^$::re_var = ($re_int).*" { set stage_flag $expect_out(1,string) if {$stage_flag != $num} { set stage_flag 0 @@ -131,8 +138,8 @@ if {![wait_for_stage 1]} { if {[target_info exists gdb_protocol] && ([target_info gdb_protocol] == "remote" || [target_info gdb_protocol] == "extended-remote")} { - set new_thread_re "\\\[New Thread \[^\r\n\]+\\\]\r\n" - set exit_thread_re "\\\[Thread \[^\r\n\]+ exited\\\]\r\n" + set new_thread_re {\[New Thread [^\r\n]+\]\r\n} + set exit_thread_re {\[Thread [^\r\n]+ exited\]\r\n} } else { set new_thread_re "" set exit_thread_re "" @@ -141,9 +148,9 @@ if {[target_info exists gdb_protocol] # This is the test we actually care about. Check that the # $_inferior_thread_count convenience variable shows the correct # thread count; the new thread should be visible. -gdb_test "with print thread-events on -- p \$_inferior_thread_count" \ - "^${new_thread_re}\\\$$::decimal = 2" \ - "second thread visible in \$_inferior_thread_count" +gdb_test {with print thread-events on -- p $_inferior_thread_count} \ + "^${new_thread_re}$re_var = 2" \ + {second thread visible in $_inferior_thread_count} # Set a variable in the inferior, this will cause the second thread to # exit. @@ -157,19 +164,25 @@ if {![wait_for_stage 2]} { } # Check that the second thread has gone away. -gdb_test "with print thread-events on -- p \$_inferior_thread_count" \ - "^${exit_thread_re}\\\$$::decimal = 1" \ - "back to one thread visible in \$_inferior_thread_count" +gdb_test {with print thread-events on -- p $_inferior_thread_count} \ + "^${exit_thread_re}$re_var = 1" \ + {back to one thread visible in $_inferior_thread_count} # Set a variable in the inferior, this will cause the second thread to # exit. -gdb_test_no_output "set variable spin = 0" \ +gdb_test_no_output -no-prompt-anchor "set variable spin = 0" \ "set 'spin' flag to allow main thread to exit" # When the second thread exits, the main thread joins with it, and # then proceeds to hit the breakpt function again. +set re_breakpt [string_to_regexp "breakpt ()"] +set re \ + [multi_line \ + "Thread 1 \[^\r\n\]+ hit Breakpoint $decimal, $re_breakpt\[^\r\n\]+" \ + "\[^\r\n\]+" \ + ""] gdb_test_multiple "" "wait for main thread to stop" { - -re "Thread 1 \[^\r\n\]+ hit Breakpoint $decimal, breakpt \\(\\)\[^\r\n\]+\r\n\[^\r\n\]+\r\n" { + -re $re { pass $gdb_test_name } } diff --git a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-other-thread-event.exp b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-other-thread-event.exp index 62a183c..35a1fe5 100644 --- a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-other-thread-event.exp +++ b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-other-thread-event.exp @@ -53,7 +53,7 @@ proc start_gdb_and_runto_main { target_async target_non_stop } { append ::GDBFLAGS \ " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart ${::testfile} } if { ![runto_main] } { diff --git a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-simple.exp b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-simple.exp index 0f068c6..ed98998 100644 --- a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-simple.exp +++ b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-simple.exp @@ -42,7 +42,7 @@ proc start_gdb_and_runto_main { target_async target_non_stop } { append ::GDBFLAGS \ " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart ${::testfile} } if { ![runto_main] } { diff --git a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-single.exp b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-single.exp index c404a7d..bc12fb4 100644 --- a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-single.exp +++ b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-single.exp @@ -38,7 +38,7 @@ proc start_gdb_and_runto_main { target_async target_non_stop } { append ::GDBFLAGS \ " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart ${::testfile} } if { ![runto_main] } { diff --git a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-timeout.exp b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-timeout.exp index 9dbaa4f..03c6959 100644 --- a/gdb/testsuite/gdb.threads/infcall-from-bp-cond-timeout.exp +++ b/gdb/testsuite/gdb.threads/infcall-from-bp-cond-timeout.exp @@ -52,7 +52,7 @@ proc run_test { target_async target_non_stop non_stop other_thread_bp unwind } { append ::GDBFLAGS " -ex \"maint non-stop $non_stop\"" append ::GDBFLAGS " -ex \"maintenance set target-async ${target_async}\"" - clean_restart ${::binfile} + clean_restart ${::testfile} } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.threads/infcall-thread-announce.exp b/gdb/testsuite/gdb.threads/infcall-thread-announce.exp index 68fd7b7..59a5bcf 100644 --- a/gdb/testsuite/gdb.threads/infcall-thread-announce.exp +++ b/gdb/testsuite/gdb.threads/infcall-thread-announce.exp @@ -23,7 +23,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads} return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/info-threads-cur-sal.exp b/gdb/testsuite/gdb.threads/info-threads-cur-sal.exp index 2d57136..784caf9 100644 --- a/gdb/testsuite/gdb.threads/info-threads-cur-sal.exp +++ b/gdb/testsuite/gdb.threads/info-threads-cur-sal.exp @@ -25,7 +25,7 @@ if {[gdb_compile_pthreads \ clean_restart ${executable} -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/info-threads-options.c b/gdb/testsuite/gdb.threads/info-threads-options.c new file mode 100644 index 0000000..2c4cd85 --- /dev/null +++ b/gdb/testsuite/gdb.threads/info-threads-options.c @@ -0,0 +1,77 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2022-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/>. */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pthread.h> + +#define NUM 4 + +static pthread_barrier_t threads_started_barrier; + +static void +stop_here () +{ +} + +static void +spin () +{ + while (1) + usleep (1); +} + +static void * +work (void *arg) +{ + int id = *(int *) arg; + + pthread_barrier_wait (&threads_started_barrier); + + if (id % 2 == 0) + stop_here (); + else + spin (); + + pthread_exit (NULL); +} + +int +main () +{ + /* Ensure we stop if GDB crashes and DejaGNU fails to kill us. */ + alarm (10); + + pthread_t threads[NUM]; + int ids[NUM]; + + pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1); + + for (int i = 0; i < NUM; i++) + { + ids[i] = i; + pthread_create (&threads[i], NULL, work, &ids[i]); + } + + /* Wait until all threads are seen running. */ + pthread_barrier_wait (&threads_started_barrier); + + stop_here (); + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/info-threads-options.exp b/gdb/testsuite/gdb.threads/info-threads-options.exp new file mode 100644 index 0000000..b322261 --- /dev/null +++ b/gdb/testsuite/gdb.threads/info-threads-options.exp @@ -0,0 +1,131 @@ +# Copyright (C) 2022-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 the filter flags of the "info threads" command. + +standard_testfile + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ + executable debug] != "" } { + return -1 +} + +save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"set non-stop on\"" + clean_restart $::testfile +} + +if {![runto_main]} { + return -1 +} + +gdb_breakpoint "stop_here" +gdb_test_multiple "continue -a&" "" { + -re "Continuing.\r\n$gdb_prompt " { + pass $gdb_test_name + } +} + +set expected_hits 3 +set fill "\[^\r\n\]+" +set num_hits 0 +gdb_test_multiple "" "hit the breakpoint" -lbl { + -re "\r\nThread ${fill} hit Breakpoint ${decimal}," { + incr num_hits + if {$num_hits < $expected_hits} { + exp_continue + } + } +} +gdb_assert {$num_hits == $expected_hits} "expected threads hit the bp" + +# Count the number of running/stopped threads reported +# by the "info threads" command. We also capture thread ids +# for additional tests. +set running_tid "invalid" +set stopped_tid "invalid" + +set eol "(?=\r\n)" + +foreach_with_prefix flag {"" "-running" "-stopped" "-running -stopped"} { + set num_running 0 + set num_stopped 0 + gdb_test_multiple "info threads $flag" "info threads $flag" -lbl { + -re "Id${fill}Target Id${fill}Frame${fill}${eol}" { + exp_continue + } + -re "^\r\n. (${decimal})${fill}Thread ${fill}.running.${eol}" { + incr num_running + set running_tid $expect_out(1,string) + exp_continue + } + -re "^\r\n. (${decimal})${fill}Thread ${fill}stop_here ${fill}${eol}" { + incr num_stopped + set stopped_tid $expect_out(1,string) + exp_continue + } + -re "^\r\n$gdb_prompt $" { + pass $gdb_test_name + } + } + + if {$flag eq "-running"} { + gdb_assert {$num_running == 2} "num running" + gdb_assert {$num_stopped == 0} "num stopped" + } elseif {$flag eq "-stopped"} { + gdb_assert {$num_running == 0} "num running" + gdb_assert {$num_stopped == 3} "num stopped" + } else { + gdb_assert {$num_running == 2} "num running" + gdb_assert {$num_stopped == 3} "num stopped" + } +} + +verbose -log "running_tid=$running_tid, stopped_tid=$stopped_tid" + +# Test specifying thread ids. +gdb_test "info threads -running $stopped_tid" \ + "No threads matched\\." \ + "info thread -running for a stopped thread" +gdb_test "info threads -stopped $running_tid" \ + "No threads matched\\." \ + "info thread -stopped for a running thread" + +set ws "\[ \t\]+" +foreach tid "\"$running_tid\" \"$running_tid $stopped_tid\"" { + gdb_test "info threads -running $tid" \ + [multi_line \ + "${ws}Id${ws}Target Id${ws}Frame${ws}" \ + "${ws}${running_tid}${ws}Thread ${fill}.running."] \ + "info thread -running with [llength $tid] thread ids" +} + +foreach tid "\"$stopped_tid\" \"$stopped_tid $running_tid\"" { + gdb_test "info threads -stopped $tid" \ + [multi_line \ + "${ws}Id${ws}Target Id${ws}Frame${ws}" \ + "${ws}${stopped_tid}${ws}Thread ${fill} stop_here ${fill}"] \ + "info thread -stopped with [llength $tid] thread ids" +} + +gdb_test_multiple "info threads -stopped -running $stopped_tid $running_tid" \ + "filter flags and tids combined" { + -re -wrap ".*stop_here.*running.*" { + pass $gdb_test_name + } + -re -wrap ".*running.*stop_here.*" { + pass $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp b/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp index 05587eb..d3f328b 100644 --- a/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp +++ b/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp @@ -84,7 +84,7 @@ proc test_one_iteration {} { exp_continue } -re "$gdb_prompt " { - if ![gdb_assert $saw_continuing $test] { + if {![gdb_assert $saw_continuing $test]} { return 1 } } @@ -101,7 +101,7 @@ proc test_one_iteration {} { exp_continue } -re "$gdb_prompt " { - if ![gdb_assert {$running_count == $NUM_THREADS} $test] { + if {![gdb_assert {$running_count == $NUM_THREADS} $test]} { return 1 } } @@ -151,7 +151,7 @@ proc test_one_iteration {} { exp_continue } -re "$gdb_prompt " { - if ![gdb_assert {$running_count == 0} $test] { + if {![gdb_assert {$running_count == 0} $test]} { return 1 } } @@ -169,12 +169,12 @@ proc testdriver {displaced} { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop on\"" - clean_restart $binfile + clean_restart $::testfile } gdb_test_no_output "set displaced-stepping $displaced" - if ![runto all_started] { + if {![runto all_started]} { return } set break_line [gdb_get_line_number "set breakpoint here"] diff --git a/gdb/testsuite/gdb.threads/interrupted-hand-call.exp b/gdb/testsuite/gdb.threads/interrupted-hand-call.exp index 3a2bc63..15c48b1 100644 --- a/gdb/testsuite/gdb.threads/interrupted-hand-call.exp +++ b/gdb/testsuite/gdb.threads/interrupted-hand-call.exp @@ -28,7 +28,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if { ![runto_main] } { return 0 diff --git a/gdb/testsuite/gdb.threads/kill.exp b/gdb/testsuite/gdb.threads/kill.exp index 3e6aa8b..72f829c 100644 --- a/gdb/testsuite/gdb.threads/kill.exp +++ b/gdb/testsuite/gdb.threads/kill.exp @@ -23,7 +23,7 @@ standard_testfile proc test {threaded} { global testfile srcfile decimal - with_test_prefix [expr ($threaded)?"threaded":"non-threaded"] { + with_test_prefix [expr {($threaded)?"threaded":"non-threaded"}] { set options {debug} if {$threaded} { diff --git a/gdb/testsuite/gdb.threads/killed.exp b/gdb/testsuite/gdb.threads/killed.exp index b1cec80b0..635ffc8 100644 --- a/gdb/testsuite/gdb.threads/killed.exp +++ b/gdb/testsuite/gdb.threads/killed.exp @@ -29,7 +29,7 @@ # There is absolutely no warranty for GDB. Type "show warranty" for details. # This GDB was configured as "i686-pc-linux-gnu"... # (gdb) run -# Starting program: /home/jimb/foo/play/killed +# Starting program: /home/jimb/foo/play/killed # [New Thread 1024 (LWP 6487)] # [New Thread 2049 (LWP 6488)] # [New Thread 1026 (LWP 6489)] @@ -42,17 +42,17 @@ # Cannot find thread 2049: generic error # (gdb) The program is running. Exit anyway? (y or n) y # Cannot find thread 2049: generic error -# (gdb) +# (gdb) # [7]+ Stopped $D6/gdb/gdb -nw killed # $ kill %7 -# +# # [7]+ Stopped $D6/gdb/gdb -nw killed # $ kill -9 %7 -# +# # [7]+ Stopped $D6/gdb/gdb -nw killed -# $ +# $ # [7]+ Killed $D6/gdb/gdb -nw killed -# $ +# $ standard_testfile @@ -62,7 +62,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_run_cmd gdb_test "" "" "run program to completion" diff --git a/gdb/testsuite/gdb.threads/leader-exit-attach.exp b/gdb/testsuite/gdb.threads/leader-exit-attach.exp index 641d6b5..2df4a18 100644 --- a/gdb/testsuite/gdb.threads/leader-exit-attach.exp +++ b/gdb/testsuite/gdb.threads/leader-exit-attach.exp @@ -31,7 +31,7 @@ set testpid [spawn_id_get_pid $test_spawn_id] # Wait a bit for the leader thread to exit, before attaching. sleep 2 -clean_restart ${binfile} +clean_restart ${::testfile} # Save this early as we may not be able to talk with GDBserver anymore # when we need to check it. diff --git a/gdb/testsuite/gdb.threads/leader-exit.exp b/gdb/testsuite/gdb.threads/leader-exit.exp index 1bc017b..85039b8 100644 --- a/gdb/testsuite/gdb.threads/leader-exit.exp +++ b/gdb/testsuite/gdb.threads/leader-exit.exp @@ -26,7 +26,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab clean_restart ${executable} -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/linux-dp.exp b/gdb/testsuite/gdb.threads/linux-dp.exp index 1652f78..c0ef9c7 100644 --- a/gdb/testsuite/gdb.threads/linux-dp.exp +++ b/gdb/testsuite/gdb.threads/linux-dp.exp @@ -44,7 +44,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" runto_main @@ -117,7 +117,7 @@ for {set i 0} {$i < 5} {incr i} { } else { fail "create philosopher: $i" } - + set threads_after {} gdb_test_multiple "info threads" "info threads after: $i" { -re "info threads\r\n" { @@ -172,7 +172,7 @@ for {set i 1} {$i < $nthreads} {incr i} { append info_threads_ptn "$i *Thread .*" } append info_threads_ptn "\[\r\n\]+$gdb_prompt $" -set info_threads_manager_ptn "[expr $nthreads + 1] *Thread .*$info_threads_ptn" +set info_threads_manager_ptn "[expr {$nthreads + 1}] *Thread .*$info_threads_ptn" gdb_test_multiple "info threads" "info threads 2" { -re "$info_threads_manager_ptn" { @@ -241,7 +241,7 @@ for {set i 0} {$only_five > 0 && $i < 10} {incr i} { -re ".*$gdb_prompt $" { set only_five 0 } - timeout { + timeout { set only_five -1 } } @@ -331,7 +331,7 @@ set any_interesting 0 catch {unset seen} array set seen {} for {set i 1} {$i <= $nthreads} {incr i} { - if [check_philosopher_stack $i seen] { + if {[check_philosopher_stack $i seen]} { set any_interesting 1 } } diff --git a/gdb/testsuite/gdb.threads/local-watch-wrong-thread.exp b/gdb/testsuite/gdb.threads/local-watch-wrong-thread.exp index 3006b83..a63f0be 100644 --- a/gdb/testsuite/gdb.threads/local-watch-wrong-thread.exp +++ b/gdb/testsuite/gdb.threads/local-watch-wrong-thread.exp @@ -28,7 +28,7 @@ if {[gdb_compile_pthreads \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set can-use-hw-watchpoints 1" "" diff --git a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp index 20e7bc4..1ce0194 100644 --- a/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp +++ b/gdb/testsuite/gdb.threads/main-thread-exit-during-detach.exp @@ -50,7 +50,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile \ proc run_test { spawn_inferior } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"set non-stop on\"" - clean_restart $::binfile + clean_restart $::testfile } # Setup the inferior. When complete the main thread (#1) will diff --git a/gdb/testsuite/gdb.threads/manythreads.exp b/gdb/testsuite/gdb.threads/manythreads.exp index ae51c5a..0a09897 100644 --- a/gdb/testsuite/gdb.threads/manythreads.exp +++ b/gdb/testsuite/gdb.threads/manythreads.exp @@ -22,7 +22,7 @@ require {!target_info exists gdb,nointerrupts} standard_testfile set opts { debug } -if [info exists DEBUG] { +if {[info exists DEBUG]} { # make check RUNTESTFLAGS='gdb.threads/manythreads.exp DEBUG=1' lappend opts "additional_flags=-DDEBUG" } @@ -31,7 +31,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" runto_main diff --git a/gdb/testsuite/gdb.threads/multi-create-ns-info-thr.exp b/gdb/testsuite/gdb.threads/multi-create-ns-info-thr.exp index 1c3231c..c42c1a9 100644 --- a/gdb/testsuite/gdb.threads/multi-create-ns-info-thr.exp +++ b/gdb/testsuite/gdb.threads/multi-create-ns-info-thr.exp @@ -25,7 +25,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads} gdb_test_no_output "set pagination off" gdb_test_no_output "set non-stop on" -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/multi-create.exp b/gdb/testsuite/gdb.threads/multi-create.exp index 966d44d..cb86aac 100644 --- a/gdb/testsuite/gdb.threads/multi-create.exp +++ b/gdb/testsuite/gdb.threads/multi-create.exp @@ -21,7 +21,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main # Run to the beginning of create_function several times. Make sure diff --git a/gdb/testsuite/gdb.threads/multiple-step-overs.exp b/gdb/testsuite/gdb.threads/multiple-step-overs.exp index 84eef1a..c3456c2 100644 --- a/gdb/testsuite/gdb.threads/multiple-step-overs.exp +++ b/gdb/testsuite/gdb.threads/multiple-step-overs.exp @@ -35,7 +35,7 @@ proc setup {} { with_test_prefix "setup" { clean_restart $executable - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp index 1aa9253..2694ce5 100644 --- a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp +++ b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp @@ -23,7 +23,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart "${binfile}" +clean_restart "${::testfile}" if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/names.exp b/gdb/testsuite/gdb.threads/names.exp index 6f38c4e..808fa24 100644 --- a/gdb/testsuite/gdb.threads/names.exp +++ b/gdb/testsuite/gdb.threads/names.exp @@ -20,11 +20,11 @@ require {!target_info exists gdb,no_thread_names} standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}]} { return -1 } -if ![runto "all_threads_ready"] { +if {![runto "all_threads_ready"]} { return } diff --git a/gdb/testsuite/gdb.threads/next-bp-other-thread.exp b/gdb/testsuite/gdb.threads/next-bp-other-thread.exp index cf8d687..293b100 100644 --- a/gdb/testsuite/gdb.threads/next-bp-other-thread.exp +++ b/gdb/testsuite/gdb.threads/next-bp-other-thread.exp @@ -28,9 +28,9 @@ if {[build_executable "failed to prepare" $testfile $srcfile \ # Test all "set scheduler-locking" variants. foreach schedlock {"off" "step" "on" } { with_test_prefix "schedlock=$schedlock" { - clean_restart $binfile + clean_restart $::testfile - if ![runto_main] { + if {![runto_main]} { continue } diff --git a/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp b/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp index bd81438..82e85a6 100644 --- a/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp +++ b/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp @@ -25,6 +25,8 @@ # 20.04.5 LTS with 32-bit kernel + 32-bit userland. It was NOT reproducible # using a circa 2023 Raspberry Pi OS w/ 64-bit kernel and 32-bit userland. +require allow_fork_tests + standard_testfile # Line where to stop the main thread. @@ -65,7 +67,7 @@ proc do_test { fork_func target-non-stop non-stop displaced-stepping } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart ${::binfile}-${fork_func} + clean_restart ${::testfile}-${fork_func} } gdb_test_no_output "set displaced-stepping ${displaced-stepping}" diff --git a/gdb/testsuite/gdb.threads/next-fork-other-thread.exp b/gdb/testsuite/gdb.threads/next-fork-other-thread.exp index 183fda6..9349091 100644 --- a/gdb/testsuite/gdb.threads/next-fork-other-thread.exp +++ b/gdb/testsuite/gdb.threads/next-fork-other-thread.exp @@ -16,6 +16,8 @@ # Test doing a "next" on a thread during which forks or vforks happen in other # threads. +require allow_fork_tests + standard_testfile # Line where to stop the main thread. @@ -56,7 +58,7 @@ proc do_test { fork_func target-non-stop non-stop displaced-stepping } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart ${::binfile}-${fork_func} + clean_restart ${::testfile}-${fork_func} } gdb_test_no_output "set displaced-stepping ${displaced-stepping}" diff --git a/gdb/testsuite/gdb.threads/no-unwaited-for-left.exp b/gdb/testsuite/gdb.threads/no-unwaited-for-left.exp index edeabaf..96b5433 100644 --- a/gdb/testsuite/gdb.threads/no-unwaited-for-left.exp +++ b/gdb/testsuite/gdb.threads/no-unwaited-for-left.exp @@ -25,7 +25,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab clean_restart ${executable} -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-1.exp b/gdb/testsuite/gdb.threads/non-ldr-exc-1.exp index 846fe89..7d2956d 100644 --- a/gdb/testsuite/gdb.threads/non-ldr-exc-1.exp +++ b/gdb/testsuite/gdb.threads/non-ldr-exc-1.exp @@ -31,7 +31,7 @@ proc do_test { lock_sched nonstop } { clean_restart ${executable} } - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp b/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp index 860b6b5..bb66644 100644 --- a/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp +++ b/gdb/testsuite/gdb.threads/non-ldr-exc-2.exp @@ -33,7 +33,7 @@ proc do_test { lock_sched nonstop } { clean_restart ${executable} } - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-3.exp b/gdb/testsuite/gdb.threads/non-ldr-exc-3.exp index b50bfac..4490b30 100644 --- a/gdb/testsuite/gdb.threads/non-ldr-exc-3.exp +++ b/gdb/testsuite/gdb.threads/non-ldr-exc-3.exp @@ -34,7 +34,7 @@ proc do_test { lock_sched nonstop } { clean_restart ${executable} } - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-ldr-exc-4.exp b/gdb/testsuite/gdb.threads/non-ldr-exc-4.exp index 9892d83..533e14f 100644 --- a/gdb/testsuite/gdb.threads/non-ldr-exc-4.exp +++ b/gdb/testsuite/gdb.threads/non-ldr-exc-4.exp @@ -33,7 +33,7 @@ proc do_test { lock_sched nonstop } { clean_restart ${executable} } - if ![runto_main] { + if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-ldr-exit.exp b/gdb/testsuite/gdb.threads/non-ldr-exit.exp index b09a37e..4dd1b79 100644 --- a/gdb/testsuite/gdb.threads/non-ldr-exit.exp +++ b/gdb/testsuite/gdb.threads/non-ldr-exit.exp @@ -22,7 +22,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads} return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/non-stop-fair-events.exp b/gdb/testsuite/gdb.threads/non-stop-fair-events.exp index 5def610..788a7e8 100644 --- a/gdb/testsuite/gdb.threads/non-stop-fair-events.exp +++ b/gdb/testsuite/gdb.threads/non-stop-fair-events.exp @@ -28,7 +28,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options] == -1} gdb_test_no_output "set non-stop on" -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/omp-par-scope.exp b/gdb/testsuite/gdb.threads/omp-par-scope.exp index 27dbaf0..2a097f5 100644 --- a/gdb/testsuite/gdb.threads/omp-par-scope.exp +++ b/gdb/testsuite/gdb.threads/omp-par-scope.exp @@ -30,7 +30,7 @@ if { [test_compiler_info "clang*"] } { set have_nested_function_support 0 set opts {openmp debug} -if [support_nested_function_tests] { +if {[support_nested_function_tests]} { lappend opts "additional_flags=-DHAVE_NESTED_FUNCTION_SUPPORT" set have_nested_function_support 1 } @@ -191,7 +191,7 @@ with_test_prefix "multi_scope" { # Nested functions in C are a GNU extension, so only do the nested function # tests if compiling with -DHAVE_NESTED_FUNCTION_SUPPORT was successful. -if $have_nested_function_support { +if {$have_nested_function_support} { with_test_prefix "nested_func" { gdb_breakpoint [gdb_get_line_number "nested_func: tn="] diff --git a/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp b/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp index e6e311e..9cc4978 100644 --- a/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp +++ b/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp @@ -29,6 +29,8 @@ # parent thread from waitpid'ing it, preventing the main thread from joining # it, prevent it from writing the flag file, failing the test. +require allow_fork_tests + standard_testfile if { [is_remote target] } { @@ -50,7 +52,7 @@ proc do_test { } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"set non-stop on\"" - clean_restart $::binfile + clean_restart $::testfile } if { ![runto break_here_first] } { diff --git a/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp b/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp index 8e77ab0..fa86488 100644 --- a/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp +++ b/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp @@ -34,6 +34,8 @@ # event, and erroneously create a new inferior for it. Once fixed, the child # process' thread is hidden by whoever holds the pending fork event. +require allow_fork_tests + standard_testfile .c -touch-file.c set touch_file_bin $binfile-touch-file @@ -91,7 +93,8 @@ proc do_test { target-non-stop who_forks fork_function stop_mode } { save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" - clean_restart $this_binfile + clean_restart + gdb_load $this_binfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.threads/pending-step.exp b/gdb/testsuite/gdb.threads/pending-step.exp index 1c2422e..d31f879 100644 --- a/gdb/testsuite/gdb.threads/pending-step.exp +++ b/gdb/testsuite/gdb.threads/pending-step.exp @@ -54,7 +54,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/print-threads.exp b/gdb/testsuite/gdb.threads/print-threads.exp index 51a14b2..a3fcba3 100644 --- a/gdb/testsuite/gdb.threads/print-threads.exp +++ b/gdb/testsuite/gdb.threads/print-threads.exp @@ -32,7 +32,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab # Now we can proceed with the real testing. -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" #gdb_test_no_output "set print address off" @@ -50,13 +50,13 @@ proc test_all_threads { name kill } { set j 0 gdb_test_multiple "continue" "all threads ran once" { -re "Breakpoint \[0-9\]+, thread_function \\(arg=.*\\) at .*print-threads.c:\[0-9\]+.*$gdb_prompt" { - set i [expr $i + 1] + set i [expr {$i + 1}] pass "hit thread_function breakpoint, $i" send_gdb "continue\n" exp_continue } -re "Breakpoint \[0-9\]+, .* kill \\(.*\\) .*$gdb_prompt" { - set j [expr $j + 1] + set j [expr {$j + 1}] if { $kill == 1 } { pass "hit kill breakpoint, $j" } else { @@ -96,7 +96,7 @@ runto_main gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function, 2" gdb_test_no_output "set var slow = 1" # Extend the timeout for slower tests. -set timeout [expr $oldtimeout + 120] +set timeout [expr {$oldtimeout + 120}] test_all_threads "slow" 0 set timeout $oldtimeout @@ -105,6 +105,6 @@ gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*p gdb_test_no_output "set var slow = 1" "set var slow = 1, 2" gdb_breakpoint "kill" # Extend the timeout for slower tests. -set timeout [expr $oldtimeout + 120] +set timeout [expr {$oldtimeout + 120}] test_all_threads "slow with kill breakpoint" 1 set timeout $oldtimeout diff --git a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp index 776c08e..63ddfec 100644 --- a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp +++ b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp @@ -43,6 +43,7 @@ # threads are reaped. We test that as well. standard_testfile +set testfile_base $testfile # Test that GDBserver exits. @@ -187,7 +188,7 @@ proc do_detach {multi_process cmd child_exit} { perror "unhandled command: $cmd" } } else { - if $is_remote { + if {$is_remote} { set extra "\r\nEnding remote debugging\." } else { set extra "" @@ -214,9 +215,9 @@ proc test_detach {multi_process cmd} { with_test_prefix "detach" { global binfile - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -242,9 +243,9 @@ proc test_detach_watch {wp multi_process cmd} { with_test_prefix "watchpoint:$wp" { global binfile decimal - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -290,9 +291,9 @@ proc test_detach_killed_outside {multi_process cmd} { with_test_prefix "killed outside" { global binfile - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -334,14 +335,15 @@ proc do_test {multi_process cmd} { return } - set binfile [standard_output_file ${testfile}-$multi_process-$cmd] + set testfile $::testfile_base-$multi_process-$cmd + set binfile [standard_output_file $testfile] set options {debug pthreads} if {$multi_process} { lappend options "additional_flags=-DMULTIPROCESS" } if {[build_executable "failed to build" \ - $testfile-$multi_process-$cmd $srcfile $options] == -1} { + $testfile $srcfile $options] == -1} { return -1 } diff --git a/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp b/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp index 26dc8cc..a990dc9 100644 --- a/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp +++ b/gdb/testsuite/gdb.threads/process-dies-while-handling-bp.exp @@ -42,7 +42,7 @@ proc do_test { non_stop cond_bp_target } { save_vars { GDBFLAGS } { set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop $non_stop\""] - clean_restart $binfile + clean_restart $::testfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp index c1be1cd..e11b904 100644 --- a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp +++ b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp @@ -17,7 +17,7 @@ # bug-gdb@gnu.org # This file verifies that GDB is able to compute a backtrace for a thread -# being blocked on a call to pthread_cond_wait(). +# being blocked on a call to pthread_cond_wait(). standard_testfile @@ -25,7 +25,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main gdb_test "break break_me" \ @@ -36,7 +36,7 @@ gdb_test "continue" \ ".*Breakpoint 2, break_me ().*" \ "run to break_me" -# +# # Backtrace all threads, find the one running noreturn, and # verify that we are able to get a sensible backtrace, including # the frame for the pthread_cond_wait() call. diff --git a/gdb/testsuite/gdb.threads/pthreads.exp b/gdb/testsuite/gdb.threads/pthreads.exp index 0437e74..04ae91e2 100644 --- a/gdb/testsuite/gdb.threads/pthreads.exp +++ b/gdb/testsuite/gdb.threads/pthreads.exp @@ -34,7 +34,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" #gdb_test_no_output "set print address off" diff --git a/gdb/testsuite/gdb.threads/queue-signal.exp b/gdb/testsuite/gdb.threads/queue-signal.exp index f791ffa..6ab8bbb 100644 --- a/gdb/testsuite/gdb.threads/queue-signal.exp +++ b/gdb/testsuite/gdb.threads/queue-signal.exp @@ -20,9 +20,9 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/schedlock-new-thread.exp b/gdb/testsuite/gdb.threads/schedlock-new-thread.exp index c398137..0937e2a 100644 --- a/gdb/testsuite/gdb.threads/schedlock-new-thread.exp +++ b/gdb/testsuite/gdb.threads/schedlock-new-thread.exp @@ -18,7 +18,7 @@ standard_testfile .c foreach_with_prefix schedlock {off on} { - set sl [expr $schedlock == "on" ? 1 : 0] + set sl [expr {$schedlock == "on" ? 1 : 0}] if { [build_executable "failed to prepare" $testfile-$sl \ $srcfile \ [list debug pthreads additional_flags=-DSCHEDLOCK=$sl]] \ @@ -30,8 +30,8 @@ foreach_with_prefix schedlock {off on} { proc test {non-stop schedlock} { save_vars ::GDBFLAGS { append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - set sl [expr $schedlock == "on" ? 1 : 0] - clean_restart $::binfile-$sl + set sl [expr {$schedlock == "on" ? 1 : 0}] + clean_restart $::testfile-$sl } set linenum1 [gdb_get_line_number "set break 1 here"] diff --git a/gdb/testsuite/gdb.threads/schedlock-thread-exit.exp b/gdb/testsuite/gdb.threads/schedlock-thread-exit.exp index 434b058..137f652 100644 --- a/gdb/testsuite/gdb.threads/schedlock-thread-exit.exp +++ b/gdb/testsuite/gdb.threads/schedlock-thread-exit.exp @@ -28,7 +28,7 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile} \ } proc do_test { } { - clean_restart $::binfile + clean_restart $::testfile # One of the launched threads will report a stop on thread_func. Some # others will also stop on thread_func and have a pending status. diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp index 4e2b835..1257868 100644 --- a/gdb/testsuite/gdb.threads/schedlock.exp +++ b/gdb/testsuite/gdb.threads/schedlock.exp @@ -41,7 +41,7 @@ proc get_args { description } { global NUM set pattern "(\[0-9\]+)" - for {set i 1} {[expr $i < $NUM]} {incr i} { + for {set i 1} {$i < $NUM} {incr i} { append pattern ", (\[0-9\]+)" } @@ -51,7 +51,7 @@ proc get_args { description } { pass $test set result "" - for {set i 1} {[expr $i <= $NUM]} {incr i} { + for {set i 1} {[expr {$i <= $NUM}]} {incr i} { lappend result $expect_out($i,string) } return $result @@ -122,7 +122,7 @@ proc my_continue { msg } { proc step_ten_loops { cmd } { global gdb_prompt - for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} { + for {set i 0} {$i < 10} {incr i} { set other_step 0 set test "$cmd to increment, $i" gdb_test_multiple $cmd $test { @@ -183,7 +183,7 @@ my_continue "initial" set cont_args [get_args "after initial"] set bad 0 -for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { +for {set i 0} {$i < $NUM} {incr i} { if {[lindex $start_args $i] == [lindex $cont_args $i]} { incr bad } @@ -233,7 +233,7 @@ proc check_result { cmd before_thread before_args locked } { } else { if {$i == $before_thread} { if {$cmd == "continue" - || [lindex $before_args $i] == [expr [lindex $after_args $i] - 10]} { + || [lindex $before_args $i] == [lindex $after_args $i] - 10} { pass "$test" } else { fail "$test (wrong amount)" diff --git a/gdb/testsuite/gdb.threads/siginfo-threads.exp b/gdb/testsuite/gdb.threads/siginfo-threads.exp index ecc372d..253c4c0 100644 --- a/gdb/testsuite/gdb.threads/siginfo-threads.exp +++ b/gdb/testsuite/gdb.threads/siginfo-threads.exp @@ -25,7 +25,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \ clean_restart $testfile -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/signal-command-handle-nopass.exp b/gdb/testsuite/gdb.threads/signal-command-handle-nopass.exp index 2586800..6d344e3 100644 --- a/gdb/testsuite/gdb.threads/signal-command-handle-nopass.exp +++ b/gdb/testsuite/gdb.threads/signal-command-handle-nopass.exp @@ -35,7 +35,7 @@ proc test { step_over } { global srcfile binfile tdlabel_re with_test_prefix "step-over $step_over" { - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/signal-command-multiple-signals-pending.exp b/gdb/testsuite/gdb.threads/signal-command-multiple-signals-pending.exp index 73f88c1..acb018b 100644 --- a/gdb/testsuite/gdb.threads/signal-command-multiple-signals-pending.exp +++ b/gdb/testsuite/gdb.threads/signal-command-multiple-signals-pending.exp @@ -32,7 +32,7 @@ proc test { schedlock } { global srcfile binfile tdlabel_re with_test_prefix "schedlock $schedlock" { - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/signal-delivered-right-thread.exp b/gdb/testsuite/gdb.threads/signal-delivered-right-thread.exp index 7445cad..9de0908 100644 --- a/gdb/testsuite/gdb.threads/signal-delivered-right-thread.exp +++ b/gdb/testsuite/gdb.threads/signal-delivered-right-thread.exp @@ -29,7 +29,7 @@ proc test { command } { global srcfile binfile tdlabel_re with_test_prefix "$command" { - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/signal-sigtrap.exp b/gdb/testsuite/gdb.threads/signal-sigtrap.exp index 8154ddf..849d628 100644 --- a/gdb/testsuite/gdb.threads/signal-sigtrap.exp +++ b/gdb/testsuite/gdb.threads/signal-sigtrap.exp @@ -32,7 +32,7 @@ proc test { sigtrap_thread } { global srcfile binfile tdlabel_re with_test_prefix "sigtrap thread $sigtrap_thread" { - clean_restart ${binfile} + clean_restart ${::testfile} if {![runto "thread_function"]} { return 0 diff --git a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp index e2f7581..b7a110d 100644 --- a/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp +++ b/gdb/testsuite/gdb.threads/signal-while-stepping-over-bp-other-thread.exp @@ -51,7 +51,7 @@ proc get_value {var test} { clean_restart $executable -if ![runto_main] { +if {![runto_main]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/sigstep-threads.exp b/gdb/testsuite/gdb.threads/sigstep-threads.exp index 0580cd0..9aed9e3 100644 --- a/gdb/testsuite/gdb.threads/sigstep-threads.exp +++ b/gdb/testsuite/gdb.threads/sigstep-threads.exp @@ -23,7 +23,7 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa clean_restart $executable -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -65,7 +65,7 @@ for {set i 0} {$i < 100} {incr i} { set step_at $now } } - if $failed { + if {$failed} { return } } diff --git a/gdb/testsuite/gdb.threads/sigthread.exp b/gdb/testsuite/gdb.threads/sigthread.exp index 9d2f9b5..dea8eb8 100644 --- a/gdb/testsuite/gdb.threads/sigthread.exp +++ b/gdb/testsuite/gdb.threads/sigthread.exp @@ -24,7 +24,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/staticthreads.exp b/gdb/testsuite/gdb.threads/staticthreads.exp index 0374666..44cc686 100644 --- a/gdb/testsuite/gdb.threads/staticthreads.exp +++ b/gdb/testsuite/gdb.threads/staticthreads.exp @@ -34,7 +34,7 @@ foreach_with_prefix have_tls { "-DHAVE_TLS" "" } { } } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" @@ -51,7 +51,7 @@ gdb_test_multiple "continue" "$test" { kfail gdb/1328 "$test" } } - + # See if handle SIG32 helps (a little) with a static multi-threaded # program. @@ -59,7 +59,7 @@ gdb_test_multiple "continue" "$test" { set sig "SIG32" # SIGRTMIN is 37 on hppa-linux -if [istarget hppa*-*-*] { +if {[istarget hppa*-*-*]} { set sig "SIG37" } @@ -94,11 +94,11 @@ gdb_test_multiple "quit" "$test" { pass "$test" } } -clean_restart ${binfile} +clean_restart ${::testfile} if { "$have_tls" != "" } { - if ![runto_main] { + if {![runto_main]} { return -1 } gdb_breakpoint [gdb_get_line_number "tlsvar-is-set"] diff --git a/gdb/testsuite/gdb.threads/step-N-all-progress.exp b/gdb/testsuite/gdb.threads/step-N-all-progress.exp index c874d79..031e36a 100644 --- a/gdb/testsuite/gdb.threads/step-N-all-progress.exp +++ b/gdb/testsuite/gdb.threads/step-N-all-progress.exp @@ -31,7 +31,7 @@ proc test {non-stop target-non-stop} { save_vars ::GDBFLAGS { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart $::binfile + clean_restart $::testfile } if { ![runto_main] } { diff --git a/gdb/testsuite/gdb.threads/step-bg-decr-pc-switch-thread.exp b/gdb/testsuite/gdb.threads/step-bg-decr-pc-switch-thread.exp index 309c826..82861a9 100644 --- a/gdb/testsuite/gdb.threads/step-bg-decr-pc-switch-thread.exp +++ b/gdb/testsuite/gdb.threads/step-bg-decr-pc-switch-thread.exp @@ -34,7 +34,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads} return -1 } -if ![runto_main] { +if {![runto_main]} { return } @@ -55,7 +55,7 @@ gdb_test_no_output "next&" "next& over inf loop" set test "switch to main thread" gdb_test_multiple "thread 1" $test { -re "Cannot execute this command while the target is running.*$gdb_prompt $" { - + # With remote targets, we can't send any other remote packet # until the target stops. Switching thread wants to ask the # remote side whether the thread is alive. diff --git a/gdb/testsuite/gdb.threads/step-over-exec.exp b/gdb/testsuite/gdb.threads/step-over-exec.exp index 7c553f2..22b9a13 100644 --- a/gdb/testsuite/gdb.threads/step-over-exec.exp +++ b/gdb/testsuite/gdb.threads/step-over-exec.exp @@ -71,11 +71,12 @@ proc do_test { execr_thread different_text_segments displaced_stepping } { return -1 } - clean_restart ${execr_binfile} + clean_restart + gdb_load $execr_binfile gdb_test_no_output "set displaced-stepping $displaced_stepping" - if ![runto_main] { + if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp index 65aa2f1..3a96e0e 100644 --- a/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp +++ b/gdb/testsuite/gdb.threads/step-over-lands-on-breakpoint.exp @@ -32,7 +32,7 @@ proc do_test {displaced command} { with_test_prefix "displaced=$displaced: $command" { clean_restart $executable - if ![runto_main] { + if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp index cf10bdc..fdd2b27 100644 --- a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp @@ -29,7 +29,7 @@ if { [build_executable "failed to prepare" $testfile \ proc test {displaced-stepping target-non-stop} { save_vars ::GDBFLAGS { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" - clean_restart $::binfile + clean_restart $::testfile } gdb_test_no_output "set displaced-stepping ${displaced-stepping}" diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp index 31037a7..8ed2b21 100644 --- a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp @@ -55,7 +55,7 @@ proc test {step_over_mode non-stop target-non-stop schedlock cmd ns_stop_all} { save_vars ::GDBFLAGS { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart $::binfile + clean_restart $::testfile } if { $step_over_mode == "none" } { diff --git a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp index 9a028fe..0e99656 100644 --- a/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp +++ b/gdb/testsuite/gdb.threads/step-over-trips-on-watchpoint.exp @@ -38,7 +38,7 @@ proc do_test { displaced with_bp } { global gdb_prompt global hex - if ${with_bp} { + if {${with_bp}} { set prefix "with thread-specific bp" } else { set prefix "no thread-specific bp" @@ -49,7 +49,7 @@ proc do_test { displaced with_bp } { with_test_prefix $command { clean_restart $executable - if ![runto_main] { + if {![runto_main]} { continue } @@ -106,7 +106,7 @@ proc do_test { displaced with_bp } { gdb_test "p watch_me = 0" " = 0" "clear watch_me" gdb_test "watch watch_me" "Hardware watchpoint .*" - if ${with_bp} { + if {${with_bp}} { gdb_test "b *$after_address_triggers_watch thread 1" \ "Breakpoint .*" \ "set breakpoint specific to thread 1" diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp index 5da123e..e0b14cb 100644 --- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp +++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp @@ -58,8 +58,8 @@ gdb_test "continue" \ # Return true if INSN is a syscall instruction. proc is_syscall_insn { insn } { - if [istarget x86_64-*-* ] { - return { $insn == "syscall" } + if {[istarget x86_64-*-* ]} { + return [string equal $insn "syscall"] } else { error "port me" } @@ -76,7 +76,7 @@ gdb_test_multiple "disassemble" "" { -re "^(?:=>)?\\s+(${hex})\\s+<\\+${decimal}>:\\s+(\[^\r\n\]+)\r\n" { set addr $expect_out(1,string) set insn [string trim $expect_out(2,string)] - if [is_syscall_insn $insn] { + if {[is_syscall_insn $insn]} { verbose -log "Found a syscall at: $addr" lappend syscall_addrs $addr } @@ -106,7 +106,7 @@ proc test {non_stop displaced third_thread} { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop $non_stop\"" append GDBFLAGS " -ex \"set displaced $displaced\"" - clean_restart $binfile + clean_restart $::testfile } runto_main diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.exp b/gdb/testsuite/gdb.threads/stepi-random-signal.exp index 8ac81e8..a2d7743 100644 --- a/gdb/testsuite/gdb.threads/stepi-random-signal.exp +++ b/gdb/testsuite/gdb.threads/stepi-random-signal.exp @@ -31,7 +31,7 @@ if { [gdb_compile_pthreads \ clean_restart $executable # Start the second thread. -if ![runto start] { +if {![runto start]} { return -1 } diff --git a/gdb/testsuite/gdb.threads/switch-threads.exp b/gdb/testsuite/gdb.threads/switch-threads.exp index d43603c..1f67a45 100644 --- a/gdb/testsuite/gdb.threads/switch-threads.exp +++ b/gdb/testsuite/gdb.threads/switch-threads.exp @@ -29,7 +29,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main diff --git a/gdb/testsuite/gdb.threads/thread-bp-deleted.exp b/gdb/testsuite/gdb.threads/thread-bp-deleted.exp index 2eadd38..19b5001 100644 --- a/gdb/testsuite/gdb.threads/thread-bp-deleted.exp +++ b/gdb/testsuite/gdb.threads/thread-bp-deleted.exp @@ -31,14 +31,15 @@ if {[build_executable "failed to prepare" $testfile $srcfile \ # We need to do things a little differently when using the remote protocol. set is_remote \ - [expr [target_info exists gdb_protocol] \ - && ([string equal [target_info gdb_protocol] "remote"] \ - || [string equal [target_info gdb_protocol] "extended-remote"])] + [expr \ + {[target_info exists gdb_protocol] + && ([string equal [target_info gdb_protocol] "remote"] + || [string equal [target_info gdb_protocol] "extended-remote"])}] # This test requires background execution, which relies on non-stop mode. save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart ${binfile} + clean_restart ${::testfile} } if {![runto_main]} { @@ -147,7 +148,7 @@ if {$is_remote} { exp_continue } - -re "No threads match '99'\\.\r\n$gdb_prompt $" { + -re "No threads matched\\.\r\n$gdb_prompt $" { if {!$saw_thread_exited && !$saw_bp_deleted && $attempt_count > 0} { sleep 1 incr attempt_count -1 diff --git a/gdb/testsuite/gdb.threads/thread-execl.c b/gdb/testsuite/gdb.threads/thread-execl.c index 403aa31..2d312d4 100644 --- a/gdb/testsuite/gdb.threads/thread-execl.c +++ b/gdb/testsuite/gdb.threads/thread-execl.c @@ -25,8 +25,9 @@ static const char *image; void * thread_execler (void *arg) { - /* Exec ourselves again. */ - if (execl (image, image, NULL) == -1) + /* Exec ourselves again. Pass an extra argument so that the + post-exec image knows to not re-exec yet again. */ + if (execl (image, image, "1", NULL) == -1) { perror ("execl"); abort (); @@ -40,6 +41,11 @@ main (int argc, char **argv) { pthread_t thread; + /* An extra argument means we're in the post-exec image, so we're + done. Don't re-exec again. */ + if (argc > 1) + exit (0); + image = argv[0]; pthread_create (&thread, NULL, thread_execler, NULL); diff --git a/gdb/testsuite/gdb.threads/thread-execl.exp b/gdb/testsuite/gdb.threads/thread-execl.exp index 04ba518..d1c80df 100644 --- a/gdb/testsuite/gdb.threads/thread-execl.exp +++ b/gdb/testsuite/gdb.threads/thread-execl.exp @@ -35,13 +35,13 @@ proc do_test { schedlock } { set prefix "schedlock $schedlock" } with_test_prefix "$prefix" { - clean_restart ${binfile} + clean_restart ${::testfile} if {$schedlock == "non-stop"} { gdb_test_no_output "set non-stop 1" } - if ![runto_main] { + if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/thread-find.exp b/gdb/testsuite/gdb.threads/thread-find.exp index 456f7d3..171b94b 100644 --- a/gdb/testsuite/gdb.threads/thread-find.exp +++ b/gdb/testsuite/gdb.threads/thread-find.exp @@ -21,7 +21,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" runto_main diff --git a/gdb/testsuite/gdb.threads/thread-specific-bp.exp b/gdb/testsuite/gdb.threads/thread-specific-bp.exp index c4858f2..8f48b61 100644 --- a/gdb/testsuite/gdb.threads/thread-specific-bp.exp +++ b/gdb/testsuite/gdb.threads/thread-specific-bp.exp @@ -118,7 +118,7 @@ proc check_thread_specific_breakpoint {non_stop} { foreach_with_prefix non_stop {on off} { save_vars { GDBFLAGS } { append GDBFLAGS " -ex \"set non-stop $non_stop\"" - clean_restart $binfile + clean_restart $::testfile } check_thread_specific_breakpoint $non_stop diff --git a/gdb/testsuite/gdb.threads/thread-specific.exp b/gdb/testsuite/gdb.threads/thread-specific.exp index bf9c63b..d1e6f4d 100644 --- a/gdb/testsuite/gdb.threads/thread-specific.exp +++ b/gdb/testsuite/gdb.threads/thread-specific.exp @@ -62,7 +62,7 @@ proc get_thread_list { } { return $thr_list } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set width 0" diff --git a/gdb/testsuite/gdb.threads/thread-unwindonsignal.exp b/gdb/testsuite/gdb.threads/thread-unwindonsignal.exp index 5f4ac1f..dc74714 100644 --- a/gdb/testsuite/gdb.threads/thread-unwindonsignal.exp +++ b/gdb/testsuite/gdb.threads/thread-unwindonsignal.exp @@ -28,7 +28,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if { ![runto_main] } { return 0 diff --git a/gdb/testsuite/gdb.threads/thread_check.exp b/gdb/testsuite/gdb.threads/thread_check.exp index ee5f35a..6378e8a 100644 --- a/gdb/testsuite/gdb.threads/thread_check.exp +++ b/gdb/testsuite/gdb.threads/thread_check.exp @@ -15,16 +15,16 @@ # This file was written by Manoj Iyer. (manjo@austin.ibm.com) # Test break points and single step on thread functions. -# +# # Test Purpose: -# - Test that breakpoints, continue in a threaded application works. +# - Test that breakpoints, continue in a threaded application works. # On powerpc64-unknown-linux-gnu system, running kernel version # 2.6.5-7.71-pseries64 this test is known to fail due to kernel bug # in ptrace system call. # # Test Strategy: # - thread_check.c creates 2 threads -# - start gdb +# - start gdb # - create 2 breakpoints #1 main() #2 tf() (the thread function) # - run gdb till #1 main() breakpoint is reached # - continue to breakpoint #2 tf() @@ -39,7 +39,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 1 @@ -62,7 +62,7 @@ gdb_test "continue" \ ".*Breakpoint 2,.*tf.*at.*$srcfile:.*" \ "continue to tf" -# +# # backtrace from thread function. # gdb_test "backtrace" \ diff --git a/gdb/testsuite/gdb.threads/threadapply.exp b/gdb/testsuite/gdb.threads/threadapply.exp index c53db79..de264b6 100644 --- a/gdb/testsuite/gdb.threads/threadapply.exp +++ b/gdb/testsuite/gdb.threads/threadapply.exp @@ -25,7 +25,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} # # Run to `main' where we begin our tests. @@ -60,7 +60,7 @@ gdb_test "thread apply all backthread" "Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..* # Go into the thread_function to check that a simple "thread apply" # does not change the selected frame. gdb_test "step" "thread_function.*" "step to the thread_function" -gdb_test "up" ".*in main.*" "go up in the stack frame" +gdb_test "up" ".*in main.*" "go up in the stack frame" gdb_test "thread apply all print 1" "Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1" "run a simple print command on all threads" gdb_test "down" "#0.*thread_function.*" "go down and check selected frame" @@ -73,9 +73,9 @@ proc thr_apply_detach {thread_set} { global binfile global break_line - clean_restart ${binfile} + clean_restart ${::testfile} - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -104,7 +104,7 @@ proc kill_and_remove_inferior {thread_set} { # The test starts multiple inferiors, therefore non-extended # remote is not supported. - if [use_gdb_stub] { + if {[use_gdb_stub]} { unsupported "using gdb stub" return } @@ -112,7 +112,7 @@ proc kill_and_remove_inferior {thread_set} { set any "\[^\r\n\]*" set ws "\[ \t\]\+" - clean_restart ${binfile} + clean_restart ${::testfile} with_test_prefix "start inferior 1" { runto_main @@ -224,6 +224,8 @@ proc kill_and_remove_inferior {thread_set} { # Test both "all" and a thread list, because those are implemented as # different commands in GDB. -foreach_with_prefix thread_set {"all" "1.1"} { - kill_and_remove_inferior $thread_set +if {[allow_multi_inferior_tests]} { + foreach_with_prefix thread_set {"all" "1.1"} { + kill_and_remove_inferior $thread_set + } } diff --git a/gdb/testsuite/gdb.threads/threadcrash.exp b/gdb/testsuite/gdb.threads/threadcrash.exp index 15d2a20..d57f437 100644 --- a/gdb/testsuite/gdb.threads/threadcrash.exp +++ b/gdb/testsuite/gdb.threads/threadcrash.exp @@ -132,8 +132,9 @@ proc do_full_test {} { set pthread_kill ".*" } - for {set i 0} {$i < $thread_count } {incr i} { - set thread_num [expr [llength $test_list] - $i] + set loop_iterations [llength $test_list] + for {set i 0} {$i < $loop_iterations } {incr i} { + set thread_num [expr {$loop_iterations - $i}] set type [lindex $test_list $i] if { $type == 1 } { @@ -237,7 +238,7 @@ proc_with_prefix test_corefile {} { proc_with_prefix test_gcore {} { - clean_restart "$::binfile" + clean_restart "$::testfile" gdb_test "handle SIGUSR1 nostop print pass" \ ".*SIGUSR1.*No.*Yes.*Yes.*User defined signal 1" \ @@ -270,12 +271,12 @@ proc_with_prefix test_gcore {} { standard_testfile -if [prepare_for_testing "failed to prepare" $testfile $srcfile \ - {debug pthreads}] { +if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ + {debug pthreads}]} { return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set backtrace limit unlimited" diff --git a/gdb/testsuite/gdb.threads/threads-after-exec.exp b/gdb/testsuite/gdb.threads/threads-after-exec.exp index db26315..a6a3fb7 100644 --- a/gdb/testsuite/gdb.threads/threads-after-exec.exp +++ b/gdb/testsuite/gdb.threads/threads-after-exec.exp @@ -19,11 +19,11 @@ standard_testfile .c proc do_test { } { - if [prepare_for_testing "failed to prepare" $::testfile $::srcfile {debug pthreads}] { + if {[prepare_for_testing "failed to prepare" $::testfile $::srcfile {debug pthreads}]} { return -1 } - if ![runto_main] { + if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.threads/threxit-hop-specific.exp b/gdb/testsuite/gdb.threads/threxit-hop-specific.exp index ce2df7c..b55e80c 100644 --- a/gdb/testsuite/gdb.threads/threxit-hop-specific.exp +++ b/gdb/testsuite/gdb.threads/threxit-hop-specific.exp @@ -23,7 +23,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} runto_main diff --git a/gdb/testsuite/gdb.threads/tid-reuse.exp b/gdb/testsuite/gdb.threads/tid-reuse.exp index 6762127..ca5edc1 100644 --- a/gdb/testsuite/gdb.threads/tid-reuse.exp +++ b/gdb/testsuite/gdb.threads/tid-reuse.exp @@ -22,7 +22,7 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile { debug pthreads return -1 } -if ![runto_main] { +if {![runto_main]} { return -1 } @@ -72,6 +72,6 @@ delete_breakpoints gdb_breakpoint "after_reuse_time" # Higher than what the test program sleeps before exiting. -set timeout [expr $reuse_time * 2] +set timeout [expr {$reuse_time * 2}] gdb_continue_to_breakpoint "after_reuse_time" diff --git a/gdb/testsuite/gdb.threads/tls-core.exp b/gdb/testsuite/gdb.threads/tls-core.exp index 96b1c6a..587ae61 100644 --- a/gdb/testsuite/gdb.threads/tls-core.exp +++ b/gdb/testsuite/gdb.threads/tls-core.exp @@ -27,7 +27,7 @@ set core_supported [expr {$corefile != ""}] # Generate a core file with "gcore". -clean_restart ${binfile} +clean_restart ${::testfile} runto thread_proc @@ -43,7 +43,7 @@ proc tls_core_test {supported corefile} { upvar host_triplet host_triplet upvar binfile binfile - clean_restart ${binfile} + clean_restart ${::testfile} set test "load core file" if {$supported} { diff --git a/gdb/testsuite/gdb.threads/tls-nodebug-pie.exp b/gdb/testsuite/gdb.threads/tls-nodebug-pie.exp index 01abcfa..44c12f5 100644 --- a/gdb/testsuite/gdb.threads/tls-nodebug-pie.exp +++ b/gdb/testsuite/gdb.threads/tls-nodebug-pie.exp @@ -20,7 +20,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/tls-nodebug.exp b/gdb/testsuite/gdb.threads/tls-nodebug.exp index ebfa752..971f26c 100644 --- a/gdb/testsuite/gdb.threads/tls-nodebug.exp +++ b/gdb/testsuite/gdb.threads/tls-nodebug.exp @@ -26,7 +26,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/tls-sepdebug.exp b/gdb/testsuite/gdb.threads/tls-sepdebug.exp index 6f3c711..fb684c9 100644 --- a/gdb/testsuite/gdb.threads/tls-sepdebug.exp +++ b/gdb/testsuite/gdb.threads/tls-sepdebug.exp @@ -83,7 +83,7 @@ foreach library_path [list $absdir [relative_filename [pwd] $absdir]] \ gdb_load ${binmainfile} - if ![runto_main] { + if {![runto_main]} { return } diff --git a/gdb/testsuite/gdb.threads/tls-shared.exp b/gdb/testsuite/gdb.threads/tls-shared.exp index 35596bc..66dd52f 100644 --- a/gdb/testsuite/gdb.threads/tls-shared.exp +++ b/gdb/testsuite/gdb.threads/tls-shared.exp @@ -29,7 +29,7 @@ if { [gdb_compile_shlib_pthreads ${srcdir}/${subdir}/${srcfile_lib} ${binfile_li } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_load_shlib ${binfile_lib} if {![runto_main]} { @@ -52,6 +52,6 @@ gdb_test "break $line_number" \ gdb_test "continue" \ "main .* at .*:.*return 0.*break here to check result.*" \ "continue to break" -# This is more of a gcc/glibc test, really. +# This is more of a gcc/glibc test, really. # gdb_test "print result" "3" diff --git a/gdb/testsuite/gdb.threads/tls-so_extern.exp b/gdb/testsuite/gdb.threads/tls-so_extern.exp index 3cef672..a0aa5f8 100644 --- a/gdb/testsuite/gdb.threads/tls-so_extern.exp +++ b/gdb/testsuite/gdb.threads/tls-so_extern.exp @@ -28,7 +28,7 @@ if { [gdb_compile_shlib_pthreads ${srcdir}/${subdir}/${srcfile_lib} ${binfile_li } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_load_shlib ${binfile_lib} if {![runto_main]} { diff --git a/gdb/testsuite/gdb.threads/tls-var.exp b/gdb/testsuite/gdb.threads/tls-var.exp index de74bd9..8d8b82e 100644 --- a/gdb/testsuite/gdb.threads/tls-var.exp +++ b/gdb/testsuite/gdb.threads/tls-var.exp @@ -27,7 +27,7 @@ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${objfile} object {debug}] != " clean_restart ${executable} -if ![runto_main] { +if {![runto_main]} { return 0 } diff --git a/gdb/testsuite/gdb.threads/tls.exp b/gdb/testsuite/gdb.threads/tls.exp index 1bc5df2..3dbc802 100644 --- a/gdb/testsuite/gdb.threads/tls.exp +++ b/gdb/testsuite/gdb.threads/tls.exp @@ -56,7 +56,7 @@ proc get_me_variable {tnum} { fail "$tnum thread print me" } timeout { - fail "$tnum thread print me (timeout)" + fail "$tnum thread print me (timeout)" } } return ${value_of_me} @@ -116,8 +116,8 @@ proc select_thread {thread} { ### Do a backtrace for the current thread, and check that the 'spin' routine ### is in it. This means we have one of the threads we created, rather -### than the main thread. Record the thread in the spin_threads -### array. Also remember the level of the 'spin' routine in the backtrace, for +### than the main thread. Record the thread in the spin_threads +### array. Also remember the level of the 'spin' routine in the backtrace, for ### later use. proc check_thread_stack {number spin_threads spin_threads_level} { global gdb_prompt @@ -148,18 +148,18 @@ proc check_thread_stack {number spin_threads spin_threads_level} { pass "backtrace of thread number $number not relevant" } timeout { - fail "backtrace of thread number $number (timeout)" + fail "backtrace of thread number $number (timeout)" } } } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_multiple "print a_thread_local" "" { -re -wrap "Cannot find thread-local variables on this target" { kfail "gdb/25807" $gdb_test_name } - -re -wrap "Cannot read .a_thread_local. without registers" { + -re -wrap "Cannot (?:read|find address of TLS symbol) .a_thread_local. without registers" { pass $gdb_test_name } } @@ -169,7 +169,7 @@ if {![runto_main]} { } # Set a breakpoint at the "spin" routine to -# test the thread local's value. +# test the thread local's value. # gdb_test "b [gdb_get_line_number "here we know tls value"]" \ ".*Breakpoint 2.*tls.*" "set breakpoint at all threads" @@ -247,7 +247,7 @@ array set spin_threads_level {} unset spin_threads_level # For each thread check its backtrace to see if it is stopped at the -# spin routine. +# spin routine. for {set i 1} {$i <= $no_of_threads} {incr i} { check_thread_stack $i spin_threads spin_threads_level } @@ -268,7 +268,7 @@ foreach i [array names spin_threads] { # any intermediate point in spin, too, but that is much less # likely. gdb_test "up $level" ".*spin.*sem_(wait|post).*" "thread $i up" - check_thread_local $i + check_thread_local $i } } @@ -278,7 +278,7 @@ if {$thrs_in_spin == 0} { gdb_test "continue" ".*Breakpoint 4.*before exit.*" "threads exited" -send_gdb "info thread\n" +send_gdb "info thread\n" gdb_expect { -re ".* 1 *${tdlabel_re}.*2 *${tdlabel_re}.*$gdb_prompt $" { fail "too many threads left at end" diff --git a/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp b/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp index e23db0a..7c2b309 100644 --- a/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp +++ b/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp @@ -16,6 +16,8 @@ # Test following a vfork child that execs, when the vfork parent is a # threaded program, and it's a non-main thread that vforks. +require allow_fork_tests + standard_testfile if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} { @@ -28,7 +30,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} proc test_vfork {detach} { global binfile - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp b/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp index a6b7f49..a5e7475 100644 --- a/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp +++ b/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp @@ -16,6 +16,8 @@ # Test following a vfork child that exits, when the vfork parent is a # threaded program, and it's a non-main thread that vforks. +require allow_fork_tests + standard_testfile if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} { @@ -28,7 +30,7 @@ if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} proc test_vfork {detach} { global binfile - clean_restart $binfile + clean_restart $::testfile if {![runto_main]} { return 0 diff --git a/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp b/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp index fd081b3..1f87427 100644 --- a/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp +++ b/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp @@ -25,6 +25,10 @@ # To catch the bug, this test verifies that we can hit a breakpoint after a # vfork call, while a second inferior runs in the background. +require allow_fork_tests + +require allow_multi_inferior_tests + require !use_gdb_stub standard_testfile .c -sleep.c diff --git a/gdb/testsuite/gdb.threads/vfork-multi-thread.exp b/gdb/testsuite/gdb.threads/vfork-multi-thread.exp index 2b9294d..fce974b 100644 --- a/gdb/testsuite/gdb.threads/vfork-multi-thread.exp +++ b/gdb/testsuite/gdb.threads/vfork-multi-thread.exp @@ -30,6 +30,8 @@ # breakpoints are removed, so the main thread would miss the breakpoint and run # until exit. +require allow_fork_tests + standard_testfile if { [build_executable "failed to prepare" ${testfile} ${srcfile} {debug pthreads}] } { @@ -57,7 +59,7 @@ proc do_test { target-non-stop non-stop follow-fork-mode detach-on-fork schedule save_vars { ::GDBFLAGS } { append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" - clean_restart ${::binfile} + clean_restart ${::testfile} } gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp index 376ca2a..68fc99e 100644 --- a/gdb/testsuite/gdb.threads/watchpoint-fork.exp +++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp @@ -21,6 +21,8 @@ # must be done before starting the test so as to not disrupt the execution # of the actual test. +require allow_fork_tests + set allow_hw_watchpoint_tests_p [allow_hw_watchpoint_tests] set testfile watchpoint-fork @@ -67,7 +69,7 @@ proc test {type symbol} { # Testcase uses it for the `follow-fork-mode child' type. gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*" - if ![runto_main] { + if {![runto_main]} { return } @@ -124,7 +126,7 @@ proc test {type symbol} { # Testcase uses it for the `follow-fork-mode child' type. gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*" - if ![runto_main] { + if {![runto_main]} { return } @@ -163,7 +165,7 @@ proc test {type symbol} { test parent FOLLOW_PARENT # Only GNU/Linux is known to support `set follow-fork-mode child'. -if [istarget "*-*-linux*"] { +if {[istarget "*-*-linux*"]} { test child FOLLOW_CHILD } else { untested "${testfile}: child" diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp index 5d98913..067986a 100644 --- a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp +++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp @@ -41,7 +41,7 @@ foreach reorder {0 1} { with_test_prefix "reorder$reorder" { gdb_test "set can-use-hw-watchpoints 1" - if ![runto_main] { + if {![runto_main]} { return -1 } @@ -72,7 +72,7 @@ foreach reorder {0 1} { with_test_prefix "reorder$reorder" { "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \ "continue a" - if $reorder { + if {$reorder} { # GDB orders watchpoints by their addresses so inserting new variables # with lower addresses will shift the former watchpoints to higher # debug registers. diff --git a/gdb/testsuite/gdb.threads/watchthreads.exp b/gdb/testsuite/gdb.threads/watchthreads.exp index 49fc762..e2d629d 100644 --- a/gdb/testsuite/gdb.threads/watchthreads.exp +++ b/gdb/testsuite/gdb.threads/watchthreads.exp @@ -31,7 +31,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart $binfile +clean_restart $::testfile gdb_test_no_output "set can-use-hw-watchpoints 1" "" # @@ -67,11 +67,11 @@ for {set i 0} {$i < 30} {incr i} { # At least one hardware watchpoint was hit. Check if both were. set string $expect_out(1,string) - if [regexp "Hardware watchpoint 2: args\\\[0\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_0\[^\r\]*\r\[^\r\]*New value = [expr $args_0+1]\r" $string] { + if {[regexp "Hardware watchpoint 2: args\\\[0\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_0\[^\r\]*\r\[^\r\]*New value = [expr {$args_0+1}]\r" $string]} { incr args_0 incr test_flag_0 } - if [regexp "Hardware watchpoint 3: args\\\[1\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_1\[^\r\]*\r\[^\r\]*New value = [expr $args_1+1]\r" $string] { + if {[regexp "Hardware watchpoint 3: args\\\[1\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_1\[^\r\]*\r\[^\r\]*New value = [expr {$args_1+1}]\r" $string]} { incr args_1 incr test_flag_1 } @@ -97,7 +97,7 @@ for {set i 0} {$i < 30} {incr i} { } } - if [ regexp "$expected_loc" $string ] { + if {[ regexp "$expected_loc" $string ]} { set test_flag 1 } else { fail "threaded watch loop" @@ -140,23 +140,23 @@ if { $test_flag == 1 } { # Verify that we hit first watchpoint in main thread. set message "first watchpoint on args\[0\] hit" if { $args_0 > 0 } { - pass $message + pass $message } else { - fail $message + fail $message } # Verify that we hit second watchpoint in main thread. set message "first watchpoint on args\[1\] hit" if { $args_1 > 0 } { - pass $message + pass $message } else { - fail $message + fail $message } # Verify that we hit first watchpoint in child thread. set message "watchpoint on args\[0\] hit in thread" if { $args_0 > 1 } { - pass $message + pass $message } else { fail $message } @@ -164,9 +164,9 @@ if { $args_0 > 1 } { # Verify that we hit second watchpoint in child thread. set message "watchpoint on args\[1\] hit in thread" if { $args_1 > 1 } { - pass $message + pass $message } else { - fail $message + fail $message } # Verify that all watchpoint hits are accounted for. @@ -174,12 +174,12 @@ set message "combination of threaded watchpoints = 30" if { [target_no_stopped_data] } { # See above. If we allow two watchpoints to be hit at once, we # may have more than 30 hits total. - set result [expr $args_0 + $args_1 >= 30] + set result [expr {$args_0 + $args_1 >= 30}] } else { - set result [expr $args_0 + $args_1 == 30] + set result [expr {$args_0 + $args_1 == 30}] } if { $result } { - pass $message + pass $message } else { - fail $message + fail $message } diff --git a/gdb/testsuite/gdb.threads/watchthreads2.exp b/gdb/testsuite/gdb.threads/watchthreads2.exp index 2426be4..a31c1a7 100644 --- a/gdb/testsuite/gdb.threads/watchthreads2.exp +++ b/gdb/testsuite/gdb.threads/watchthreads2.exp @@ -31,7 +31,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} gdb_test_no_output "set can-use-hw-watchpoints 1" "" @@ -89,7 +89,7 @@ set x_thread_loc "thread_function \\\(arg=.*\\\) at .*watchthreads.c:$x_inc_line # X is incremented under a mutex, so we should get NR_THREADS * X_INCR_COUNT # hits. -set limit [expr $NR_THREADS*$X_INCR_COUNT] +set limit [expr {$NR_THREADS*$X_INCR_COUNT}] set x_count 0 set done 0 @@ -102,7 +102,7 @@ for {set i 0} {!$done && $i < $limit} {incr i} { -re "(.*Hardware watchpoint.*)$gdb_prompt $" { set string $expect_out(1,string) - if [regexp "Hardware watchpoint 3: x\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $x_count\[^\r\]*\r\[^\r\]*New value = [expr $x_count+1]\r" $string] { + if {[regexp "Hardware watchpoint 3: x\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $x_count\[^\r\]*\r\[^\r\]*New value = [expr {$x_count+1}]\r" $string]} { incr x_count set test_flag 1 } else { diff --git a/gdb/testsuite/gdb.threads/wp-replication.exp b/gdb/testsuite/gdb.threads/wp-replication.exp index 68f5eb0..1b63d57 100644 --- a/gdb/testsuite/gdb.threads/wp-replication.exp +++ b/gdb/testsuite/gdb.threads/wp-replication.exp @@ -34,7 +34,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab return -1 } -clean_restart ${binfile} +clean_restart ${::testfile} # Force hardware watchpoints to be used. gdb_test_no_output "set can-use-hw-watchpoints 1" "" @@ -126,7 +126,7 @@ gdb_test_no_output "set var test_ready=1" \ "set var test_ready=1" # Set the number of expected watchpoint triggers. -set TRIGGERS [expr "$NR_THREADS * $hwatch_count * $NR_TRIGGERS_PER_THREAD"] +set TRIGGERS [expr {$NR_THREADS * $hwatch_count * $NR_TRIGGERS_PER_THREAD}] # Move the threads and hit the watchpoints TRIGGERS times. for { set i 1 } { $i <= $TRIGGERS } { incr i } { diff --git a/gdb/testsuite/gdb.trace/ax.exp b/gdb/testsuite/gdb.trace/ax.exp index 3380cdf..cc40853 100644 --- a/gdb/testsuite/gdb.trace/ax.exp +++ b/gdb/testsuite/gdb.trace/ax.exp @@ -30,7 +30,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -clean_restart $binfile +clean_restart $testfile runto_main gdb_test "maint agent 12" ".*const8 12.*pop.*end.*" diff --git a/gdb/testsuite/gdb.trace/basic-libipa.exp b/gdb/testsuite/gdb.trace/basic-libipa.exp index e7612ac..27be96b 100644 --- a/gdb/testsuite/gdb.trace/basic-libipa.exp +++ b/gdb/testsuite/gdb.trace/basic-libipa.exp @@ -42,7 +42,7 @@ save_vars { env(ASAN_OPTIONS) } { # LD_PRELOAD. append_environment_default ASAN_OPTIONS verify_asan_link_order 0 - clean_restart $binfile + clean_restart $testfile } if {![runto_main]} { diff --git a/gdb/testsuite/gdb.trace/entry-values.exp b/gdb/testsuite/gdb.trace/entry-values.exp index f6bcf66..1d2e8e9 100644 --- a/gdb/testsuite/gdb.trace/entry-values.exp +++ b/gdb/testsuite/gdb.trace/entry-values.exp @@ -29,7 +29,7 @@ if {[gdb_compile [list ${binfile}1.o] \ return -1 } -clean_restart ${binfile}1 +clean_restart ${testfile}1 set returned_from_foo "" @@ -90,61 +90,63 @@ Dwarf::assemble $asm_file { set bar_length [lindex $bar_result 1] cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { int_label: base_type { - {name int} - {encoding @DW_ATE_signed} - {byte_size 4 DW_FORM_sdata} + DW_AT_name int + DW_AT_encoding @DW_ATE_signed + DW_AT_byte_size 4 DW_FORM_sdata } foo_label: subprogram { - {decl_file 0 udata} - {MACRO_AT_func { foo }} + DW_AT_decl_file 0 udata + MACRO_AT_func { foo } } { formal_parameter { - {type :$int_label} - {name i} - {location {DW_OP_reg0} SPECIAL_expr} + DW_AT_type :$int_label + DW_AT_name i + DW_AT_location {DW_OP_reg0} SPECIAL_expr } formal_parameter { - {type :$int_label} - {name j} - {location {DW_OP_reg1} SPECIAL_expr} + DW_AT_type :$int_label + DW_AT_name j + DW_AT_location {DW_OP_reg1} SPECIAL_expr } } subprogram { - {name bar} - {decl_file 0 udata} - {low_pc $bar_start addr} - {high_pc "$bar_start + $bar_length" addr} - {GNU_all_call_sites 1 sdata} + DW_AT_name bar + DW_AT_decl_file 0 udata + DW_AT_low_pc $bar_start addr + DW_AT_high_pc "$bar_start + $bar_length" addr + DW_AT_GNU_all_call_sites 1 sdata } { formal_parameter { - {type :$int_label} - {name i} + DW_AT_type :$int_label + DW_AT_name i } GNU_call_site { - {low_pc "$bar_start + $returned_from_foo" addr} - {abstract_origin :$foo_label} + DW_AT_low_pc "$bar_start + $returned_from_foo" addr + DW_AT_abstract_origin :$foo_label } { # Faked entry values are reference to variables 'global1' # and 'global2' and faked locations are register 0 and # register 1. GNU_call_site_parameter { - {location {DW_OP_reg0} SPECIAL_expr} - {GNU_call_site_value { + DW_AT_location {DW_OP_reg0} SPECIAL_expr + DW_AT_GNU_call_site_value { addr global1 deref_size 4 - } SPECIAL_expr} + } SPECIAL_expr } GNU_call_site_parameter { - {location {DW_OP_reg1} SPECIAL_expr} - {GNU_call_site_value { + DW_AT_location {DW_OP_reg1} SPECIAL_expr + DW_AT_GNU_call_site_value { addr global2 deref_size 4 - } SPECIAL_expr} + } SPECIAL_expr } } } @@ -193,7 +195,7 @@ gdb_test_sequence "bt" "bt, 2" { # Restart GDB and trace. -clean_restart $binfile +clean_restart $testfile load_lib "trace-support.exp" diff --git a/gdb/testsuite/gdb.trace/ftrace-lock.exp b/gdb/testsuite/gdb.trace/ftrace-lock.exp index 36a7566..8c9d4aa 100644 --- a/gdb/testsuite/gdb.trace/ftrace-lock.exp +++ b/gdb/testsuite/gdb.trace/ftrace-lock.exp @@ -32,7 +32,7 @@ set options [list debug pthreads [gdb_target_symbol_prefix_flags] \ additional_flags=-DNUM_THREADS=$NUM_THREADS] with_test_prefix "runtime trace support check" { - if { [prepare_for_testing "prepare for testing" ${binfile}-check \ + if { [prepare_for_testing "prepare for testing" ${testfile}-check \ $srcfile $options] } { return } @@ -55,7 +55,7 @@ set remote_libipa [gdb_load_shlib $libipa] lappend options shlib=$libipa if { [prepare_for_testing "prepare for testing with libipa" \ - $binfile $srcfile $options] } { + $testfile $srcfile $options] } { return } diff --git a/gdb/testsuite/gdb.trace/mi-trace-frame-collected.exp b/gdb/testsuite/gdb.trace/mi-trace-frame-collected.exp index dd0d785..9b4f053 100644 --- a/gdb/testsuite/gdb.trace/mi-trace-frame-collected.exp +++ b/gdb/testsuite/gdb.trace/mi-trace-frame-collected.exp @@ -37,7 +37,7 @@ gdb_exit load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $testfile mi_runto_main mi_gdb_test "-break-insert end" \ diff --git a/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp b/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp index dde6d8b..dd22046 100644 --- a/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp +++ b/gdb/testsuite/gdb.trace/mi-trace-unavailable.exp @@ -35,7 +35,7 @@ gdb_exit load_lib mi-support.exp set MIFLAGS "-i=mi" -mi_clean_restart $binfile +mi_clean_restart $testfile mi_runto_main mi_gdb_test "-break-insert marker" \ diff --git a/gdb/testsuite/gdb.trace/mi-traceframe-changed.exp b/gdb/testsuite/gdb.trace/mi-traceframe-changed.exp index 05c10ed..90a053c 100644 --- a/gdb/testsuite/gdb.trace/mi-traceframe-changed.exp +++ b/gdb/testsuite/gdb.trace/mi-traceframe-changed.exp @@ -45,11 +45,10 @@ remote_file target delete $tfile_basic proc test_tfind_tfile { } { with_test_prefix "tfile" { - global binfile global decimal global tfile_basic - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_gdb_test "-target-select tfile ${tfile_basic}" \ ".*=breakpoint-created,bkpt=\{number=\"${decimal}\",type=\"tracepoint\",disp=\"keep\",enabled=\"y\",.*,func=\"write_basic_trace_file\".*\\^connected" \ @@ -92,8 +91,8 @@ if [generate_tracefile $binfile] { # Change to a different test case in order to run it on target, and get # several traceframes. standard_testfile status-stop.c -append testfile -1 -append binfile -1 +append testfile "-1" +append binfile "-1" set executable $testfile if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ @@ -120,9 +119,8 @@ gdb_exit proc test_tfind_remote { } { with_test_prefix "remote" { global decimal - global binfile - mi_clean_restart $binfile + mi_clean_restart $::testfile mi_runto_main mi_gdb_test "-break-insert end" "\\^done.*" "break end" diff --git a/gdb/testsuite/gdb.trace/mi-tracepoint-changed.exp b/gdb/testsuite/gdb.trace/mi-tracepoint-changed.exp index 90654c0..99f7bf9 100644 --- a/gdb/testsuite/gdb.trace/mi-tracepoint-changed.exp +++ b/gdb/testsuite/gdb.trace/mi-tracepoint-changed.exp @@ -89,9 +89,7 @@ proc test_reconnect { } { } } - global binfile - - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } @@ -155,11 +153,10 @@ proc test_pending_resolved { } { with_test_prefix "pending resolved" { global decimal hex global executable - global binfile global lib_sl1 lib_sl2 global mi_gdb_prompt - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } mi_load_shlibs $lib_sl1 $lib_sl2 diff --git a/gdb/testsuite/gdb.trace/mi-tsv-changed.exp b/gdb/testsuite/gdb.trace/mi-tsv-changed.exp index f90d9a4..6f71e79 100644 --- a/gdb/testsuite/gdb.trace/mi-tsv-changed.exp +++ b/gdb/testsuite/gdb.trace/mi-tsv-changed.exp @@ -77,7 +77,7 @@ proc test_create_delete_modify_tsv { } { } gdb_exit - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } @@ -145,7 +145,7 @@ proc test_upload_tsv { } { return 0 } - clean_restart $testfile + clean_restart $::testfile if {![runto_main]} { return 0 } @@ -175,8 +175,7 @@ proc test_upload_tsv { } { } } - global binfile - if {[mi_clean_restart $binfile]} { + if {[mi_clean_restart $::testfile]} { return } diff --git a/gdb/testsuite/gdb.trace/packetlen.exp b/gdb/testsuite/gdb.trace/packetlen.exp index cf9fcc4..52a34b9 100644 --- a/gdb/testsuite/gdb.trace/packetlen.exp +++ b/gdb/testsuite/gdb.trace/packetlen.exp @@ -25,7 +25,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -clean_restart $binfile +clean_restart $testfile gdb_test "tstop" ".*" "" gdb_test "tfind none" ".*" "" runto_main diff --git a/gdb/testsuite/gdb.trace/passc-dyn.exp b/gdb/testsuite/gdb.trace/passc-dyn.exp index 0a67df1..b4ec45a 100644 --- a/gdb/testsuite/gdb.trace/passc-dyn.exp +++ b/gdb/testsuite/gdb.trace/passc-dyn.exp @@ -25,7 +25,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -clean_restart $binfile +clean_restart $testfile runto_main if {![gdb_target_supports_trace]} { diff --git a/gdb/testsuite/gdb.trace/report.exp b/gdb/testsuite/gdb.trace/report.exp index 45857a1..f2a04f7 100644 --- a/gdb/testsuite/gdb.trace/report.exp +++ b/gdb/testsuite/gdb.trace/report.exp @@ -24,7 +24,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ untested "failed to compile" return -1 } -clean_restart $binfile +clean_restart $testfile runto_main if {![gdb_target_supports_trace]} { diff --git a/gdb/testsuite/gdb.trace/tfile.exp b/gdb/testsuite/gdb.trace/tfile.exp index 020f4d4..4d156f7 100644 --- a/gdb/testsuite/gdb.trace/tfile.exp +++ b/gdb/testsuite/gdb.trace/tfile.exp @@ -61,7 +61,7 @@ if {!$purely_local} { remote_download host [remote_upload target tfile-error.tf] tfile-error.tf } -clean_restart $binfile +clean_restart $testfile # Program has presumably exited, now target a trace file it created. @@ -121,7 +121,7 @@ gdb_test "info registers" "The program has no registers now\." \ # Now start afresh, using only a trace file. -clean_restart $binfile +clean_restart $testfile gdb_test "target tfile $tfile_error" "Created tracepoint.*" \ "target tfile [file tail $tfile_error]" diff --git a/gdb/testsuite/gdb.trace/tfind.exp b/gdb/testsuite/gdb.trace/tfind.exp index ae73206..92386e4 100644 --- a/gdb/testsuite/gdb.trace/tfind.exp +++ b/gdb/testsuite/gdb.trace/tfind.exp @@ -27,7 +27,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" "$binfile" \ return -1 } -clean_restart $binfile +clean_restart $testfile # 6.2 test help tstart gdb_test "help tstart" \ diff --git a/gdb/testsuite/gdb.trace/trace-mt.exp b/gdb/testsuite/gdb.trace/trace-mt.exp index 0c6e4e5..092dc6d 100644 --- a/gdb/testsuite/gdb.trace/trace-mt.exp +++ b/gdb/testsuite/gdb.trace/trace-mt.exp @@ -22,7 +22,7 @@ set additional_flags [gdb_target_symbol_prefix_flags] require gdb_trace_common_supports_arch with_test_prefix "runtime trace support check" { - if { [prepare_for_testing "prepare for testing" ${binfile} $srcfile \ + if { [prepare_for_testing "prepare for testing" $testfile $srcfile \ [list debug pthreads $additional_flags]] } { return } @@ -37,13 +37,13 @@ with_test_prefix "runtime trace support check" { } } -proc step_over_tracepoint { binfile trace_type } \ +proc step_over_tracepoint { testfile trace_type } \ {with_test_prefix "step over $trace_type" \ { global hex # Start with a fresh gdb. - clean_restart $binfile + clean_restart $testfile # Make sure inferior is running in all-stop mode. gdb_test_no_output "set non-stop 0" @@ -63,13 +63,13 @@ proc step_over_tracepoint { binfile trace_type } \ # Set breakpoint and tracepoint at the same address. -proc break_trace_same_addr { binfile trace_type option } \ +proc break_trace_same_addr { testfile trace_type option } \ {with_test_prefix "$trace_type $option" \ { global hex # Start with a fresh gdb. - clean_restart $binfile + clean_restart $testfile if ![runto_main] { return -1 } @@ -96,10 +96,10 @@ proc break_trace_same_addr { binfile trace_type option } \ }} foreach break_always_inserted { "on" "off" } { - break_trace_same_addr $binfile "trace" ${break_always_inserted} + break_trace_same_addr $testfile "trace" ${break_always_inserted} } -step_over_tracepoint $binfile "trace" +step_over_tracepoint $testfile "trace" require allow_shlib_tests @@ -108,8 +108,8 @@ set libipa [get_in_proc_agent] set remote_libipa [gdb_load_shlib $libipa] # Compile test case again with IPA. -set binfile_ipa ${binfile}-ipa -if { [prepare_for_testing "prepare for testing" $binfile_ipa $srcfile \ +set testfile_ipa $testfile-ipa +if { [prepare_for_testing "prepare for testing" $testfile_ipa $srcfile \ [list debug pthreads $additional_flags shlib=$libipa]] } { return } @@ -122,8 +122,8 @@ if { [gdb_test "info sharedlibrary" ".*${remote_libipa}.*" "IPA loaded"] != 0 } untested "could not find IPA lib loaded" } else { foreach break_always_inserted { "on" "off" } { - break_trace_same_addr $binfile_ipa "ftrace" ${break_always_inserted} + break_trace_same_addr $testfile_ipa "ftrace" ${break_always_inserted} } - step_over_tracepoint $binfile_ipa "ftrace" + step_over_tracepoint $testfile_ipa "ftrace" } diff --git a/gdb/testsuite/gdb.trace/tspeed.exp b/gdb/testsuite/gdb.trace/tspeed.exp index 25862bf..be7f37e 100644 --- a/gdb/testsuite/gdb.trace/tspeed.exp +++ b/gdb/testsuite/gdb.trace/tspeed.exp @@ -17,7 +17,7 @@ load_lib "trace-support.exp" require allow_shlib_tests -# Do not run if gdbsever debug is enabled - the output file is many Gb. +# Do not run if gdbserver debug is enabled - the output file is many Gb. if [gdbserver_debug_enabled] { return 0 } diff --git a/gdb/testsuite/gdb.trace/tsv.exp b/gdb/testsuite/gdb.trace/tsv.exp index 96c7c35..837633d 100644 --- a/gdb/testsuite/gdb.trace/tsv.exp +++ b/gdb/testsuite/gdb.trace/tsv.exp @@ -23,7 +23,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -clean_restart $binfile +clean_restart $testfile # PR gdb/21352: Command tsave does not support -r argument gdb_test "tsave -r" "Argument required \\\(file in which to save trace data\\\)\." \ @@ -193,7 +193,7 @@ gdb_test_multiple "target ctf ${tracefile}.ctf" "" { } # Restart. -clean_restart ${binfile} +clean_restart $testfile if {![runto_main]} { return diff --git a/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp index 98207f0..3adf24a 100644 --- a/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp +++ b/gdb/testsuite/gdb.trace/unavailable-dwarf-piece.exp @@ -32,165 +32,167 @@ Dwarf::assemble $asm_file { declare_labels uchar_label struct_s_label foo_label struct_t_label bar_label cu {} { - compile_unit {{language @DW_LANG_C}} { + compile_unit { + DW_AT_language @DW_LANG_C + } { uchar_label: DW_TAG_base_type { - {name "unsigned char"} - {byte_size 1 DW_FORM_sdata} - {encoding @DW_ATE_unsigned_char} + DW_AT_name "unsigned char" + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_encoding @DW_ATE_unsigned_char } struct_s_label: DW_TAG_structure_type { - {name s} - {byte_size 3 DW_FORM_sdata} - {decl_file 0 DW_FORM_udata} - {decl_line 1 DW_FORM_udata} + DW_AT_name s + DW_AT_byte_size 3 DW_FORM_sdata + DW_AT_decl_file 0 DW_FORM_udata + DW_AT_decl_line 1 DW_FORM_udata } { DW_TAG_member { - {name a} - {type :$uchar_label} - {data_member_location { + DW_AT_name a + DW_AT_type :$uchar_label + DW_AT_data_member_location { DW_OP_plus_uconst 0 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name b} - {type :$uchar_label} - {data_member_location { + DW_AT_name b + DW_AT_type :$uchar_label + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name c} - {type :$uchar_label} - {data_member_location { + DW_AT_name c + DW_AT_type :$uchar_label + DW_AT_data_member_location { DW_OP_plus_uconst 2 - } SPECIAL_expr} + } SPECIAL_expr } } struct_t_label: DW_TAG_structure_type { - {name t} - {byte_size 3 DW_FORM_sdata} - {decl_file 0 DW_FORM_udata} - {decl_line 1 DW_FORM_udata} + DW_AT_name t + DW_AT_byte_size 3 DW_FORM_sdata + DW_AT_decl_file 0 DW_FORM_udata + DW_AT_decl_line 1 DW_FORM_udata } { DW_TAG_member { - {name a} - {type :$uchar_label} - {data_member_location { + DW_AT_name a + DW_AT_type :$uchar_label + DW_AT_data_member_location { DW_OP_plus_uconst 0 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name b} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 7 DW_FORM_sdata} - {data_member_location { + DW_AT_name b + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 7 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name c} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 6 DW_FORM_sdata} - {data_member_location { + DW_AT_name c + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 6 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name d} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 5 DW_FORM_sdata} - {data_member_location { + DW_AT_name d + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 5 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name e} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 4 DW_FORM_sdata} - {data_member_location { + DW_AT_name e + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 4 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name f} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 3 DW_FORM_sdata} - {data_member_location { + DW_AT_name f + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 3 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name g} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 2 DW_FORM_sdata} - {data_member_location { + DW_AT_name g + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 2 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name h} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 1 DW_FORM_sdata} - {data_member_location { + DW_AT_name h + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 1 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name i} - {type :$uchar_label} - {byte_size 1 DW_FORM_sdata} - {bit_size 1 DW_FORM_sdata} - {bit_offset 0 DW_FORM_sdata} - {data_member_location { + DW_AT_name i + DW_AT_type :$uchar_label + DW_AT_byte_size 1 DW_FORM_sdata + DW_AT_bit_size 1 DW_FORM_sdata + DW_AT_bit_offset 0 DW_FORM_sdata + DW_AT_data_member_location { DW_OP_plus_uconst 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_member { - {name j} - {type :$uchar_label} - {data_member_location { + DW_AT_name j + DW_AT_type :$uchar_label + DW_AT_data_member_location { DW_OP_plus_uconst 2 - } SPECIAL_expr} + } SPECIAL_expr } } DW_TAG_subprogram { - {name foo} - {decl_file 0 udata} - {low_pc foo_start_lbl addr} - {high_pc foo_end_lbl addr} + DW_AT_name foo + DW_AT_decl_file 0 udata + DW_AT_low_pc foo_start_lbl addr + DW_AT_high_pc foo_end_lbl addr } { DW_TAG_formal_parameter { - {type :$struct_s_label} - {name x} - {location { + DW_AT_type :$struct_s_label + DW_AT_name x + DW_AT_location { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 2 DW_OP_reg0 DW_OP_piece 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_formal_parameter { - {type :$struct_s_label} - {name y} - {location { + DW_AT_type :$struct_s_label + DW_AT_name y + DW_AT_location { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 @@ -199,32 +201,32 @@ Dwarf::assemble $asm_file { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_formal_parameter { - {type :$struct_s_label} - {name z} - {location { + DW_AT_type :$struct_s_label + DW_AT_name z + DW_AT_location { DW_OP_reg0 DW_OP_piece 1 DW_OP_lit0 DW_OP_stack_value DW_OP_piece 2 - } SPECIAL_expr} + } SPECIAL_expr } } DW_TAG_subprogram { - {name bar} - {decl_file 0 udata} - {low_pc bar_start_lbl addr} - {high_pc bar_end_lbl addr} + DW_AT_name bar + DW_AT_decl_file 0 udata + DW_AT_low_pc bar_start_lbl addr + DW_AT_high_pc bar_end_lbl addr } { DW_TAG_formal_parameter { - {type :$struct_t_label} - {name x} - {location { + DW_AT_type :$struct_t_label + DW_AT_name x + DW_AT_location { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 @@ -236,12 +238,12 @@ Dwarf::assemble $asm_file { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_formal_parameter { - {type :$struct_t_label} - {name y} - {location { + DW_AT_type :$struct_t_label + DW_AT_name y + DW_AT_location { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 @@ -256,12 +258,12 @@ Dwarf::assemble $asm_file { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 - } SPECIAL_expr} + } SPECIAL_expr } DW_TAG_formal_parameter { - {type :$struct_t_label} - {name z} - {location { + DW_AT_type :$struct_t_label + DW_AT_name z + DW_AT_location { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 @@ -273,7 +275,7 @@ Dwarf::assemble $asm_file { DW_OP_lit0 DW_OP_stack_value DW_OP_piece 1 - } SPECIAL_expr} + } SPECIAL_expr } } diff --git a/gdb/testsuite/gdb.trace/while-dyn.exp b/gdb/testsuite/gdb.trace/while-dyn.exp index 53a8e54..3940ff6 100644 --- a/gdb/testsuite/gdb.trace/while-dyn.exp +++ b/gdb/testsuite/gdb.trace/while-dyn.exp @@ -26,7 +26,7 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -clean_restart $binfile +clean_restart $testfile runto_main if {![gdb_target_supports_trace]} { diff --git a/gdb/testsuite/gdb.tui/basic.exp b/gdb/testsuite/gdb.tui/basic.exp index 35c99bd..8ecc91a 100644 --- a/gdb/testsuite/gdb.tui/basic.exp +++ b/gdb/testsuite/gdb.tui/basic.exp @@ -112,5 +112,9 @@ set re_noattr "\[^<\]" set status_window_line 15 set status [Term::get_line_with_attrs $status_window_line] -gdb_assert { [regexp "^<reverse:1>$re_noattr*<reverse:0>$" $status] == 1} \ +verbose -log "status line: '$status'" + +# The status line uses standout, which may translate to different attributes +# depending on the terminal settings. Just check for at least one attribute. +gdb_assert { [regexp "^<.*>(exec|extended-r)" $status] == 1 } \ "status window: reverse" diff --git a/gdb/testsuite/gdb.tui/color-prompt.exp b/gdb/testsuite/gdb.tui/color-prompt.exp index a95b24a..af6e467 100644 --- a/gdb/testsuite/gdb.tui/color-prompt.exp +++ b/gdb/testsuite/gdb.tui/color-prompt.exp @@ -15,18 +15,16 @@ # Check using a prompt with color in TUI. +require allow_tui_tests + tuiterm_env Term::clean_restart 24 80 -# Set colored prompt. if {![Term::enter_tui]} { unsupported "TUI not supported" return } -Term::command "set prompt \\033\[31m(gdb) \\033\[0m" - -set line [Term::get_line_with_attrs $Term::_cur_row] -gdb_assert { [regexp "^<fg:red>$gdb_prompt <fg:default> *$" $line] } \ - "prompt with color" +set tui 1 +source $srcdir/$subdir/color-prompt.exp.tcl diff --git a/gdb/testsuite/gdb.tui/color-prompt.exp.tcl b/gdb/testsuite/gdb.tui/color-prompt.exp.tcl new file mode 100644 index 0000000..e6f4d3b --- /dev/null +++ b/gdb/testsuite/gdb.tui/color-prompt.exp.tcl @@ -0,0 +1,80 @@ +# 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/>. + +# Check using a prompt with color in TUI ($tui == 0) or CLI ($tui == 0). + +set csi [string cat {\033} "\["] +set rl_prompt_start_ignore {\001} +set rl_prompt_end_ignore {\002} + +foreach_with_prefix rl_prompt_start_end_ignore { 0 1 } { + set color_on [string cat $csi 31m] + set color_off [string cat $csi 0m] + + if { $rl_prompt_start_end_ignore } { + set color_on \ + [string cat \ + $rl_prompt_start_ignore \ + $color_on \ + $rl_prompt_end_ignore] + set color_off \ + [string cat \ + $rl_prompt_start_ignore \ + $color_off \ + $rl_prompt_end_ignore] + } + + # Set prompt with color. + set prompt "${color_on}(gdb) $color_off" + Term::command "set prompt $prompt" + + # Check the color. + set line [Term::get_line_with_attrs $Term::_cur_row] + gdb_assert { [regexp "^<fg:red>$gdb_prompt <fg:default> *$" $line] } \ + "prompt with color" + + # Type a string. + set cmd "some long command" + send_gdb $cmd + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] 23 + + # Send ^A, aka C-a, trigger beginning-of-line. + send_gdb "\001" + if { $tui || $rl_prompt_start_end_ignore } { + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] 6 + } else { + # Without the markers, readline may get the cursor position wrong, so + # match less strict. + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] + } + Term::dump_screen + + # Type something else to flush out the effect of the ^A. + set prefix "A" + send_gdb $prefix + if { $tui || $rl_prompt_start_end_ignore } { + Term::wait_for_line ^[string_to_regexp "(gdb) $prefix$cmd"] 7 + } else { + # Without the markers, readline may get the cursor position wrong, so + # match less strict. + Term::wait_for_line [string_to_regexp "$prefix"] + } + + # Abort command line editing, and regenerate prompt. + send_gdb "\003" + + # Reset prompt to default prompt. + Term::command "set prompt (gdb) " +} diff --git a/gdb/testsuite/gdb.tui/compact-source.exp b/gdb/testsuite/gdb.tui/compact-source.exp index b050159..31bc1dc 100644 --- a/gdb/testsuite/gdb.tui/compact-source.exp +++ b/gdb/testsuite/gdb.tui/compact-source.exp @@ -41,7 +41,7 @@ if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} { return -1 } -Term::clean_restart 24 80 $binfile +Term::clean_restart 24 80 $testfile gdb_test_no_output "maint set tui-left-margin-verbose on" gdb_test_no_output "set tui compact-source on" @@ -55,9 +55,9 @@ set re_border "\\|" set max_line_nr_in_source_file [llength $src_list] # Ensure there are more lines in the window than in the source file. -set src_window_lines [expr $max_line_nr_in_source_file + 2] +set src_window_lines [expr {$max_line_nr_in_source_file + 2}] # Account for border size. -set src_window_size [expr $src_window_lines + 2] +set src_window_size [expr {$src_window_lines + 2}] Term::command "wh src $src_window_size" set re_left_margin "___4_" @@ -65,6 +65,6 @@ set re_left_margin "___4_" Term::check_contents "compact source format" \ "$re_border$re_left_margin$re_line_four *$re_border" -set re_left_margin "___0*[expr $max_line_nr_in_source_file + 1]_" +set re_left_margin "___0*[expr {$max_line_nr_in_source_file + 1}]_" Term::check_contents_not "no surplus line number" \ "$re_border$re_left_margin *$re_border" diff --git a/gdb/testsuite/gdb.tui/corefile-run.exp b/gdb/testsuite/gdb.tui/corefile-run.exp index 89a48b5..657fc83 100644 --- a/gdb/testsuite/gdb.tui/corefile-run.exp +++ b/gdb/testsuite/gdb.tui/corefile-run.exp @@ -18,6 +18,8 @@ # # Ref.: https://bugzilla.redhat.com/show_bug.cgi?id=1765117 +require gcore_cmd_available + tuiterm_env standard_testfile tui-layout.c diff --git a/gdb/testsuite/gdb.tui/empty.exp b/gdb/testsuite/gdb.tui/empty.exp index 33710ff..19196e8 100644 --- a/gdb/testsuite/gdb.tui/empty.exp +++ b/gdb/testsuite/gdb.tui/empty.exp @@ -65,7 +65,7 @@ set layouts { proc check_boxes {boxes} { set boxno 1 foreach box $boxes { - eval Term::check_box [list "box $boxno"] $box + Term::check_box "box $boxno" {*}$box incr boxno } } diff --git a/gdb/testsuite/gdb.tui/esc-match.exp b/gdb/testsuite/gdb.tui/esc-match.exp new file mode 100644 index 0000000..db78ebe --- /dev/null +++ b/gdb/testsuite/gdb.tui/esc-match.exp @@ -0,0 +1,48 @@ +# 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 that the ANSI escape sequence matcher works +# character-by-character. + +load_lib gdb-python.exp +require allow_python_tests allow_tui_tests + +tuiterm_env + +Term::clean_restart 24 80 + +set remote_python_file [gdb_remote_download host \ + ${srcdir}/${subdir}/esc-match.py] +gdb_test_no_output "source ${remote_python_file}" \ + "source esc-match.py" + +if {![Term::enter_tui]} { + unsupported "TUI not supported" + return +} + +Term::command "python print_it()" + +Term::dump_screen + +set text [Term::get_all_lines] +# We should not see the control sequence here. +gdb_assert {![regexp -- "\\\[35;1mOUTPUT\\\[m" $text]} \ + "output visible without control sequences" + +# Also check the styling. +set text [Term::get_region 0 1 78 23 "\n" true] +gdb_assert {[regexp -- "<fg:magenta>.*OUTPUT" $text]} \ + "output is magenta" diff --git a/gdb/testsuite/gdb.tui/esc-match.py b/gdb/testsuite/gdb.tui/esc-match.py new file mode 100644 index 0000000..7816002 --- /dev/null +++ b/gdb/testsuite/gdb.tui/esc-match.py @@ -0,0 +1,26 @@ +# Copyright (C) 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/>. + +import sys + +# Some text to print that includes styling. +OUT = "\033[35;1mOUTPUT\033[m" + + +def print_it(): + # Print to stderr avoids any buffering, showing the bug. + for c in OUT: + print(c, end="", file=sys.stderr) + print(file=sys.stderr) diff --git a/gdb/testsuite/gdb.tui/gdb.sh b/gdb/testsuite/gdb.tui/gdb.sh new file mode 100755 index 0000000..0079a3f --- /dev/null +++ b/gdb/testsuite/gdb.tui/gdb.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# 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/>. + +printf "foo\033(%%5" + +read diff --git a/gdb/testsuite/gdb.tui/main-2.exp b/gdb/testsuite/gdb.tui/main-2.exp index 2b0fb6b..2bc6b8d 100644 --- a/gdb/testsuite/gdb.tui/main-2.exp +++ b/gdb/testsuite/gdb.tui/main-2.exp @@ -26,7 +26,7 @@ if { [build_executable "failed to prepare" $testfile $srcfile ] == -1} { return -1 } -Term::clean_restart 24 80 $binfile +Term::clean_restart 24 80 $testfile if {![runto_main]} { perror "test suppressed" @@ -41,7 +41,7 @@ if {![Term::enter_tui]} { set line " return 0;" set nr [gdb_get_line_number $line] -set screen_line [Term::get_line_with_attrs 6] +set screen_line [Term::get_string_with_attrs 6 11 79] verbose -log "screen line 6: '$screen_line'" -gdb_assert { [regexp "$nr <reverse:1>$line<reverse:0>" $screen_line] } \ +gdb_assert { [regexp "<reverse:1>$line<reverse:0>" $screen_line] } \ "highlighted line in middle of source window" diff --git a/gdb/testsuite/gdb.tui/main.exp b/gdb/testsuite/gdb.tui/main.exp index d6960c7..e49da35 100644 --- a/gdb/testsuite/gdb.tui/main.exp +++ b/gdb/testsuite/gdb.tui/main.exp @@ -43,7 +43,10 @@ if {![Term::enter_tui]} { } send_gdb "file [standard_output_file $testfile]\n" -gdb_assert { [Term::wait_for "Reading symbols from"] } "file command" +# Matching the output is difficult because it may or may not wrap. Simply +# match the resulting prompt. +gdb_assert { [Term::wait_for ""] } "file command" + Term::check_contents "show main after file" \ [string_to_regexp "|___[format %06d $nr]_$line"] diff --git a/gdb/testsuite/gdb.tui/new-layout.exp b/gdb/testsuite/gdb.tui/new-layout.exp index f517997..6a4c68f 100644 --- a/gdb/testsuite/gdb.tui/new-layout.exp +++ b/gdb/testsuite/gdb.tui/new-layout.exp @@ -45,15 +45,12 @@ gdb_test "tui new-layout example src 1 src 1" \ gdb_test "tui new-layout example src 1" \ "New layout does not contain the \"cmd\" window" -# Avoid unbalanced curly braces problems with tcl 8.5. -if { [tcl_version_at_least 8 6] } { - gdb_test "tui new-layout example src 1\}" \ - "Extra '\}' in layout specification" - gdb_test "tui new-layout example {src 1} 1\}" \ - "Extra '\}' in layout specification" - gdb_test "tui new-layout example \{src 1" \ - "Missing '\}' in layout specification" -} +gdb_test "tui new-layout example src 1\}" \ + "Extra '\}' in layout specification" +gdb_test "tui new-layout example {src 1} 1\}" \ + "Extra '\}' in layout specification" +gdb_test "tui new-layout example \{src 1" \ + "Missing '\}' in layout specification" # Each entry of this list describes a layout, and some associated # tests. The items within each entry are: @@ -84,7 +81,7 @@ set layouts \ proc check_boxes {boxes} { set boxno 1 foreach box $boxes { - eval Term::check_box [list "box $boxno"] $box + Term::check_box "box $boxno" {*}$box incr boxno } } @@ -150,4 +147,7 @@ Term::check_box "before cmd_only: src box in src layout" 0 0 80 15 Term::command "layout cmd_only" Term::command "layout src" + +# Flush out and check the resulting src box. +Term::command "print 1" Term::check_box "after cmd_only: src box in src layout" 0 0 80 15 diff --git a/gdb/testsuite/gdb.tui/pr30056.exp b/gdb/testsuite/gdb.tui/pr30056.exp index 1123593..3cf5e90 100644 --- a/gdb/testsuite/gdb.tui/pr30056.exp +++ b/gdb/testsuite/gdb.tui/pr30056.exp @@ -22,67 +22,72 @@ require {have_host_locale C.UTF-8} tuiterm_env +standard_testfile tui-long-line.c + +if { [build_executable "failed to prepare" $testfile $srcfile] == -1 } { + return +} + save_vars { env(LC_ALL) } { setenv LC_ALL C.UTF-8 # Start terminal. - Term::clean_restart 24 80 - - # Start TUI. - if {![Term::enter_tui]} { - unsupported "TUI not supported" - return - } - - # Send "^R", starting reverse-i-search. - send_gdb "\022" - Term::wait_for_region_contents 0 $Term::_cur_row $Term::_cols 1 \ - [string_to_regexp "(reverse-i-search)`': "] - - # Send "xyz". - send_gdb "xyz" - Term::wait_for_region_contents 0 $Term::_cur_row $Term::_cols 1 \ - [string_to_regexp "(failed reverse-i-search)`xyz': "] - - # Send arrow-right. - send_gdb "\033\[C" + Term::clean_restart 24 80 $testfile +} - # We need to the arrow-right to be processed by readline, before we - # send the following ^C. Waiting 1 ms seems to do that. - after 1 +# Start TUI. +if {![Term::enter_tui]} { + unsupported "TUI not supported" + return +} - # Send ^C. +# Send "^R", starting reverse-i-search. +send_gdb "\022" +gdb_assert { [Term::wait_for_region_contents 0 $Term::_cur_row $Term::_cols 1 \ + [string_to_regexp "(reverse-i-search)`': "]] } \ + "reverse-i-search" + +# Send "xyz". +send_gdb "xyz" +gdb_assert { [Term::wait_for_region_contents 0 $Term::_cur_row $Term::_cols 1 \ + [string_to_regexp "(failed reverse-i-search)`xyz': "]] } \ + "xyz" + +# Send arrow-right. +send_gdb "\033\[C" +# Wait for arrow-right effect. +gdb_assert { [Term::wait_for_region_contents 1 5 78 1 \ + [string_to_regexp " ain (void)"]] } "arrow right" + +# Send ^C. +send_gdb "\003" +gdb_assert { [Term::wait_for "Quit"] } "Control-C" + +set test "Control-C aborts isearch" + +# Send "xyz", again. +send_gdb "xyz" +# Wait for xyx to appear. +gdb_assert { [Term::wait_for_region_contents \ + 0 $Term::_cur_row $Term::_cols 1 "xyz"] } \ + "xyz, again" + +if { [Term::check_region_contents_p 0 $Term::_cur_row $Term::_cols 1 \ + "^$gdb_prompt xyz"] } { + pass $test + + # Send ^C to clear the command line. send_gdb "\003" - gdb_assert { [Term::wait_for "Quit"] } "Control-C" - - # Uncomment this to simulate that PR cli/30498 is fixed. - #send_gdb "\007" - - set test "Control-C aborts isearch" - - # Send "xyz", again. - send_gdb "xyz" - # Wait for xyx to appear. - Term::wait_for_region_contents 0 $Term::_cur_row $Term::_cols 1 "xyz" - - if { [Term::check_region_contents_p 0 $Term::_cur_row $Term::_cols 1 \ - "^$gdb_prompt xyz"] } { - pass $test - - # Send ^C to clear the command line. - send_gdb "\003" - } else { - # Sending ^C currently doesn't abort the i-search. PR cli/30498 is - # open about this. - kfail cli/30498 $test - - # At this point we don't have a reponsive prompt. Send ^G to abort - # the i-search. - send_gdb "\007" - } - - # We need a reponsive prompt here, to deal with the "monitor exit" - # that native-extended-gdbserver will send. Check that we have a - # responsive prompt. - Term::command "echo \\n" +} else { + # Sending ^C currently doesn't abort the i-search. + fail $test + + # At this point we don't have a responsive prompt. Send ^G to abort + # the i-search. + send_gdb "\007" } + +# We need a responsive prompt here, to deal with the "monitor exit" +# that native-extended-gdbserver will send. Check that we have a +# responsive prompt. +Term::command "echo \\n" diff --git a/gdb/testsuite/gdb.tui/source-search.c b/gdb/testsuite/gdb.tui/source-search.c new file mode 100644 index 0000000..2320c5c --- /dev/null +++ b/gdb/testsuite/gdb.tui/source-search.c @@ -0,0 +1,127 @@ +/* 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/>. */ + +int +main (void) +{ + /* Line 21 */ + /* Line 22 */ + /* Line 23 */ + /* Line 24 */ + /* Line 25 */ + /* Line 26 */ + /* Line 27 */ + /* Line 28 */ + /* Line 29 */ + /* Line 30 */ + /* Line 31 */ + /* Line 32 */ + /* Line 33 */ + /* Line 34 */ + /* Line 35 */ + /* Line 36 */ + /* Line 37 */ + /* Line 38 */ + /* Line 39 */ + /* Line 40 */ + /* Line 41 */ + /* Line 42 */ + /* Line 43 */ + /* Line 44 */ + /* Line 45 */ + /* Line 46 */ + /* Line 47 */ + /* Line 48 */ + /* Line 49 */ + /* Line 50 */ + /* Line 51 */ + /* Line 52 */ + /* Line 53 */ + /* Line 54 */ + /* Line 55 */ + /* Line 56 */ + /* Line 57 */ + /* Line 58 */ + /* Line 59 */ + /* Line 60 */ + /* Line 61 */ + /* Line 62 */ + /* Line 63 */ + /* Line 64 */ + /* Line 65 */ + /* Line 66 */ + /* Line 67 */ + /* Line 68 */ + /* Line 69 */ + /* Line 70 */ + /* Line 71 */ + /* Line 72 */ + /* Line 73 */ + /* Line 74 */ + /* Line 75 */ + /* Line 76 */ + /* Line 77 */ + /* Line 78 */ + /* Line 79 */ + /* Line 80 */ + /* Line 81 */ + /* Line 82 */ + /* Line 83 */ + /* Line 84 */ + /* Line 85 */ + /* Line 86 */ + /* Line 87 */ + /* Line 88 */ + /* Line 89 */ + /* Line 90 */ + /* Line 91 */ + /* Line 92 */ + /* Line 93 */ + /* Line 94 */ + /* Line 95 */ + /* Line 96 */ + /* Line 97 */ + /* Line 98 */ + /* Line 99 */ + /* Line 100 */ + /* Line 101 */ + /* Line 102 */ + /* Line 103 */ + /* Line 104 */ + /* Line 105 */ + /* Line 106 */ + /* Line 107 */ + /* Line 108 */ + /* Line 109 */ + /* Line 110 */ + /* Line 111 */ + /* Line 112 */ + /* Line 113 */ + /* Line 114 */ + /* Line 115 */ + /* Line 116 */ + /* Line 117 */ + /* Line 118 */ + /* Line 119 */ + /* Line 120 */ + /* Line 121 */ + /* Line 122 */ + /* Line 123 */ + /* Line 124 */ + /* Line 125 */ + return 0; +} /* Last line. */ diff --git a/gdb/testsuite/gdb.tui/source-search.exp b/gdb/testsuite/gdb.tui/source-search.exp new file mode 100644 index 0000000..4fcdca3 --- /dev/null +++ b/gdb/testsuite/gdb.tui/source-search.exp @@ -0,0 +1,72 @@ +# 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 forward-search and reverse-search within the TUI src window. + +tuiterm_env + +standard_testfile .c + +if {[build_executable "failed to build" ${testfile} ${srcfile}] == -1} { + return +} + +Term::clean_restart 24 80 $testfile +if {![Term::enter_tui]} { + unsupported "TUI not supported" + return +} + +proc check_src_window { testname first_line } { + set last_line [expr {$first_line + 12}] + Term::check_box_contents $testname 0 0 80 15 \ + "^\\s+${first_line}\\s+.*\\s+${last_line}\\s+/\\* Line ${last_line} \\*/\\s+$" + +} + +# Initialise the src window so that it is displaying known contents. +# Check that the expected contents are displayed. +Term::command "list 20" +set first_line 15 +check_src_window "initial src contents" $first_line + +# Search forward. Searches are from the last line displayed, so this +# will move the next source line onto the screen each time. +for { set i 1 } { $i < 4 } { incr i } { + incr first_line + Term::command "forward-search Line" + check_src_window "src windows after forward-search $i" $first_line +} + +# Reverse search. Like forward-search, but move backward through the +# source. +for { set i 1 } { $i < 3 } { incr i } { + incr first_line -1 + Term::command "reverse-search Line" + check_src_window "src windows after reverse-search $i" $first_line +} + +# Until there are no matching lines left. +Term::command "reverse-search Line" +gdb_assert {[regexp -- "^Expression not found\\s+$" [Term::get_line 22]]} \ + "check start of source was reached" + +Term::command "forward-search Last line" +Term::check_box_contents "forward-search to end of file" 0 0 80 15 \ + "^\\s+122\\s+.*/\\* Last line\\. \\*/\\s+$" + +Term::command "reverse-search This testcase is part" +Term::check_box_contents "reverse-search to start of file" 0 0 80 15 \ + "^\\s+1\\s+.*\\s+13\\s+GNU General Public License for more details\\.\\s+$" diff --git a/gdb/testsuite/gdb.tui/tui-disasm-long-lines.exp b/gdb/testsuite/gdb.tui/tui-disasm-long-lines.exp index 35f990d..7a9841f 100644 --- a/gdb/testsuite/gdb.tui/tui-disasm-long-lines.exp +++ b/gdb/testsuite/gdb.tui/tui-disasm-long-lines.exp @@ -35,7 +35,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "$binfile" \ } } -Term::clean_restart 24 80 $binfile +Term::clean_restart 24 80 $testfile if {![Term::prepare_for_tui]} { unsupported "TUI not supported" return diff --git a/gdb/testsuite/gdb.tui/tui-disasm-styling.exp b/gdb/testsuite/gdb.tui/tui-disasm-styling.exp index 513d787..6859744 100644 --- a/gdb/testsuite/gdb.tui/tui-disasm-styling.exp +++ b/gdb/testsuite/gdb.tui/tui-disasm-styling.exp @@ -37,12 +37,15 @@ proc check_asm_output { expect_styled testname } { $testname } -Term::clean_restart 24 80 $binfile +Term::clean_restart 24 80 $testfile if {![Term::enter_tui]} { unsupported "TUI not supported" return } +# Proc enter_tui switches off styling, re-enable it. +Term::command "set style enabled on" + Term::command "layout asm" Term::check_box "asm box" 0 0 80 15 diff --git a/gdb/testsuite/gdb.tui/tui-focus.exp b/gdb/testsuite/gdb.tui/tui-focus.exp index 4c9d2a0..50a3315 100644 --- a/gdb/testsuite/gdb.tui/tui-focus.exp +++ b/gdb/testsuite/gdb.tui/tui-focus.exp @@ -36,7 +36,7 @@ foreach spec {{src true} {cmd true} {status true} {regs false} \ lassign $spec window valid_p with_test_prefix "window=$window" { - Term::clean_restart 24 80 $binfile + Term::clean_restart 24 80 $testfile if {![Term::prepare_for_tui]} { unsupported "TUI not supported" return @@ -73,9 +73,9 @@ foreach spec {{src true} {cmd true} {status true} {regs false} \ } } -# Use the Python TUI API to exercise some of the ambigous window name +# Use the Python TUI API to exercise some of the ambiguous window name # handling parts of the 'focus' command. -Term::clean_restart 24 80 $binfile +Term::clean_restart 24 80 $testfile if {[allow_python_tests]} { # Create a very simple tui window. gdb_py_test_silent_cmd \ diff --git a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S index 9d69236..6e36152 100644 --- a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S +++ b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S @@ -20,8 +20,11 @@ _start: .rept 5 nop .endr + +#ifndef __CYGWIN__ #ifdef __arm__ .section .note.GNU-stack,"",%progbits #else .section .note.GNU-stack,"",@progbits #endif +#endif diff --git a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp index 51623e8..e21914b 100644 --- a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp +++ b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp @@ -20,9 +20,13 @@ tuiterm_env standard_testfile tui-layout-asm-short-prog.S -if {[build_executable "failed to prepare" ${testfile} ${srcfile} \ - {debug additional_flags=-nostdlib \ - additional_flags=-nostartfiles}] == -1} { +set opts {} +lappend opts debug +lappend opts additional_flags=-static +lappend opts additional_flags=-nostdlib +lappend opts ldflags=-nostartfiles + +if { [build_executable "failed to prepare" $testfile $srcfile $opts] == -1 } { return -1 } @@ -53,7 +57,7 @@ gdb_assert { [string match "|___0x*" $first_line] } \ # Scroll forward a large amount, this should take us to the last # instruction in the program. -Term::command "+ 13" +Term::command "+ 15" Term::check_box_contents "check asm box contents again" 0 0 80 15 \ [multi_line \ "^___$hex\[^\r\n\]+" \ @@ -61,6 +65,6 @@ Term::check_box_contents "check asm box contents again" 0 0 80 15 \ # Now scroll backward again, we should return to the start of the # program. -Term::command "- 13" +Term::command "- 15" gdb_assert {[string eq "$first_line" [Term::get_line 1]]} \ "check first line is back" diff --git a/gdb/testsuite/gdb.tui/tui-layout-asm.exp b/gdb/testsuite/gdb.tui/tui-layout-asm.exp index ec78a0c..333276e 100644 --- a/gdb/testsuite/gdb.tui/tui-layout-asm.exp +++ b/gdb/testsuite/gdb.tui/tui-layout-asm.exp @@ -24,7 +24,9 @@ if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} { return -1 } -# PPC currently needs a minimum window width of 90 to work correctly. +# The wider the window is, the less line truncation happens, so matching +# pre-scroll to post-scroll lines is more accurate. But 100% accurate line +# matching isn't a goal of the test-case. set tui_asm_window_width 90 Term::clean_restart 24 ${tui_asm_window_width} $testfile @@ -33,15 +35,41 @@ if {![Term::prepare_for_tui]} { return } -# Helper proc, returns a count of the ' ' characters in STRING. -proc count_whitespace { string } { - return [expr {[llength [split $string { }]] - 1}] -} - # This puts us into TUI mode, and should display the ASM window. Term::command_no_prompt_prefix "layout asm" Term::check_box_contents "check asm box contents" 0 0 ${tui_asm_window_width} 15 "<main>" +set re_border [string_to_regexp "|"] + +proc drop_borders { line } { + # Drop left border. + set line [regsub -- ^$::re_border $line {}] + # Drop right border. + set line [regsub -- $::re_border$ $line {}] + + return $line +} + +proc lines_match { line1 line2 } { + set line1 [drop_borders $line1] + set line2 [drop_borders $line2] + + foreach line [list $line1 $line2] re [list $line2 $line1] { + # Convert to regexp. + set re [string_to_regexp $re] + + # Ignore whitespace mismatches. + regsub -all {\s+} $re {\s+} re + + # Allow a substring match. + if { [regexp -- $re $line] } { + return 1 + } + } + + return 0 +} + # Scroll the ASM window down using the down arrow key. In an ideal # world we'd like to use PageDown here, but currently our terminal # library doesn't support such advanced things. @@ -58,51 +86,55 @@ while (1) { # below will just timeout. So for now we avoid testing the edge # case. if {[regexp -- "^\\| +\\|$" $line]} { - # Second line is blank, we're at the end of the assembler. - pass $testname + # Second line is blank, we're at the end of the assembly. + pass "$testname (end of assembly reached)" break } # Send the down key to GDB. send_gdb "\033\[B" incr down_count - set re_line [string_to_regexp $line] - # Ignore whitespace mismatches. - regsub -all {\s+} $re_line {\s+} re_line + + # Get address from the line. + regexp \ + [join \ + [list \ + ^ \ + $re_border \ + {\s+} \ + ($hex) \ + {\s+}] \ + ""] \ + $line \ + match \ + address + + # Regexp to match line containing address. + set re_line \ + [join \ + [list \ + ^ \ + $re_border \ + {\s+} \ + $address \ + {\s+} \ + {[^\r\n]+} \ + $re_border \ + $] \ + ""] + if {[Term::wait_for $re_line] \ - && [regexp $re_line [Term::get_line 1]]} { + && [lines_match $line [Term::get_line 1]]} { # We scrolled successfully. } else { - if {[count_whitespace ${line}] != \ - [count_whitespace [Term::get_line 1]]} { - # GDB's TUI assembler display will widen columns based on - # the longest item that appears in a column on any line. - # As we have just scrolled, and so revealed a new line, it - # is possible that the width of some columns has changed. - # - # As a result it is possible that part of the line we were - # expected to see in the output is now off the screen. And - # this test will fail. - # - # This is unfortunate, but, right now, there's no easy way - # to "lock" the format of the TUI assembler window. The - # only option appears to be making the window width wider, - # this can be done by adjusting TUI_ASM_WINDOW_WIDTH. - verbose -log "WARNING: The following failure is probably due to the TUI window" - verbose -log " width. See the comments in the test script for more" - verbose -log " details." - } - fail "$testname (scroll failed)" Term::dump_screen break } - if { $down_count > 250 } { - # Maybe we should accept this as a pass in case a target - # really does have loads of assembler to scroll through. - fail "$testname (too much assembler)" - Term::dump_screen + if { $down_count > 25 } { + # We've scrolled enough, we're done. + pass "$testname (scroll limit reached)" break } } diff --git a/gdb/testsuite/gdb.tui/tui-layout.exp b/gdb/testsuite/gdb.tui/tui-layout.exp index 7bb0ea1..f604871 100644 --- a/gdb/testsuite/gdb.tui/tui-layout.exp +++ b/gdb/testsuite/gdb.tui/tui-layout.exp @@ -40,7 +40,7 @@ if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { # happens to be in after a call to clean_restart. proc test_layout_or_focus {layout_name terminal execution} { - global binfile gdb_prompt + global gdb_prompt set dumb_terminal [string equal $terminal "dumb"] @@ -48,9 +48,9 @@ proc test_layout_or_focus {layout_name terminal execution} { save_vars { env(TERM) } { setenv TERM $terminal if {$dumb_terminal} { - clean_restart $binfile + clean_restart $::testfile } else { - Term::clean_restart 24 80 $binfile + Term::clean_restart 24 80 $::testfile if {![Term::prepare_for_tui]} { unsupported "TUI not supported" return diff --git a/gdb/testsuite/gdb.tui/tui-long-line.c b/gdb/testsuite/gdb.tui/tui-long-line.c new file mode 100644 index 0000000..8f1d6eb --- /dev/null +++ b/gdb/testsuite/gdb.tui/tui-long-line.c @@ -0,0 +1,24 @@ +/* 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/>. */ + + +int +main (void) +{ + /* This is a comment that is meant to be longer than the usual 80 characters width of a tuiterm. */ + return 0; +} diff --git a/gdb/testsuite/gdb.tui/tui-missing-src.exp b/gdb/testsuite/gdb.tui/tui-missing-src.exp index f29ec8c..ae98775 100644 --- a/gdb/testsuite/gdb.tui/tui-missing-src.exp +++ b/gdb/testsuite/gdb.tui/tui-missing-src.exp @@ -27,6 +27,7 @@ # Check if start command is supported. require !use_gdb_stub +require allow_tui_tests tuiterm_env @@ -64,10 +65,8 @@ f2 (int x) close $fd # Step 3: Compile the source files. -if { [gdb_compile "${srcfiles}" "${binfile}" \ - executable {debug additional_flags=-O0}] != "" } { - untested "failed to compile" - return -1 +if { [build_executable "failed to prepare" $testfile $srcfiles] == -1 } { + return } # Step 4: Remove the main.c file. diff --git a/gdb/testsuite/gdb.tui/tui-mode-switch.exp b/gdb/testsuite/gdb.tui/tui-mode-switch.exp new file mode 100644 index 0000000..c605962 --- /dev/null +++ b/gdb/testsuite/gdb.tui/tui-mode-switch.exp @@ -0,0 +1,57 @@ +require allow_tui_tests + +tuiterm_env + +if { [ishost *-*-*bsd*] } { + # We need support for alternate screen, and xterm doesn't have it. + set term xterm-clear +} else { + set term xterm +} + +Term::with_term $term { + Term::clean_restart 12 40 +} + +if {![Term::prepare_for_tui]} { + unsupported "TUI not supported" + return 0 +} + +# Generate prompt. +Term::gen_prompt + +# Move to last line. +for { set i 1 } { $i <= 11 } { incr i } { + send_gdb "\n" + Term::wait_for "" +} + +# Type "foo". +send_gdb "foo" +set line { 0 11 40 1 } +gdb_assert { [Term::wait_for_region_contents {*}$line "^$gdb_prompt foo"] } \ + "type foo" + +# Enter TUI. +send_gdb "\030\001" +gdb_assert { [Term::wait_for ""] } "enter TUI" + +# Exit TUI. +send_gdb "\030\001" +gdb_assert { [Term::wait_for ""] } "exit TUI" + +# Type b. +send_gdb "b" +gdb_assert { [Term::wait_for_region_contents {*}$line "^$gdb_prompt b"] } \ + "type b" + +# Check that we don't see "boo". +gdb_assert { ![Term::check_region_contents_p {*}$line "^$gdb_prompt boo"] } \ + "no boo" +Term::dump_screen + +# We need an empty prompt here, to deal with the "monitor exit" that +# native-extended-gdbserver will send. Send a backspace. +send_gdb "\010" +Term::wait_for "" diff --git a/gdb/testsuite/gdb.tui/tuiterm-2.exp b/gdb/testsuite/gdb.tui/tuiterm-2.exp index 5992271..9e3ddc7 100644 --- a/gdb/testsuite/gdb.tui/tuiterm-2.exp +++ b/gdb/testsuite/gdb.tui/tuiterm-2.exp @@ -106,6 +106,84 @@ with_override Term::accept_gdb_output test_accept_gdb_output { } gdb_assert { [Term::wait_for ""] } } + + with_test_prefix "Term::wait_for 2" { + Term::_setup 4 20 + set send_cnt 0 + set expect_send {} + set action_cnt 0 + set actions { + { + Term::_move_cursor 0 0 + + Term::_insert "${::border}(gdb) " + set pos $Term::_cur_col + + Term::_insert "foo" + + Term::_move_cursor 19 0 + Term::_insert "$::border" + + Term::_move_cursor $pos 0 + } + { + Term::_move_cursor 0 1 + + Term::_insert "${::border}(gdb) " + set pos $Term::_cur_col + + Term::_move_cursor 19 1 + Term::_insert "$::border" + + Term::_move_cursor $pos 1 + } + } + + # Wait for a prompt. + gdb_assert { [Term::wait_for ""] } + + # The first action sets the cursor after the prompt on the + # first line. The second action sets the cursor after the + # prompt on the second line. Check that wait_for returns + # after the second action, not the first. + gdb_assert { $Term::_cur_row == 1 } + } } } } + +proc_with_prefix unrecognized_escape_sequence {} { + if { [spawn $::srcdir/$::subdir/gdb.sh] == 0 } { + unsupported "cannot spawn gdb.sh" + return + } + switch_gdb_spawn_id $spawn_id + + Term::_setup 4 20 + + save_vars ::timeout { + set ::timeout 1 + + set line { 0 0 20 1 } + + # Parse "foo". + gdb_assert { [Term::wait_for_region_contents \ + {*}$line \ + [string_to_regexp "foo"]] } \ + "foo" + + # Parse "\033(%5". + gdb_assert { ![Term::accept_gdb_output 0] } \ + "fail to parse escape sequence" + gdb_assert { [Term::wait_for_region_contents \ + {*}$line \ + [string_to_regexp "^\[(%5"]] } \ + "echoed escape sequence" + } + Term::dump_screen + + close $spawn_id + clear_gdb_spawn_id +} + +unrecognized_escape_sequence diff --git a/gdb/testsuite/gdb.tui/tuiterm.exp b/gdb/testsuite/gdb.tui/tuiterm.exp index 9dc2402..a91643e 100644 --- a/gdb/testsuite/gdb.tui/tuiterm.exp +++ b/gdb/testsuite/gdb.tui/tuiterm.exp @@ -102,7 +102,7 @@ proc test_backspace {} { Term::_move_cursor 1 2 - Term::_ctl_0x08 + Term::_ctl_0x08 0 check "backspace one" { "abcdefgh" "ijklmnop" @@ -111,13 +111,22 @@ proc test_backspace {} { } 0 2 # Cursor should not move if it is already at column 0. - Term::_ctl_0x08 + Term::_ctl_0x08 0 check "backspace 2" { "abcdefgh" "ijklmnop" "qrstuvwx" "yz01234 " } 0 2 + + # Cursor should wrap to previous line. + Term::_ctl_0x08 1 + check "backspace 3" { + "abcdefgh" + "ijklmnop" + "qrstuvwx" + "yz01234 " + } 7 1 } proc test_linefeed { } { @@ -435,6 +444,30 @@ proc test_horizontal_absolute { } { "qrstuvwx" "yz01234 " } 3 2 + + Term::_csi_G 8 + check "cursor horizontal absolute 3" { + "abcdefgh" + "ijklmnop" + "qrstuvwx" + "yz01234 " + } 7 2 + + Term::_csi_G 9 + check "cursor horizontal absolute 4" { + "abcdefgh" + "ijklmnop" + "qrstuvwx" + "yz01234 " + } 7 2 + + Term::_csi_` + check "horizontal position absolute 1" { + "abcdefgh" + "ijklmnop" + "qrstuvwx" + "yz01234 " + } 0 2 } proc test_cursor_position { } { @@ -620,13 +653,21 @@ proc test_cursor_backward_tabulation { } { } proc test_repeat { } { - Term::_move_cursor 2 1 - set Term::_last_char X + Term::_move_cursor 0 1 - Term::_csi_b 3 + Term::_insert "xxX" + gdb_assert { $Term::_last_char == "X" } + check "insert" { + "abcdefgh" + "xxXlmnop" + "qrstuvwx" + "yz01234 " + } 3 1 + + Term::_csi_b 2 check "repeat" { "abcdefgh" - "ijXXXnop" + "xxXXXnop" "qrstuvwx" "yz01234 " } 5 1 @@ -750,6 +791,15 @@ proc test_attrs {} { set line [Term::get_line_with_attrs 0] gdb_assert { [regexp $re $line] } "attribute: $attr" } + + # Regression test: Check that _csi_m works without arguments. + setup_terminal 4 1 + Term::_csi_m 7 + Term::_insert "a" + Term::_csi_m + Term::_insert "a" + set line [Term::get_line_with_attrs 0] + gdb_assert { [string equal $line "<reverse:1>a<reverse:0>a "] } } # Run proc TEST_PROC_NAME with a "small" terminal. @@ -757,7 +807,7 @@ proc test_attrs {} { proc run_one_test_small { test_proc_name } { save_vars { env(TERM) stty_init } { setup_small - eval $test_proc_name + $test_proc_name } } @@ -766,7 +816,7 @@ proc run_one_test_small { test_proc_name } { proc run_one_test_large { test_proc_name } { save_vars { env(TERM) stty_init } { setup_large - eval $test_proc_name + $test_proc_name } } diff --git a/gdb/testsuite/gdb.tui/wrap-line.exp b/gdb/testsuite/gdb.tui/wrap-line.exp index aa2b1c6..67ad36c 100644 --- a/gdb/testsuite/gdb.tui/wrap-line.exp +++ b/gdb/testsuite/gdb.tui/wrap-line.exp @@ -37,11 +37,11 @@ proc fill_line { width } { # Take into account that the prompt also takes space. set prefix [string length "(gdb) "] - set start [expr $prefix + 1] + set start [expr {$prefix + 1}] # Print chars. for { set i $start } { $i <= $width } { incr i } { - set c [expr $i % 10] + set c [expr {$i % 10}] send_gdb $c append res $c } @@ -59,7 +59,7 @@ proc test_wrap { wrap_width tui } { set str [fill_line $wrap_width] # Remaining space on line. - set space [string repeat " " [expr $::cols - $wrap_width]] + set space [string repeat " " [expr {$::cols - $wrap_width}]] # Now print the first char we expect to wrap. send_gdb "W" @@ -104,29 +104,35 @@ proc test_wrap_cli_tui { auto_detected_width } { set re1 "Number of characters gdb thinks are in a line is ($::decimal)\\." set re2 \ "Number of characters readline reports are in a line is ($::decimal)\\." + set re3 \ + "Readline wrapping mode: (\[a-z\]+) \[\^\r\n]*" set cmd "maint info screen" set re \ [multi_line \ "^$re1" \ $re2 \ - ".*"] + ".*" \ + $re3] gdb_test_multiple $cmd "" { -re -wrap $re { set gdb_width $expect_out(1,string) set readline_width $expect_out(2,string) + set wrapping_mode $expect_out(3,string) pass $gdb_test_name } } - gdb_assert { $gdb_width == $::cols } "width" + if { $wrapping_mode == "readline" } { + gdb_assert { $gdb_width == $::cols } "width" - # TERM=ansi, so readline hides the last column. - gdb_assert { $gdb_width == [expr $readline_width + 1] } + # TERM=ansi, so readline hides the last column. + gdb_assert { $gdb_width == [expr $readline_width + 1] } - with_test_prefix cli { - set wrap_width $readline_width + with_test_prefix cli { + set wrap_width $readline_width - test_wrap $wrap_width 0 + test_wrap $wrap_width 0 + } } with_test_prefix tui { @@ -172,7 +178,7 @@ with_test_prefix width-auto-detected { set test "startup prompt" gdb_test_multiple "" $test { - -re "^$gdb_prompt $" { + -re "^(\033\\\[6n)?$gdb_prompt $" { pass "$test" } } diff --git a/gdb/testsuite/gdb.xml/bad-include.xml b/gdb/testsuite/gdb.xml/bad-include.xml index f7a2b72..cd9cce3 100644 --- a/gdb/testsuite/gdb.xml/bad-include.xml +++ b/gdb/testsuite/gdb.xml/bad-include.xml @@ -1 +1 @@ -<xi:include href="nonexistant.xml"/> +<xi:include href="nonexistent.xml"/> diff --git a/gdb/testsuite/gdb.xml/tdesc-xinclude.exp b/gdb/testsuite/gdb.xml/tdesc-xinclude.exp index 885d217..b934c80 100644 --- a/gdb/testsuite/gdb.xml/tdesc-xinclude.exp +++ b/gdb/testsuite/gdb.xml/tdesc-xinclude.exp @@ -43,7 +43,7 @@ set_arch "includes.xml" \ # This file contains a missing include. We should warn the user about # it. set_arch "bad-include.xml" \ - "warning:.*Could not load XML document \"nonexistant.xml\"$common_warn" + "warning:.*Could not load XML document \"nonexistent.xml\"$common_warn" # Make sure we detect infinite loops, eventually. set_arch "loop.xml" \ diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp index 37bed85..50067eb 100644 --- a/gdb/testsuite/lib/ada.exp +++ b/gdb/testsuite/lib/ada.exp @@ -220,7 +220,8 @@ proc gnat_runtime_has_debug_info_1 { shared } { return 0 } - clean_restart $dst + clean_restart + gdb_load $dst if { ! [runto "GNAT_Debug_Info_Test"] } { return 0 diff --git a/gdb/testsuite/lib/cache.exp b/gdb/testsuite/lib/cache.exp index 6ca3f18..4ebb825 100644 --- a/gdb/testsuite/lib/cache.exp +++ b/gdb/testsuite/lib/cache.exp @@ -24,26 +24,9 @@ proc ignore_pass { msg } { # Call proc real_name and return the result, while ignoring calls to pass. proc gdb_do_cache_wrap {real_name args} { - if { [info procs save_pass] != "" } { - return [uplevel 2 $real_name] + with_override pass ignore_pass { + return [uplevel 2 [list $real_name {*}$args]] } - - rename pass save_pass - rename ignore_pass pass - - set code [catch {uplevel 2 [list $real_name {*}$args]} result] - - rename pass ignore_pass - rename save_pass pass - - if {$code == 1} { - global errorInfo errorCode - return -code error -errorinfo $errorInfo -errorcode $errorCode $result - } elseif {$code > 1} { - return -code $code $result - } - - return $result } # Global written to by gdb_exit_called proc. Is set to true to diff --git a/gdb/testsuite/lib/check-test-names.exp b/gdb/testsuite/lib/check-test-names.exp index 049addd..d099ffc 100644 --- a/gdb/testsuite/lib/check-test-names.exp +++ b/gdb/testsuite/lib/check-test-names.exp @@ -146,7 +146,7 @@ namespace eval ::CheckTestNames { # If ARGS is the empty list then we don't want to pass a single # empty string as a parameter here. - eval "CheckTestNames::log_summary $args" + CheckTestNames::log_summary {*}$args if { [llength $args] == 0 } { set which "count" @@ -184,10 +184,10 @@ foreach nm {pass fail xfail kfail xpass kpass unresolved untested \ # Create new global log_summary to replace Dejagnu's. proc log_summary { args } { - eval "CheckTestNames::do_log_summary $args" + CheckTestNames::do_log_summary {*}$args } # Create new global reset_vars to replace Dejagnu's. proc reset_vars {} { - eval "CheckTestNames::do_reset_vars" + CheckTestNames::do_reset_vars } diff --git a/gdb/testsuite/lib/compile-support.exp b/gdb/testsuite/lib/compile-support.exp index dd0b9a9..8472d8d 100644 --- a/gdb/testsuite/lib/compile-support.exp +++ b/gdb/testsuite/lib/compile-support.exp @@ -265,7 +265,7 @@ namespace eval ::CompileExpression { if {[string match $cmd "print"]} { if {!$is_explicit} { - eval setup_failures_ $fail_print + setup_failures_ {*}$fail_print return [compile_command_ "compile print $exp" $result $tst] } } else { @@ -274,11 +274,11 @@ namespace eval ::CompileExpression { } else { set command "compile code $varName_ = $exp" } - eval setup_failures_ $fail_compile + setup_failures_ {*}$fail_compile if {![compile_command_ $command "" $tst]} { return 0 } - eval setup_failures_ $fail_value + setup_failures_ {*}$fail_value gdb_test "p $varName_" "= $result" "result of $tst" } return 1 @@ -292,11 +292,11 @@ namespace eval ::CompileExpression { proc setup_failures_ {how args} { switch -nocase $how { xfail { - eval setup_xfail $args + setup_xfail {*}$args } kfail { - eval setup_kfail $args + setup_kfail {*}$args } default { diff --git a/gdb/testsuite/lib/dap-support.exp b/gdb/testsuite/lib/dap-support.exp index d61b1c4..5c078ca 100644 --- a/gdb/testsuite/lib/dap-support.exp +++ b/gdb/testsuite/lib/dap-support.exp @@ -117,6 +117,7 @@ proc dap_to_ton {obj} { # Format the object OBJ, in TON format, as JSON and send it to gdb. proc _dap_send_ton {obj} { + # tclint-disable-next-line command-args set json [namespace eval ton::2json $obj] # FIXME this is wrong for non-ASCII characters. set len [string length $json] @@ -170,7 +171,7 @@ proc _dap_read_json {} { } if {$seen_timeout} { - error "timeout reading json header" + error "timeout reading json header" } if {$seen_eof} { error "eof reading json header" @@ -200,7 +201,7 @@ proc _dap_read_json {} { } if {$seen_timeout} { - error "timeout reading json header" + error "timeout reading json header" } if {$seen_eof} { error "eof reading json header" @@ -211,6 +212,7 @@ proc _dap_read_json {} { global last_ton set last_ton [ton::json2ton $json] + # tclint-disable-next-line command-args return [namespace eval ton::2dict $last_ton] } @@ -229,9 +231,9 @@ proc dap_read_response {cmd num} { set d [_dap_read_json] if {[dict get $d type] == "response"} { if {[dict get $d request_seq] != $num} { - error "saw wrong request_seq in $obj" + error "saw wrong request_seq in $d" } elseif {[dict get $d command] != $cmd} { - error "saw wrong command in $obj" + error "saw wrong command in $d" } else { return [list $d $result] } @@ -443,7 +445,7 @@ proc dap_search_output {name rx events} { # key/value pairs given in ARGS. NAME is used as the test name. proc dap_match_values {name d args} { foreach {key value} $args { - if {[eval dict get [list $d] $key] != $value} { + if {[dict get $d {*}$key] != $value} { fail "$name (checking $key)" return "" } @@ -494,7 +496,7 @@ proc dap_wait_for_event_and_check {name type args} { set result [_dap_wait_for_event $type] set event [lindex $result 0] - eval dap_match_values [list $name $event] $args + dap_match_values $name $event {*}$args return $result } diff --git a/gdb/testsuite/lib/debuginfod-support.exp b/gdb/testsuite/lib/debuginfod-support.exp index 674888a..7a8baf4 100644 --- a/gdb/testsuite/lib/debuginfod-support.exp +++ b/gdb/testsuite/lib/debuginfod-support.exp @@ -37,7 +37,7 @@ proc allow_debuginfod_tests {} { # (installed by ASan) exist on startup. That makes TCL's exec throw an # error. This is dealt with by the --quiet in INTERNAL_GDBFLAGS. if { [string first "with-debuginfod" \ - [eval exec $::GDB $::INTERNAL_GDBFLAGS \ + [exec $::GDB {*}$::INTERNAL_GDBFLAGS \ --configuration]] == -1 } { return false } diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 46b39a1..911ec88 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -461,16 +461,13 @@ proc get_func_info { name {options {debug}} } { # # proc DW_TAG_mumble {{attrs {}} {children {}}} { ... } # -# ATTRS is an optional list of attributes. -# It is run through 'subst' in the caller's context before processing. +# ATTRS holds optional attributes. It is just Tcl code and is +# evaluated in the caller's context. Each attribute is a proc of the +# form: # -# Each attribute in the list has one of two forms: -# 1. { NAME VALUE } -# 2. { NAME VALUE FORM } +# proc DW_AT_mumble {value {form {}}} { ... } # -# In each case, NAME is the attribute's name. -# This can either be the full name, like 'DW_AT_name', or a shortened -# name, like 'name'. These are fully equivalent. +# Only the full name can be used here. # # Besides DWARF standard attributes, assembler supports 'macro' attribute # which will be substituted by one or more standard or macro attributes. @@ -522,8 +519,6 @@ namespace eval Dwarf { # Constants from dwarf2.h. variable _constants - # DW_AT short names. - variable _AT # DW_FORM short names. variable _FORM # DW_OP short names. @@ -594,7 +589,6 @@ namespace eval Dwarf { proc _process_one_constant {name value} { variable _constants - variable _AT variable _FORM variable _OP @@ -633,7 +627,8 @@ namespace eval Dwarf { } AT { - set _AT($name2) $name + proc $name {value {form {}}} \ + "_handle_DW_AT $name \$value \$form" } FORM { @@ -678,6 +673,11 @@ namespace eval Dwarf { } } close $fd + + variable _constants + + # Add DW_FORM_strx_id as alias of DW_FORM_strx. + _process_one_constant DW_FORM_strx_id $_constants(DW_FORM_strx) } proc _quote {string} { @@ -823,6 +823,12 @@ namespace eval Dwarf { DW_FORM_indirect - DW_FORM_exprloc - + # Generate a DW_FORM_str index, but assume generation of .debug_str and + # .debug_str_offsets is taken care of elsewhere. + DW_FORM_strx_id { + _op .uleb128 $value + } + DW_FORM_strx - DW_FORM_strx1 - DW_FORM_strx2 - @@ -906,11 +912,27 @@ namespace eval Dwarf { return $name } - proc _handle_attribute { attr_name attr_value attr_form } { + # Implementation of all the DW_AT_* procs. + proc _handle_DW_AT {attr_name attr_value attr_form} { variable _abbrev_section variable _constants variable _cu_version + if {$attr_form == ""} { + set attr_form [_guess_form $attr_value attr_value] + if { $attr_form eq "" } { + set attr_form [_default_form $attr_name] + } + if { $attr_form eq "" } { + error "No form for $attr_name $attr_value" + } + } elseif { [string index $attr_value 0] == ":" } { + # It is a label, get its value. + _guess_form $attr_value attr_value + } + + set attr_form [_map_name $attr_form _FORM] + _handle_DW_FORM $attr_form $attr_value _defer_output $_abbrev_section { @@ -931,9 +953,8 @@ namespace eval Dwarf { } } - # Handle macro attribute MACRO_AT_range. - - proc _handle_macro_at_range { attr_value } { + # Handle extension attribute MACRO_AT_range. + proc MACRO_AT_range { attr_value } { variable _cu_is_fission if {[llength $attr_value] != 1} { @@ -950,19 +971,17 @@ namespace eval Dwarf { set form DW_FORM_GNU_addr_index } - _handle_attribute DW_AT_low_pc [lindex $result 0] $form - _handle_attribute DW_AT_high_pc \ - "[lindex $result 0] + [lindex $result 1]" $form + DW_AT_low_pc [lindex $result 0] $form + DW_AT_high_pc "[lindex $result 0] + [lindex $result 1]" $form } - # Handle macro attribute MACRO_AT_func. - - proc _handle_macro_at_func { attr_value } { + # Handle extension attribute MACRO_AT_func. + proc MACRO_AT_func { attr_value } { if {[llength $attr_value] != 1} { error "usage: MACRO_AT_func { func file }" } - _handle_attribute DW_AT_name [lindex $attr_value 0] DW_FORM_string - _handle_macro_at_range $attr_value + DW_AT_name [lindex $attr_value 0] DW_FORM_string + MACRO_AT_range $attr_value } # Return the next available abbrev number in the current CU's abbrev @@ -992,47 +1011,7 @@ namespace eval Dwarf { _op .uleb128 $my_abbrev "Abbrev ($tag_name)" - foreach attr $attrs { - set attr_name [_map_name [lindex $attr 0] _AT] - - # When the length of ATTR is greater than 2, the last - # element of the list must be a form. The second through - # the penultimate elements are joined together and - # evaluated using subst. This allows constructs such as - # [gdb_target_symbol foo] to be used. - - if {[llength $attr] > 2} { - set attr_value [uplevel 2 [list subst [join [lrange $attr 1 end-1]]]] - } else { - set attr_value [uplevel 2 [list subst [lindex $attr 1]]] - } - - if { [string equal "MACRO_AT_func" $attr_name] } { - _handle_macro_at_func $attr_value - } elseif { [string equal "MACRO_AT_range" $attr_name] } { - _handle_macro_at_range $attr_value - } else { - if {[llength $attr] > 2} { - set attr_form [uplevel 2 [list subst [lindex $attr end]]] - - if { [string index $attr_value 0] == ":" } { - # It is a label, get its value. - _guess_form $attr_value attr_value - } - } else { - set attr_form [_guess_form $attr_value attr_value] - if { $attr_form eq "" } { - set attr_form [_default_form $attr_name] - } - if { $attr_form eq "" } { - error "No form for $attr_name $attr_value" - } - } - set attr_form [_map_name $attr_form _FORM] - - _handle_attribute $attr_name $attr_value $attr_form - } - } + uplevel 2 $attrs _defer_output $_abbrev_section { # Terminator. @@ -1061,7 +1040,10 @@ namespace eval Dwarf { } proc _section {name {flags ""} {type ""}} { - if {$flags == "" && $type == ""} { + if {$name == ".debug_str"} { + # Hard-code this because it's always desirable. + _emit " .section $name, \"MS\", %progbits, 1" + } elseif {$flags == "" && $type == ""} { _emit " .section $name" } elseif {$type == ""} { _emit " .section $name, \"$flags\"" @@ -1080,7 +1062,7 @@ namespace eval Dwarf { if {![info exists _deferred_output($_defer)]} { set _deferred_output($_defer) "" - eval _section $section_spec + _section {*}$section_spec } uplevel $body @@ -3068,6 +3050,24 @@ namespace eval Dwarf { } } + # Emit a .debug_sup section with the given file name and build-id. + # The buildid should be represented as a hexadecimal string, like + # "ffeeddcc". + proc debug_sup {is_sup filename buildid} { + _defer_output .debug_sup { + # The version. + _op .2byte 0x5 + # Supplementary marker. + _op .byte $is_sup + _op .ascii [_quote $filename] + set len [expr {[string length $buildid] / 2}] + _op .uleb128 $len + foreach {a b} [split $buildid {}] { + _op .byte 0x$a$b + } + } + } + proc _note {type name hexdata} { set namelen [expr [string length $name] + 1] set datalen [expr [string length $hexdata] / 2] @@ -3367,6 +3367,58 @@ namespace eval Dwarf { debug_names_end: } + # Add the strings in ARGS to the .debug_str section, and create a + # .debug_str_offsets section pointing to those strings. + # Current options are: + # dwo 0|1 - boolean indicating if the sections have the dwo suffix. + # default = 0 (no .dwo suffix) + # base_offset label + # - generate label, to be used in DW_AT_str_offsets_base. + # default = "" (don't generate a label). + proc debug_str_offsets { options args } { + parse_options { + { dwo 0 } + { base_offset "" } + } + + if { $dwo } { + _section .debug_str.dwo + } else { + _section .debug_str + } + + set num 0 + foreach arg $args { + set str_label [_compute_label "str_${num}"] + define_label $str_label + _op .asciz \"$arg\" ".debug_str_offsets string $num" + incr num + } + + declare_labels debug_str_offsets_start debug_str_offsets_end + set initial_length "$debug_str_offsets_end - $debug_str_offsets_start" + + if { $dwo } { + _section .debug_str_offsets.dwo + } else { + _section .debug_str_offsets + } + _op .4byte $initial_length "Initial_length" + debug_str_offsets_start: + _op .2byte 0x5 "version" + _op .2byte 0x0 "padding" + if { $base_offset != "" } { + $base_offset: + } + set num 0 + foreach arg $args { + set str_label [_compute_label "str_${num}"] + _op .4byte $str_label "string $num" + incr num + } + debug_str_offsets_end: + } + # The top-level interface to the DWARF assembler. # OPTIONS is a list with an even number of elements containing # option-name and option-value pairs. diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp index 161c31c..6643187 100644 --- a/gdb/testsuite/lib/future.exp +++ b/gdb/testsuite/lib/future.exp @@ -749,19 +749,6 @@ if { [array size use_gdb_compile] != 0 } { rename gdb_default_target_compile "" } - -# Provide 'lreverse' missing in Tcl before 7.5. - -if {[info procs lreverse] == ""} { - proc lreverse { arg } { - set retval {} - while { [llength $retval] < [llength $arg] } { - lappend retval [lindex $arg end-[llength $retval]] - } - return $retval - } -} - # Various ccache versions provide incorrect debug info such as ignoring # different current directory, breaking GDB testsuite. set env(CCACHE_DISABLE) 1 diff --git a/gdb/testsuite/lib/gdb-python.exp b/gdb/testsuite/lib/gdb-python.exp index b4eb40d..e026c1b 100644 --- a/gdb/testsuite/lib/gdb-python.exp +++ b/gdb/testsuite/lib/gdb-python.exp @@ -77,3 +77,24 @@ proc gdb_py_module_available { name } { return ${available} } + +# Run a memory leak test within the Python script FILENAME. This proc +# checks that the required Python modules are available, sets up the +# syspath so that the helper module can be found (in the same +# directory as FILENAME), then loads FILENAME to run the test. +proc gdb_py_run_memory_leak_test { filename testname } { + if { ![gdb_py_module_available "tracemalloc"] } { + unsupported "$testname (tracemalloc module not available)" + } + + gdb_test_no_output -nopass "python import sys" + gdb_test_no_output -nopass \ + "python sys.path.insert(0, \"[file dirname $filename]\")" \ + "setup sys.path" + + set pyfile [gdb_remote_download host ${filename}] + + # Source the Python script, this runs the test, and either prints + # PASS, or throws an exception. + gdb_test "source ${pyfile}" "^PASS" $testname +} diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp index fe2cfca..c24e7ed 100644 --- a/gdb/testsuite/lib/gdb-utils.exp +++ b/gdb/testsuite/lib/gdb-utils.exp @@ -70,6 +70,8 @@ proc style {str style} { set fg 39 set bg 49 set intensity 22 + set italic 23 + set underline 24 set reverse 27 switch -exact -- $style { title { set intensity 1 } @@ -84,7 +86,7 @@ proc style {str style} { line-number { set intensity 2 } none { return $str } } - return "\033\\\[${fg};${bg};${intensity};${reverse}m${str}\033\\\[m" + return "\033\\\[${fg};${bg};${intensity};${italic};${underline};${reverse}m${str}\033\\\[m" } # gdb_get_bp_addr num diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index c37cc89..9497850 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -15,6 +15,8 @@ # This file was written by Fred Fish. (fnf@cygnus.com) +package require Tcl 8.6.2 + # Generic gdb subroutines that should work for any target. If these # need to be modified for any target, it can be done with a variable # or by passing arguments. @@ -269,6 +271,13 @@ if ![info exists INTERNAL_GDBFLAGS] { } set INTERNAL_GDBFLAGS [append_gdb_data_directory_option $INTERNAL_GDBFLAGS] + + # Handle the case that "interactive-mode auto" reports off. + append INTERNAL_GDBFLAGS { -iex "set interactive-mode on"} + + if { [ishost "*-*-mingw*"] } { + append INTERNAL_GDBFLAGS { --binary-output} + } } # The variable gdb_prompt is a regexp which matches the gdb prompt. @@ -280,10 +289,13 @@ if {![info exists gdb_prompt]} { set gdb_prompt "\\(gdb\\)" } -# A regexp that matches the pagination prompt. -set pagination_prompt \ +# The pagination prompt. +set pagination_prompt_str \ "--Type <RET> for more, q to quit, c to continue without paging--" +# A regexp that matches the pagination prompt. +set pagination_prompt [string_to_regexp $pagination_prompt_str] + # The variable fullname_syntax_POSIX is a regexp which matches a POSIX # absolute path ie. /foo/ set fullname_syntax_POSIX {/[^\n]*/} @@ -346,7 +358,7 @@ proc default_gdb_version {} { global inotify_pid if {[info exists inotify_pid]} { - eval exec kill $inotify_pid + exec kill $inotify_pid } set output [remote_exec host "$GDB $INTERNAL_GDBFLAGS --version"] @@ -1026,7 +1038,10 @@ proc command_to_message { command } { # should not be anchored at the end of the buffer. This means that the # pattern can match even if there is stuff output after the prompt. Does not # have any effect if -prompt is specified. -# -lbl specifies that line-by-line matching will be used. +# -lbl specifies that line-by-line matching will be used. This means +# that lines from GDB not matched by any pattern will be consumed from +# the output buffer. This helps avoid buffer overflows and timeouts +# when testing verbose commands. # EXPECT_ARGUMENTS will be fed to expect in addition to the standard # patterns. Pattern elements will be evaluated in the caller's # context; action elements will be executed in the caller's context. @@ -1124,6 +1139,7 @@ proc gdb_test_multiple { command message args } { global any_spawn_id set line_by_line 0 + set lbl_anchor_re "" set prompt_regexp "" set prompt_anchor 1 for {set i 0} {$i < [llength $args]} {incr i} { @@ -1133,6 +1149,7 @@ proc gdb_test_multiple { command message args } { set prompt_regexp [lindex $args $i] } elseif { $arg == "-lbl" } { set line_by_line 1 + set lbl_anchor_re "^" } elseif { $arg == "-no-prompt-anchor" } { set prompt_anchor 0 } else { @@ -1391,7 +1408,7 @@ proc gdb_test_multiple { command message args } { fail "$errmsg" set result -1 } - -re "\r\n$prompt_regexp" { + -re "${lbl_anchor_re}\r\n$prompt_regexp" { if {![string match "" $message]} { fail "$message" } @@ -1663,76 +1680,9 @@ proc python_version_at_least { major minor } { # Return 1 if tcl version used is at least MAJOR.MINOR.PATCHLEVEL. proc tcl_version_at_least { major minor {patchlevel 0} } { - global tcl_patchLevel - regexp {^([0-9]+)\.([0-9]+)\.([0-9]+)$} \ - $tcl_patchLevel dummy \ - tcl_version_major tcl_version_minor tcl_version_patchlevel - return \ - [version_compare \ - [list \ - $major \ - $minor \ - $patchlevel] \ - <= \ - [list \ - $tcl_version_major \ - $tcl_version_minor \ - $tcl_version_patchlevel]] -} - -if { [tcl_version_at_least 8 5] == 0 } { - # lrepeat was added in tcl 8.5. Only add if missing. - proc lrepeat { n element } { - if { [string is integer -strict $n] == 0 } { - error "expected integer but got \"$n\"" - } - if { $n < 0 } { - error "bad count \"$n\": must be integer >= 0" - } - set res [list] - for {set i 0} {$i < $n} {incr i} { - lappend res $element - } - return $res - } -} - -if { [tcl_version_at_least 8 6] == 0 } { - # lmap was added in tcl 8.6. Only add if missing. - - # Note that we only implement the simple variant for now. - proc lmap { varname list body } { - set res {} - foreach val $list { - uplevel 1 "set $varname $val" - lappend res [uplevel 1 $body] - } - - return $res - } - - # ::tcl_platform(pathSeparator) was added in 8.6. - switch $::tcl_platform(platform) { - windows { - set ::tcl_platform(pathSeparator) ; - } - default { - set ::tcl_platform(pathSeparator) : - } - } -} - -if { [tcl_version_at_least 8 6 2] == 0 } { - # string cat was added in tcl 8.6.2. Only add if missing. - - rename string tcl_proc_string - - proc string { what args } { - if { $what == "cat" } { - return [join $args ""] - } - return [tcl_proc_string $what {*}$args] - } + set current_version [package require Tcl] + set min_version "$major.$minor.$patchlevel" + return [expr {[package vcompare $current_version $min_version] >= 0}] } # gdb_test_no_output [-prompt PROMPT_REGEXP] [-nopass] COMMAND [MESSAGE] @@ -2237,6 +2187,209 @@ proc gdb_assert { condition {message ""} } { return $res } +# Comparison command for "lsort -command". Sorts two strings by +# descending file name length. + +proc compare_length_desc {a b} { + expr {[string length $b] - [string length $a]} +} + +# Fill in and return the global cache for Windows <=> Unix mount point +# mappings, for Windows. +# +# Calling external processes on MSYS2/Cygwin is expensive so instead +# of calling "cygpath -ua $FILENAME" or "cygpath -ma $FILENAME" for +# every file name, we extract the Windows and Unix file names of each +# mount point using the 'mount' command output, and cache the +# mappings, for both directions. + +gdb_caching_proc get_mount_point_map {} { + array set win_to_unix {} + array set unix_to_win {} + + # The 'mount' command provides all mappings. The general format + # is: 'WindowsFileName on UnixFileName type ...' + # + # For example: + # 'C:/msys64 on / type ntfs (binary,auto)' + # 'C: on /c type ntfs (binary,posix=0,user,noumount,auto)' + set mount_output [exec mount] + + foreach line [split $mount_output \n] { + if {[regexp {^(.+) on (.+) type } $line -> win_filename unix_filename]} { + set win_to_unix($win_filename) $unix_filename + set unix_to_win($unix_filename) $win_filename + } + } + + # Sort each mapping's keys by descending file name length, + # otherwise we wouldn't be able to look for '/foo' in '/' (for + # example). + + set sorted_win {} + foreach k [lsort -command compare_length_desc [array names win_to_unix]] { + lappend sorted_win $k $win_to_unix($k) + } + + set sorted_unix {} + foreach k [lsort -command compare_length_desc [array names unix_to_win]] { + lappend sorted_unix $k $unix_to_win($k) + } + + # Return both sorted lists: {win => unix} {unix => win} + return [list $sorted_win $sorted_unix] +} + +# Normalize backward slashes to forward slashes. + +proc normalize_slashes {filename} { + return [string map {\\ /} $filename] +} + +# Sanitize a host file name, without making it absolute or resolving +# symlinks. On native Windows, this normalizes slashes to forward +# slashes, and makes sure that if the file name starts with a drive +# letter, it is upper case. On other systems, it just returns the +# file name unmodified. + +proc host_file_sanitize {filename} { + if {[ishost *-*-mingw*]} { + set filename [normalize_slashes $filename] + + # If the file name starts with a drive letter, uppercase it. + if {[regexp {^([a-zA-Z]):(/.*)?} $filename -> drive rest]} { + set filename "[string toupper $drive]:$rest" + } + } + + return $filename +} + +# Normalize a file name for the build machine. If running native +# Windows GDB, this converts a Windows file name to the corresponding +# Unix filename, per the mount table. For example, this replaces +# 'c:/foo' with '/c/foo' (on MSYS2) or '/cygdrive/c/foo' (on Cygwin). +# On other systems, it just wraps "file normalize". + +proc build_file_normalize {filename} { + if {[ishost *-*-mingw*]} { + set filename [host_file_sanitize $filename] + + # Handle Windows => Unix mount point conversion. We assume + # there are no symlinks to resolve, which is a reasonable + # assumption for native Windows testing. + + # Get Windows => Unix map. + lassign [get_mount_point_map] win_to_unix _ + + foreach {win_filename unix_filename} $win_to_unix { + if {[string equal -length [string length $win_filename] \ + $win_filename $filename]} { + set rest [string range $filename \ + [string length $win_filename] end] + return "${unix_filename}$rest" + } + } + } + + return [file normalize $filename] +} + +# Normalize a file name for the host machine and native Windows GDB. +# This converts a Unix file name to a Windows filename, +# per the mount table. E.g., '/c/foo' (on MSYS2) or '/cygdrive/c/foo' +# (on Cygwin) is converted to 'c:/foo'. + +proc host_file_normalize_mingw {filename unix_to_win} { + set filename [host_file_sanitize $filename] + + # If the file name already starts with a drive letter (e.g., + # C:/foo), we're done. Don't let it fallthrough to "file + # normalize", which would misinterpret it as a relative file + # name. + if {[regexp {^[A-Z]:/} $filename]} { + return $filename + } + + # Collapse all repeated forward slashes. + set filename [regsub -all {//+} $filename {/}] + + # Strip trailing slash, except for root. + if {$filename ne "/" && [string match */ $filename]} { + set filename [string range $filename 0 end-1] + } + + foreach {unix_filename win_filename} $unix_to_win { + set mount_len [string length $unix_filename] + if {[string equal -length $mount_len $unix_filename $filename]} { + if {$unix_filename eq "/"} { + if {$filename eq "/"} { + return "$win_filename" + } else { + return "$win_filename$filename" + } + } elseif {[string length $filename] == $mount_len} { + # Like "cygpath -ma" if the file name resolves to a + # drive letter, append a slash, to make it unambiguous + # that we resolved to the root of the drive and not + # the drive's current directory. + if {[string match {[A-Za-z]:} $win_filename]} { + return "$win_filename/" + } else { + return "$win_filename" + } + } elseif {[string index $filename $mount_len] eq "/"} { + set rest [string range $filename $mount_len end] + return "$win_filename$rest" + } + } + } + + return [file normalize $filename] +} + +# Normalize a file name for the host machine. If running native +# Windows GDB, this converts a Unix file name to a Windows filename, +# per the mount table. E.g., '/c/foo' (on MSYS2) or '/cygdrive/c/foo' +# (on Cygwin) is converted to 'c:/foo'. + +proc host_file_normalize {filename} { + if {[ishost *-*-mingw*]} { + # Get Unix => Windows map. + lassign [get_mount_point_map] _ unix_to_win + return [host_file_normalize_mingw $filename $unix_to_win] + } + + return [file normalize $filename] +} + +# Wrapper around "file join" that handles host-specific details. +# +# For Cygwin/MSYS2's Tcl, file names that start with a drive letter +# are not considered absolute file names, thus 'file join "c:/" "d:/"' +# returns "c:/d:". This procedure thus detects absolute Windows-style +# file names, and treats them as absolute, bypassing "file join". + +proc host_file_join {args} { + if {[isbuild *-*-mingw*]} { + set result "" + foreach filename $args { + set filename [host_file_sanitize $filename] + + # If the file name starts with drive letter and colon + # (e.g., "C:/"), treat it as absolute. + if {[regexp {^[A-Z]:/} $filename]} { + set result $filename + } else { + set result [file join $result $filename] + } + } + return $result + } else { + return [file join {*}$args] + } +} + proc gdb_reinitialize_dir { subdir } { global gdb_prompt @@ -2251,7 +2404,8 @@ proc gdb_reinitialize_dir { subdir } { } gdb_expect 60 { -re "Source directories searched.*$gdb_prompt $" { - send_gdb "dir $subdir\n" + set dir [host_file_normalize $subdir] + send_gdb "dir $dir\n" gdb_expect 60 { -re "Source directories searched.*$gdb_prompt $" { verbose "Dir set to $subdir" @@ -2301,7 +2455,8 @@ proc default_gdb_exit {} { } } - if { [is_remote host] && [board_info host exists fileid] } { + if { ([is_remote host] && [board_info host exists fileid]) + || [istarget *-*-mingw*] } { send_gdb "quit\n" gdb_expect 10 { -re "y or n" { @@ -2314,7 +2469,9 @@ proc default_gdb_exit {} { } if ![is_remote host] { - remote_close host + if {[catch { remote_close host } message]} { + warning "closing gdb failed with: $message" + } } unset gdb_spawn_id unset ::gdb_tty_name @@ -2577,6 +2734,17 @@ proc default_gdb_start { } { # Output with -q, and bracketed paste mode enabled, see above. verbose "GDB initialized." } + -re "^\033\\\[6n$gdb_prompt $" { + # With MSYS2 and TERM={xterm,ansi}, I get: + # + # builtin_spawn gdb -q ... + # ^[[6n(gdb) + # + # We set TERM to dumb by default to avoid this, but some + # test-cases set TERM to xterm or ansi, in which case we get this + # output. + verbose "GDB initialized." + } -re "$gdb_prompt $" { perror "GDB never initialized." unset gdb_spawn_id @@ -2823,11 +2991,6 @@ gdb_caching_proc allow_dap_tests {} { return 0 } - # ton.tcl uses "string is entier", supported starting tcl 8.6. - if { ![tcl_version_at_least 8 6] } { - return 0 - } - # With set auto-connect-native-target off, we run into: # +++ run # Traceback (most recent call last): @@ -2959,6 +3122,10 @@ gdb_caching_proc allow_dlmopen_tests {} { # Return 1 if we should allow TUI-related tests. gdb_caching_proc allow_tui_tests {} { + if { [istarget *-*-mingw*] } { + # Avoid "Cannot enable the TUI when output is not a terminal". + return 0 + } set output [remote_exec host $::GDB "$::INTERNAL_GDBFLAGS --configuration"] return [expr {[string first "--enable-tui" $output] != -1}] } @@ -3758,7 +3925,8 @@ proc supports_reverse {} { || [istarget "aarch64*-*-linux*"] || [istarget "loongarch*-*-linux*"] || [istarget "powerpc*-*-linux*"] - || [istarget "s390*-*-linux*"] } { + || [istarget "s390*-*-linux*"] + || [istarget "riscv*-*-*"] } { return 1 } @@ -4264,6 +4432,76 @@ gdb_caching_proc allow_tsx_tests {} { return $allow_tsx_tests } +# Run a test on the target to check if it supports x86 shadow stack. Return 1 +# if shadow stack is enabled, 0 otherwise. + +gdb_caching_proc allow_ssp_tests {} { + global srcdir subdir gdb_prompt hex + + set me "allow_ssp_tests" + + if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } { + verbose "$me: target known to not support shadow stack." + return 0 + } + + # There is no need to check the actual HW in addition to ptrace support. + # We need both checks and ptrace will tell us about the HW state. + set compile_flags "{additional_flags=-fcf-protection=return}" + set src { int main() { return 0; } } + if {![gdb_simple_compile $me $src executable $compile_flags]} { + return 0 + } + + save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + # No error message, compilation succeeded so now run it via gdb. + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load $obj + if {![runto_main]} { + remote_file build delete $obj + return 0 + } + set shadow_stack_disabled_re "(<unavailable>)" + if {[istarget *-*-linux*]} { + # Starting with v6.6, the Linux kernel supports CET shadow stack. + # Dependent on the target we can see a nullptr or "<unavailable>" + # when shadow stack is supported by HW and the Linux kernel but + # not enabled for the current thread (for example due to a lack + # of compiler or glibc support for -fcf-protection). + set shadow_stack_disabled_re "$shadow_stack_disabled_re|(.*0x0)" + } + + set allow_ssp_tests 0 + gdb_test_multiple "print \$pl3_ssp" "test shadow stack support" { + -re -wrap "(.*$hex)((?!(.*0x0)).)" { + verbose -log "$me: Shadow stack support detected." + set allow_ssp_tests 1 + } + -re -wrap $shadow_stack_disabled_re { + # In case shadow stack is not enabled (for example due to a + # lack of compiler or glibc support for -fcf-protection). + verbose -log "$me: Shadow stack is not enabled." + } + -re -wrap "void" { + # In case we don't have hardware or kernel support. + verbose -log "$me: No shadow stack support." + } + } + + gdb_exit + } + + remote_file build delete $obj + + verbose "$me: returning $allow_ssp_tests" 2 + return $allow_ssp_tests +} + # Run a test on the target to see if it supports avx512bf16. Return 1 if so, # 0 if it does not. Based on 'check_vmx_hw_available' from the GCC testsuite. @@ -4406,7 +4644,8 @@ gdb_caching_proc allow_lam_tests {} { # No error message, compilation succeeded so now run it via gdb. set allow_lam_tests 0 - clean_restart $obj + clean_restart + gdb_load $obj gdb_run_cmd gdb_expect { -re ".*$inferior_exited_re with code.*${gdb_prompt} $" { @@ -4689,7 +4928,8 @@ gdb_caching_proc allow_aarch64_sve_tests {} { } # Compilation succeeded so now run it via gdb. - clean_restart $obj + clean_restart + gdb_load $obj gdb_run_cmd gdb_expect { -re ".*Illegal instruction.*${gdb_prompt} $" { @@ -4749,7 +4989,8 @@ gdb_caching_proc aarch64_initialize_sve_information { } { return [array get supported_vl] } - clean_restart $test_exec + clean_restart + gdb_load $test_exec if {![runto_main]} { return [array get supported_vl] @@ -4846,7 +5087,8 @@ gdb_caching_proc allow_aarch64_sme_tests {} { } # Compilation succeeded so now run it via gdb. - clean_restart $obj + clean_restart + gdb_load $obj gdb_run_cmd gdb_expect { -re ".*Illegal instruction.*${gdb_prompt} $" { @@ -4906,7 +5148,8 @@ gdb_caching_proc aarch64_initialize_sme_information { } { return [array get supported_svl] } - clean_restart $test_exec + clean_restart + gdb_load $test_exec if {![runto_main]} { return [array get supported_svl] @@ -5000,7 +5243,8 @@ gdb_caching_proc allow_aarch64_mops_tests {} { } # Compilation succeeded so now run it via gdb. - clean_restart $obj + clean_restart + gdb_load $obj gdb_run_cmd gdb_expect { -re ".*$inferior_exited_re with code 01.*${gdb_prompt} $" { @@ -5023,6 +5267,61 @@ gdb_caching_proc allow_aarch64_mops_tests {} { return $allow_mops_tests } +# Run a test on the target to see if it supports AArch64 GCS extensions. +# Return 1 if so, 0 if it does not. Note this causes a restart of GDB. + +gdb_caching_proc allow_aarch64_gcs_tests {} { + global srcdir subdir gdb_prompt inferior_exited_re + + set me "allow_aarch64_gcs_tests" + + if { ![is_aarch64_target]} { + return 0 + } + + # Compile a program that tests the GCS feature. + set src { + #include <stdbool.h> + #include <sys/auxv.h> + + /* Feature check for Guarded Control Stack. */ + #ifndef HWCAP_GCS + #define HWCAP_GCS (1ULL << 32) + #endif + + int main (void) { + bool gcs_supported = getauxval (AT_HWCAP) & HWCAP_GCS; + + /* Return success if GCS is supported. */ + return !gcs_supported; + } + } + + if {![gdb_simple_compile $me $src executable]} { + return 0 + } + + # Compilation succeeded so now run it via gdb. + set allow_gcs_tests 0 + clean_restart + gdb_load $obj + gdb_run_cmd + gdb_expect { + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + verbose -log "\n$me: gcs support detected" + set allow_gcs_tests 1 + } + -re ".*$inferior_exited_re with code 01.*${gdb_prompt} $" { + verbose -log "\n$me: gcs support not detected" + } + } + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $allow_gcs_tests" 2 + return $allow_gcs_tests +} + # A helper that compiles a test case to see if __int128 is supported. proc gdb_int128_helper {lang} { return [gdb_can_simple_compile "i128-for-$lang" { @@ -5056,7 +5355,7 @@ gdb_caching_proc allow_ifunc_tests {} { } # Return whether we should skip tests for showing inlined functions in -# backtraces. Requires get_compiler_info and get_debug_format. +# backtraces. Requires get_debug_format. proc skip_inline_frame_tests {} { # GDB only recognizes inlining information in DWARF. @@ -5075,7 +5374,7 @@ proc skip_inline_frame_tests {} { } # Return whether we should skip tests for showing variables from -# inlined functions. Requires get_compiler_info and get_debug_format. +# inlined functions. Requires get_debug_format. proc skip_inline_var_tests {} { # GDB only recognizes inlining information in DWARF. @@ -5086,6 +5385,40 @@ proc skip_inline_var_tests {} { return 0 } +# Return whether we allow running fork-related testcases. Targets +# that don't even have any concept of fork will just fail to compile +# the testcases and skip the tests that way if this returns true for +# them. Unix targets that do have a fork system call, but don't +# support intercepting forks will want to return false here, otherwise +# the testcases that exercise fork may hit a number of long cascading +# time out sequences. + +proc allow_fork_tests {} { + if {[istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"]} { + return 0 + } + + return 1 +} + +# Return whether we allow running testcases that want to debug +# multiple inferiors with the same target. Not all targets support +# this. Note that some tests add a second inferior but never start +# it. Those tests should not be skipped due to this proc returning +# false. + +proc allow_multi_inferior_tests {} { + if {[istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"]} { + return 0 + } + + if {[use_gdb_stub]} { + return 0 + } + + return 1 +} + # Return a 1 if we should run tests that require hardware breakpoints proc allow_hw_breakpoint_tests {} { @@ -5313,14 +5646,6 @@ gdb_caching_proc target_is_gdbserver {} { return $is_gdbserver } -# N.B. compiler_info is intended to be local to this file. -# Call test_compiler_info with no arguments to fetch its value. -# Yes, this is counterintuitive when there's get_compiler_info, -# but that's the current API. -if [info exists compiler_info] { - unset compiler_info -} - # Figure out what compiler I am using. # The result is cached so only the first invocation runs the compiler. # @@ -5372,8 +5697,18 @@ if [info exists compiler_info] { # I didn't get desperate enough to try this. # # -- chastain 2004-01-06 +# +# Returns "unsupported" if LANGUAGE is not supported, and "unknown" if +# LANGUAGE is supported but extracting the information out of the +# compiler for LANGUAGE failed. Otherwise returns the compiler we're +# using for LANGUAGE. proc get_compiler_info {{language "c"}} { + # Split to a helper procedure because gdb_caching_proc does not + # support optional arguments. + return [get_compiler_info_1 $language] +} +gdb_caching_proc get_compiler_info_1 {language} { # For compiler.c, compiler.cc and compiler.F90. global srcdir @@ -5382,13 +5717,8 @@ proc get_compiler_info {{language "c"}} { global outdir global tool - # These come from compiler.c, compiler.cc or compiler.F90. - gdb_persistent_global compiler_info_cache - - if [info exists compiler_info_cache($language)] { - # Already computed. - return 0 - } + # 'compiler_info' comes from evaluating the result of + # preprocessing compiler.c, compiler.cc or compiler.F90. # Choose which file to preprocess. if { $language == "c++" } { @@ -5399,7 +5729,7 @@ proc get_compiler_info {{language "c"}} { set ifile "${srcdir}/lib/compiler.c" } else { perror "Unable to fetch compiler version for language: $language" - return -1 + return "unsupported" } # Run $ifile through the right preprocessor. @@ -5423,7 +5753,7 @@ proc get_compiler_info {{language "c"}} { set ifile $tofile set cppout [ gdb_compile "${ifile}" "" preprocess [list "$language" quiet getting_compiler_info] ] } - eval log_file $saved_log + log_file {*}$saved_log # Eval the output. set unknown 0 @@ -5461,22 +5791,21 @@ proc get_compiler_info {{language "c"}} { set compiler_info "unknown" } - set compiler_info_cache($language) $compiler_info - # Log what happened. verbose -log "get_compiler_info: $compiler_info" - return 0 + return $compiler_info } -# Return the compiler_info string if no arg is provided. -# Otherwise the argument is a glob-style expression to match against -# compiler_info. +# Return the compiler_info string if COMPILER is not provided. +# Otherwise COMPILER is a glob-style expression to match against +# compiler_info, and this returns true/false depending on whether the +# expression matches or not. proc test_compiler_info { {compiler ""} {language "c"} } { - gdb_persistent_global compiler_info_cache + set compiler_info [get_compiler_info $language] - if [get_compiler_info $language] { + if {$compiler_info == "unsupported"} { # An error will already have been printed in this case. Just # return a suitable result depending on how the user called # this function. @@ -5489,10 +5818,10 @@ proc test_compiler_info { {compiler ""} {language "c"} } { # If no arg, return the compiler_info string. if [string match "" $compiler] { - return $compiler_info_cache($language) + return $compiler_info } - return [string match $compiler $compiler_info_cache($language)] + return [string match $compiler $compiler_info] } # Return true if the C compiler is GCC, otherwise, return false. @@ -5665,6 +5994,10 @@ proc gdb_simple_compile {name code {type object} {compile_flags {}} {object obj} set ext "d" break } + if { "$flag" eq "rust" } { + set ext "rs" + break + } } set src [standard_temp_file $name.$ext] set obj [standard_temp_file $name.$postfix] @@ -6243,6 +6576,9 @@ proc gdb_compile {source dest type options} { } } + # Automatically handle includes in testsuite/lib/. + auto_lappend_include_files options $source + cond_wrap [expr $pie != -1 || $nopie != -1] \ with_PIE_multilib_flags_filtered { set result [target_compile $source $dest $type $options] @@ -6778,7 +7114,20 @@ gdb_caching_proc can_spawn_for_attach {} { set me "can_spawn_for_attach" set src { - #include <unistd.h> + #ifdef _WIN32 + # include <windows.h> + #else + # include <unistd.h> + #endif + + #ifdef _WIN32 + unsigned + sleep (unsigned seconds) + { + Sleep (seconds * 1000); + return 0; + } + #endif int main (void) @@ -6919,7 +7268,7 @@ proc kill_wait_spawned_process { proc_spawn_id } { proc spawn_id_get_pid { spawn_id } { set testpid [exp_pid -i $spawn_id] - if { [istarget "*-*-cygwin*"] } { + if { [istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"] } { # testpid is the Cygwin PID, GDB uses the Windows PID, which # might be different due to the way fork/exec works. set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ] @@ -7006,6 +7355,24 @@ proc gdb_load_cmd { args } { return -1 } +# Return non-zero if 'gcore' command is available. +gdb_caching_proc gcore_cmd_available { } { + gdb_exit + gdb_start + + # Does this gdb support gcore? + gdb_test_multiple "help gcore" "" { + -re -wrap "Undefined command: .*" { + return 0 + } + -re -wrap "Save a core file .*" { + return 1 + } + } + + return 0 +} + # Invoke "gcore". CORE is the name of the core file to write. TEST # is the name of the test case. This will return 1 if the core file # was created, 0 otherwise. If this fails to make a core file because @@ -7371,13 +7738,13 @@ proc clean_standard_output_dir {} { } # Directory containing the standard output files. - set standard_output_dir [file normalize [standard_output_file ""]] + set standard_output_dir [build_standard_output_file ""] # Ensure that standard_output_dir is clean, or only contains # gdb.log / gdb.sum. set log_file_info [split [log_file -info]] set log_file [file normalize [lindex $log_file_info end]] - if { $log_file == [file normalize [standard_output_file gdb.log]] } { + if { $log_file == [file normalize [build_standard_output_file gdb.log]] } { # Dir already contains active gdb.log. Don't remove the dir, but # check that it's clean otherwise. set res [glob -directory $standard_output_dir -tails *] @@ -7470,6 +7837,22 @@ proc default_gdb_init { test_file_name } { setenv LC_CTYPE C setenv LANG C + # With MSYS2 and TERM={xterm,ansi}, I get: + # + # builtin_spawn gdb -q ... + # ^[[6n(gdb) + # + # While we're addressing this in default_gdb_start, this is not specific + # to gdb, other tools produce the same CSI sequence, and consequently we + # run into trouble in other places (like get_compiler_info). + # + # Set TERM to dumb to prevent the '^[[6n' from occurring. + # + # We could do this only for ishost *-*-mingw*, but that introduces + # inconsistency between platforms, with test-cases passing on one platform + # but failing on the other. So, we do this for all platforms. + setenv TERM dumb + # Don't let a .inputrc file or an existing setting of INPUTRC mess # up the test results. Certain tests (style tests and TUI tests) # want to set the terminal to a non-"dumb" value, and for those we @@ -7607,31 +7990,48 @@ proc default_gdb_init { test_file_name } { proc make_gdb_parallel_path { args } { global GDB_PARALLEL objdir - set joiner [list "file" "join" $objdir] + set joiner [list $objdir] if { [info exists GDB_PARALLEL] && $GDB_PARALLEL != "yes" } { lappend joiner $GDB_PARALLEL } set joiner [concat $joiner $args] - return [eval $joiner] + return [file join {*}$joiner] } # Turn BASENAME into a full file name in the standard output -# directory. It is ok if BASENAME is the empty string; in this case -# the directory is returned. +# directory, as seen from the build machine. I.e., as seen from the +# system driving DejaGnu. (E.g., if DejaGnu is being driven by MSYS2 +# to test native Windows GDB, the "build" file names should be file +# names TCL understands, i.e., Unix file names.) It is OK if BASENAME +# is the empty string; in this case the directory is returned. -proc standard_output_file {basename} { +proc build_standard_output_file {basename} { global objdir subdir gdb_test_file_name set dir [make_gdb_parallel_path outputs $subdir $gdb_test_file_name] file mkdir $dir - # If running on MinGW, replace /c/foo with c:/foo - if { [ishost *-*-mingw*] } { - set dir [exec sh -c "cd ${dir} && pwd -W"] - } return [file join $dir $basename] } -# Turn BASENAME into a file name on host. +# Turn BASENAME into a full file name in the standard output +# directory, as seen from a non-remote host. I.e., assuming the build +# and the host share the filesystem. E.g., if DejaGnu is being driven +# by MSYS2 to test native Windows GDB, the "host" file names should be +# file names GDB understands, i.e., Windows file names. It is OK if +# BASENAME is the empty string; in this case the directory is +# returned. + +proc standard_output_file {basename} { + global objdir subdir gdb_test_file_name + + set dir [make_gdb_parallel_path outputs $subdir $gdb_test_file_name] + file mkdir $dir + set dir [host_file_normalize $dir] + return [host_file_join $dir $basename] +} + +# Like standard_output_file, but handles remote hosts. Turn BASENAME +# into a file name on (potentially remote) host. proc host_standard_output_file { basename } { if { [is_remote host] } { @@ -7866,7 +8266,7 @@ set temp [interp create] if { [interp eval $temp "info procs ::unknown"] != "" } { set old_args [interp eval $temp "info args ::unknown"] set old_body [interp eval $temp "info body ::unknown"] - eval proc gdb_tcl_unknown {$old_args} {$old_body} + proc gdb_tcl_unknown $old_args $old_body } interp delete $temp unset temp @@ -7901,11 +8301,11 @@ proc gdb_finish { } { gdb_exit if { [llength $cleanfiles_target] > 0 } { - eval remote_file target delete $cleanfiles_target + remote_file target delete {*}$cleanfiles_target set cleanfiles_target {} } if { [llength $cleanfiles_host] > 0 } { - eval remote_file host delete $cleanfiles_host + remote_file host delete {*}$cleanfiles_host set cleanfiles_host {} } @@ -8851,7 +9251,7 @@ proc build_executable { testname executable {sources ""} {options {debug}} } { lappend arglist $source $options } - return [eval build_executable_from_specs $arglist] + return [build_executable_from_specs {*}$arglist] } # Starts fresh GDB binary and loads an optional executable into GDB. @@ -8885,6 +9285,10 @@ proc clean_restart {{executable ""}} { gdb_reinitialize_dir $srcdir/$subdir if {$executable != ""} { + if { [file pathtype $executable] == "absolute" } { + error "absolute path used" + } + set binfile [standard_output_file ${executable}] return [gdb_load ${binfile}] } @@ -8902,7 +9306,7 @@ proc clean_restart {{executable ""}} { # Returns 0 on success, non-zero on failure. proc prepare_for_testing_full {testname args} { foreach spec $args { - if {[eval build_executable_from_specs [list $testname] $spec] == -1} { + if {[build_executable_from_specs $testname {*}$spec] == -1} { return -1 } set executable [lindex $spec 0] @@ -9135,7 +9539,8 @@ gdb_caching_proc target_endianness {} { return 0 } - clean_restart $obj + clean_restart + gdb_load $obj if ![runto_main] { return 0 } @@ -9158,12 +9563,12 @@ proc relative_filename {root full} { set len [llength $root_split] - if {[eval file join $root_split] - != [eval file join [lrange $full_split 0 [expr {$len - 1}]]]} { + if {[file join {*}$root_split] + != [file join {*}[lrange $full_split 0 [expr {$len - 1}]]]} { error "$full not a subdir of $root" } - return [eval file join [lrange $full_split $len end]] + return [file join {*}[lrange $full_split $len end]] } # If GDB_PARALLEL exists, then set up the parallel-mode directories. @@ -9261,7 +9666,13 @@ proc remove_core {pid {test ""}} { } } -proc core_find {binfile {deletefiles {}} {arg ""}} { +# Runs ${binfile} expecting it to crash and generate a core file. +# If DELETEFILES is provided, remove these files after running the program. +# If ARG is provided, pass it as a command line argument to the program. +# If OUTPUT_FILE is provided, save the program output to it. +# Returns the name of the core dump, or empty string if not found. + +proc core_find {binfile {deletefiles {}} {arg ""} {output_file "/dev/null"}} { global objdir subdir set destcore "$binfile.core" @@ -9283,9 +9694,14 @@ proc core_find {binfile {deletefiles {}} {arg ""}} { set found 0 set coredir [standard_output_file coredir.[getpid]] file mkdir $coredir - catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile} ${arg}; true) >/dev/null 2>&1\"" + catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile} ${arg}; true) >${output_file} 2>&1\"" # remote_exec host "${binfile}" - foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" { + set binfile_basename [file tail $binfile] + foreach i [list \ + ${coredir}/core \ + ${coredir}/core.coremaker.c \ + ${coredir}/${binfile_basename}.core \ + ${coredir}/${binfile_basename}.exe.core] { if [remote_file build exists $i] { remote_exec build "mv $i $destcore" set found 1 @@ -9369,7 +9785,8 @@ gdb_caching_proc target_supports_scheduler_locking {} { return 0 } - clean_restart $obj + clean_restart + gdb_load $obj if ![runto_main] { return 0 } @@ -9495,7 +9912,7 @@ proc run_on_host { test program args } { if {[llength $args] > 1 && [lindex $args 1] == ""} { set args [lreplace $args 1 1 "/dev/null"] } - set result [eval remote_exec host [list $program] $args] + set result [remote_exec host $program {*}$args] verbose "result is $result" set status [lindex $result 0] set output [lindex $result 1] @@ -9890,6 +10307,10 @@ proc gdb_stdin_log_init { } { set logfile [standard_output_file_with_gdb_instance gdb.in] set in_file [open $logfile w] + + verbose -log "" + verbose -log "Starting logfile: $logfile" + verbose -log "" } # Write to the file for logging gdb input. @@ -10295,14 +10716,14 @@ proc with_override { name override body } { # Install the override. set new_args [info_args_with_defaults $override] set new_body [info body $override] - eval proc $name {$new_args} {$new_body} + proc $name $new_args $new_body # Execute body. set code [catch {uplevel 1 $body} result] # Restore old proc if it existed on entry, else delete it. if { $existed } { - eval proc $name {$old_args} {$old_body} + proc $name $old_args $old_body } else { rename $name "" } @@ -10323,7 +10744,11 @@ proc with_override { name override body } { proc with_ansi_styling_terminal { body } { save_vars { ::env(TERM) ::env(NO_COLOR) ::env(COLORTERM) } { # Set environment variables to allow styling. - setenv TERM ansi + if { [ishost *-*-*bsd*] } { + setenv TERM ansiw + } else { + setenv TERM ansi + } unset -nocomplain ::env(NO_COLOR) unset -nocomplain ::env(COLORTERM) @@ -10856,7 +11281,8 @@ gdb_caching_proc have_epilogue_line_info {} { return False } - clean_restart $obj + clean_restart + gdb_load $obj gdb_test_multiple "info line 6" "epilogue test" { -re -wrap ".*starts at address.*and ends at.*" { @@ -10999,6 +11425,66 @@ proc lappend_include_file { flags file } { } } +# Helper for auto_lappend_include_files that handles one source file, +# and tracks the list of already-visited files. + +proc auto_lappend_include_files_1 {flags source {visited {}}} { + upvar $flags up_flags + upvar $visited up_visited + global srcdir + + set ext [string tolower [file extension $source]] + if {$ext ni {".c" ".cpp" ".cc" ".h" ".s"}} { + return + } + + if {[catch {open $source r} fh err]} { + error "Failed to open file '$source': $err" + } + set contents [read $fh] + close $fh + + lappend up_visited $source + + # Match lines like: + # #include "gdb_foo.h" + set re "^\\s*#include\\s+\"(.*)\"" + + foreach line [split $contents "\n"] { + if {[regexp $re $line -> basename]} { + set lib_file "$srcdir/lib/$basename" + + # If already processed, skip. + if {[lsearch -exact $up_visited $lib_file] != -1} { + continue + } + + if {![file exists $lib_file]} { + continue + } + + # Append to include list, and recurse into the included + # file. + lappend_include_file up_flags $lib_file + auto_lappend_include_files_1 up_flags $lib_file up_visited + } + } +} + +# Automatically handle includes under gdb/testsuite/lib/. +# +# For each source file in SOURCES, look for #include directives +# including files that live in testsuite/lib/. For each such included +# file, call lappend_include_file for it. + +proc auto_lappend_include_files {flags sources} { + upvar $flags up_flags + set visited {} + foreach src $sources { + auto_lappend_include_files_1 up_flags $src visited + } +} + # Return a list of supported host locales. gdb_caching_proc host_locales { } { @@ -11110,5 +11596,46 @@ gdb_caching_proc have_builtin_trap {} { } executable] } +# Return 1 if there is a startup shell. Return -1 if there's no startup shell. +# Return -1 otherwise. + +gdb_caching_proc have_startup_shell {} { + if { [is_remote target] } { + # For remote debugging targets, there is no guarantee that a "shell" + # is used. + return -1 + } + + + gdb_exit + gdb_start + + set re_on \ + [string_to_regexp "Use of shell to start subprocesses is on."] + set re_off \ + [string_to_regexp "Use of shell to start subprocesses is off."] + set re_cmd_unsupported \ + [string_to_regexp \ + {Undefined show command: "startup-with-shell". Try "help show".}] + + set supported -1 + gdb_test_multiple "show startup-with-shell" "" { + -re -wrap $re_on { + set supported 1 + } + -re -wrap $re_off { + set supported 0 + } + -re -wrap $re_cmd_unsupported { + } + -re -wrap "" { + } + } + + gdb_exit + + return $supported +} + # Always load compatibility stuff. load_lib future.exp diff --git a/gdb/testsuite/lib/gdb_watchdog.h b/gdb/testsuite/lib/gdb_watchdog.h new file mode 100644 index 0000000..15d63e7 --- /dev/null +++ b/gdb/testsuite/lib/gdb_watchdog.h @@ -0,0 +1,75 @@ +/* This file 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/>. */ + +/* Set a watchdog that aborts the testcase after a timeout. */ + +#ifndef GDB_WATCHDOG_H +#define GDB_WATCHDOG_H + +/* Forward declaration to make sure the definitions have the right + prototype, at least in C. */ +static void gdb_watchdog (unsigned int seconds); + +static const char _gdb_watchdog_msg[] + = "gdb_watchdog: timeout expired - aborting test\n"; + +#ifdef _WIN32 +#include <windows.h> +#include <stdlib.h> +#include <stdio.h> + +static VOID CALLBACK +_gdb_watchdog_timer_routine (PVOID lpParam, BOOLEAN TimerOrWaitFired) +{ + fputs (_gdb_watchdog_msg, stderr); + abort (); +} + +static void +gdb_watchdog (unsigned int seconds) +{ + HANDLE timer; + + if (!CreateTimerQueueTimer (&timer, NULL, + _gdb_watchdog_timer_routine, NULL, + seconds * 1000, 0, 0)) + abort (); +} + +#else /* POSIX systems */ + +#include <unistd.h> +#include <signal.h> +#include <stdlib.h> + +static void +_gdb_sigalrm_handler (int signo) +{ + write (2, _gdb_watchdog_msg, sizeof (_gdb_watchdog_msg) - 1); + abort (); +} + +static void +gdb_watchdog (unsigned int seconds) +{ + signal (SIGALRM, _gdb_sigalrm_handler); + alarm (seconds); +} + +#endif + +#endif /* GDB_WATCHDOG_H */ diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp index c285072..6ff00ba 100644 --- a/gdb/testsuite/lib/gdbserver-support.exp +++ b/gdb/testsuite/lib/gdbserver-support.exp @@ -69,7 +69,7 @@ proc gdb_target_cmd_ext { targetname serialport {additional_text ""} } { } -re "Non-stop mode requested, but remote does not support non-stop.*$gdb_prompt $" { verbose "remote does not support non-stop" - return 1 + return 2 } -re "Remote MIPS debugging.*$additional_text.*$gdb_prompt" { verbose "Set target to $targetname" @@ -125,7 +125,7 @@ proc gdb_target_cmd_ext { targetname serialport {additional_text ""} } { # Like gdb_target_cmd_ext, but returns 0 on success, 1 on failure. proc gdb_target_cmd { args } { - set res [eval gdb_target_cmd_ext $args] + set res [gdb_target_cmd_ext {*}$args] return [expr $res == 0 ? 0 : 1] } diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index aba13a2..fcbcddc 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -340,7 +340,7 @@ proc default_mi_gdb_start { { flags {} } } { # baseboard file. # proc mi_gdb_start { args } { - return [eval default_mi_gdb_start $args] + return [default_mi_gdb_start {*}$args] } # Many of the tests depend on setting breakpoints at various places and @@ -1010,14 +1010,14 @@ proc mi_run_cmd_full {use_mi_command args} { # -exec-continue, as appropriate. ARGS are passed verbatim to # mi_run_cmd_full. proc mi_run_cmd {args} { - return [eval mi_run_cmd_full 1 $args] + return [mi_run_cmd_full 1 {*}$args] } # A wrapper for mi_run_cmd_full which uses the CLI commands 'run' and # 'continue', as appropriate. ARGS are passed verbatim to # mi_run_cmd_full. proc mi_run_with_cli {args} { - return [eval mi_run_cmd_full 0 $args] + return [mi_run_cmd_full 0 {*}$args] } # Starts fresh GDB binary and loads an optional executable into GDB. @@ -1044,6 +1044,9 @@ proc mi_clean_restart {{executable ""} {flags {}}} { mi_gdb_reinitialize_dir $srcdir/$subdir if {$executable != ""} { + if { [file pathtype $executable] == "absolute" } { + error "absolute path used" + } set binfile [standard_output_file ${executable}] return [mi_gdb_load ${binfile}] } @@ -1394,7 +1397,7 @@ proc mi_continue_to {func} { # returns the breakpoint regexp from that procedure. proc mi_create_breakpoint {location test args} { - set bp [eval mi_make_breakpoint $args] + set bp [mi_make_breakpoint {*}$args] mi_gdb_test "222-break-insert $location" "222\\^done,$bp" $test return $bp } @@ -1403,7 +1406,7 @@ proc mi_create_breakpoint {location test args} { # locations using mi_make_breakpoint_multi instead. proc mi_create_breakpoint_multi {location test args} { - set bp [eval mi_make_breakpoint_multi $args] + set bp [mi_make_breakpoint_multi {*}$args] mi_gdb_test "222-break-insert $location" "222\\^done,$bp" $test return $bp } @@ -1411,7 +1414,7 @@ proc mi_create_breakpoint_multi {location test args} { # Like mi_create_breakpoint, but creates a pending breakpoint. proc mi_create_breakpoint_pending {location test args} { - set bp [eval mi_make_breakpoint_pending $args] + set bp [mi_make_breakpoint_pending {*}$args] mi_gdb_test "222-break-insert $location" ".*\r\n222\\^done,$bp" $test return $bp } @@ -2683,7 +2686,7 @@ proc mi_make_info_frame_regexp {args} { proc mi_info_frame { test args } { parse_some_args {{frame ""} {thread ""}} - set re [eval mi_make_info_frame_regexp $args] + set re [mi_make_info_frame_regexp {*}$args] set cmd "235-stack-info-frame" if {$frame ne ""} { diff --git a/gdb/testsuite/lib/selftest-support.exp b/gdb/testsuite/lib/selftest-support.exp index e037664..af8ec6f 100644 --- a/gdb/testsuite/lib/selftest-support.exp +++ b/gdb/testsuite/lib/selftest-support.exp @@ -16,7 +16,7 @@ # Find a pathname to a file that we would execute if the shell was asked # to run $arg using the current PATH. -proc find_gdb { arg } { +proc _selftest_find_gdb { arg } { # If the arg directly specifies an existing executable file, then # simply use it. @@ -36,65 +36,163 @@ proc find_gdb { arg } { return $arg } -# A helper proc that sets up for self-testing. -# EXECUTABLE is the gdb to use. -# FUNCTION is the function to break in, either captured_main -# or captured_command_loop. -# Return 0 in case of success, -1 in case of failure, and -2 in case of -# skipping the test-case. +# Return true if the GDB under test is installed (as opposed to a GDB in its +# build directory). -proc selftest_setup { executable function } { - global gdb_prompt - global INTERNAL_GDBFLAGS +proc _selftest_gdb_is_installed {} { + # If GDB_DATA_DIRECTORY is empty, assume that it is an installed GDB. It is + # not a perfectly accurate check, but should be good enough. + return [expr {"$::GDB_DATA_DIRECTORY" == ""}] +} + +# Return true if the libtool binary is present on the host. + +proc _selftest_has_libtool {} { + lassign [remote_exec host "sh -c \"command -v libtool\""] status output + return [expr {$status == 0}] +} + +# If GDB is executed from a build tree, run libtool to obtain the real +# executable path for EXECUTABLE, which may be a libtool wrapper. Return +# the path on success. On failure, issue an UNTESTED test result and return +# an empty string. +# +# If GDB is executed from an installed location, return EXECUTABLE unchanged. +# +# If libtool is not present on the host system, return EXECUTABLE unchanged. +# The test might still work, because the GDB binary is not always a libtool +# wrapper. + +proc selftest_libtool_get_real_gdb_executable { executable } { + if [_selftest_gdb_is_installed] { + return $executable + } - # load yourself into the debugger + if ![_selftest_has_libtool] { + return $executable + } + + lassign [remote_exec host libtool "--mode=execute echo -n $executable"] \ + status executable + + if { $status != 0 } { + untested "failed to run libtool" + return "" + } - global gdb_file_cmd_debug_info - set gdb_file_cmd_debug_info "unset" + return $executable +} + +# Return true if EXECUTABLE has debug info. +# +# If it doesn't, or if it's not possible to determine, issue an UNTESTED test +# result and return false. + +proc _selftest_check_executable_debug_info { executable } { + set ::gdb_file_cmd_debug_info "unset" + set result true + + # On Cygwin (at least), gdb/gdb.exe is a libtool wrapper (which happens to + # be a PE executable). The real binary is gdb/.libs/gdb.exe. If we load + # gdb/gdb.exe, we won't see any debug info and conclude that we can't run + # the test. Obtain the real executable path using libtool. + # + # At the time of writing, we don't see a libtool wrapper generated on Linux. + # But if there was one, it would be a shell script, and it would not be + # possible to load it in gdb. This conversion would therefore also be + # necessary. + # + # If testing against an installed GDB, then there won't be a libtool + # wrapper, no need to convert. + set executable [selftest_libtool_get_real_gdb_executable $executable] + + if { $executable == "" } { + # selftest_libtool_get_real_gdb_executable already records an UNTESTED + # on failure. + return false + } - set result [gdb_load $executable] + gdb_start - if {$result != 0} { - return -1 + if {[gdb_load $executable] != 0} { + untested "failed to load executable when checking for debug info" + set result false } - if {$gdb_file_cmd_debug_info != "debug"} { + if {$::gdb_file_cmd_debug_info != "debug"} { untested "no debug information, skipping testcase." - return -2 + set result false } - # Set a breakpoint at $function. + gdb_exit + + return $result +} + +# A helper proc that sets up for self-testing. +# +# Assumes that the inferior GDB is already loaded in the top-level GDB. +# +# Return 0 in case of success, -1 in case of failure, and -2 in case of +# skipping the test-case. + +proc _selftest_setup { } { + global gdb_prompt + global INTERNAL_GDBFLAGS + + # Set a breakpoint at main + set function main if { [gdb_breakpoint $function "no-message"] != 1 } { untested "Cannot set breakpoint at $function, skipping testcase." return -2 } + # Debugging on Windows shows random threads starting and exiting, + # interfering with the tests. Disable them, since they are not useful here. + gdb_test_no_output "set print thread-events off" + # run yourself set description "run until breakpoint at $function" + set re_hs {[^\r\n]+} + set re_args [string cat \ + [string_to_regexp "("] \ + $re_hs \ + [string_to_regexp ")"]] + set re_pass \ + [multi_line \ + "Starting program: $re_hs" \ + ".*" \ + [string cat "Breakpoint $::decimal, $function $re_args at" \ + " ${re_hs}gdb.c:$re_hs"] \ + ".*"] + set re_xfail \ + [multi_line \ + "Starting program: $re_hs" \ + ".*" \ + "Breakpoint $::decimal, $function $re_args$re_hs" \ + ".*"] gdb_test_multiple "run $INTERNAL_GDBFLAGS" "$description" { - -re "Starting program.*Breakpoint \[0-9\]+,.*$function \\(.*\\).* at .*main.c:.*$gdb_prompt $" { - pass "$description" - } - -re "Starting program.*Breakpoint \[0-9\]+,.*$function \\(.*\\).*$gdb_prompt $" { - xfail "$description (line numbers scrambled?)" - } - -re "vfork: No more processes.*$gdb_prompt $" { - fail "$description (out of virtual memory)" - return -1 - } - -re ".*$gdb_prompt $" { - fail "$description" - return -1 - } + -re -wrap $re_pass { + pass $description + } + -re -wrap $re_xfail { + xfail "$description (line numbers scrambled?)" + } + -re -wrap "vfork: No more processes.*" { + fail "$description (out of virtual memory)" + return -1 + } + -re -wrap "" { + fail $description + return -1 + } } return 0 } -# Prepare for running a self-test by moving the GDB executable to a -# location where we can use it as the inferior. Return the filename -# of the new location. +# Return the location of the gdb executable to test. # # If the current testing setup is not suitable for running a # self-test, then return an empty string. @@ -114,52 +212,54 @@ proc selftest_prepare {} { # ... or with a stub-like server? I.e., gdbserver + "target # remote"? In that case we won't be able to pass command line - # arguments to GDB, and selftest_setup wants to do exactly that. + # arguments to GDB, and _selftest_setup wants to do exactly that. if [use_gdb_stub] { return } - # Run the test with self. Copy the file executable file in case - # this OS doesn't like to edit its own text space. - - set gdb_fullpath [find_gdb $::GDB] - - if {[is_remote host]} { - set xgdb x$::tool - } else { - set xgdb [standard_output_file x$::tool] - } - - # Remove any old copy lying around. - remote_file host delete $xgdb - - set filename [remote_download host $gdb_fullpath $xgdb] - - return $filename + return [_selftest_find_gdb $::GDB] } # A simple way to run some self-tests. -proc do_self_tests {function body} { +proc do_self_tests {body} { set file [selftest_prepare] if { $file eq "" } { return } - gdb_start + # Check if the gdb executable has debug info. + if { ![_selftest_check_executable_debug_info $file] } { + return + } + + # FILE might be a libtool wrapper. In order to debug the real thing, pass + # FILE on the command-line of the top-level gdb, and run under + # `libtool --mode=execute. libtool will replace FILE with the path to the + # real executable and set any path required for it to find its dependent + # libraries. + # + # If testing against an installed GDB, there won't be a libtool wrapper. + save_vars { ::GDB ::GDBFLAGS } { + if { ![_selftest_gdb_is_installed] && [_selftest_has_libtool] } { + set ::GDB "libtool --mode=execute $::GDB" + } + + set ::GDBFLAGS "$::GDBFLAGS $file" + gdb_start + } # When debugging GDB with GDB, some operations can take a relatively long # time, especially if the build is non-optimized. Bump the timeout for the # duration of the test. with_timeout_factor 10 { - set result [selftest_setup $file $function] + set result [_selftest_setup] if {$result == 0} { set result [uplevel $body] } } gdb_exit - catch "remote_file host delete $file" if {$result == -1} { warning "Couldn't test self" diff --git a/gdb/testsuite/lib/trace-support.exp b/gdb/testsuite/lib/trace-support.exp index a8d0699..8543de3 100644 --- a/gdb/testsuite/lib/trace-support.exp +++ b/gdb/testsuite/lib/trace-support.exp @@ -219,14 +219,14 @@ proc gdb_trace_setactions_command { actions_command testname tracepoint args } { # gdb_trace_setactions_command. # proc gdb_trace_setactions { testname tracepoint args } { - eval gdb_trace_setactions_command "actions" {$testname} {$tracepoint} $args + gdb_trace_setactions_command "actions" $testname $tracepoint {*}$args } # Define actions for a tracepoint, using the "commands" command. See # gdb_trace_setactions_command. # proc gdb_trace_setcommands { testname tracepoint args } { - eval gdb_trace_setactions_command "commands" {$testname} {$tracepoint} $args + gdb_trace_setactions_command "commands" $testname $tracepoint {*}$args } # diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp index a0cd199..68fd677 100644 --- a/gdb/testsuite/lib/tuiterm.exp +++ b/gdb/testsuite/lib/tuiterm.exp @@ -33,1264 +33,1690 @@ namespace eval Term { variable _resize_count - proc _log { what } { - verbose "+++ $what" - } + variable _TERM + set _TERM "" - # Call BODY, then log WHAT along with the original and new cursor position. - proc _log_cur { what body } { - variable _cur_row - variable _cur_col + variable _alternate + variable _alternate_setup + set _alternate 0 + set _alternate_setup 0 +} + +proc Term::_log { what } { + verbose "+++ $what" +} - set orig_cur_row $_cur_row - set orig_cur_col $_cur_col +# Call BODY, then log WHAT along with the original and new cursor position. +proc Term::_log_cur { what body } { + variable _cur_row + variable _cur_col - uplevel $body + set orig_cur_row $_cur_row + set orig_cur_col $_cur_col + + set code [catch {uplevel $body} result] - _log "$what, cursor: ($orig_cur_row, $orig_cur_col) -> ($_cur_row, $_cur_col)" + _log "$what, cursor: ($orig_cur_row, $orig_cur_col) -> ($_cur_row, $_cur_col)" + + if { $code == 1 } { + global errorInfo errorCode + return -code $code -errorinfo $errorInfo -errorcode $errorCode $result + } else { + return -code $code $result } +} - # If ARG is empty, return DEF: otherwise ARG. This is useful for - # defaulting arguments in CSIs. - proc _default {arg def} { - if {$arg == ""} { - return $def - } - return $arg +# If ARG is empty, return DEF: otherwise ARG. This is useful for +# defaulting arguments in CSIs. +proc Term::_default {arg def} { + if {$arg == ""} { + return $def } + return $arg +} - # Erase in the line Y from SX to just before EX. - proc _clear_in_line {sx ex y} { - variable _attrs - variable _chars - set lattr [array get _attrs] - while {$sx < $ex} { - set _chars($sx,$y) [list " " $lattr] - incr sx - } +# Erase in the line Y from SX to just before EX. +proc Term::_clear_in_line {sx ex y} { + variable _attrs + variable _chars + set lattr [array get _attrs] + while {$sx < $ex} { + set _chars($sx,$y) [list " " $lattr] + incr sx } +} - # Erase the lines from SY to just before EY. - proc _clear_lines {sy ey} { - variable _cols - while {$sy < $ey} { - _clear_in_line 0 $_cols $sy - incr sy - } +# Erase the lines from SY to just before EY. +proc Term::_clear_lines {sy ey} { + variable _cols + while {$sy < $ey} { + _clear_in_line 0 $_cols $sy + incr sy } +} + +# Beep. +proc Term::_ctl_0x07 {} { +} + +# Return 1 if tuiterm has the bw/auto_left_margin enabled. +proc Term::_have_bw {} { + return [expr \ + { [string equal $Term::_TERM "ansiw"] \ + || [string equal $Term::_TERM "ansis"] }] +} - # Beep. - proc _ctl_0x07 {} { +# Backspace. +proc Term::_ctl_0x08 { {bw -1} } { + if { $bw == -1 } { + set bw [_have_bw] } + _log_cur "Backspace, bw == $bw" { + variable _cur_col + variable _cur_row + variable _cols - # Backspace. - proc _ctl_0x08 {} { - _log_cur "Backspace" { - variable _cur_col + if { $_cur_col > 0 } { + # No wrapping needed. + incr _cur_col -1 + return + } - if {$_cur_col > 0} { - incr _cur_col -1 - } + if { ! $bw } { + # Wrapping not enabled. + return } + + if { $_cur_row == 0 } { + # Can't wrap. + return + } + + # Wrap to previous line. + set _cur_col [expr $_cols - 1] + incr _cur_row -1 } +} - # Linefeed. - proc _ctl_0x0a {} { - _log_cur "Line feed" { - variable _cur_row - variable _rows - variable _cols - variable _chars - - incr _cur_row 1 - while {$_cur_row >= $_rows} { - # Scroll the display contents. We scroll one line at - # a time here; as _cur_row was only increased by one, - # a single line scroll should be enough to put the - # cursor back on the screen. But we wrap the - # scrolling inside a while loop just to be on the safe - # side. - for {set y 0} {$y < [expr $_rows - 1]} {incr y} { - set next_y [expr $y + 1] - for {set x 0} {$x < $_cols} {incr x} { - set _chars($x,$y) $_chars($x,$next_y) - } - } +# Linefeed. +proc Term::_ctl_0x0a {} { + _log_cur "Line feed" { + variable _cur_row + variable _rows + variable _cols + variable _chars - incr _cur_row -1 + incr _cur_row 1 + while {$_cur_row >= $_rows} { + # Scroll the display contents. We scroll one line at + # a time here; as _cur_row was only increased by one, + # a single line scroll should be enough to put the + # cursor back on the screen. But we wrap the + # scrolling inside a while loop just to be on the safe + # side. + for {set y 0} {$y < [expr $_rows - 1]} {incr y} { + set next_y [expr $y + 1] + for {set x 0} {$x < $_cols} {incr x} { + set _chars($x,$y) $_chars($x,$next_y) + } } + + incr _cur_row -1 } } +} - # Carriage return. - proc _ctl_0x0d {} { - _log_cur "Carriage return" { - variable _cur_col +# Carriage return. +proc Term::_ctl_0x0d {} { + _log_cur "Carriage return" { + variable _cur_col - set _cur_col 0 - } + set _cur_col 0 } +} - # Insert Character. - # - # https://vt100.net/docs/vt510-rm/ICH.html - proc _csi_@ {args} { - set n [_default [lindex $args 0] 1] +# Designate G0 Character Set, USASCII (ESC ( B) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html (see "ESC ( C", case C = B) +proc Term::_esc_0x28_B {} { + _log "ignored: G0: USASCII" +} - _log_cur "Insert Character ($n)" { - variable _cur_col - variable _cur_row - variable _cols - variable _chars +# Designate G0 Character Set, DEC Special Character and Line Drawing Set (ESC ( 0) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html (see "ESC ( C", case C = 0) +proc Term::_esc_0x28_0 {} { + _log "ignored: G0: DEC Special Character and Line Drawing Set" +} - # Move characters right of the cursor right by N positions, - # starting with the rightmost one. - for {set in_col [expr $_cols - $n - 1]} {$in_col >= $_cur_col} {incr in_col -1} { - set out_col [expr $in_col + $n] - set _chars($out_col,$_cur_row) $_chars($in_col,$_cur_row) - } +# DECKPAM (Application Keypad, ESC =) +# +# https://vt100.net/docs/vt510-rm/DECKPAM.html +proc Term::_esc_0x3d {} { + _log "ignored: Application Keypad" +} + +# DECKPNM (Normal Keypad, ESC >) +# +# https://vt100.net/docs/vt510-rm/DECKPNM.html +proc Term::_esc_0x3e {} { + _log "ignored: Normal Keypad" +} - # Write N blank spaces starting from the cursor. - _clear_in_line $_cur_col [expr $_cur_col + $n] $_cur_row +# Insert Character. +# +# https://vt100.net/docs/vt510-rm/ICH.html +proc Term::_csi_@ {args} { + set n [_default [lindex $args 0] 1] + + _log_cur "Insert Character ($n)" { + variable _cur_col + variable _cur_row + variable _cols + variable _chars + + # Move characters right of the cursor right by N positions, + # starting with the rightmost one. + for {set in_col [expr $_cols - $n - 1]} {$in_col >= $_cur_col} {incr in_col -1} { + set out_col [expr $in_col + $n] + set _chars($out_col,$_cur_row) $_chars($in_col,$_cur_row) } + + # Write N blank spaces starting from the cursor. + _clear_in_line $_cur_col [expr $_cur_col + $n] $_cur_row } +} - # Cursor Up. - # - # https://vt100.net/docs/vt510-rm/CUU.html - proc _csi_A {args} { - set arg [_default [lindex $args 0] 1] +# Horizontal Position Absolute. +# +# https://vt100.net/docs/vt510-rm/HPA.html +proc Term::_csi_` {args} { + # Same as Cursor Horizontal Absolute. + return [Term::_csi_G {*}$args] +} - _log_cur "Cursor Up ($arg)" { - variable _cur_row +# Cursor Up. +# +# https://vt100.net/docs/vt510-rm/CUU.html +proc Term::_csi_A {args} { + set arg [_default [lindex $args 0] 1] - set _cur_row [expr {max ($_cur_row - $arg, 0)}] - } + _log_cur "Cursor Up ($arg)" { + variable _cur_row + + set _cur_row [expr {max ($_cur_row - $arg, 0)}] } +} - # Cursor Down. - # - # https://vt100.net/docs/vt510-rm/CUD.html - proc _csi_B {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Down. +# +# https://vt100.net/docs/vt510-rm/CUD.html +proc Term::_csi_B {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Down ($arg)" { - variable _cur_row - variable _rows + _log_cur "Cursor Down ($arg)" { + variable _cur_row + variable _rows - set _cur_row [expr {min ($_cur_row + $arg, $_rows - 1)}] - } + set _cur_row [expr {min ($_cur_row + $arg, $_rows - 1)}] } +} - # Cursor Forward. - # - # https://vt100.net/docs/vt510-rm/CUF.html - proc _csi_C {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Forward. +# +# https://vt100.net/docs/vt510-rm/CUF.html +proc Term::_csi_C {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Forward ($arg)" { - variable _cur_col - variable _cols + _log_cur "Cursor Forward ($arg)" { + variable _cur_col + variable _cols - set _cur_col [expr {min ($_cur_col + $arg, $_cols - 1)}] - } + set _cur_col [expr {min ($_cur_col + $arg, $_cols - 1)}] } +} - # Cursor Backward. - # - # https://vt100.net/docs/vt510-rm/CUB.html - proc _csi_D {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Backward. +# +# https://vt100.net/docs/vt510-rm/CUB.html +proc Term::_csi_D {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Backward ($arg)" { - variable _cur_col + _log_cur "Cursor Backward ($arg)" { + variable _cur_col - set _cur_col [expr {max ($_cur_col - $arg, 0)}] - } + set _cur_col [expr {max ($_cur_col - $arg, 0)}] } +} - # Cursor Next Line. - # - # https://vt100.net/docs/vt510-rm/CNL.html - proc _csi_E {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Next Line. +# +# https://vt100.net/docs/vt510-rm/CNL.html +proc Term::_csi_E {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Next Line ($arg)" { - variable _cur_col - variable _cur_row - variable _rows + _log_cur "Cursor Next Line ($arg)" { + variable _cur_col + variable _cur_row + variable _rows - set _cur_col 0 - set _cur_row [expr {min ($_cur_row + $arg, $_rows - 1)}] - } + set _cur_col 0 + set _cur_row [expr {min ($_cur_row + $arg, $_rows - 1)}] } +} - # Cursor Previous Line. - # - # https://vt100.net/docs/vt510-rm/CPL.html - proc _csi_F {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Previous Line. +# +# https://vt100.net/docs/vt510-rm/CPL.html +proc Term::_csi_F {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Previous Line ($arg)" { - variable _cur_col - variable _cur_row - variable _rows + _log_cur "Cursor Previous Line ($arg)" { + variable _cur_col + variable _cur_row + variable _rows - set _cur_col 0 - set _cur_row [expr {max ($_cur_row - $arg, 0)}] - } + set _cur_col 0 + set _cur_row [expr {max ($_cur_row - $arg, 0)}] } +} - # Cursor Horizontal Absolute. - # - # https://vt100.net/docs/vt510-rm/CHA.html - proc _csi_G {args} { - set arg [_default [lindex $args 0] 1] +# Cursor Horizontal Absolute. +# +# https://vt100.net/docs/vt510-rm/CHA.html +proc Term::_csi_G {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Cursor Horizontal Absolute ($arg)" { - variable _cur_col - variable _cols + _log_cur "Cursor Horizontal Absolute ($arg)" { + variable _cur_col + variable _cols - set _cur_col [expr {min ($arg - 1, $_cols)}] - } + set _cur_col [expr {min ($arg, $_cols)} - 1] } +} - # Cursor Position. - # - # https://vt100.net/docs/vt510-rm/CUP.html - proc _csi_H {args} { - set row [_default [lindex $args 0] 1] - set col [_default [lindex $args 1] 1] +# Cursor Position. +# +# https://vt100.net/docs/vt510-rm/CUP.html +proc Term::_csi_H {args} { + set row [_default [lindex $args 0] 1] + set col [_default [lindex $args 1] 1] - _log_cur "Cursor Position ($row, $col)" { - variable _cur_col - variable _cur_row + _log_cur "Cursor Position ($row, $col)" { + variable _cur_col + variable _cur_row - set _cur_row [expr {$row - 1}] - set _cur_col [expr {$col - 1}] - } + set _cur_row [expr {$row - 1}] + set _cur_col [expr {$col - 1}] } +} - # Cursor Horizontal Forward Tabulation. - # - # https://vt100.net/docs/vt510-rm/CHT.html - proc _csi_I {args} { - set n [_default [lindex $args 0] 1] +# Cursor Horizontal Forward Tabulation. +# +# https://vt100.net/docs/vt510-rm/CHT.html +proc Term::_csi_I {args} { + set n [_default [lindex $args 0] 1] - _log_cur "Cursor Horizontal Forward Tabulation ($n)" { - variable _cur_col - variable _cols + _log_cur "Cursor Horizontal Forward Tabulation ($n)" { + variable _cur_col + variable _cols - incr _cur_col [expr {$n * 8 - $_cur_col % 8}] - if {$_cur_col >= $_cols} { - set _cur_col [expr {$_cols - 1}] - } + incr _cur_col [expr {$n * 8 - $_cur_col % 8}] + if {$_cur_col >= $_cols} { + set _cur_col [expr {$_cols - 1}] } } +} - # Erase in Display. - # - # https://vt100.net/docs/vt510-rm/ED.html - proc _csi_J {args} { - set arg [_default [lindex $args 0] 0] - - _log_cur "Erase in Display ($arg)" { - variable _cur_col - variable _cur_row - variable _rows - variable _cols - - if {$arg == 0} { - # Cursor (inclusive) to end of display. - _clear_in_line $_cur_col $_cols $_cur_row - _clear_lines [expr {$_cur_row + 1}] $_rows - } elseif {$arg == 1} { - # Beginning of display to cursor (inclusive). - _clear_lines 0 $_cur_row - _clear_in_line 0 [expr $_cur_col + 1] $_cur_row - } elseif {$arg == 2} { - # Entire display. - _clear_lines 0 $_rows - } +# Erase in Display. +# +# https://vt100.net/docs/vt510-rm/ED.html +proc Term::_csi_J {args} { + set arg [_default [lindex $args 0] 0] + + _log_cur "Erase in Display ($arg)" { + variable _cur_col + variable _cur_row + variable _rows + variable _cols + + if {$arg == 0} { + # Cursor (inclusive) to end of display. + _clear_in_line $_cur_col $_cols $_cur_row + _clear_lines [expr {$_cur_row + 1}] $_rows + } elseif {$arg == 1} { + # Beginning of display to cursor (inclusive). + _clear_lines 0 $_cur_row + _clear_in_line 0 [expr $_cur_col + 1] $_cur_row + } elseif {$arg == 2} { + # Entire display. + _clear_lines 0 $_rows } } +} - # Erase in Line. - # - # https://vt100.net/docs/vt510-rm/EL.html - proc _csi_K {args} { - set arg [_default [lindex $args 0] 0] +# Erase in Line. +# +# https://vt100.net/docs/vt510-rm/EL.html +proc Term::_csi_K {args} { + set arg [_default [lindex $args 0] 0] - _log_cur "Erase in Line ($arg)" { - variable _cur_col - variable _cur_row - variable _cols + _log_cur "Erase in Line ($arg)" { + variable _cur_col + variable _cur_row + variable _cols - if {$arg == 0} { - # Cursor (inclusive) to end of line. - _clear_in_line $_cur_col $_cols $_cur_row - } elseif {$arg == 1} { - # Beginning of line to cursor (inclusive). - _clear_in_line 0 [expr $_cur_col + 1] $_cur_row - } elseif {$arg == 2} { - # Entire line. - _clear_in_line 0 $_cols $_cur_row - } + if {$arg == 0} { + # Cursor (inclusive) to end of line. + _clear_in_line $_cur_col $_cols $_cur_row + } elseif {$arg == 1} { + # Beginning of line to cursor (inclusive). + _clear_in_line 0 [expr $_cur_col + 1] $_cur_row + } elseif {$arg == 2} { + # Entire line. + _clear_in_line 0 $_cols $_cur_row } } +} - # Insert Line - # - # https://vt100.net/docs/vt510-rm/IL.html - proc _csi_L {args} { - set arg [_default [lindex $args 0] 1] +# Insert Line +# +# https://vt100.net/docs/vt510-rm/IL.html +proc Term::_csi_L {args} { + set arg [_default [lindex $args 0] 1] - _log_cur "Insert Line ($arg)" { - variable _cur_col - variable _cur_row - variable _rows - variable _cols - variable _chars + _log_cur "Insert Line ($arg)" { + variable _cur_col + variable _cur_row + variable _rows + variable _cols + variable _chars - set y [expr $_rows - 2] - set next_y [expr $y + $arg] - while {$y >= $_cur_row} { - for {set x 0} {$x < $_cols} {incr x} { - set _chars($x,$next_y) $_chars($x,$y) - } - incr y -1 - incr next_y -1 + set y [expr $_rows - 2] + set next_y [expr $y + $arg] + while {$y >= $_cur_row} { + for {set x 0} {$x < $_cols} {incr x} { + set _chars($x,$next_y) $_chars($x,$y) } - - _clear_lines $_cur_row [expr $_cur_row + $arg] + incr y -1 + incr next_y -1 } + + _clear_lines $_cur_row [expr $_cur_row + $arg] } +} - # Delete line. - # - # https://vt100.net/docs/vt510-rm/DL.html - proc _csi_M {args} { - set count [_default [lindex $args 0] 1] +# Delete line. +# +# https://vt100.net/docs/vt510-rm/DL.html +proc Term::_csi_M {args} { + set count [_default [lindex $args 0] 1] - _log_cur "Delete line ($count)" { - variable _cur_row - variable _rows - variable _cols - variable _chars + _log_cur "Delete line ($count)" { + variable _cur_row + variable _rows + variable _cols + variable _chars - set y $_cur_row - set next_y [expr {$y + $count}] - while {$next_y < $_rows} { - for {set x 0} {$x < $_cols} {incr x} { - set _chars($x,$y) $_chars($x,$next_y) - } - incr y - incr next_y + set y $_cur_row + set next_y [expr {$y + $count}] + while {$next_y < $_rows} { + for {set x 0} {$x < $_cols} {incr x} { + set _chars($x,$y) $_chars($x,$next_y) } - _clear_lines $y $_rows + incr y + incr next_y } + _clear_lines $y $_rows } +} - # Delete Character. - # - # https://vt100.net/docs/vt510-rm/DCH.html - proc _csi_P {args} { - set count [_default [lindex $args 0] 1] - - _log_cur "Delete character ($count)" { - variable _cur_row - variable _cur_col - variable _chars - variable _cols +# Delete Character. +# +# https://vt100.net/docs/vt510-rm/DCH.html +proc Term::_csi_P {args} { + set count [_default [lindex $args 0] 1] - # Move all characters right of the cursor N positions left. - set out_col [expr $_cur_col] - set in_col [expr $_cur_col + $count] + _log_cur "Delete character ($count)" { + variable _cur_row + variable _cur_col + variable _chars + variable _cols - while {$in_col < $_cols} { - set _chars($out_col,$_cur_row) $_chars($in_col,$_cur_row) - incr in_col - incr out_col - } + # Move all characters right of the cursor N positions left. + set out_col [expr $_cur_col] + set in_col [expr $_cur_col + $count] - # Clear the rest of the line. - _clear_in_line $out_col $_cols $_cur_row + while {$in_col < $_cols} { + set _chars($out_col,$_cur_row) $_chars($in_col,$_cur_row) + incr in_col + incr out_col } + + # Clear the rest of the line. + _clear_in_line $out_col $_cols $_cur_row } +} - # Pan Down - # - # https://vt100.net/docs/vt510-rm/SU.html - proc _csi_S {args} { - set count [_default [lindex $args 0] 1] +# Pan Down +# +# https://vt100.net/docs/vt510-rm/SU.html +proc Term::_csi_S {args} { + set count [_default [lindex $args 0] 1] - _log_cur "Pan Down ($count)" { - variable _cur_col - variable _cur_row - variable _cols - variable _rows - variable _chars + _log_cur "Pan Down ($count)" { + variable _cur_col + variable _cur_row + variable _cols + variable _rows + variable _chars - # The following code is written without consideration for - # the scroll margins. At this time this comment was - # written the tuiterm library doesn't support the scroll - # margins. If/when that changes, then the following will - # need to be updated. + # The following code is written without consideration for + # the scroll margins. At this time this comment was + # written the tuiterm library doesn't support the scroll + # margins. If/when that changes, then the following will + # need to be updated. - set dy 0 - set y $count + set dy 0 + set y $count - while {$y < $_rows} { - for {set x 0} {$x < $_cols} {incr x} { - set _chars($x,$dy) $_chars($x,$y) - } - incr y 1 - incr dy 1 + while {$y < $_rows} { + for {set x 0} {$x < $_cols} {incr x} { + set _chars($x,$dy) $_chars($x,$y) } - - _clear_lines $dy $_rows + incr y 1 + incr dy 1 } + + _clear_lines $dy $_rows } +} - # Pan Up - # - # https://vt100.net/docs/vt510-rm/SD.html - proc _csi_T {args} { - set count [_default [lindex $args 0] 1] +# Pan Up +# +# https://vt100.net/docs/vt510-rm/SD.html +proc Term::_csi_T {args} { + set count [_default [lindex $args 0] 1] - _log_cur "Pan Up ($count)" { - variable _cur_col - variable _cur_row - variable _cols - variable _rows - variable _chars + _log_cur "Pan Up ($count)" { + variable _cur_col + variable _cur_row + variable _cols + variable _rows + variable _chars - # The following code is written without consideration for - # the scroll margins. At this time this comment was - # written the tuiterm library doesn't support the scroll - # margins. If/when that changes, then the following will - # need to be updated. + # The following code is written without consideration for + # the scroll margins. At this time this comment was + # written the tuiterm library doesn't support the scroll + # margins. If/when that changes, then the following will + # need to be updated. - set y [expr $_rows - $count] - set dy $_rows + set y [expr $_rows - $count] + set dy $_rows - while {$dy >= $count} { - for {set x 0} {$x < $_cols} {incr x} { - set _chars($x,$dy) $_chars($x,$y) - } - incr y -1 - incr dy -1 + while {$dy >= $count} { + for {set x 0} {$x < $_cols} {incr x} { + set _chars($x,$dy) $_chars($x,$y) } - - _clear_lines 0 $count + incr y -1 + incr dy -1 } + + _clear_lines 0 $count } +} - # Erase chars. - # - # https://vt100.net/docs/vt510-rm/ECH.html - proc _csi_X {args} { - set n [_default [lindex $args 0] 1] +# Erase chars. +# +# https://vt100.net/docs/vt510-rm/ECH.html +proc Term::_csi_X {args} { + set n [_default [lindex $args 0] 1] - _log_cur "Erase chars ($n)" { - # Erase characters but don't move cursor. - variable _cur_col - variable _cur_row - variable _attrs - variable _chars + _log_cur "Erase chars ($n)" { + # Erase characters but don't move cursor. + variable _cur_col + variable _cur_row + variable _attrs + variable _chars - set lattr [array get _attrs] - set x $_cur_col - for {set i 0} {$i < $n} {incr i} { - set _chars($x,$_cur_row) [list " " $lattr] - incr x - } + set lattr [array get _attrs] + set x $_cur_col + for {set i 0} {$i < $n} {incr i} { + set _chars($x,$_cur_row) [list " " $lattr] + incr x } } +} - # Cursor Backward Tabulation. - # - # https://vt100.net/docs/vt510-rm/CBT.html - proc _csi_Z {args} { - set n [_default [lindex $args 0] 1] +# Cursor Backward Tabulation. +# +# https://vt100.net/docs/vt510-rm/CBT.html +proc Term::_csi_Z {args} { + set n [_default [lindex $args 0] 1] - _log_cur "Cursor Backward Tabulation ($n)" { - variable _cur_col + _log_cur "Cursor Backward Tabulation ($n)" { + variable _cur_col - set _cur_col [expr {max (int (($_cur_col - 1) / 8) * 8 - ($n - 1) * 8, 0)}] - } + set _cur_col [expr {max (int (($_cur_col - 1) / 8) * 8 - ($n - 1) * 8, 0)}] } +} - # Repeat. - # - # https://www.xfree86.org/current/ctlseqs.html (See `(REP)`) - proc _csi_b {args} { - set n [_default [lindex $args 0] 1] +# Repeat. +# +# https://www.xfree86.org/current/ctlseqs.html (See `(REP)`) +proc Term::_csi_b {args} { + set n [_default [lindex $args 0] 1] - _log_cur "Repeat ($n)" { - variable _last_char + _log_cur "Repeat ($n)" { + variable _last_char - _insert [string repeat $_last_char $n] - } + _insert [string repeat $_last_char $n] } +} - # Vertical Line Position Absolute. - # - # https://vt100.net/docs/vt510-rm/VPA.html - proc _csi_d {args} { - set row [_default [lindex $args 0] 1] +# Vertical Line Position Absolute. +# +# https://vt100.net/docs/vt510-rm/VPA.html +proc Term::_csi_d {args} { + set row [_default [lindex $args 0] 1] - _log_cur "Vertical Line Position Absolute ($row)" { - variable _cur_row - variable _rows + _log_cur "Vertical Line Position Absolute ($row)" { + variable _cur_row + variable _rows - set _cur_row [expr min ($row - 1, $_rows - 1)] - } + set _cur_row [expr min ($row - 1, $_rows - 1)] } +} - # Reset the attributes in attributes array UPVAR_NAME to the default values. - proc _reset_attrs { upvar_name } { - upvar $upvar_name var - array set var { - intensity normal - fg default - bg default - underline 0 - reverse 0 - invisible 0 - blinking 0 +# Set Mode (SM, CSI h) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +proc Term::_csi_h { args } { + foreach item $args { + switch -exact -- $item { + 4 { + # Insert Mode (IRM) + _log "ignored: insert mode" + } + default { + error unsupported + } } } +} - # Translate the color numbers as used in proc _csi_m to a name. - proc _color_attr { n } { - switch -exact -- $n { - 0 { - return black +# Reset Mode (RM, CSI l) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +proc Term::_csi_l { args } { + foreach item $args { + switch -exact -- $item { + 4 { + # Replace Mode (IRM) + _log "ignored: replace mode" + } + default { + error unsupported } + } + } +} + +# Set Scrolling Region (DECSTBM, CSI Ps ; Ps r) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +proc Term::_csi_r { top bottom } { + _log "ignored: set scrolling region" +} + +# Window manipulation (XTWINOPS, CSI Ps ; Ps ; Ps t) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +proc Term::_csi_t { arg1 arg2 arg3 } { + if { $arg1 == 22 && $arg2 == 0 && $arg3 == 0 } { + _log "ignored: Save xterm icon and window title on stack" + return + } + + if { $arg1 == 23 && $arg2 == 0 && $arg3 == 0 } { + _log "ignored: Restore xterm icon and window title from stack" + return + } + + error unsupported +} + +# DECSET (CSI ? h) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +proc Term::_csi_0x3f_h { args } { + foreach item $args { + switch -exact -- $item { 1 { - return red + _log "ignored: Application Cursor Keys" } - 2 { - return green + 7 { + _log "ignored: autowrap mode" } - 3 { - return yellow + 1000 { + _log "ignored: Send Mouse X & Y on button press and release" } - 4 { - return blue + 1006 { + _log "ignored: Enable SGR Mouse Mode" } - 5 { - return magenta + 1049 { + _log "switch to alternate screen" + _set_alternate 1 } - 6 { - return cyan + default { + error unsupported + } + } + } +} + +# DECRST (CSI ? l) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +proc Term::_csi_0x3f_l { args } { + foreach item $args { + switch -exact -- $item { + 1 { + _log "ignored: Normal Cursor Keys" } 7 { - return white + _log "ignored: no autowrap mode" + } + 1000 { + _log "ignored: Don't send Mouse X & Y on button press and release" + } + 1006 { + _log "ignored: Disable SGR Mouse Mode" + } + 1049 { + _log "switch from alternate screen" + _set_alternate 0 + } + default { + error "unsupported" } - default { error "unsupported color number: $n" } } } +} - # Select Graphic Rendition. - # - # https://vt100.net/docs/vt510-rm/SGR.html - proc _csi_m {args} { - _log_cur "Select Graphic Rendition ([join $args {, }])" { - variable _attrs +# Reset the attributes in attributes array UPVAR_NAME to the default values. +proc Term::_reset_attrs { upvar_name } { + upvar $upvar_name var + array set var { + intensity normal + fg default + bg default + underline 0 + reverse 0 + invisible 0 + blinking 0 + } +} - foreach item $args { - switch -exact -- $item { - "" - 0 { - _reset_attrs _attrs - } - 1 { - set _attrs(intensity) bold - } - 2 { - set _attrs(intensity) dim - } - 4 { - set _attrs(underline) 1 - } - 5 { - set _attrs(blinking) 1 - } - 7 { - set _attrs(reverse) 1 - } - 8 { - set _attrs(invisible) 1 - } - 22 { - set _attrs(intensity) normal - } - 24 { - set _attrs(underline) 0 - } - 25 { - set _attrs(blinking) 0 - } - 27 { - set _attrs(reverse) 0 - } - 28 { - set _attrs(invisible) 0 - } - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 { - set _attrs(fg) [_color_attr [expr $item - 30]] - } - 39 { - set _attrs(fg) default - } - 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 { - set _attrs(bg) [_color_attr [expr $item - 40]] - } - 49 { - set _attrs(bg) default - } +# Translate the color numbers as used in proc _csi_m to a name. +proc Term::_color_attr { n } { + switch -exact -- $n { + 0 { + return black + } + 1 { + return red + } + 2 { + return green + } + 3 { + return yellow + } + 4 { + return blue + } + 5 { + return magenta + } + 6 { + return cyan + } + 7 { + return white + } + default { error "unsupported color number: $n" } + } +} + +# Select Graphic Rendition. +# +# https://vt100.net/docs/vt510-rm/SGR.html +proc Term::_csi_m {args} { + if { [llength $args] == 0 } { + # Apply default. + set args [list 0] + } + + _log_cur "Select Graphic Rendition ([join $args {, }])" { + variable _attrs + + foreach item $args { + switch -exact -- $item { + "" - 0 { + _reset_attrs _attrs + } + 1 { + set _attrs(intensity) bold + } + 2 { + set _attrs(intensity) dim + } + 4 { + set _attrs(underline) 1 + } + 5 { + set _attrs(blinking) 1 + } + 7 { + set _attrs(reverse) 1 + } + 8 { + set _attrs(invisible) 1 + } + 22 { + set _attrs(intensity) normal + } + 24 { + set _attrs(underline) 0 + } + 25 { + set _attrs(blinking) 0 + } + 27 { + set _attrs(reverse) 0 + } + 28 { + set _attrs(invisible) 0 + } + 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 { + set _attrs(fg) [_color_attr [expr $item - 30]] + } + 39 { + set _attrs(fg) default + } + 40 - 41 - 42 - 43 - 44 - 45 - 46 - 47 { + set _attrs(bg) [_color_attr [expr $item - 40]] + } + 49 { + set _attrs(bg) default } } } } +} - # Insert string at the cursor location. - proc _insert {str} { - _log_cur "Inserted string '$str'" { - _log "Inserting string '$str'" - - variable _cur_col - variable _cur_row - variable _rows - variable _cols - variable _attrs - variable _chars - set lattr [array get _attrs] - foreach char [split $str {}] { - _log_cur " Inserted char '$char'" { - set _chars($_cur_col,$_cur_row) [list $char $lattr] - incr _cur_col - if {$_cur_col >= $_cols} { - set _cur_col 0 - incr _cur_row - if {$_cur_row >= $_rows} { - error "FIXME scroll" - } +# Request Terminal Parameters (DECREQTPARM) +# +# https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +# https://vt100.net/docs/vt100-ug/chapter3.html +proc Term::_csi_x {} { + # Ignore. +} + +# Insert string at the cursor location. +proc Term::_insert {str} { + _log_cur "Inserted string '$str'" { + _log "Inserting string '$str'" + + variable _cur_col + variable _cur_row + variable _rows + variable _cols + variable _attrs + variable _chars + set lattr [array get _attrs] + foreach char [split $str {}] { + _log_cur " Inserted char '$char'" { + set _chars($_cur_col,$_cur_row) [list $char $lattr] + incr _cur_col + if {$_cur_col >= $_cols} { + set _cur_col 0 + incr _cur_row + if {$_cur_row >= $_rows} { + error "FIXME scroll" } } } } + + variable _last_char + set _last_char [string index $str end] } +} - # Move the cursor to the (0-based) COL and ROW positions. - proc _move_cursor { col row } { - variable _cols - variable _rows - variable _cur_col - variable _cur_row +# Move the cursor to the (0-based) COL and ROW positions. +proc Term::_move_cursor { col row } { + variable _cols + variable _rows + variable _cur_col + variable _cur_row - if { $col < 0 || $col >= $_cols } { - error "_move_cursor: invalid col value: $col" - } + if { $col < 0 || $col >= $_cols } { + error "_move_cursor: invalid col value: $col" + } + + if { $row < 0 || $row >= $_rows } { + error "_move_cursor: invalid row value: $row" + } - if { $row < 0 || $row >= $_rows } { - error "_move_cursor: invalid row value: $row" - } + set _cur_col $col + set _cur_row $row +} - set _cur_col $col - set _cur_row $row +# Enable or disable alternate screen. +proc Term::_set_alternate { enable } { + variable _alternate + if { $enable == $_alternate } { + return } + set _alternate $enable - # Initialize. - proc _setup {rows cols} { - global stty_init - set stty_init "rows $rows columns $cols" + variable _attrs + variable _chars + variable _cur_col + variable _cur_row - variable _rows - variable _cols - variable _cur_col - variable _cur_row - variable _attrs - variable _resize_count + variable _save_attrs + variable _save_chars + variable _save_cur_col + variable _save_cur_row - set _rows $rows - set _cols $cols - set _cur_col 0 - set _cur_row 0 - set _resize_count 0 - _reset_attrs _attrs - - _clear_lines 0 $_rows - } - - # Accept some output from gdb and update the screen. - # Return 1 if successful, or 0 if a timeout occurred. - proc accept_gdb_output { } { - global expect_out - gdb_expect { - -re "^\[\x07\x08\x0a\x0d\]" { - scan $expect_out(0,string) %c val - set hexval [format "%02x" $val] - _log "wait_for: _ctl_0x${hexval}" - _ctl_0x${hexval} - } - -re "^\x1b(\[0-9a-zA-Z\])" { - _log "wait_for: unsupported escape" - error "unsupported escape" - } - -re "^\x1b\\\[(\[0-9;\]*)(\[a-zA-Z@\])" { - set cmd $expect_out(2,string) - set params [split $expect_out(1,string) ";"] - _log "wait_for: _csi_$cmd <<<$expect_out(1,string)>>>" - eval _csi_$cmd $params - } - -re "^\[^\x07\x08\x0a\x0d\x1b\]+" { - _insert $expect_out(0,string) - variable _last_char - set _last_char [string index $expect_out(0,string) end] - } + variable _alternate_setup - timeout { - # Assume a timeout means we somehow missed the - # expected result, and carry on. - warning "timeout in accept_gdb_output" - dump_screen - return 0 - } - } + if { $_alternate_setup } { + set tmp $_save_chars + } + set _save_chars [array get _chars] + if { $_alternate_setup } { + array set _chars $tmp + } - return 1 + if { $_alternate_setup } { + set tmp $_save_attrs + } + set _save_attrs [array get _attrs] + if { $_alternate_setup } { + array set _attrs $tmp } - # Print arg using "verbose -log" if DEBUG_TUI_MATCHING == 1. - proc debug_tui_matching { arg } { - set debug 0 - if { [info exists ::DEBUG_TUI_MATCHING] } { - set debug $::DEBUG_TUI_MATCHING - } + if { $_alternate_setup } { + set tmp $_save_cur_col + } + set _save_cur_col $_cur_col + if { $_alternate_setup } { + set _cur_col $tmp + } - if { ! $debug } { - return - } + if { $_alternate_setup } { + set tmp $_save_cur_row + } + set _save_cur_row $_cur_row + if { $_alternate_setup } { + set _cur_row $tmp + } - verbose -log "$arg" + if { ! $_alternate_setup } { + variable _rows + variable _cols + _setup $_rows $_cols + set _alternate_setup 1 } +} - # Accept some output from gdb and update the screen. WAIT_FOR is - # a regexp matching the line to wait for. Return 0 on timeout, 1 - # on success. - proc wait_for {wait_for} { - global gdb_prompt - variable _cur_col - variable _cur_row +# Initialize. +proc Term::_setup {rows cols} { + global stty_init + set stty_init "rows $rows columns $cols" + + variable _rows + variable _cols + variable _cur_col + variable _cur_row + variable _attrs + variable _resize_count + + set _rows $rows + set _cols $cols + set _cur_col 0 + set _cur_row 0 + set _resize_count 0 + _reset_attrs _attrs - set fn "wait_for" + _clear_lines 0 $_rows +} - set prompt_wait_for "(^|\\|)$gdb_prompt \$" - if { $wait_for == "" } { - set wait_for $prompt_wait_for +# Accept some output from gdb and update the screen. +# Return 1 if successful, or 0 if a timeout occurred. +proc Term::accept_gdb_output { {warn 1} } { + global expect_out + + set ctls "\x07\x08\x0a\x0d" + set esc "\x1b" + set re_ctls "\[$ctls\]" + set re_others "\[^$esc$ctls\]" + set have_esc 0 + gdb_expect { + -re ^$re_ctls { + scan $expect_out(0,string) %c val + set hexval [format "%02x" $val] + _log "wait_for: _ctl_0x${hexval}" + _ctl_0x${hexval} + } + -re "^$esc" { + _log "wait_for: ESC" + set have_esc 1 + } + -re "^$re_others+" { + _insert $expect_out(0,string) + } + + timeout { + # Assume a timeout means we somehow missed the + # expected result, and carry on. + warning "timeout in accept_gdb_output" + dump_screen + return 0 } + } - debug_tui_matching "$fn: regexp: '$wait_for'" + if { !$have_esc } { + return 1 + } - while 1 { - if { [accept_gdb_output] == 0 } { - return 0 - } + set re_csi [string_to_regexp "\["] + set have_csi 0 + gdb_expect { + -re "^(\[0-9a-zA-Z\])" { + _log "wait_for: unsupported escape" + error "unsupported escape" + } + -re "^(\[\\(\])(\[a-zA-Z\])" { + scan $expect_out(1,string) %c val + set hexval [format "%02x" $val] + set cmd $expect_out(2,string) + _esc_0x${hexval}_$cmd + } + -re "^(\[=>\])" { + scan $expect_out(1,string) %c val + set hexval [format "%02x" $val] + _esc_0x$hexval + } + -re "^$re_csi" { + _log "wait_for: CSI" + set have_csi 1 + } - # If the cursor appears just after the prompt, return. It - # isn't reliable to check this only after an insertion, - # because curses may make "unusual" redrawing decisions. - if {$wait_for == "$prompt_wait_for"} { - set prev [get_line $_cur_row $_cur_col] - } else { - set prev [get_line $_cur_row] - } - if {[regexp -- $wait_for $prev]} { - debug_tui_matching "$fn: match: '$prev'" - if {$wait_for == "$prompt_wait_for"} { - break - } - set wait_for $prompt_wait_for - debug_tui_matching "$fn: regexp prompt: '$wait_for'" - } else { - debug_tui_matching "$fn: mismatch: '$prev'" + timeout { + # Assume a timeout means we somehow missed the + # expected result, and carry on. + if { $warn } { + warning "timeout in accept_gdb_output following ESC" + dump_screen } + _insert "^\[" + return 0 } + } + if { !$have_csi } { return 1 } - # Accept some output from gdb and update the screen. Wait for the screen - # region X/Y/WIDTH/HEIGTH to matches REGEXP. Return 0 on timeout, 1 on - # success. - proc wait_for_region_contents {x y width height regexp} { - while 1 { - if { [accept_gdb_output] == 0 } { - return 0 - } - - if { [check_region_contents_p $x $y $width $height $regexp] } { - break + set re_csi_prefix {[?]} + set re_csi_args {[0-9;]} + set re_csi_cmd {[a-zA-Z@`]} + gdb_expect { + -re "^($re_csi_cmd)" { + set cmd $expect_out(1,string) + _log "wait_for: _csi_$cmd" + _csi_$cmd + } + -re "^($re_csi_args*)($re_csi_cmd)" { + set params [split $expect_out(1,string) ";"] + set cmd $expect_out(2,string) + _log "wait_for: _csi_$cmd <<<$params>>>" + _csi_$cmd {*}$params + } + -re "^($re_csi_prefix?)($re_csi_args*)($re_csi_cmd)" { + set prefix $expect_out(1,string) + set params [split $expect_out(2,string) ";"] + set cmd $expect_out(3,string) + scan $prefix %c val + set hexval [format "%02x" $val] + _log "wait_for: _csi_0x${hexval}_$cmd <<<$expect_out(1,string)>>>" + _csi_0x${hexval}_$cmd {*}$params + } + + timeout { + # Assume a timeout means we somehow missed the + # expected result, and carry on. + if { $warn } { + warning "timeout in accept_gdb_output following CSI" + dump_screen } + _insert "^\[\[" + return 0 } + } - return 1 + return 1 +} + +# Print arg using "verbose -log" if DEBUG_TUI_MATCHING == 1. +proc Term::debug_tui_matching { arg } { + set debug 0 + if { [info exists ::DEBUG_TUI_MATCHING] } { + set debug $::DEBUG_TUI_MATCHING } - # Setup the terminal with dimensions ROWSxCOLS, TERM=ansi, and execute - # BODY. - proc with_tuiterm {rows cols body} { - global env stty_init - save_vars {env(TERM) env(NO_COLOR) stty_init} { - setenv TERM ansi - setenv NO_COLOR "" - _setup $rows $cols + if { ! $debug } { + return + } - uplevel $body - } + verbose -log "$arg" +} + +# Accept some output from gdb and update the screen. WAIT_FOR is +# a regexp matching the line to wait for. Return 0 on timeout, 1 +# on success. +proc Term::wait_for {wait_for} { + global gdb_prompt + variable _cur_col + variable _cur_row + + set fn "wait_for" + + set prompt_wait_for "(^|\\|)$gdb_prompt \$" + if { $wait_for == "" } { + set wait_for $prompt_wait_for } - # Like ::clean_restart, but ensures that gdb starts in an - # environment where the TUI can work. ROWS and COLS are the size - # of the terminal. EXECUTABLE, if given, is passed to - # clean_restart. - proc clean_restart {rows cols {executable {}}} { - with_tuiterm $rows $cols { - save_vars { ::GDBFLAGS } { - # Make GDB not print the directory names. Use this setting to - # remove the differences in test runs due to varying directory - # names. - append ::GDBFLAGS " -ex \"set filename-display basename\"" + debug_tui_matching "$fn: regexp: '$wait_for'" - if {$executable == ""} { - ::clean_restart - } else { - ::clean_restart $executable - } - } + while 1 { + if { [accept_gdb_output] == 0 } { + return 0 + } - ::gdb_test_no_output "set pagination off" + # If the cursor appears just after the prompt, return. It + # isn't reliable to check this only after an insertion, + # because curses may make "unusual" redrawing decisions. + if {$wait_for == "$prompt_wait_for"} { + set prev [get_line $_cur_row $_cur_col] + } else { + set prev [get_line $_cur_row] } - } - # Generate prompt on TUIterm. - proc gen_prompt {} { - # Generate a prompt. - send_gdb "echo\n" + if { ![regexp -- $wait_for $prev] } { + debug_tui_matching "$fn: mismatch: '$prev'" + continue + } - # Drain the output before the prompt. - gdb_expect { - -re "echo\r\n" { + if {$wait_for == "$prompt_wait_for"} { + # We've detected that the cursor is just after the prompt. + # Now check that there's nothing else on the line. + set prev [get_line $_cur_row] + if { ![regexp -- "(^|\\|)$gdb_prompt +($|\\||\\+)" $prev] } { + debug_tui_matching "$fn: mismatch: '$prev'" + continue } } - # Interpret prompt using TUIterm. - wait_for "" - } + debug_tui_matching "$fn: match: '$prev'" - # Setup ready for starting the tui, but don't actually start it. - # Returns 1 on success, 0 if TUI tests should be skipped. - proc prepare_for_tui {} { - if { [is_remote host] } { - # In clean_restart, we're using "setenv TERM ansi", which has - # effect on build. If we have [is_remote host] == 0, so - # build == host, then it also has effect on host. But for - # [is_remote host] == 1, it has no effect on host. - return 0 + if {$wait_for == "$prompt_wait_for"} { + # Matched the prompt, we're done. + break } - if {![allow_tui_tests]} { + # Now try to match the prompt. + set wait_for $prompt_wait_for + debug_tui_matching "$fn: regexp prompt: '$wait_for'" + } + + return 1 +} + +# Accept some output from gdb and update the screen. Wait for the screen +# region X/Y/WIDTH/HEIGTH to matches REGEXP. Return 0 on timeout, 1 on +# success. +proc Term::wait_for_region_contents {x y width height regexp} { + while 1 { + if { [accept_gdb_output] == 0 } { return 0 } - gdb_test_no_output "set tui border-kind ascii" - gdb_test_no_output "maint set tui-resize-message on" - return 1 + if { [check_region_contents_p $x $y $width $height $regexp] } { + break + } } - # Start the TUI. Returns 1 on success, 0 if TUI tests should be - # skipped. - proc enter_tui {} { - if {![prepare_for_tui]} { + return 1 +} + +# Accept some output from gdb and update the screen. Wait for the current +# screen line to match REGEXP and cursor position POS, unless POS is empty. +# Return 0 on timeout, 1 on success. +proc Term::wait_for_line { regexp {pos ""} } { + variable _cur_row + variable _cur_col + variable _cols + + while 1 { + if { [accept_gdb_output] == 0 } { return 0 } - command_no_prompt_prefix "tui enable" - return 1 - } + if { ![check_region_contents_p 0 $_cur_row $_cols 1 $regexp] } { + continue + } - # Send the command CMD to gdb, then wait for a gdb prompt to be - # seen in the TUI. CMD should not end with a newline -- that will - # be supplied by this function. - proc command {cmd} { - global gdb_prompt - send_gdb "$cmd\n" - set str [string_to_regexp $cmd] - set str "(^|\\|)$gdb_prompt $str" - wait_for $str - } - - # As proc command, but don't wait for an initial prompt. This is used for - # initial terminal commands, where there's no prompt yet. - proc command_no_prompt_prefix {cmd} { - gen_prompt - command $cmd - } - - # Apply the attribute list in ATTRS to attributes array UPVAR_NAME. - # Return a string annotating the changed attributes. - proc apply_attrs { upvar_name attrs } { - set res "" - upvar $upvar_name var - foreach { attr val } $attrs { - if { $var($attr) != $val } { - append res "<$attr:$val>" - set var($attr) $val - } + if { $pos == "" || $_cur_col == $pos } { + break } + } - return $res + return 1 +} + +# In BODY, when using Term::with_tuiterm, use TERM instead of the default. + +proc Term::with_term { term body } { + save_vars { Term::_TERM } { + set Term::_TERM $term + uplevel $body } +} - # Return the text of screen line N. Lines are 0-based. If C is given, - # stop before column C. Columns are also zero-based. If ATTRS, annotate - # with attributes. - proc get_line_1 {n c attrs} { - variable _rows - # This can happen during resizing, if the cursor seems to - # temporarily be off-screen. - if {$n >= $_rows} { - return "" +# Setup the terminal with dimensions ROWSxCOLS, TERM=ansi, and execute +# BODY. +proc Term::with_tuiterm {rows cols body} { + global env stty_init + variable _TERM + save_vars {env(TERM) env(NO_COLOR) stty_init} { + if { $Term::_TERM != "" } { + setenv TERM $Term::_TERM + } elseif { [ishost *-*-*bsd*] } { + setenv TERM ansiw + } else { + setenv TERM ansi } + # Save active TERM variable. + set Term::_TERM $env(TERM) - set result "" - variable _cols - variable _chars - set c [_default $c $_cols] - set x 0 - if { $attrs } { - _reset_attrs line_attrs - } - while {$x < $c} { - if { $attrs } { - set char_attrs [lindex $_chars($x,$n) 1] - append result [apply_attrs line_attrs $char_attrs] + setenv NO_COLOR "" + _setup $rows $cols + + uplevel $body + } +} + +# Like ::clean_restart, but ensures that gdb starts in an +# environment where the TUI can work. ROWS and COLS are the size +# of the terminal. EXECUTABLE, if given, is passed to +# clean_restart. +proc Term::clean_restart {rows cols {executable {}}} { + with_tuiterm $rows $cols { + save_vars { ::GDBFLAGS } { + # Make GDB not print the directory names. Use this setting to + # remove the differences in test runs due to varying directory + # names. + append ::GDBFLAGS " -ex \"set filename-display basename\"" + + if {$executable == ""} { + ::clean_restart + } else { + ::clean_restart $executable } - append result [lindex $_chars($x,$n) 0] - incr x } - if { $attrs } { - _reset_attrs zero_attrs - set char_attrs [array get zero_attrs] - append result [apply_attrs line_attrs $char_attrs] + + ::gdb_test_no_output "set pagination off" + } +} + +# Generate prompt on TUIterm. +proc Term::gen_prompt {} { + # Generate a prompt. + send_gdb "echo\n" + + # Drain the output before the prompt. + gdb_expect { + -re "echo\r\n" { } - return $result } - # Return the text of screen line N, without attributes. Lines are - # 0-based. If C is given, stop before column C. Columns are also - # zero-based. - proc get_line {n {c ""} } { - return [get_line_1 $n $c 0] + # Interpret prompt using TUIterm. + wait_for "" +} + +# Setup ready for starting the tui, but don't actually start it. +# Returns 1 on success, 0 if TUI tests should be skipped. +proc Term::prepare_for_tui {} { + if { [is_remote host] } { + # In clean_restart, we're using "setenv TERM ansi", which has + # effect on build. If we have [is_remote host] == 0, so + # build == host, then it also has effect on host. But for + # [is_remote host] == 1, it has no effect on host. + return 0 } - # As get_line, but annotate with attributes. - proc get_line_with_attrs {n {c ""}} { - return [get_line_1 $n $c 1] + if {![allow_tui_tests]} { + return 0 } - # Get just the character at (X, Y). - proc get_char {x y} { - variable _chars - return [lindex $_chars($x,$y) 0] + gdb_test_no_output "set tui border-kind ascii" + gdb_test_no_output "maint set tui-resize-message on" + # When matching GDB output using Term::wait_for, the number of + # matching attempts in wait_for can be influenced by CLI styling. + # Disable it by default to avoid this. + gdb_test_no_output "set style enabled off" + return 1 +} + +# Start the TUI. Returns 1 on success, 0 if TUI tests should be +# skipped. +proc Term::enter_tui {} { + if {![prepare_for_tui]} { + return 0 } - # Get the entire screen as a string. - proc get_all_lines {} { - variable _rows - variable _cols - variable _chars + command_no_prompt_prefix "tui enable" + return 1 +} - set result "" - for {set y 0} {$y < $_rows} {incr y} { - for {set x 0} {$x < $_cols} {incr x} { - append result [lindex $_chars($x,$y) 0] - } - append result "\n" +# Send the command CMD to gdb, then wait for a gdb prompt to be +# seen in the TUI. CMD should not end with a newline -- that will +# be supplied by this function. +proc Term::command {cmd} { + global gdb_prompt + send_gdb "$cmd\n" + set str [string_to_regexp $cmd] + set str "(^|\\|)$gdb_prompt $str" + wait_for $str +} + +# As proc command, but don't wait for an initial prompt. This is used for +# initial terminal commands, where there's no prompt yet. +proc Term::command_no_prompt_prefix {cmd} { + gen_prompt + command $cmd +} + +# Apply the attribute list in ATTRS to attributes array UPVAR_NAME. +# Return a string annotating the changed attributes. +proc Term::apply_attrs { upvar_name attrs } { + set res "" + upvar $upvar_name var + foreach { attr val } $attrs { + if { $var($attr) != $val } { + append res "<$attr:$val>" + set var($attr) $val } + } - return $result + return $res +} + +# Return the text of screen line N. Lines are 0-based. Start at column +# X. If C is non-empty, stop before column C. Columns are also +# zero-based. If ATTRS, annotate with attributes. +proc Term::get_string {n x c {attrs 0}} { + variable _rows + # This can happen during resizing, if the cursor seems to + # temporarily be off-screen. + if {$n >= $_rows} { + return "" } - # Get the text just before the cursor. - proc get_current_line {} { - variable _cur_col - variable _cur_row - return [get_line $_cur_row $_cur_col] + set result "" + variable _cols + variable _chars + set c [_default $c $_cols] + if { $attrs } { + _reset_attrs line_attrs } + while {$x < $c} { + if { $attrs } { + set char_attrs [lindex $_chars($x,$n) 1] + append result [apply_attrs line_attrs $char_attrs] + } + append result [lindex $_chars($x,$n) 0] + incr x + } + if { $attrs } { + _reset_attrs zero_attrs + set char_attrs [array get zero_attrs] + append result [apply_attrs line_attrs $char_attrs] + } + return $result +} - # Helper function for check_box. Returns empty string if the box - # is found, description of why not otherwise. - proc _check_box {x y width height} { - set x2 [expr {$x + $width - 1}] - set y2 [expr {$y + $height - 1}] +# Return the text of screen line N. Lines are 0-based. Start at column +# X. If C is non-empty, stop before column C. Columns are also +# zero-based. Annotate with attributes. +proc Term::get_string_with_attrs { n x c } { + return [get_string $n $x $c 1] +} - verbose -log "_check_box x=$x, y=$y, x2=$x2, y2=$y2, width=$width, height=$height" +# Return the text of screen line N. Lines are 0-based. If C is +# non-empty, stop before column C. Columns are also zero-based. If +# ATTRS, annotate with attributes. +proc Term::get_line_1 {n c attrs} { + return [get_string $n 0 $c $attrs] +} - set c [get_char $x $y] - if {$c != "+"} { - return "ul corner is $c, not +" - } +# Return the text of screen line N, without attributes. Lines are +# 0-based. If C is given, stop before column C. Columns are also +# zero-based. +proc Term::get_line {n {c ""} } { + return [get_line_1 $n $c 0] +} - set c [get_char $x $y2] - if {$c != "+"} { - return "ll corner is $c, not +" - } +# As get_line, but annotate with attributes. +proc Term::get_line_with_attrs {n {c ""}} { + return [get_line_1 $n $c 1] +} - set c [get_char $x2 $y] - if {$c != "+"} { - return "ur corner is $c, not +" - } +# Get just the character at (X, Y). +proc Term::get_char {x y} { + variable _chars + return [lindex $_chars($x,$y) 0] +} - set c [get_char $x2 $y2] - if {$c != "+"} { - return "lr corner is $c, not +" - } +# Get the entire screen as a string. +proc Term::get_all_lines {} { + variable _rows + variable _cols + variable _chars - # Note we do not check the full horizonal borders of the box. - # The top will contain a title, and the bottom may as well, if - # it is overlapped by some other border. However, at most a - # title should appear as '+-VERY LONG TITLE-+', so we can - # check for the '+-' on the left, and '-+' on the right. - set c [get_char [expr {$x + 1}] $y] - if {$c != "-"} { - return "ul title padding is $c, not -" + set result "" + for {set y 0} {$y < $_rows} {incr y} { + for {set x 0} {$x < $_cols} {incr x} { + append result [lindex $_chars($x,$y) 0] } + append result "\n" + } - set c [get_char [expr {$x2 - 1}] $y] - if {$c != "-"} { - return "ul title padding is $c, not -" - } + return $result +} - # Now check the vertical borders. - for {set i [expr {$y + 1}]} {$i < $y2 - 1} {incr i} { - set c [get_char $x $i] - if {$c != "|"} { - return "left side $i is $c, not |" - } +# Get the text just before the cursor. +proc Term::get_current_line {} { + variable _cur_col + variable _cur_row + return [get_line $_cur_row $_cur_col] +} - set c [get_char $x2 $i] - if {$c != "|"} { - return "right side $i is $c, not |" - } - } +# Helper function for check_box. Returns empty string if the box +# is found, description of why not otherwise. +proc Term::_check_box {x y width height} { + set x2 [expr {$x + $width - 1}] + set y2 [expr {$y + $height - 1}] - return "" + verbose -log "_check_box x=$x, y=$y, x2=$x2, y2=$y2, width=$width, height=$height" + + set c [get_char $x $y] + if {$c != "+"} { + return "ul corner is $c, not +" } - # Check for a box at the given coordinates. - proc check_box {test_name x y width height} { - dump_box $x $y $width $height - set why [_check_box $x $y $width $height] - if {$why == ""} { - pass $test_name - } else { - fail "$test_name ($why)" - } + set c [get_char $x $y2] + if {$c != "+"} { + return "ll corner is $c, not +" } - # Wait until a box appears at the given coordinates. - proc wait_for_box {test_name x y width height} { - while 1 { - if { [accept_gdb_output] == 0 } { - return 0 - } + set c [get_char $x2 $y] + if {$c != "+"} { + return "ur corner is $c, not +" + } - set why [_check_box $x $y $width $height] - if {$why == ""} { - pass $test_name - break - } - } + set c [get_char $x2 $y2] + if {$c != "+"} { + return "lr corner is $c, not +" } - # Check whether the text contents of the terminal match the - # regular expression. Note that text styling is not considered. - proc check_contents {test_name regexp} { - dump_screen - set contents [get_all_lines] - gdb_assert {[regexp -- $regexp $contents]} $test_name + # Note we do not check the full horizonal borders of the box. + # The top will contain a title, and the bottom may as well, if + # it is overlapped by some other border. However, at most a + # title should appear as '+-VERY LONG TITLE-+', so we can + # check for the '+-' on the left, and '-+' on the right. + set c [get_char [expr {$x + 1}] $y] + if {$c != "-"} { + return "ul title padding is $c, not -" } - # As check_contents, but check that the text contents of the terminal does - # not match the regular expression. - proc check_contents_not {test_name regexp} { - dump_screen - set contents [get_all_lines] - gdb_assert {![regexp -- $regexp $contents]} $test_name + set c [get_char [expr {$x2 - 1}] $y] + if {$c != "-"} { + return "ul title padding is $c, not -" } - # Get the region of the screen described by X, Y, WIDTH, and - # HEIGHT, and separate the lines using SEP. If ATTRS is true then - # include attribute information in the output. - proc get_region { x y width height sep { attrs false } } { - variable _chars + # Now check the vertical borders. + for {set i [expr {$y + 1}]} {$i < $y2 - 1} {incr i} { + set c [get_char $x $i] + if {$c != "|"} { + return "left side $i is $c, not |" + } - if { $attrs } { - _reset_attrs region_attrs + set c [get_char $x2 $i] + if {$c != "|"} { + return "right side $i is $c, not |" } + } - # Grab the contents of the box, join each line together - # using $sep. - set result "" - for {set yy $y} {$yy < [expr {$y + $height}]} {incr yy} { - if {$yy > $y} { - # Add the end of line sequence only if this isn't the - # first line. - append result $sep - } - for {set xx $x} {$xx < [expr {$x + $width}]} {incr xx} { - if { $attrs } { - set char_attrs [lindex $_chars($xx,$yy) 1] - append result [apply_attrs region_attrs $char_attrs] - } + return "" +} - append result [get_char $xx $yy] - } +# Check for a box at the given coordinates. +proc Term::check_box {test_name x y width height} { + dump_box $x $y $width $height + set why [_check_box $x $y $width $height] + if {$why == ""} { + pass $test_name + } else { + fail "$test_name ($why)" + } +} + +# Wait until a box appears at the given coordinates. +proc Term::wait_for_box {test_name x y width height} { + while 1 { + if { [accept_gdb_output] == 0 } { + return 0 } - if { $attrs } { - _reset_attrs zero_attrs - set char_attrs [array get zero_attrs] - append result [apply_attrs region_attrs $char_attrs] + + set why [_check_box $x $y $width $height] + if {$why == ""} { + pass $test_name + break } - return $result } +} - # Check that the region of the screen described by X, Y, WIDTH, - # and HEIGHT match REGEXP. This is like check_contents except - # only part of the screen is checked. This can be used to check - # the contents within a box (though check_box_contents is a better - # choice for boxes with a border). Return 1 if check succeeded. - proc check_region_contents_p { x y width height regexp } { - variable _chars - dump_box $x $y $width $height +# Check whether the text contents of the terminal match the +# regular expression. Note that text styling is not considered. +proc Term::check_contents {test_name regexp} { + dump_screen + set contents [get_all_lines] + gdb_assert {[regexp -- $regexp $contents]} $test_name +} - # Now grab the contents of the box, join each line together - # with a '\r\n' sequence and match against REGEXP. - set result [get_region $x $y $width $height "\r\n"] - return [regexp -- $regexp $result] - } +# As check_contents, but check that the text contents of the terminal does +# not match the regular expression. +proc Term::check_contents_not {test_name regexp} { + dump_screen + set contents [get_all_lines] + gdb_assert {![regexp -- $regexp $contents]} $test_name +} - # Check that the region of the screen described by X, Y, WIDTH, - # and HEIGHT match REGEXP. As check_region_contents_p, but produce - # a pass/fail message. - proc check_region_contents { test_name x y width height regexp } { - set ok [check_region_contents_p $x $y $width $height $regexp] - gdb_assert {$ok} $test_name - } +# Get the region of the screen described by X, Y, WIDTH, and +# HEIGHT, and separate the lines using SEP. If ATTRS is true then +# include attribute information in the output. +proc Term::get_region { x y width height sep { attrs false } } { + variable _chars - # Check the contents of a box on the screen. This is a little - # like check_contents, but doesn't check the whole screen - # contents, only the contents of a single box. This procedure - # includes (effectively) a call to check_box to ensure there is a - # box where expected, if there is then the contents of the box are - # matched against REGEXP. - proc check_box_contents {test_name x y width height regexp} { - variable _chars + if { $attrs } { + _reset_attrs region_attrs + } - dump_box $x $y $width $height - set why [_check_box $x $y $width $height] - if {$why != ""} { - fail "$test_name (box check: $why)" - return + # Grab the contents of the box, join each line together + # using $sep. + set result "" + for {set yy $y} {$yy < $y + $height} {incr yy} { + if {$yy > $y} { + # Add the end of line sequence only if this isn't the + # first line. + append result $sep } + for {set xx $x} {$xx < $x + $width} {incr xx} { + if { $attrs } { + set char_attrs [lindex $_chars($xx,$yy) 1] + append result [apply_attrs region_attrs $char_attrs] + } - check_region_contents $test_name [expr {$x + 1}] [expr {$y + 1}] \ - [expr {$width - 2}] [expr {$height - 2}] $regexp + append result [get_char $xx $yy] + } + } + if { $attrs } { + _reset_attrs zero_attrs + set char_attrs [array get zero_attrs] + append result [apply_attrs region_attrs $char_attrs] } + return $result +} - # A debugging function to dump the current screen, with line - # numbers. If ATTRS, annotate with attributes. - proc dump_screen { {attrs 0} } { - variable _rows - variable _cols - variable _cur_row - variable _cur_col +# Check that the region of the screen described by X, Y, WIDTH, +# and HEIGHT match REGEXP. This is like check_contents except +# only part of the screen is checked. This can be used to check +# the contents within a box (though check_box_contents is a better +# choice for boxes with a border). Return 1 if check succeeded. +proc Term::check_region_contents_p { x y width height regexp } { + variable _chars + dump_box $x $y $width $height - verbose -log "Screen Dump (size $_cols columns x $_rows rows, cursor at column $_cur_col, row $_cur_row):" + # Now grab the contents of the box, join each line together + # with a '\r\n' sequence and match against REGEXP. + set result [get_region $x $y $width $height "\r\n"] + return [regexp -- $regexp $result] +} - for {set y 0} {$y < $_rows} {incr y} { - set fmt [format %5d $y] - verbose -log "$fmt [get_line_1 $y "" $attrs]" - } +# Check that the region of the screen described by X, Y, WIDTH, +# and HEIGHT match REGEXP. As check_region_contents_p, but produce +# a pass/fail message. +proc Term::check_region_contents { test_name x y width height regexp } { + set ok [check_region_contents_p $x $y $width $height $regexp] + gdb_assert {$ok} $test_name +} + +# Check the contents of a box on the screen. This is a little +# like check_contents, but doesn't check the whole screen +# contents, only the contents of a single box. This procedure +# includes (effectively) a call to check_box to ensure there is a +# box where expected, if there is then the contents of the box are +# matched against REGEXP. +proc Term::check_box_contents {test_name x y width height regexp} { + variable _chars + + dump_box $x $y $width $height + set why [_check_box $x $y $width $height] + if {$why != ""} { + fail "$test_name (box check: $why)" + return } - # As dump_screen, but with attributes annotation. - proc dump_screen_with_attrs {} { - return [dump_screen 1] + check_region_contents $test_name [expr {$x + 1}] [expr {$y + 1}] \ + [expr {$width - 2}] [expr {$height - 2}] $regexp +} + +# A debugging function to dump the current screen, with line +# numbers. If ATTRS, annotate with attributes. +proc Term::dump_screen { {attrs 0} } { + variable _rows + variable _cols + variable _cur_row + variable _cur_col + + verbose -log "Screen Dump (size $_cols columns x $_rows rows, cursor at column $_cur_col, row $_cur_row):" + + for {set y 0} {$y < $_rows} {incr y} { + set fmt [format %5d $y] + verbose -log "$fmt [get_line_1 $y {} $attrs]" } +} - # A debugging function to dump a box from the current screen, with line - # numbers. - proc dump_box { x y width height } { - verbose -log "Box Dump ($width x $height) @ ($x, $y):" - set region [get_region $x $y $width $height "\n"] - set lines [split $region "\n"] - set nr $y - foreach line $lines { - set fmt [format %5d $nr] - verbose -log "$fmt $line" - incr nr - } +# As dump_screen, but with attributes annotation. +proc Term::dump_screen_with_attrs {} { + return [dump_screen 1] +} + +# A debugging function to dump a box from the current screen, with line +# numbers. +proc Term::dump_box { x y width height } { + verbose -log "Box Dump ($width x $height) @ ($x, $y):" + set region [get_region $x $y $width $height "\n"] + set lines [split $region "\n"] + set nr $y + foreach line $lines { + set fmt [format %5d $nr] + verbose -log "$fmt $line" + incr nr } +} - # Resize the terminal. - proc _do_resize {rows cols} { - variable _chars - variable _rows - variable _cols +# Resize the terminal. +proc Term::_do_resize {rows cols} { + variable _chars + variable _rows + variable _cols - set old_rows [expr {min ($_rows, $rows)}] - set old_cols [expr {min ($_cols, $cols)}] + set old_rows [expr {min ($_rows, $rows)}] + set old_cols [expr {min ($_cols, $cols)}] - # Copy locally. - array set local_chars [array get _chars] - unset _chars + # Copy locally. + array set local_chars [array get _chars] + unset _chars - set _rows $rows - set _cols $cols - _clear_lines 0 $_rows + set _rows $rows + set _cols $cols + _clear_lines 0 $_rows - for {set x 0} {$x < $old_cols} {incr x} { - for {set y 0} {$y < $old_rows} {incr y} { - set _chars($x,$y) $local_chars($x,$y) - } + for {set x 0} {$x < $old_cols} {incr x} { + for {set y 0} {$y < $old_rows} {incr y} { + set _chars($x,$y) $local_chars($x,$y) } } +} - proc resize {rows cols {wait_for_msg 1}} { - variable _rows - variable _cols - variable _resize_count +proc Term::resize {rows cols {wait_for_msg 1}} { + variable _rows + variable _cols + variable _resize_count - # expect handles each argument to stty separately. This means - # that gdb will see SIGWINCH twice. Rather than rely on this - # behavior (which, after all, could be changed), we make it - # explicit here. This also simplifies waiting for the redraw. - _do_resize $rows $_cols - stty rows $_rows < $::gdb_tty_name - if { $wait_for_msg } { - wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}" - } - incr _resize_count - _do_resize $_rows $cols - stty columns $_cols < $::gdb_tty_name - if { $wait_for_msg } { - wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}" - } - incr _resize_count - } + # expect handles each argument to stty separately. This means + # that gdb will see SIGWINCH twice. Rather than rely on this + # behavior (which, after all, could be changed), we make it + # explicit here. This also simplifies waiting for the redraw. + _do_resize $rows $_cols + stty rows $_rows < $::gdb_tty_name + if { $wait_for_msg } { + wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}" + } + incr _resize_count + _do_resize $_rows $cols + stty columns $_cols < $::gdb_tty_name + if { $wait_for_msg } { + wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}" + } + incr _resize_count } diff --git a/gdb/testsuite/make-check-all.sh b/gdb/testsuite/make-check-all.sh index c2fbadb..ab72574 100755 --- a/gdb/testsuite/make-check-all.sh +++ b/gdb/testsuite/make-check-all.sh @@ -192,7 +192,7 @@ do_tests () # Run make check. make $maketarget \ - RUNTESTFLAGS="${rtf[*]} ${tests[*]}" \ + RUNTESTFLAGS="${rtf[*]}" TESTS="${tests[*]}" \ 2>&1 \ | summary @@ -216,7 +216,7 @@ do_tests () cp gdb.sum gdb.log "$dir" # Record the 'make check' command to enable easy re-running. - echo "make $maketarget RUNTESTFLAGS=\"${rtf[*]} ${tests[*]}\"" \ + echo "make $maketarget RUNTESTFLAGS=\"${rtf[*]}\" TESTS=\"${tests[*]}\"" \ > "$dir/make-check.sh" fi } |