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
|
# Copyright (C) 2008, 2009, 2010 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 Python-based
# pretty-printing for MI.
load_lib mi-support.exp
set MIFLAGS "-i=mi2"
gdb_exit
if [mi_gdb_start] {
continue
}
set testfile "py-prettyprint"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DMI}] != "" } {
untested mi2-var-child.exp
return -1
}
mi_delete_breakpoints
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}
if {[lsearch -exact [mi_get_features] python] < 0} {
unsupported "python support is disabled"
return -1
}
mi_runto main
set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
mi_gdb_test "python execfile ('${remote_python_file}')" ""
mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${testfile}.c] \
"step to breakpoint"
mi_create_dynamic_varobj container c \
"create container varobj, no pretty-printing"
mi_list_varobj_children container {
{ container.name name 1 string }
{ container.len len 0 int }
{ container.elements elements 1 "int ." }
} "examine container children=0, no pretty-printing"
mi_delete_varobj container "delete varobj"
mi_gdb_test "-enable-pretty-printing" ""
mi_create_varobj_checked string string_1 \
"struct string_repr" \
"create string_1 varobj"
mi_create_varobj_checked lstring estring \
"struct lazystring" \
"create estring varobj"
mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \
"assign string_1 from string_2"
mi_gdb_test "-var-update string" \
"\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \
"update string varobj after assignment"
mi_create_dynamic_varobj container c \
"create container varobj"
mi_list_varobj_children container {
} "examine container children=0"
mi_next "next over update 1"
mi_varobj_update_dynamic container "varobj update 1" {
type_changed false new_num_children 1 dynamic 1 has_more 0
} {
} {
{ name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
}
mi_next "next over update 2"
mi_varobj_update_dynamic container "varobj update 2" {
type_changed false new_num_children 2 dynamic 1 has_more 0
} {
} {
{ name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
}
mi_gdb_test "-var-set-visualizer container None" \
"\\^done" \
"clear visualizer"
mi_gdb_test "-var-update container" \
"\\^done,changelist=\\\[\\\]" \
"varobj update after clearing"
mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \
"\\^done" \
"choose default visualizer"
mi_varobj_update_dynamic container "varobj update after choosing default" {
type_changed false new_num_children 2 dynamic 1 has_more 0
} {
} {
{ name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
{ name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
}
mi_gdb_test "-var-set-visualizer container ContainerPrinter" \
"\\^done" \
"choose visualizer using expression"
mi_varobj_update_dynamic container \
"varobj update after choosing via expression" {
type_changed false new_num_children 2 dynamic 1 has_more 0
} {
} {
{ name {container.\[0\]} exp {\[0\]} numchild 0 type int thread-id 1 }
{ name {container.\[1\]} exp {\[1\]} numchild 0 type int thread-id 1 }
}
mi_list_varobj_children_range container 1 2 2 {
{ {container.\[1\]} {\[1\]} 0 int }
} "list varobj children after selecting child range"
mi_list_varobj_children_range container -1 -1 2 {
{ {container.\[0\]} {\[0\]} 0 int }
{ {container.\[1\]} {\[1\]} 0 int }
} "list varobj children after resetting child range"
mi_next "next over update 3"
mi_gdb_test "-var-set-update-range container 0 1" \
"\\^done" \
"set update range"
# This should truncate the list.
mi_list_varobj_children container {
{ {container.\[0\]} {\[0\]} 0 int }
} "list children after setting update range"
# This should return just the items in [1,2).
mi_list_varobj_children_range container 1 2 2 {
{ {container.\[1\]} {\[1\]} 0 int }
} "list selected children after setting range"
# This should not be affected by the previous list-children request.
mi_list_varobj_children container {
{ {container.\[0\]} {\[0\]} 0 int }
} "list children after listing selected range"
mi_next "next over update 4"
# This should only show the first child, because the update range has
# been set.
mi_varobj_update_dynamic container \
"update after next with restricted range" {
type_changed false new_num_children 1 dynamic 1 has_more 1
} {
{ name {container.\[0\]} in_scope true type_changed false dynamic 1 has_more 0 }
} {
}
mi_gdb_test "-var-set-update-range container 3 4" \
"\\^done" \
"set update range with non-zero start"
# Elements were updated but should not be reported.
mi_varobj_update_dynamic container \
"update varobj with change outside selected range" {
type_changed false new_num_children 3 dynamic 1 has_more 0
} {
} {
}
mi_next "next over update 5"
# Regression test: examine an object that has no children, then update
# it to ensure that we don't print the children.
mi_create_dynamic_varobj container2 c2 \
"create second container varobj"
mi_gdb_test "-var-update container2" \
"\\^done,changelist=.." \
"update varobj, no children requested"
mi_next "next over update 6"
# Now container2 has an element -- and an update should mention that
# it has_more. But, because we did not request children, we still
# should not actually see them.
mi_varobj_update_dynamic container2 \
"update varobj 2, no children requested" {
type_changed false dynamic 1 has_more 1
} {} {}
mi_continue_to_line \
[gdb_get_line_number {MI outer breakpoint here} ${testfile}.c] \
"step to outer breakpoint"
mi_create_dynamic_varobj outer outer \
"create outer varobj"
mi_list_varobj_children outer {
{ outer.s s 2 "struct substruct" }
{ outer.x x 0 "int" }
} "list children of outer"
mi_list_varobj_children outer.s {
{ outer.s.a a 0 int }
{ outer.s.b b 0 int }
} "list children of outer.s"
mi_next "next over outer update"
mi_gdb_test "-var-update outer" \
".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}." \
"update after updating element of outer"
mi_continue_to_line \
[gdb_get_line_number {Another MI breakpoint} ${testfile}.c] \
"step to second breakpoint"
mi_varobj_update_with_type_change container int 0 "update after type change"
remote_file host delete ${remote_python_file}
|