]>
Commit | Line | Data |
---|---|---|
5a03b7c3 MT |
1 | http://sourceware.org/ml/gdb-patches/2011-09/msg00449.html |
2 | Subject: [patch] Fix internal error on optimized-out values (regression by me) | |
3 | ||
4 | Hi, | |
5 | ||
6 | since: | |
7 | Re: [patch] Code cleanup: Introduce allocate_optimized_out_value | |
8 | http://sourceware.org/ml/gdb-patches/2011-07/msg00327.html | |
9 | acfe85f56075910a3ba5e8b76189e0770079b8d1 | |
10 | can occur: | |
11 | (gdb) p p->f | |
12 | valops.c:1118: internal-error: Unexpected lazy value type. | |
13 | A problem internal to GDB has been detected, | |
14 | ||
15 | in that mail referenced above: | |
16 | # It is true it would be definitely a bug in a code incompatible with such | |
17 | # change so one may rather fix that possible regression there. | |
18 | ||
19 | so this testcase exploits such case. The problem is formerly the code | |
20 | allocated (in some cases) optimized out values as non-lazy ones. Now they are | |
21 | allocated all as lazy (*) which breaks some code not expecting lazy values. | |
22 | ||
23 | (*) Such lazy optimized out value still gets silently allocate_value_contents | |
24 | by value_fetch_lazy, allocate_value_contents should be suppressed in such | |
25 | case; such more radical change has never been made. | |
26 | ||
27 | Formerly (incl. gdb-7.3) did: | |
28 | (gdb) p p->f | |
29 | $1 = 0 | |
30 | which was also wrong, ((struct *) <optimized out>)->field should be IMO still | |
31 | <optimized out>; just it became internal-error now. | |
32 | ||
33 | GDB usually does require_not_optimized_out throwing error() when it meets any | |
34 | first <optimized out> value. I have just produced new optimized value | |
35 | instead; require_not_optimized_out is not exported and I find it better this | |
36 | way. | |
37 | ||
38 | Following the rule that it is better if GDB does something wrong rather then | |
39 | it throws internal-error to make the patch from July above fully safe one | |
40 | would have to change allocate_optimized_out_value to allocate everything as | |
41 | non-lazy. I find that as a too ugly workaround of the codebase. | |
42 | ||
43 | No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu. | |
44 | ||
45 | ||
46 | Andre, do you still see the bug even with this patch? | |
47 | ||
48 | ||
49 | Thanks, | |
50 | Jan | |
51 | ||
52 | ||
53 | gdb/ | |
54 | 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com> | |
55 | ||
56 | Fix internal error regression. | |
57 | * value.c (value_primitive_field): Handle value_optimized_out. Move | |
58 | packed bitfields comment. | |
59 | ||
60 | gdb/testsuite/ | |
61 | 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com> | |
62 | ||
63 | Fix internal error regression. | |
64 | * gdb.dwarf2/implptr-optimized-out.S: New file. | |
65 | * gdb.dwarf2/implptr-optimized-out.exp: New file. | |
66 | ||
67 | --- a/gdb/value.c | |
68 | +++ b/gdb/value.c | |
69 | @@ -2482,16 +2482,19 @@ value_primitive_field (struct value *arg1, int offset, | |
70 | description correctly. */ | |
71 | check_typedef (type); | |
72 | ||
73 | - /* Handle packed fields */ | |
74 | - | |
75 | - if (TYPE_FIELD_BITSIZE (arg_type, fieldno)) | |
76 | + if (value_optimized_out (arg1)) | |
77 | + v = allocate_optimized_out_value (type); | |
78 | + else if (TYPE_FIELD_BITSIZE (arg_type, fieldno)) | |
79 | { | |
80 | - /* Create a new value for the bitfield, with bitpos and bitsize | |
81 | + /* Handle packed fields. | |
82 | + | |
83 | + Create a new value for the bitfield, with bitpos and bitsize | |
84 | set. If possible, arrange offset and bitpos so that we can | |
85 | do a single aligned read of the size of the containing type. | |
86 | Otherwise, adjust offset to the byte containing the first | |
87 | bit. Assume that the address, offset, and embedded offset | |
88 | are sufficiently aligned. */ | |
89 | + | |
90 | int bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno); | |
91 | int container_bitsize = TYPE_LENGTH (type) * 8; | |
92 | ||
93 | --- /dev/null | |
94 | +++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S | |
95 | @@ -0,0 +1,166 @@ | |
96 | +/* Copyright 2010, 2011 Free Software Foundation, Inc. | |
97 | + | |
98 | + This program is free software; you can redistribute it and/or modify | |
99 | + it under the terms of the GNU General Public License as published by | |
100 | + the Free Software Foundation; either version 3 of the License, or | |
101 | + (at your option) any later version. | |
102 | + | |
103 | + This program is distributed in the hope that it will be useful, | |
104 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
105 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
106 | + GNU General Public License for more details. | |
107 | + | |
108 | + You should have received a copy of the GNU General Public License | |
109 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
110 | + | |
111 | + .section .debug_info | |
112 | +d: | |
113 | + .long debug_end - 1f /* Length of Compilation Unit Info */ | |
114 | +1: | |
115 | + .2byte 0x3 /* DWARF version number */ | |
116 | + .long .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ | |
117 | + .byte 0x4 /* Pointer Size (in bytes) */ | |
118 | + .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ | |
119 | + .ascii "GNU C 4.4.3\0" /* DW_AT_producer */ | |
120 | + .byte 0x1 /* DW_AT_language */ | |
121 | + .ascii "1.c\0" /* DW_AT_name */ | |
122 | + | |
123 | +.Ltype_int: | |
124 | + .uleb128 0x7 /* DW_TAG_base_type */ | |
125 | + .byte 0x4 /* DW_AT_byte_size */ | |
126 | + .byte 0x5 /* DW_AT_encoding */ | |
127 | + .ascii "int\0" /* DW_AT_name */ | |
128 | + | |
129 | +.Ltype_struct: | |
130 | + .uleb128 0x2 /* DW_TAG_structure_type */ | |
131 | + .ascii "s\0" /* DW_AT_name */ | |
132 | + .byte 4 /* DW_AT_byte_size */ | |
133 | + | |
134 | + .uleb128 0x3 /* DW_TAG_member */ | |
135 | + .ascii "f\0" /* DW_AT_name */ | |
136 | + .4byte .Ltype_int - d /* DW_AT_type */ | |
137 | + .byte 0 /* DW_AT_data_member_location */ | |
138 | + | |
139 | + .byte 0x0 /* end of children of DW_TAG_structure_type */ | |
140 | + | |
141 | + .uleb128 6 /* Abbrev: DW_TAG_subprogram */ | |
142 | + .ascii "main\0" /* DW_AT_name */ | |
143 | + .4byte main /* DW_AT_low_pc */ | |
144 | + .4byte main + 0x100 /* DW_AT_high_pc */ | |
145 | + .4byte .Ltype_int - d /* DW_AT_type */ | |
146 | + .byte 1 /* DW_AT_external */ | |
147 | + | |
148 | +.Ltype_structptr: | |
149 | + .uleb128 0x5 /* DW_TAG_pointer_type */ | |
150 | + .byte 0x4 /* DW_AT_byte_size */ | |
151 | + .long .Ltype_struct - d /* DW_AT_type */ | |
152 | + | |
153 | +.Lvar_out: | |
154 | + .uleb128 0x4 /* (DW_TAG_variable) */ | |
155 | + .ascii "v\0" /* DW_AT_name */ | |
156 | + .byte 0 /* DW_AT_location: DW_FORM_block1 */ | |
157 | + .4byte .Ltype_struct - d /* DW_AT_type */ | |
158 | + | |
159 | + .uleb128 0x4 /* (DW_TAG_variable) */ | |
160 | + .ascii "p\0" /* DW_AT_name */ | |
161 | + .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */ | |
162 | +1: | |
163 | + .byte 0xf2 /* DW_OP_GNU_implicit_pointer */ | |
164 | + .4byte .Lvar_out - d /* referenced DIE */ | |
165 | + .sleb128 0 /* offset */ | |
166 | +2: | |
167 | + .4byte .Ltype_structptr - d /* DW_AT_type */ | |
168 | + | |
169 | + .byte 0x0 /* end of children of main */ | |
170 | + | |
171 | + .byte 0x0 /* end of children of CU */ | |
172 | +debug_end: | |
173 | + | |
174 | + .section .debug_abbrev | |
175 | +.Ldebug_abbrev0: | |
176 | + | |
177 | + .uleb128 0x1 /* (abbrev code) */ | |
178 | + .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ | |
179 | + .byte 0x1 /* DW_children_yes */ | |
180 | + .uleb128 0x25 /* (DW_AT_producer) */ | |
181 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
182 | + .uleb128 0x13 /* (DW_AT_language) */ | |
183 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
184 | + .uleb128 0x3 /* (DW_AT_name) */ | |
185 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
186 | + .byte 0x0 | |
187 | + .byte 0x0 | |
188 | + | |
189 | + .uleb128 0x2 /* (abbrev code) */ | |
190 | + .uleb128 0x13 /* (TAG: DW_TAG_structure_type) */ | |
191 | + .byte 0x1 /* DW_children_yes */ | |
192 | + .uleb128 0x3 /* (DW_AT_name) */ | |
193 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
194 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
195 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
196 | + .byte 0 | |
197 | + .byte 0 | |
198 | + | |
199 | + .uleb128 0x3 /* (abbrev code) */ | |
200 | + .uleb128 0xd /* (TAG: DW_TAG_member) */ | |
201 | + .byte 0 /* DW_children_no */ | |
202 | + .uleb128 0x3 /* (DW_AT_name) */ | |
203 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
204 | + .uleb128 0x49 /* (DW_AT_type) */ | |
205 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
206 | + .uleb128 0x38 /* (DW_AT_data_member_location) */ | |
207 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
208 | + .byte 0 | |
209 | + .byte 0 | |
210 | + | |
211 | + .uleb128 0x4 /* (abbrev code) */ | |
212 | + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ | |
213 | + .byte 0x0 /* DW_children_yes */ | |
214 | + .uleb128 0x3 /* (DW_AT_name) */ | |
215 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
216 | + .uleb128 0x02 /* (DW_AT_location) */ | |
217 | + .uleb128 0xa /* (DW_FORM_block1) */ | |
218 | + .uleb128 0x49 /* (DW_AT_type) */ | |
219 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
220 | + .byte 0x0 | |
221 | + .byte 0x0 | |
222 | + | |
223 | + .uleb128 0x5 /* (abbrev code) */ | |
224 | + .uleb128 0xf /* (TAG: DW_TAG_pointer_type) */ | |
225 | + .byte 0x0 /* DW_children_no */ | |
226 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
227 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
228 | + .uleb128 0x49 /* (DW_AT_type) */ | |
229 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
230 | + .byte 0x0 | |
231 | + .byte 0x0 | |
232 | + | |
233 | + .uleb128 6 /* Abbrev code */ | |
234 | + .uleb128 0x2e /* DW_TAG_subprogram */ | |
235 | + .byte 1 /* has_children */ | |
236 | + .uleb128 0x3 /* DW_AT_name */ | |
237 | + .uleb128 0x8 /* DW_FORM_string */ | |
238 | + .uleb128 0x11 /* DW_AT_low_pc */ | |
239 | + .uleb128 0x1 /* DW_FORM_addr */ | |
240 | + .uleb128 0x12 /* DW_AT_high_pc */ | |
241 | + .uleb128 0x1 /* DW_FORM_addr */ | |
242 | + .uleb128 0x49 /* DW_AT_type */ | |
243 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
244 | + .uleb128 0x3f /* DW_AT_external */ | |
245 | + .uleb128 0xc /* DW_FORM_flag */ | |
246 | + .byte 0x0 /* Terminator */ | |
247 | + .byte 0x0 /* Terminator */ | |
248 | + | |
249 | + .uleb128 0x7 /* (abbrev code) */ | |
250 | + .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ | |
251 | + .byte 0 /* DW_children_no */ | |
252 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
253 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
254 | + .uleb128 0x3e /* (DW_AT_encoding) */ | |
255 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
256 | + .uleb128 0x3 /* (DW_AT_name) */ | |
257 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
258 | + .byte 0 | |
259 | + .byte 0 | |
260 | + | |
261 | + .byte 0x0 | |
262 | --- /dev/null | |
263 | +++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp | |
264 | @@ -0,0 +1,37 @@ | |
265 | +# Copyright 2011 Free Software Foundation, Inc. | |
266 | + | |
267 | +# This program is free software; you can redistribute it and/or modify | |
268 | +# it under the terms of the GNU General Public License as published by | |
269 | +# the Free Software Foundation; either version 3 of the License, or | |
270 | +# (at your option) any later version. | |
271 | +# | |
272 | +# This program is distributed in the hope that it will be useful, | |
273 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
274 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
275 | +# GNU General Public License for more details. | |
276 | +# | |
277 | +# You should have received a copy of the GNU General Public License | |
278 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
279 | +load_lib dwarf.exp | |
280 | + | |
281 | +# This test can only be run on targets which support DWARF-2 and use gas. | |
282 | +if {![dwarf2_support]} { | |
283 | + return 0 | |
284 | +} | |
285 | + | |
286 | +set testfile "implptr-optimized-out" | |
287 | +set srcfile ${testfile}.S | |
288 | +set mainfile main.c | |
289 | +set executable ${testfile} | |
290 | +set binfile ${objdir}/${subdir}/${executable} | |
291 | + | |
292 | +if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" {}] { | |
293 | + return -1 | |
294 | +} | |
295 | + | |
296 | +# DW_OP_GNU_implicit_pointer implementation requires a valid frame. | |
297 | +if ![runto_main] { | |
298 | + return -1 | |
299 | +} | |
300 | + | |
301 | +gdb_test "p p->f" " = <optimized out>" | |
302 |