aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.python/py-finish-breakpoint.exp
blob: 6ffa17a357700a9a95441a0ee86835e91ba7c943 (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
# Copyright (C) 2011-2019 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 file is part of the GDB testsuite.  It tests the mechanism
# exposing values to Python.

if {[skip_shlib_tests]} {
	untested "skipping shared library tests"
    return 0
}

load_lib gdb-python.exp

set libfile "py-events-shlib"
set libsrc  $srcdir/$subdir/$libfile.c
set lib_sl  [standard_output_file $libfile-nodebug.so]
set lib_opts ""

standard_testfile
set exec_opts [list debug shlib=$lib_sl]

if [get_compiler_info] {
    return -1
}

if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
     || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != ""} {
    untested "failed to compile"
    return -1
}

# Start with a fresh gdb.
clean_restart ${testfile}

if { [skip_python_tests] } { continue }

#
# Test FinishBreakpoint in normal conditions
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

if ![runto_main] then {
    fail "cannot run to main."
    return 0
}

set python_file [gdb_remote_download host \
		     ${srcdir}/${subdir}/${testfile}.py]

gdb_test_no_output "set confirm off" "disable confirmation"
gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"
gdb_breakpoint "increase_1"
gdb_test "continue" "Breakpoint .*at.*" "continue to the function to finish"

# set FinishBreakpoint

gdb_test "python finishbp_default = gdb.FinishBreakpoint ()" \
         "Temporary breakpoint.*" "set FinishBreakpoint with default frame value"
gdb_test "python finishbp = MyFinishBreakpoint (gdb.parse_and_eval ('a'), gdb.newest_frame ())" \
         "Temporary breakpoint.*" "set FinishBreakpoint"
gdb_test "python print (finishbp.return_value)" "None.*" \
         "check return_value at init"

# check normal bp hit

gdb_test "continue" "MyFinishBreakpoint stop with.*return_value is: -5.*#0.*increase.*" \
         "check MyFinishBreakpoint hit"
gdb_test "python print (finishbp.return_value)" "-5.*" "check return_value"

gdb_test "python print (finishbp_default.hit_count)" "1.*" "check finishBP on default frame has been hit"
gdb_test "python print (finishbp.is_valid())" "False.*"\
         "ensure that finish bp is invalid afer normal hit"

# check FinishBreakpoint in main no allowed

gdb_test "finish" "main.*" "return to main()"
gdb_test "python MyFinishBreakpoint (None, gdb.selected_frame ())" \
         "ValueError: \"FinishBreakpoint\" not meaningful in the outermost frame..*" \
         "check FinishBP not allowed in main"

#
# Test FinishBreakpoint with no debug symbol 
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"
set cond_line [gdb_get_line_number "Condition Break."]

if ![runto_main] then {
    fail "cannot run to main."
    return 0
}

gdb_test "print do_nothing" "no debug info.*" "ensure that shared lib has no debug info"
gdb_breakpoint "do_nothing" {temporary}
gdb_test "continue" "Temporary breakpoint .*in \\.?do_nothing.*" \
         "continue to do_nothing"

gdb_test "python finishBP = SimpleFinishBreakpoint(gdb.newest_frame())" \
         "SimpleFinishBreakpoint init" \
         "set finish breakpoint"
gdb_test "continue" "SimpleFinishBreakpoint stop.*" "check FinishBreakpoint hit"
gdb_test "python print (finishBP.return_value)" "None" "check return value without debug symbol"

#
# Test FinishBreakpoint in function returned by longjmp 
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"

if ![runto call_longjmp_1] then {
    perror "couldn't run to breakpoint call_longjmp"
    continue
}

gdb_test "python finishbp = SimpleFinishBreakpoint(gdb.newest_frame())" \
         "SimpleFinishBreakpoint init" \
         "set finish breakpoint" 
gdb_test "break [gdb_get_line_number "after longjmp."]" "Breakpoint.* at .*" \
         "set BP after the jump"
gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" \
         "check FinishBP out of scope notification"
gdb_test "python print (finishbp.is_valid())" "False.*"\
         "ensure that finish bp is invalid afer out of scope notification"

#
# Test FinishBreakpoint in BP condition evaluation 
# (finish in dummy frame)
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"


if ![runto_main] then {
    fail "cannot run to main."
    return 0
}
         
gdb_test "break ${cond_line} if test_1(i,8)" "Breakpoint .* at .*" \
         "set a conditional BP"
gdb_test "python TestBreakpoint()" "TestBreakpoint init" \
         "set FinishBP in a breakpoint condition"
gdb_test "continue" \
         "\"FinishBreakpoint\" cannot be set on a dummy frame.*" \
         "don't allow FinishBreakpoint on dummy frames"
gdb_test "print i" "8" "check stopped location"

#
# Test FinishBreakpoint in BP condition evaluation 
# (finish in normal frame)
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"

if ![runto_main] then {
    fail "cannot run to main."
    return 0
}

gdb_test "break ${cond_line} if test(i,8)" \
         "Breakpoint .* at .*" "set conditional BP"
gdb_test "python TestBreakpoint()" "TestBreakpoint init" "set BP in condition"

gdb_test "continue" \
         "test don't stop: 1.*test don't stop: 2.*test stop.*Error in testing breakpoint condition.*The program being debugged stopped while in a function called from GDB.*" \
         "stop in condition function"

gdb_test "continue" "Continuing.*" "finish condition evaluation"
gdb_test "continue" "Breakpoint.*" "stop at conditional breakpoint"
gdb_test "print i" "8" "check stopped location"

#
# Test FinishBreakpoint in explicit inferior function call
#

clean_restart ${testfile}
gdb_load_shlib ${lib_sl}

gdb_test "source $python_file" "Python script imported.*" \
         "import python scripts"

if ![runto_main] then {
    fail "cannot run to main."
    return 0
}

# return address in dummy frame

gdb_test "python TestExplicitBreakpoint('increase_1')" "Breakpoint.*at.*" \
         "prepare TestExplicitBreakpoint"
gdb_test "print increase_1(&i)" \
         "\"FinishBreakpoint\" cannot be set on a dummy frame.*" \
         "don't allow FinishBreakpoint on dummy frames"

# return address in normal frame

delete_breakpoints
gdb_test "python TestExplicitBreakpoint(\"increase_1\")" "Breakpoint.*at.*" \
         "prepare TestExplicitBreakpoint"
gdb_test "print increase(&i)" \
         "SimpleFinishBreakpoint init.*SimpleFinishBreakpoint stop.*The program being debugged stopped while in a function called from GDB.*" \
         "FinishBP stop at during explicit function call"


#
# Test FinishBreakpoint when inferior exits
#

if ![runto "test_exec_exit"] then {
    fail "cannot run to test_exec_exit."
    return 0
}

gdb_test_no_output "set var self_exec = 0" "switch to exit() test"
gdb_test "python SimpleFinishBreakpoint(gdb.newest_frame())" "SimpleFinishBreakpoint init" "set FinishBP after the exit()"
gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" "catch out of scope after exit"

#
# Test FinishBreakpoint when inferior execs
#

if ![runto "test_exec_exit"] then {
    fail "cannot run to test_exec_exit."
    return 0
}     

gdb_test "python SimpleFinishBreakpoint(gdb.newest_frame())" "SimpleFinishBreakpoint init" "set FinishBP after the exec"
gdb_test "catch exec" "Catchpoint.*\(exec\).*" "catch exec"
gdb_test "continue" "SimpleFinishBreakpoint out of scope.*" "catch out of scope after exec"