aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/condbreak.exp
blob: b8067291d70c0440bff12537eca7e1d73a1e0218 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# Copyright 1997-2001, 2003, 2007-2012 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 was written by Rich Title. 
# Purpose is to test conditional breakpoints.
# Modeled after "break.exp".

if $tracelevel then {
	strace $tracelevel
	}

#
# test running programs
#

set testfile "break"
set srcfile ${testfile}.c
set srcfile1 ${testfile}1.c
set binfile ${objdir}/${subdir}/${testfile}

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}0.o" object {debug nowarnings}] != "" } {
     untested condbreak.exp
     return -1
}

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}1.o" object {debug nowarnings}] != "" } {
     untested condbreak.exp
     return -1
}

if  { [gdb_compile "${binfile}0.o ${binfile}1.o" "${binfile}" executable {debug nowarnings}] != "" } {
     untested condbreak.exp
     return -1
}

if [get_compiler_info ${binfile}] {
    return -1;
}

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}


set bp_location1  [gdb_get_line_number "set breakpoint 1 here"]
set bp_location6  [gdb_get_line_number "set breakpoint 6 here"]
set bp_location8  [gdb_get_line_number "set breakpoint 8 here" $srcfile1]
set bp_location9  [gdb_get_line_number "set breakpoint 9 here" $srcfile1]
set bp_location13 [gdb_get_line_number "set breakpoint 13 here" $srcfile1]
set bp_location14 [gdb_get_line_number "set breakpoint 14 here" $srcfile1]
set bp_location15 [gdb_get_line_number "set breakpoint 15 here" $srcfile1]
set bp_location16 [gdb_get_line_number "set breakpoint 16 here" $srcfile1]
set bp_location17 [gdb_get_line_number "set breakpoint 17 here" $srcfile1]
set bp_location18 [gdb_get_line_number "set breakpoint 18 here" $srcfile1]

#
# test break at function
#
gdb_test "break main" \
    "Breakpoint.*at.* file .*$srcfile, line.*" \
    "breakpoint function"

# 
# test conditional break at function
#
gdb_test "break marker1 if 1==1" \
    "Breakpoint.*at.* file .*$srcfile1, line.*"

gdb_test_no_output "delete 2"

#
# test conditional break at line number
#
gdb_test "break $srcfile:$bp_location1 if 1==1" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\."

gdb_test_no_output "delete 3"

# 
# test conditional break at function
#
gdb_test "break marker1 if (1==1)" \
    "Breakpoint.*at.* file .*$srcfile1, line.*"

#
# test conditional break at line number
#
gdb_test "break $srcfile:$bp_location1 if (1==1)" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\."

gdb_test "break marker2 if (a==43)" \
    "Breakpoint.*at.* file .*$srcfile1, line.*"

#
# Check break involving inferior function call.
# Ensure there is at least one additional breakpoint with higher VMA.
#
gdb_test "break marker3 if (multi_line_if_conditional(1,1,1)==0)" \
    "Breakpoint.*at.* file .*$srcfile1, line.*"
gdb_test "break marker4" \
    "Breakpoint.*at.* file .*$srcfile1, line.*"

#
# check to see what breakpoints are set
#

if {$hp_aCC_compiler} {
    set marker1_proto "\\(void\\)"
    set marker2_proto "\\(int\\)"
    # Not checked.
    set marker3_proto "\\(char \\*, char \\*\\)"
    set marker4_proto "\\(long\\)"
} else {
    set marker1_proto ""
    set marker2_proto ""
    set marker3_proto ""
    set marker4_proto ""
}

gdb_test "info break" \
    "Num     Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location6.*
