Commit | Line | Data |
---|---|---|
e2882c85 | 1 | # Copyright 2016-2018 Free Software Foundation, Inc. |
b16f8a3b DB |
2 | |
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. | |
7 | # | |
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. | |
12 | # | |
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/>. | |
15 | ||
16 | # This test ensures that with "set print object on", -var-create will | |
17 | # return "<optimized out>" for an optimized out pointer to structure, | |
18 | # rather than attempting to dereference the pointer to determine its | |
19 | # actual type (instead of its declared type). We want to test that GDB | |
20 | # can display such a pointer without throwing an error, while also | |
21 | # ensuring that any attempt to dereference the pointer *will* throw an | |
22 | # error. | |
23 | ||
24 | load_lib dwarf.exp | |
25 | ||
26 | # This test can only be run on targets which support DWARF-2 and use gas. | |
27 | if {![dwarf2_support]} { | |
28 | return 0 | |
29 | } | |
30 | ||
31 | standard_testfile dw2-opt-structptr.c dw2-opt-structptr-dw.S | |
32 | ||
33 | # Generate a test program with dwarf information showing the variable | |
34 | # 'ptr', a pointer-to-struct, as optimized out. The dwarf will also | |
35 | # describe the structure as have a scalar, array, and pointer-to-struct | |
36 | # members. | |
37 | ||
38 | proc build_test_program {} { | |
39 | global testfile srcfile srcfile2 | |
40 | ||
41 | # Make some DWARF for the test. | |
42 | set asm_file [standard_output_file $srcfile2] | |
43 | Dwarf::assemble $asm_file { | |
44 | global srcdir subdir srcfile | |
45 | ||
46 | # Creating a CU with 4-byte addresses lets this test link on | |
47 | # both 32- and 64-bit machines. | |
48 | cu { addr_size 4 } { | |
49 | ||
50 | DW_TAG_compile_unit { | |
51 | {DW_AT_language @DW_LANG_C99} | |
52 | {DW_AT_name dw2-opt-structptr.c} | |
53 | {DW_AT_comp_dir /tmp} | |
54 | } { | |
55 | declare_labels int_label struct_label pointer_label \ | |
56 | array_label | |
57 | ||
58 | int_label: DW_TAG_base_type { | |
59 | {DW_AT_byte_size 4 DW_FORM_sdata} | |
60 | {DW_AT_encoding @DW_ATE_signed} | |
61 | {DW_AT_name integer} | |
62 | } | |
63 | ||
64 | array_label: DW_TAG_array_type { | |
65 | {DW_AT_name foo__array_type} | |
66 | {DW_AT_type :$int_label} | |
67 | } { | |
68 | DW_TAG_subrange_type { | |
69 | {DW_AT_type :$int_label} | |
70 | {DW_AT_lower_bound 0 DW_FORM_data1} | |
71 | {DW_AT_upper_bound 127 DW_FORM_data1} | |
72 | } | |
73 | } | |
74 | ||
75 | struct_label: DW_TAG_structure_type { | |
76 | {DW_AT_name "foo"} | |
77 | {DW_AT_byte_size 12 DW_FORM_sdata} | |
78 | } { | |
79 | member { | |
80 | {name a} | |
81 | {type :$int_label} | |
82 | {data_member_location 0 data1} | |
83 | } | |
84 | member { | |
85 | {name x} | |
86 | {type :$array_label} | |
87 | {data_member_location 4 data1} | |
88 | } | |
89 | member { | |
90 | {name y} | |
91 | {type :$pointer_label} | |
92 | {data_member_location 8 data1} | |
93 | } | |
94 | } | |
95 | ||
96 | pointer_label: DW_TAG_pointer_type { | |
97 | {DW_AT_byte_size 4 DW_FORM_sdata} | |
98 | {DW_AT_type :$struct_label} | |
99 | } | |
100 | ||
101 | DW_TAG_subprogram { | |
102 | {DW_AT_name func01} | |
103 | {DW_AT_type :$int_label} | |
104 | {external 1 flag} | |
105 | {MACRO_AT_func {func01 ${srcdir}/${subdir}/${srcfile}}} | |
106 | } { | |
107 | DW_TAG_variable { | |
108 | {DW_AT_name ptr} | |
109 | {DW_AT_type :$pointer_label} | |
110 | {DW_AT_location {} DW_FORM_block1} | |
111 | } | |
112 | } | |
113 | ||
114 | DW_TAG_subprogram { | |
115 | {DW_AT_name main} | |
116 | {DW_AT_type :$int_label} | |
117 | {external 1 flag} | |
118 | {MACRO_AT_func {main ${srcdir}/${subdir}/${srcfile}}} | |
119 | } { | |
120 | } | |
121 | } | |
122 | } | |
123 | } | |
124 | ||
125 | set sources "$srcfile $asm_file" | |
126 | if {[build_executable $testfile.exp $testfile $sources {nodebug}]} { | |
5b362f04 | 127 | untested "failed to compile" |
b16f8a3b DB |
128 | return -1 |
129 | } | |
130 | } | |
131 | ||
132 | # Test access to an optimized-out pointer-to-struct using the | |
133 | # console interpreter. | |
134 | ||
135 | proc do_console_test {} { | |
136 | global binfile | |
137 | ||
138 | clean_restart $binfile | |
139 | ||
140 | with_test_prefix "console" { | |
141 | gdb_test_no_output "set print object on" | |
142 | ||
143 | if {![runto_main]} { | |
144 | return -1 | |
145 | } | |
146 | ||
147 | if {![runto func01]} { | |
148 | return -1 | |
149 | } | |
150 | ||
151 | gdb_test "info addr ptr" "Symbol \"ptr\" is optimized out." | |
152 | ||
153 | gdb_test "print ptr" "<optimized out>" | |
154 | ||
155 | gdb_test "print *ptr" "value has been optimized out" | |
156 | ||
157 | gdb_test "print ptr->a" "value has been optimized out" | |
158 | ||
159 | gdb_test "print ptr->x" "value has been optimized out" | |
160 | ||
161 | gdb_test "print ptr->y" "value has been optimized out" | |
162 | } | |
163 | } | |
164 | ||
165 | # Test access to an optimized-out pointer-to-struct using the | |
166 | # MI interpreter. | |
167 | ||
168 | proc do_mi_test {} { | |
169 | ||
170 | load_lib mi-support.exp | |
171 | set MIFLAGS "-i=mi" | |
172 | ||
173 | global mi_gdb_prompt | |
174 | global srcdir | |
175 | global subdir | |
176 | global binfile | |
177 | ||
178 | with_test_prefix "mi" { | |
179 | gdb_exit | |
180 | if {[mi_gdb_start]} { | |
181 | return -1 | |
182 | } | |
183 | ||
184 | mi_delete_breakpoints | |
185 | mi_gdb_reinitialize_dir $srcdir/$subdir | |
186 | mi_gdb_load $binfile | |
187 | ||
188 | # This causes GDB to dereference a pointer-to-structure when doing | |
189 | # -var-create. | |
190 | mi_gdb_test "-gdb-set print object on" ".*" "set print object on" | |
191 | ||
192 | mi_gdb_test "-break-insert main" ".*" "insert breakpoint main" | |
193 | mi_gdb_test "-break-insert func01" ".*" "insert breakpoint func01" | |
194 | ||
195 | # Run to main. Use an explicit expect here since the limited | |
196 | # debug info will result in output that isn't handled by the | |
197 | # MI test utilities. | |
198 | set test "run to main" | |
199 | mi_run_cmd | |
200 | gdb_expect { | |
201 | -re "\\*stopped,reason=\"breakpoint-hit\".*func=\"main\".*$mi_gdb_prompt$" { | |
202 | pass "$test" | |
203 | } | |
204 | timeout { | |
205 | fail "$test (timeout)" | |
206 | } | |
207 | } | |
208 | ||
209 | # Run to func01. Use an explicit expect here as above. | |
210 | set test "continue to func01" | |
211 | mi_send_resuming_command "exec-continue" "$test" | |
212 | gdb_expect { | |
213 | -re "\\*stopped,reason=\"breakpoint-hit\".*func=\"func01\".*$mi_gdb_prompt$" { | |
214 | pass "$test" | |
215 | } | |
216 | timeout { | |
217 | fail "$test (timeout)" | |
218 | } | |
219 | } | |
220 | ||
221 | # Test that -var-create for 'ptr' is successful. | |
222 | mi_create_varobj "var1" "ptr" "create varobj for ptr" | |
223 | ||
224 | # Test that -var-list-children of 'ptr' is successful. | |
225 | mi_list_varobj_children "var1" { \ | |
226 | {var1.a a 0 integer} \ | |
227 | {var1.x x 128 foo__array_type} \ | |
228 | {var1.y y 3 "struct foo \\*"} \ | |
229 | } "get children of var1 (ptr)" | |
230 | ||
231 | # Test that dereferencing 'ptr' will throw an error. | |
232 | mi_gdb_test "-var-create var2 * &((ptr)->a)" \ | |
233 | "\\^error,msg=\"value has been optimized out\"" \ | |
234 | "throw error, dereference ptr to access integer member " | |
235 | ||
236 | # Test that dereferencing 'ptr' will throw an error. | |
237 | mi_gdb_test "-var-create var3 * &((ptr)->x)" \ | |
238 | "\\^error,msg=\"value has been optimized out\"" \ | |
239 | "throw error, dereference ptr to access array member " | |
240 | ||
241 | # Test that dereferencing 'ptr' will throw an error. | |
242 | mi_gdb_test "-var-create var4 * &((ptr)->y)" \ | |
243 | "\\^error,msg=\"value has been optimized out\"" \ | |
244 | "throw error, dereference ptr to access pointer member " | |
245 | } | |
246 | } | |
247 | ||
248 | build_test_program | |
249 | do_console_test | |
250 | do_mi_test |