aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/bp-cond-failure.exp
blob: b4c046c4bd6ef7b3ef146819bcb5675b751a7b47 (plain)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Copyright 2022-2024 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 the format of the error message given when a breakpoint
# condition fails.
#
# In this case the breakpoint condition does not make use of inferior
# function calls, instead, the expression used for the breakpoint
# condition will throw an error when evaluated.
#
# We check that the correct breakpoint number appears in the error
# message, and that the error is reported at the correct source
# location.

standard_testfile

if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
	  {debug c++}] == -1 } {
    return
}

# Run to main so that we connect to the target if using 'target
# remote'.  This means that the is_address_zero_readable, and the
# 'show breakpoint condition-evaluation' checks below will be
# performed with the remote connection in place.
if { ![runto_main] } {
    return -1
}

# This test relies on reading address zero triggering a SIGSEGV.
if { [is_address_zero_readable] } {
    return
}

proc run_test { cond_eval access_type bpexpr nloc } {
    clean_restart ${::binfile}

    if { ![runto_main] } {
	return -1
    }

    if { $cond_eval ne "auto" } {
	gdb_test_no_output "set breakpoint condition-evaluation ${cond_eval}"
    }

    # Setup the conditional breakpoint and record its number.
    gdb_breakpoint "${bpexpr} if (*(${access_type} *) 0) == 0"

    # This test aims to test that GDB displays the correct breakpoint number
    # and location when there is an error testing a breakpoint condition,
    # so it is important to hardcode the breakpoint number into the regex,
    # along with the location, if applicable.
    set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]

    if { $nloc > 1 } {
	# We hardcode location 2 because, for some reason, Clang will always
	# order the debug information so we hit the second location.  For
	# simplicity the .c is ordered in such a way that GCC will also order
	# the debug info to have us land on location 2.
	gdb_test "continue" \
	    [multi_line \
		 "Continuing\\." \
		 "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\]+" \
		 "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
    } else {
	gdb_test "continue" \
	    [multi_line \
		 "Continuing\\." \
		 "Error in testing condition for breakpoint ${bp_num}:" \
		 "Cannot access memory at address 0x0" \
		 "" \
		 "Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \
		 "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
    }
}

# If we're using a remote target then conditions could be evaulated
# locally on the host, or on the remote target.  Otherwise, conditions
# are always evaluated locally.
#
# Using "auto" will select the target if the target supports condition
# evaluation, otherwise, the local host will be used.
#
# So, we always include "auto", but then we look at the output of
# 'show breakpoint condition-evaluation', if this tells us that "auto"
# is using the target, then we specifically add "host" to the list of
# modes to check.

set cond_eval_modes { "auto" }

gdb_test_multiple "show breakpoint condition-evaluation" "" {
    -re -wrap "Breakpoint condition evaluation mode is auto \\(currently target\\)\\." {
	lappend cond_eval_modes "host"
	pass $gdb_test_name
    }

    -re -wrap "Breakpoint condition evaluation mode is auto \\(currently host\\)\\." {
	pass $gdb_test_name
    }
}

# Where the breakpoint will be placed.
set bp_line_multi_loc "foo"
set bp_line_single_loc [gdb_get_line_number "Single-location breakpoint here"]

foreach_with_prefix access_type { "char" "short" "int" "long long" } {
    foreach_with_prefix cond_eval $cond_eval_modes {
	with_test_prefix "multi-loc" {
	    run_test $cond_eval $access_type $bp_line_multi_loc 2
	}
	with_test_prefix "single-loc" {
	    run_test $cond_eval $access_type "${srcfile}:${bp_line_single_loc}" 1
	}
    }
}