1 # Copyright 2022-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 # This test reprocuces bug gdb/28942, performing an inferior function
17 # call from a breakpoint condition in a multi-threaded inferior.
19 # The important part of this test is that, when the conditional
20 # breakpoint is hit, and the condition (which includes an inferior
21 # function call) is evaluated, the other threads are running.
25 if { [build_executable "failed to prepare" ${binfile} "${srcfile}" \
26 {debug pthreads}] == -1 } {
30 set cond_bp_line [gdb_get_line_number "Conditional breakpoint here"]
31 set final_bp_line [gdb_get_line_number "Stop marker"]
33 # Start GDB based on TARGET_ASYNC and TARGET_NON_STOP, and then runto main.
34 proc start_gdb_and_runto_main { target_async target_non_stop } {
35 save_vars { ::GDBFLAGS } {
37 " -ex \"maint set target-non-stop $target_non_stop\""
39 " -ex \"maintenance set target-async ${target_async}\""
41 clean_restart ${::binfile}
44 if { ![runto_main] } {
51 # Run a test of GDB's conditional breakpoints, where the conditions include
52 # inferior function calls.
54 # TARGET_ASYNC and TARGET_NON_STOP are used when starting up GDB.
56 # When STOP_AT_COND is true the breakpoint condtion will evaluate to
57 # true, and GDB will stop at the breakpoint. Otherwise, the
58 # breakpoint condition will evaluate to false and GDB will not stop at
60 proc run_condition_test { stop_at_cond \
61 target_async target_non_stop } {
62 if { [start_gdb_and_runto_main $target_async \
63 $target_non_stop] == -1 } {
67 # Setup the conditional breakpoint.
68 if { $stop_at_cond } {
69 set cond_func "return_true"
71 set cond_func "return_false"
74 "${::srcfile}:${::cond_bp_line} if (${cond_func} ())"
75 set cond_bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*" \
76 "get number for conditional breakpoint"]
78 # And a breakpoint that we hit when the test is over, this one is
80 gdb_breakpoint "${::srcfile}:${::final_bp_line}"
81 set final_bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*" \
82 "get number for final breakpoint"]
84 if { $stop_at_cond } {
85 # Continue. The first breakpoint we hit should be the conditional
86 # breakpoint. The other thread will have hit its breakpoint, but
87 # that will have been deferred until the conditional breakpoint is
94 "Thread ${::decimal} \"\[^\"\r\n\]+\" hit Breakpoint ${cond_bp_num}, worker_func \[^\r\n\]+:${::cond_bp_line}" \
95 "${::decimal}\\s+\[^\r\n\]+Conditional breakpoint here\[^\r\n\]+"] \
96 "hit the conditional breakpoint"
99 # Run to the stop marker.
100 gdb_test "continue" \
105 "Thread ${::decimal} \"\[^\"\r\n\]+\" hit Breakpoint ${final_bp_num}, stop_marker \[^\r\n\]+:${::final_bp_line}" \
106 "${::decimal}\\s+\[^\r\n\]+Stop marker\[^\r\n\]+"] \
107 "hit the final breakpoint"
110 foreach_with_prefix target_async { "on" "off" } {
111 foreach_with_prefix target_non_stop { "on" "off" } {
112 foreach_with_prefix stop_at_cond { true false } {
113 run_condition_test $stop_at_cond \
114 $target_async $target_non_stop