[gdb/syscalls] Sync with strace v6.13
[binutils-gdb.git] / gdb / testsuite / gdb.base / reset-catchpoint-cond.exp
blobd9539383c95fba6777c6f34ea04b90845d2ea5f0
1 # Copyright 2024 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 # Test that the condition for a catchpoint is correctly reset after
17 # shared libraries are unloaded, as happens when an inferior is
18 # restarted.
20 # If this is not done then, when the catchpoint is hit on the second
21 # run, we'll evaluate the parsed expression from the first run, which
22 # might include references to types owned by the now deleted objfile
23 # (for the shared library loaded in the first run).
25 # This scripts tests a number of different catchpoint types.  Inside
26 # GDB these are all sub-classes of the 'catchpoint' type, which is
27 # where the fix for the above issue resides, so all catchpoint types
28 # should work correctly.
30 standard_testfile .c -lib.c
32 set libfile $binfile-lib.so
34 set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
36 if {[build_executable "build shared library" $libfile $srcfile2 \
37          {debug shlib}] == -1} {
38     return
41 # Depending on whether or not libc debug info is installed, when we
42 # hit a syscall catchpoint inside libc there might be a source line
43 # included in the output.
45 # This regexp will match an optional line and can be added to the
46 # expected catchpoint output to ignore the (possibly missing) source
47 # line.
48 set libc_src_line_re "(?:\r\n\[^\r\n\]+)?"
50 # Check the Python bp_modified_list and then reset the list back to
51 # empty.  TESTNAME is just a string.  BP_NUM is a list of breakpoint
52 # numbers that are expected to appear (in the given order) in the
53 # bp_modified_list.
55 proc check_modified_bp_list { testname bp_num } {
56     if { [allow_python_tests] } {
57         set expected [join $bp_num ", "]
59         gdb_test "python print(bp_modified_list)" "\\\[$expected\\\]" \
60             $testname
61         gdb_test_no_output -nopass "python bp_modified_list=\[\]" \
62             "reset bp_modified_list after $testname"
63     }
66 # Build an executable and run tests on 'catch MODE'.
68 proc run_test { mode } {
69     set exec_name ${::binfile}-${mode}
71     set macro TEST_[string toupper $mode]
73     if {[build_executable "build test executable" $exec_name $::srcfile \
74              [list debug shlib=$::libfile additional_flags=-D${macro}]] == -1} {
75         return
76     }
78     clean_restart $exec_name
79     gdb_load_shlib $::libfile
81     if {![runto_main]} {
82         return
83     }
85     if { $mode eq "syscall" } {
86         gdb_test "catch syscall write" \
87             "Catchpoint $::decimal \\(syscall 'write' \[^)\]+\\)"
88         set catch_re "call to syscall write"
89     } elseif { $mode eq "signal" } {
90         gdb_test "catch signal SIGUSR1" \
91             "Catchpoint $::decimal \\(signal SIGUSR1\\)"
92         set catch_re "signal SIGUSR1"
93     } elseif { $mode eq "fork" } {
94         gdb_test "catch fork" \
95             "Catchpoint $::decimal \\(fork\\)"
96         set catch_re "forked process $::decimal"
97     } else {
98         error "unknown mode $mode"
99     }
100     set cp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]
102     gdb_breakpoint "breakpt_before_exit"
104     gdb_test "continue" \
105         "Catchpoint ${cp_num} \[^\r\n\]+$::libc_src_line_re"
107     if { [allow_python_tests] } {
108         gdb_test_no_output "source $::pyfile" "import python scripts"
109         check_modified_bp_list \
110             "check b/p modified observer has not yet triggered" {}
111     }
113     with_test_prefix "with false condition" {
114         gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) != 0" \
115             "set catchpoint condition"
117         check_modified_bp_list \
118             "catchpoint modified once by setting condition" \
119             [list $cp_num]
121         gdb_run_cmd
122         gdb_test "" [multi_line \
123                          "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \
124                          "$::decimal\\s+\[^\r\n\]+"]
126         check_modified_bp_list "catchpoint modified twice at startup" \
127             [list $cp_num $cp_num "$::decimal"]
129         gdb_test "continue" \
130             [multi_line \
131                  "Breakpoint $::decimal, breakpt_before_exit \\(\\) at \[^\r\n\]+" \
132                  "$::decimal\\s+\[^\r\n\]+"] \
133             "continue to breakpt_before_exit"
134     }
136     # Check the bp_modified_list against '.*'.  We don't care at this
137     # point what's in the list (nothing relevant has happened since we
138     # last checked), but this has the side effect of clearing the list.
139     check_modified_bp_list "clear bp modified list" { .* }
141     with_test_prefix "with true condition" {
142         gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) == 0" \
143             "set catchpoint condition"
145         check_modified_bp_list \
146             "catchpoint modified once by setting condition" \
147             [list $cp_num]
149         gdb_run_cmd
150         gdb_test "" [multi_line \
151                          "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \
152                          "$::decimal\\s+\[^\r\n\]+"]
154         check_modified_bp_list "catchpoint modified twice at startup" \
155             [list $cp_num $cp_num "$::decimal"]
157         gdb_test "continue" \
158             "Catchpoint $cp_num \\($catch_re\\), \[^\r\n\]+$::libc_src_line_re" \
159             "continue until catchpoint hit"
161         check_modified_bp_list "catchpoint modified again when hit" \
162             [list $cp_num]
163     }
166 # Run the tests.
167 foreach_with_prefix mode { syscall signal fork } {
168     if { $mode == "syscall"
169          && ( ![allow_xml_test] || ![supports_catch_syscall] ) } {
170         continue
171     }
172     run_test $mode