aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/gdb.base/gstack.exp6
-rw-r--r--gdb/testsuite/gdb.base/shlib-unload.exp69
-rw-r--r--gdb/testsuite/gdb.mi/mi-dprintf-modified-lib.c22
-rw-r--r--gdb/testsuite/gdb.mi/mi-dprintf-modified.c55
-rw-r--r--gdb/testsuite/gdb.mi/mi-dprintf-modified.exp119
-rw-r--r--gdb/testsuite/lib/ada.exp10
-rw-r--r--gdb/testsuite/lib/gdb.exp15
7 files changed, 285 insertions, 11 deletions
diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp
index 8df36b1..89be676 100644
--- a/gdb/testsuite/gdb.base/gstack.exp
+++ b/gdb/testsuite/gdb.base/gstack.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2024 Free Software Foundation, Inc.
+# Copyright (C) 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
@@ -62,8 +62,10 @@ if { ![gdb_assert { ![expr {$res < 0 || $res == ""}] } $test] } {
set test "got backtrace"
set saw_backtrace false
set no_awk false
+set location_re ${srcfile}:${decimal}
+
gdb_expect {
- -i "$res" -re "#0 +(0x\[0-9a-f\]+ in )?main \(\).*\r\nGSTACK-END\r\n\$" {
+ -i "$res" -re "#0 +(0x\[0-9a-f\]+ in )?main \(\).*$location_re.*\r\nGSTACK-END\r\n\$" {
set saw_backtrace true
pass $test
exp_continue
diff --git a/gdb/testsuite/gdb.base/shlib-unload.exp b/gdb/testsuite/gdb.base/shlib-unload.exp
index f3e8cce..9d47416 100644
--- a/gdb/testsuite/gdb.base/shlib-unload.exp
+++ b/gdb/testsuite/gdb.base/shlib-unload.exp
@@ -225,6 +225,75 @@ proc_with_prefix test_dprintf_with_rerun {} {
"dprintf is non-pending after restart"
}
+# Check that we see breakpoint modified events (where appropriate)
+# when the 'nosharedlibrary' command is used to unload all shared
+# libraries.
+#
+# Also check that the 'nosharedlibrary' doesn't trigger a warning
+# about shared library breakpoints being disabled.
+proc_with_prefix test_silent_nosharedlib {} {
+ if { ![allow_python_tests] } {
+ unsupported "python support needed"
+ return
+ }
+
+ foreach_with_prefix type { breakpoint dprintf } {
+ clean_restart $::binfile
+
+ if {![runto_main]} {
+ return
+ }
+
+ gdb_breakpoint $::srcfile:$::bp_line
+ gdb_continue_to_breakpoint "stop before dlclose"
+
+ # Setup a dprintf or breakpoint in the shared library.
+ if { $type eq "breakpoint" } {
+ gdb_test "break foo"
+ } else {
+ gdb_test "dprintf foo,\"In foo\""
+ }
+
+ # Record the number of the b/p (or dprintf) we just inserted.
+ set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*" \
+ "get b/p number"]
+
+ # Load Python library to track b/p modifications.
+ gdb_test_no_output "source $::pyfile" "import python scripts"
+
+ # Initialise the b/p modified hash. Currently dprintf style
+ # breakpoints are not visible from Python, so the modification
+ # count will remain unchanged in that case.
+ gdb_test_no_output "python bp_modified_counts\[$bp_num\] = 0"
+
+ # Discard symbols from all loaded shared libraries.
+ gdb_test_no_output "nosharedlibrary"
+
+ # Check that our b/p is now showing as disabled.
+ if { $type eq "breakpoint" } {
+ set re \
+ [list "$bp_num\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo"]
+ set count 1
+ } else {
+ set re \
+ [list \
+ "$bp_num\\s+dprintf\\s+keep\\s+y\\s+<PENDING>\\s+foo" \
+ "\\s+printf \"In foo\""]
+ set count 0
+ }
+
+ gdb_test "info breakpoints $bp_num" \
+ [multi_line "^Num\\s+Type\\s+Disp\\s+Enb\\s+Address\\s+What" \
+ {*}$re]
+
+ # Check we've seen the expected number of breakpoint modified
+ # events. Currently dprintf breakpoints are not visible from
+ # Python, so we will not see an event in that case.
+ gdb_test "python print(bp_modified_counts\[$bp_num\])" "^$count"
+ }
+}
+
test_bp_modified_events
test_dprintf_after_unload
test_dprintf_with_rerun
+test_silent_nosharedlib
diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-modified-lib.c b/gdb/testsuite/gdb.mi/mi-dprintf-modified-lib.c
new file mode 100644
index 0000000..70fc328
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-dprintf-modified-lib.c
@@ -0,0 +1,22 @@
+/* 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
+foo (void)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-modified.c b/gdb/testsuite/gdb.mi/mi-dprintf-modified.c
new file mode 100644
index 0000000..7a41adbac
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-dprintf-modified.c
@@ -0,0 +1,55 @@
+/* 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 <stdlib.h>
+
+#ifdef __WIN32__
+#include <windows.h>
+#define dlopen(name, mode) LoadLibrary (TEXT (name))
+#ifdef _WIN32_WCE
+# define dlsym(handle, func) GetProcAddress (handle, TEXT (func))
+#else
+# define dlsym(handle, func) GetProcAddress (handle, func)
+#endif
+#define dlclose(handle) FreeLibrary (handle)
+#else
+#include <dlfcn.h>
+#endif
+
+#include <assert.h>
+
+int
+main (void)
+{
+ int res;
+ void *handle;
+ int (*func) (void);
+ int val = 0;
+
+ handle = dlopen (SHLIB_NAME, RTLD_LAZY); /* Break here. */
+ assert (handle != NULL);
+
+ func = (int (*)(void)) dlsym (handle, "foo");
+ assert (func != NULL);
+
+ val += func ();
+
+ res = dlclose (handle);
+ assert (res == 0);
+
+ return val;
+}
diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp b/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp
new file mode 100644
index 0000000..c3e1bdf
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-dprintf-modified.exp
@@ -0,0 +1,119 @@
+# 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 doesn't emit a 'breakpoint-modified' notification for
+# dprintf breakpoints when the dprintf commands haven't changed.
+#
+# GDB use to emit a 'breakpoint-modified' dprintf breakpoints each
+# time the dprintf_breakpoint::re_set function was called as this
+# would re-cacluate the dprintf command string, even though in most
+# cases the calculated string was no different from the previous
+# value.
+#
+# Then GDB got smarter and could recognise that the string had not
+# changed, and so would skip the 'breakpoint-modified' notification.
+#
+# This test stops at a dlopen() call in the inferior and creates a
+# dprintf breakpoint. Then we 'next' over the dlopen() which triggers
+# a call to the ::re_set() functions. We check that there is no
+# 'breakpoint-modified' event emitted for the dprintf breakpoint.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+standard_testfile .c -lib.c
+
+# Build the library.
+set libname ${testfile}-lib
+set libfile [standard_output_file $libname]
+if { [build_executable "build shlib" $libfile $srcfile2 {debug shlib}] == -1} {
+ return
+}
+
+# Build the executable.
+set opts [list debug shlib_load additional_flags=-DSHLIB_NAME=\"${libname}\"]
+if { [build_executable "build exec" $binfile $srcfile $opts] == -1} {
+ return
+}
+
+# The line number of the dlopen() call.
+set bp_line [gdb_get_line_number "Break here" $srcfile]
+
+# Start the inferior.
+mi_clean_restart $binfile
+mi_runto_main
+
+# Place a breakpoint at the dlopen() line.
+mi_create_breakpoint $srcfile:$bp_line "set breakpoint at dlopen call" \
+ -disp keep -func main -file "\[^\r\n\]+/$srcfile" -line $bp_line
+
+# And run to the breakpoint.
+mi_execute_to "exec-continue" "breakpoint-hit" main "" ".*/$srcfile" \
+ $bp_line { "" "disp=\"keep\"" } "run to breakpoint"
+
+# Cleanup breakpoints.
+mi_delete_breakpoints
+
+# Setup a dprintf breakpoint.
+mi_gdb_test "-dprintf-insert --function main \"in main\"" \
+ "\\^done,bkpt={.*}" "dprintf at main"
+
+set bpnum [mi_get_valueof "/d" "\$bpnum" "INVALID" \
+ "get number for dprintf breakpoint"]
+
+# Use 'next' to step over loading the shared library.
+mi_gdb_test "220-exec-next" ".*" "next over dlopen"
+
+# Now wait for the 'stopped' notification. While we wait we should
+# see a 'library-loaded' notification for the loading of the shared
+# library.
+#
+# In older versions of GDB we would also see a 'breakpoint-modified'
+# notification for the dprintf breakpoint, but newer versions of GDB
+# are smart enough to not emit this unnecessary notification.
+set bp_re [mi_make_breakpoint -number $bpnum \
+ -type dprintf -disp keep -enabled y -func main]
+set saw_bp_modified false
+set saw_lib_load false
+set saw_stopped false
+gdb_test_multiple "" "wait for 'next' to complete" {
+ -re "^=library-loaded,id=\[^\r\n\]+\r\n" {
+ set saw_lib_load true
+ exp_continue
+ }
+
+ -re "^=breakpoint-modified,$bp_re\r\n" {
+ set saw_bp_modified true
+ exp_continue
+ }
+
+ -re "^\\*stopped,reason=\"end-stepping-range\",\[^\r\n\]+\r\n" {
+ set saw_stopped true
+ exp_continue
+ }
+
+ -re "^$mi_gdb_prompt$" {
+ gdb_assert { $saw_lib_load } \
+ "$gdb_test_name, library was loaded"
+ gdb_assert { $saw_stopped } \
+ "$gdb_test_name, saw stopped message"
+ gdb_assert { !$saw_bp_modified } \
+ "$gdb_test_name, no breakpoint-modified"
+ }
+
+ -re "^\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+}
diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp
index 0a1231b..e1a3a23 100644
--- a/gdb/testsuite/lib/ada.exp
+++ b/gdb/testsuite/lib/ada.exp
@@ -181,12 +181,16 @@ proc find_ada_tool {tool} {
# compiler does not appear to be GCC, this will always return false.
proc gnat_version_compare {op l2} {
- set gccvers [gcc_major_version]
- if {$gccvers == -1} {
+ set gnatmake [find_gnatmake]
+ set gnatmake [lindex [split $gnatmake] 0]
+ if {[catch {exec $gnatmake --version} output]} {
+ return 0
+ }
+ if {![regexp {GNATMAKE ([0-9]+(\.[0-9]+)*)} $output match version]} {
return 0
}
- return [version_compare [split $gccvers .] $op $l2]
+ return [version_compare [split $version .] $op $l2]
}
# Return 1 if the GNAT runtime appears to have debug info.
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 761a4f1..59967c7 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -3937,13 +3937,16 @@ gdb_caching_proc is_aarch32_target {} {
return 0
}
- set list {}
- foreach reg \
- {r0 r1 r2 r3} {
- lappend list "\tmov $reg, $reg"
- }
+ return [gdb_can_simple_compile aarch32 {
+ int main (void) {
+ asm ("\tmov r0, r0");
+ asm ("\tmov r1, r1");
+ asm ("\tmov r2, r2");
+ asm ("\tmov r3, r3");
- return [gdb_can_simple_compile aarch32 [join $list \n]]
+ return 0;
+ }
+ }]
}
# Return 1 if this target is an aarch64, either lp64 or ilp32.