\[0-9\]+\[\t \]+breakpoint     keep y.* in marker1$marker1_proto at .*$srcfile1:($bp_location15|$bp_location16).*
\[\t \]+stop only if \\(1==1\\).*
\[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
\[\t \]+stop only if \\(1==1\\).*
\[0-9\]+\[\t \]+breakpoint     keep y.* in marker2$marker2_proto at .*$srcfile1:($bp_location8|$bp_location9).*
\[\t \]+stop only if \\(a==43\\).*
\[0-9\]+\[\t \]+breakpoint     keep y.* in marker3$marker3_proto at .*$srcfile1:($bp_location17|$bp_location18).*
\[\t \]+stop only if \\(multi_line_if_conditional\\(1,1,1\\)==0\\).*
\[0-9\]+\[\t \]+breakpoint     keep y.* in marker4$marker4_proto at .*$srcfile1:($bp_location13|$bp_location14).*" \
    "breakpoint info"


#
# run until the breakpoint at main is hit.
#


rerun_to_main

#
# run until the breakpoint at a line number
#
gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location1.*$bp_location1\[\t \]+printf.*factorial.*" \
			"run until breakpoint set at a line number"

#
# run until the breakpoint at marker1
#
# If the inferior stops at the first instruction of a source line, GDB
# won't print the actual PC value; the source line is enough to
# exactly specify the PC.  But if the inferior is instead stopped in
# the midst of a source line, GDB will include the PC in the
# breakpoint hit message.  This way, GDB always provides the exact
# stop location, but avoids clutter when possible.
#
# Suppose you have a function written completely on one source line, like:
#    int foo (int x) { return 0; }
# Setting a breakpoint at `foo' actually places the breakpoint after
# foo's prologue.
#
# GCC's STABS writer always emits a line entry attributing the
# prologue instructions to the line containing the function's open
# brace, even if the first user instruction is also on that line.
# This means that, in the case of a one-line function, you will get
# two line entries in the debug info for the same line: one at the
# function's entry point, and another at the first user instruction.
# GDB preserves these duplicated line entries, and prefers the later
# one; thus, when the program stops after the prologue, at the first
# user instruction, GDB's search finds the second line entry, decides
# that the PC is indeed at the beginning of a source line, and doesn't
# print an address in the breakpoint hit message.
# 
# GCC's Dwarf2 writer, on the other hand, squeezes out duplicate line
# entries, so GDB considers the source line to begin at the start of
# the function's prologue.  Thus, if the program stops at the
# breakpoint, GDB will decide that the PC is not at the beginning of a
# source line, and will print an address.
#
# I think the Dwarf2 writer's behavior is arguably correct, but not
# helpful.  If the user sets a breakpoint at that source line, they
# want that breakpoint to fall after the prologue.  Identifying the
# prologue's code with the opening brace is nice, but it shouldn't
# take precedence over real code.
#
# Until the Dwarf2 writer gets fixed, I'm going to XFAIL its behavior.
gdb_test_multiple "continue" "run until breakpoint at marker1" {
    -re  "Continuing\\..*Breakpoint \[0-9\]+, marker1 \\(\\) at .*$srcfile1:($bp_location15|$bp_location16).*($bp_location15|$bp_location16)\[\t \]+.*$gdb_prompt $" {
	pass "run until breakpoint at marker1"
    }
    -re  "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker1 \\(\\) at .*$srcfile1:($bp_location15|$bp_location16).*($bp_location15|$bp_location16)\[\t \]+.*$gdb_prompt $" {
	xfail "run until breakpoint at marker1"
    }
}

# run until the breakpoint at marker2
# Same issues here as above.
setup_xfail hppa2.0w-*-* 11512CLLbs
gdb_test_multiple "continue" "run until breakpoint at marker2" {
    -re "Continuing\\..*Breakpoint \[0-9\]+, marker2 \\(a=43\\) at .*$srcfile1:($bp_location8|$bp_location9).*($bp_location8|$bp_location9)\[\t \]+.*$gdb_prompt $" {
	pass "run until breakpoint at marker2"
    }
    -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker2 \\(a=43\\) at .*$srcfile1:($bp_location8|$bp_location9).*($bp_location8|$bp_location9)\[\t \]+.*$gdb_prompt $" {
	xfail "run until breakpoint at marker2"
    }
}

# Test combinations of conditional and thread-specific breakpoints.
gdb_test "break main if (1==1) thread 999" \
    "Unknown thread 999\\."
gdb_test "break main thread 999 if (1==1)" \
    "Unknown thread 999\\."

# Verify that both if and thread can be distinguished from a breakpoint
# address expression.
gdb_test "break *main if (1==1) thread 999" \
    "Unknown thread 999\\."
gdb_test "break *main thread 999 if (1==1)" \
    "Unknown thread 999\\."

# Similarly for task.
gdb_test "break *main if (1==1) task 999" \
    "Unknown task 999\\."
gdb_test "break *main task 999 if (1==1)" \
    "Unknown task 999\\."

# GDB accepts abbreviations for "thread" and "task".
gdb_test "break *main if (1==1) t 999" \
    "Unknown thread 999\\."
gdb_test "break *main if (1==1) th 999" \
    "Unknown thread 999\\."
gdb_test "break *main if (1==1) ta 999" \
    "Unknown task 999\\."

set test "run until breakpoint at marker3"
gdb_test_multiple "continue" $test {
    -re "Continuing\\..*Breakpoint \[0-9\]+, marker3 \\(a=$hex \"stack\", b=$hex \"trace\"\\) at .*$srcfile1:($bp_location17|$bp_location18).*($bp_location17|$bp_location18)\[\t \]+.*$gdb_prompt $" {
	pass $test
    }
    -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker3 \\(a=$hex \"stack\", b=$hex \"trace\"\\) at .*$srcfile1:($bp_location17|$bp_location18).*($bp_location17|$bp_location18)\[\t \]+.*$gdb_prompt $" {
	xfail $test
    }
}

set test "run until breakpoint at marker4"
gdb_test_multiple "continue" $test {
    -re "Continuing\\..*Breakpoint \[0-9\]+, marker4 \\(d=177601976\\) at .*$srcfile1:($bp_location13|$bp_location14).*($bp_location13|$bp_location14)\[\t \]+.*$gdb_prompt $" {
	pass $test
    }
    -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker4 \\(d=177601976\\) at .*$srcfile1:($bp_location13|$bp_location14).*($bp_location13|$bp_location14)\[\t \]+.*$gdb_prompt $" {
	xfail $test
    }
}