* how to support C type qualifiers applied to arrays?
@ 2006-11-27 22:42 Gary Funck
2006-11-27 23:10 ` Daniel Jacobowitz
0 siblings, 1 reply; 13+ messages in thread
From: Gary Funck @ 2006-11-27 22:42 UTC (permalink / raw)
To: gdb
Consider the following:
[config: Fedora Core 5, x86_64, gdb 6.3 and GCC 4.1.]
% cat -n const_array.c
1 const volatile int array[5] = {1,2,3,4,5};
2 volatile int s;
3
4 int
5 main()
6 {
7 int i;
8 for (i = 0, s = 0; i < 5; ++i) s += array[i];
9 }
Above, what we'd like to see is that the qualifiers
"const" and "volatile" on references to the array named
'array' are known to gdb.
Not so:
(gdb) ptype s
type = volatile int
(gdb) ptype array
type = int [5]
(gdb) ptype array[4]
type = int
The lack of c-v qualifiers on 'array' above, probably doesn't
impact GDB or its users very much at the moment. However,
it does impact the development of GDB support for
an experimental dialect of "C" called UPC (see http://upc.gwu.edu),
which is something that I'm working on at the moment.
In UPC a new qualifier, "shared", is added to indicate that a variable
is shared across all UPC threads. "shared" can be applied to
scalars, arrays, structures and other "C" language objects.
Thus, if 'array' above is to be shared, it would be declared:
shared int array[5];
Accesses to UPC shared objects cannot generally be implemented
as direct loads and stores. The UPC compiler also needs to
know that an array indexing operation is being performed
on a shared array, because UPC's indexing operation propagates
over every thread (A[i+1] may index the data on the next thread
in sequence from the thread with affinity to A[i], for example).
GDB will need to know about the UPC "shared" qualifier
as well so that GDB can properly access UPC shared objects.
Extending C-V qualifiers to include other qualifiers within
GDB isn't difficult. However, GDB's lack of support for C-V
qualifiers on array types is a major obstacle to properly supporting
accesses to UPC shared arrays.
I'm wondering if anyone has looked at how GDB handles qualifiers
on array types and array accesses, or if you can suggest how
that might best be supported?
-----
The discussion below adds detail, and explores a few
alternatives.
Running "objdump -W const_array", we can print out the
DWARF information.
Here is the declaration of "array":
<1><c6>: Abbrev Number: 7 (DW_TAG_variable)
DW_AT_name : array
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_type : <de>
DW_AT_external : 1
DW_AT_location : 9 byte block: 3 60 8 50 0 0 0 0 0 (DW_OP_addr:
500860)
The type definition is at die offset <de>. Following
that reference, we see the chain of const and volatile:
<1><de>: Abbrev Number: 8 (DW_TAG_const_type)
DW_AT_type : <e3>
<1><e3>: Abbrev Number: 9 (DW_TAG_volatile_type)
DW_AT_type : <a1>
Where the underlying array type is given by <a1>:
<1><a1>: Abbrev Number: 5 (DW_TAG_array_type)
DW_AT_sibling : <b1>
DW_AT_type : <9a>
<1><9a>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
There are two ways of looking at the debugging info.
generated above:
1. The DWARF 2 info. accurately reflects the original
declaration.
2. The "const" and "volatile" attributes should be
propagated to the element type. Thus above, we should
have seen the type of "array" (schematically) as:
(array_type (domain int 5)
(element_type
(const (volatile (base_type int)))))
-----
A few questions that arise:
Q: Is GCC generating an inaccurate DWARF 2 representation
to describe a qualified array type, or is GDB not
interpreting the DWARF 2 information correctly?
Q: Which representation (associating qualifiers with the
array or with the array's ultimate element type) most
accurately reflects "C" semantics?
Due to the large installed GCC installed base (as well as that of
other compilers which generate DWARF 2 information in a similar
fashion to GCC), we maximize interoperability
if we localize the representation issue to GDB, rather
than going back to GCC to generate a different
Dwarf 2 representation.
Taking a look at read_tag_const_type() in dwarf2read.c:
static void
read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *base_type;
if (die->type)
{
return;
}
base_type = die_type (die, cu);
set_die_type (die, make_cv_type (1, TYPE_VOLATILE (base_type), base_type,
0),
cu);
}
We see that make_cv_type() is called to qualify 'base_type' as "const".
Make_cv_type() does this by setting a flag bit in the 'instance_flags'
field of base_type. In our example above, 'base_type' is an array type.
Thus, gdb applies the C-V qualifiers encoded in the DWARF 2 representation
to the containing array type, but does not propagate these qualifiers to
the element type.
-----
In order to make GDB aware that an array type, or an indexed array
element is qualified, two approaches come to mind:
1) Encode the fact that the array's elements are C-V qualified
by propagating the C-V qualifiers down to the element type.
If we know that base_type above isn't otherwise aliased (i.e.,
linked into some other type chain), we could try something
like the following:
base_type = die_type (die, cu);
if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
{
struct type *final_array_type = type;
struct type *final_elem_type TYPE_TARGET_TYPE (final_array_type);
/* Propagate qualifiers down to the element type of an array. */
while (TYPE_CODE (final_elem_type) == TYPE_CODE_ARRAY)
{
final_array_type = final_elem_type;
final_elem_type = TYPE_TARGET_TYPE (final_array_type);
}
final_elem_type = make_cv_type (1, TYPE_VOLATILE (final_elem_type),
final_elem_type, 0);
TYPE_TARGET_TYPE (final_array_type) = final_elem_type;
}
else
{
base_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
}
set_die_type (die, base_type, cu);
If make_cv_type() were generalized to accept various qualifier flags, we
could place the logic that propagates the C-V qualifiers into this
new implementation of make_cv_type(), thus simplifying the callers like
read_tag_const_type() above, so that they are unaware of the propagation.
2) Dynamically compute whether and array type or array indexing
operation will result in a qualified type. This moves
the calculation shown above into GDB's expression evaluation logic.
Performing the propagation of type qualifiers in the expression
evaluator is further complicated by the fact that the
qualifier information will have to be propagated up and down the tree.
For example:
typedef const int c5_t[5];
typedef volatile c5_t v10_c5_t[10];
v10_c5_t A[20];
if we ask:
) ptype A[10]
we'd probably expect to see:
volatile const int [10][5]
which traverses down the tree, to the element type in order to
calculate the final type of the array elements. Thus, we might
view the "const" and "volatile" qualifiers as being propagated
up the tree to any referencing type or value expression.
Similarly,
) ptype A[10][9]
should yield
volatile const int [5]
which propagates the volatile attribute of A[10][9] down the expression
tree and combines it with the const qualifier of the c5_t type.
-----
I haven't looked at GDB's expression evaluator to determine if the dynamic
calculation of the qualifiers is feasible or not. The dynamic calculation
method has the advantage that it leaves the symbol readers alone and can
also properly handle cross object file references (which are handled via
symbolic tag references).
I'd appreciate hearing any comments/ideas that you have on this
topic, including whether I've properly characterized the problem
and the proposed solutions.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: how to support C type qualifiers applied to arrays?
2006-11-27 22:42 how to support C type qualifiers applied to arrays? Gary Funck
@ 2006-11-27 23:10 ` Daniel Jacobowitz
2006-11-27 23:30 ` Jim Blandy
2006-11-27 23:45 ` Joseph S. Myers
0 siblings, 2 replies; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-11-27 23:10 UTC (permalink / raw)
To: Gary Funck; +Cc: gdb
On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck wrote:
> Q: Is GCC generating an inaccurate DWARF 2 representation
> to describe a qualified array type, or is GDB not
> interpreting the DWARF 2 information correctly?
I will defer to experts on this but I believe GCC is incorrect.
In C there is no such thing as a "qualified array type". The array has
an element type (which can be c-v qualified) and a bound, and no
qualifiers of its own. But you can say "int x[const 1]". You can't
define variables of this type, but you can use them in function
declarations. I believe it means roughly "int *const x" within the
function; normally you can write:
int f(int x[1])
{
x[0] = 1;
x++;
return 0;
}
But this is invalid:
int f(int x[const 1])
{
x[0] = 1;
x++;
return 0;
}
So, by stuffing qualifiers on the outside, we lose the ability to
present that. But GCC emits debug info for those as int f(int *)
and int f(int * const) respectively, so it's irrelevant in practice.
We can assume the qualifiers belonged to the element type in GDB.
> We see that make_cv_type() is called to qualify 'base_type' as "const".
> Make_cv_type() does this by setting a flag bit in the 'instance_flags'
> field of base_type. In our example above, 'base_type' is an array type.
My first recommendation would be to have make_cv_type create a new
array type, with the qualified element type. However, doing this
without being excessively wasteful might require care - you couldn't
reuse main_type since the qualified array could not share main_type.
But the waste is acceptably small.
The alternative would be to have a function called to get the base type
of an array which did appropriate qualification at that point. The
easiest way to do it might be to make TYPE_TARGET_TYPE into an
appropriate function. Better than auditing the 465 or so calls.
The first is probably better. It should be done in gdbtypes.c, not
in the DWARF reader specifically.
I see that these are roughly the same two possibilities you offered :-)
I would do it at a different level than expression evaluation, though,
as you can see above, if I took the second option.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: how to support C type qualifiers applied to arrays?
2006-11-27 23:10 ` Daniel Jacobowitz
@ 2006-11-27 23:30 ` Jim Blandy
2006-11-27 23:52 ` Daniel Jacobowitz
2006-11-27 23:45 ` Joseph S. Myers
1 sibling, 1 reply; 13+ messages in thread
From: Jim Blandy @ 2006-11-27 23:30 UTC (permalink / raw)
To: Gary Funck; +Cc: gdb
Daniel Jacobowitz <drow@false.org> writes:
> On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck wrote:
>> Q: Is GCC generating an inaccurate DWARF 2 representation
>> to describe a qualified array type, or is GDB not
>> interpreting the DWARF 2 information correctly?
>
> I will defer to experts on this but I believe GCC is incorrect.
I think GCC is wrong, too. The DWARF is unambiguous, and it's
attaching the qualifiers to the wrong part of the type tree, just as
Daniel says.
> My first recommendation would be to have make_cv_type create a new
> array type, with the qualified element type. However, doing this
> without being excessively wasteful might require care - you couldn't
> reuse main_type since the qualified array could not share main_type.
> But the waste is acceptably small.
If this were a less obscure feature, then I could see GDB deliberately
misreading the DWARF to accomodate GCC. But in this case, it doesn't
seem like a show-stopper; wouldn't it be better to just report the GCC
bug and let GDB continue to interpret DWARF as written? These kludges
come back to haunt us. I gather Gary is working with a modified GCC
anyway, so it shouldn't be hard for him to fix his compiler. (If
that's not so, Gary, please set me straight.)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: how to support C type qualifiers applied to arrays?
2006-11-27 23:30 ` Jim Blandy
@ 2006-11-27 23:52 ` Daniel Jacobowitz
0 siblings, 0 replies; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-11-27 23:52 UTC (permalink / raw)
To: Jim Blandy; +Cc: Gary Funck, gdb
On Mon, Nov 27, 2006 at 03:31:12PM -0800, Jim Blandy wrote:
> If this were a less obscure feature, then I could see GDB deliberately
> misreading the DWARF to accomodate GCC. But in this case, it doesn't
> seem like a show-stopper; wouldn't it be better to just report the GCC
> bug and let GDB continue to interpret DWARF as written? These kludges
> come back to haunt us. I gather Gary is working with a modified GCC
> anyway, so it shouldn't be hard for him to fix his compiler. (If
> that's not so, Gary, please set me straight.)
I've no particular preference. Thanks for the PR reference, Joseph.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: how to support C type qualifiers applied to arrays?
2006-11-27 23:10 ` Daniel Jacobowitz
2006-11-27 23:30 ` Jim Blandy
@ 2006-11-27 23:45 ` Joseph S. Myers
2006-11-27 23:55 ` Daniel Jacobowitz
1 sibling, 1 reply; 13+ messages in thread
From: Joseph S. Myers @ 2006-11-27 23:45 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Gary Funck, gdb
On Mon, 27 Nov 2006, Daniel Jacobowitz wrote:
> On Mon, Nov 27, 2006 at 02:42:12PM -0800, Gary Funck wrote:
> > Q: Is GCC generating an inaccurate DWARF 2 representation
> > to describe a qualified array type, or is GDB not
> > interpreting the DWARF 2 information correctly?
>
> I will defer to experts on this but I believe GCC is incorrect.
Specifically, GCC bug 8354 (all the patch links in that bug are broken:
GCC bug 20588: so refer to the mbox archives, but there isn't anything
much worthwhile in the patch referenced) deals with the DWARF 2
information for arrays and type qualifiers.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: how to support C type qualifiers applied to arrays?
2006-11-27 23:45 ` Joseph S. Myers
@ 2006-11-27 23:55 ` Daniel Jacobowitz
2006-12-14 20:22 ` Gary Funck
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Jacobowitz @ 2006-11-27 23:55 UTC (permalink / raw)
To: gdb
On Mon, Nov 27, 2006 at 11:44:58PM +0000, Joseph S. Myers wrote:
> Specifically, GCC bug 8354 (all the patch links in that bug are broken:
> GCC bug 20588: so refer to the mbox archives, but there isn't anything
> much worthwhile in the patch referenced) deals with the DWARF 2
> information for arrays and type qualifiers.
Thanks. Having dug through the archives, Jim's message suggests that
it should be just a matter of a couple hours for someone interested to
fix GCC.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: how to support C type qualifiers applied to arrays?
2006-11-27 23:55 ` Daniel Jacobowitz
@ 2006-12-14 20:22 ` Gary Funck
2006-12-15 22:36 ` Jim Blandy
2007-01-01 22:16 ` Jim Wilson
0 siblings, 2 replies; 13+ messages in thread
From: Gary Funck @ 2006-12-14 20:22 UTC (permalink / raw)
To: gdb; +Cc: 'Daniel Jacobowitz', Jim Wilson
> -----Original Message-----
> From: Daniel Jacobowitz
> Sent: Monday, November 27, 2006 3:55 PM
>
> Thanks. Having dug through the archives, Jim's message suggests that
> it should be just a matter of a couple hours for someone interested to
> fix GCC.
The referenced PR is here:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8354
Jim's reply is here,
http://gcc.gnu.org/bugzilla/attachment.cgi?id=12702
After spending a few days on this, I can pretty safely say
that it doesn't appear to me that fixing this in GCC is
straightforward.
The main difficulty is that GCC doesn't create new qualified
types for declarations. Rather, it sets TREE_READONLY()
and TREE_THIS_VOLATILE() in the DECL node for declarations
such as:
volatile int A[10];
Structures add an additional wrinkle:
struct s_struct
{
int a;
float b;
char c[10];
};
volatile struct s_struct S;
Here, GCC sets TREE_THIS_VOLATILE in the DECL node of S,
but does not attempt to clone the type description of
s_struct, and to populate the volatile qualifier across all
contained member types. This works for GCC because it
propagates the qualifiers as it evaluates expressions.
Thus when evaluating S.c[10], GCC starts with the knowledge
that S is volatile, thus S.c is volatile, and S.c[1] is
volatile.
For GCC to fix the problem, it need to rewrite the type
definition for the type of S, along these lines:
typedef volatile int v_int;
typedef volatile float v_float;
typedef volatile char v_char;
struct v_s_struct
{
v_int a;
v_float b;
v_char c[10];
};
typedef volatile struct v_s_struct v_s_t;
v_s_t S;
Typedefs above are used to illustrate that "volatile" must
be factored to the lowest level types of the components,
and must also appear at the struct level to accommodate
operations on the entire structure.
When things are done this way, GDB gets understands
that everything related to S is volatile:
(gdb) ptype S
type = volatile struct v_s_struct {
volatile int a;
volatile float b;
char c[10];
}
well, almost. GDB didn't track the fact that the
struct member "c" is also volatile, because GCC failed
to encode the element type of the array as being
volatile:
<2><70>: Abbrev Number: 6 (DW_TAG_member)
DW_AT_name : c
DW_AT_decl_file : 1
DW_AT_decl_line : 8
DW_AT_type : <94>
DW_AT_data_member_location: 2 byte block: 23 8 (DW_OP_plus_uconst:
8)
<1><94>: Abbrev Number: 2 (DW_TAG_volatile_type)
DW_AT_type : <7d>
<1><7d>: Abbrev Number: 7 (DW_TAG_array_type)
DW_AT_sibling : <8d>
DW_AT_type : <45>
<1><45>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : (indirect string, offset: 0x3f): char
DW_AT_byte_size : 1
DW_AT_encoding : 6 (signed char)
If GDB tracked the type qualifiers applied during
expression evaluation in a fashion similar to GCC, there
would be no issue.
This lack of ability to properly track qualifiers when
evaluating expressions isn't much of an issue for regular "C",
though it might confuse users of GDB who do things like
ptype S.a
and expect GDB to come back with "volatile int" (in the
first version of the example which did not use typedefs).
To implement debugging of "UPC" programs it
is important to be able to track the "shared" qualifier,
because accesses to shared variables generally requires
callng a runtime procedure in the program being debugged,
or knowledge of the methods for accessing shared variables.
The bottom line is that the fix in GCC appears to be more
difficult than it first appears, and probably the best
approach is for GDB to properly track type qualifiers
as it evaluates expressions.
I'd appreciate hearing from developers more knowledgeable
in the internals of GCC and GDB, to confirm/deny my observations
above, and to perhaps suggest better approaches.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: how to support C type qualifiers applied to arrays?
2006-12-14 20:22 ` Gary Funck
@ 2006-12-15 22:36 ` Jim Blandy
2006-12-19 19:09 ` Gary Funck
2006-12-20 2:40 ` Gary Funck
2007-01-01 22:16 ` Jim Wilson
1 sibling, 2 replies; 13+ messages in thread
From: Jim Blandy @ 2006-12-15 22:36 UTC (permalink / raw)
To: Gary Funck; +Cc: gdb, 'Daniel Jacobowitz', Jim Wilson
"Gary Funck" <gary@intrepid.com> writes:
> The main difficulty is that GCC doesn't create new qualified
> types for declarations. Rather, it sets TREE_READONLY()
> and TREE_THIS_VOLATILE() in the DECL node for declarations
> such as:
>
> volatile int A[10];
Ugh. That's a shame. Can't dwarf2out.c fix things up as it builds
the tree of struct die_structs from the GCC 'tree' type tree?
> Structures add an additional wrinkle:
>
> struct s_struct
> {
> int a;
> float b;
> char c[10];
> };
> volatile struct s_struct S;
>
> Here, GCC sets TREE_THIS_VOLATILE in the DECL node of S,
> but does not attempt to clone the type description of
> s_struct, and to populate the volatile qualifier across all
> contained member types. This works for GCC because it
> propagates the qualifiers as it evaluates expressions.
> Thus when evaluating S.c[10], GCC starts with the knowledge
> that S is volatile, thus S.c is volatile, and S.c[1] is
> volatile.
Okay --- this is a different problem altogether. This one is indeed
GDB's fault: referring to a field of a volatile- or const-qualified
structure should get you a member with the same qualifiers. ISO/IEC
9899:1999 (E), 6.5.2.3 paragraph 3 says:
A postfix expression followed by the . operator and an identifier
designates a member of a structure or union object. The value is
that of the named member, and is an lvalue if the first expression
is an lvalue. If the first expression has qualified type, the
result has the so-qualified version of the type of the designated
member.
GDB doesn't implement the behavior described in that that last
sentence.
GCC, however, is producing the right DWARF for this (in Fedora Core
5, at least):
$ cat volatile-struct.c
struct s_struct
{
int a;
float b;
char c[10];
};
volatile struct s_struct S;
$ gcc -c -g volatile-struct.c
$ readelf -wi volatile-struct.o
The section .debug_info contains:
Compilation Unit @ offset 0x0:
Length: 226
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0
DW_AT_low_pc : 0
DW_AT_producer : GNU C 4.1.1 20060525 (Red Hat 4.1.1-1)
DW_AT_language : 1 (ANSI C)
DW_AT_name : volatile-struct.c
DW_AT_comp_dir : /home/jimb/play
<1><62>: Abbrev Number: 2 (DW_TAG_structure_type)
DW_AT_sibling : <98>
DW_AT_name : s_struct
DW_AT_byte_size : 20
DW_AT_decl_file : 1
DW_AT_decl_line : 2
<2><73>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : a
DW_AT_decl_file : 1
DW_AT_decl_line : 3
DW_AT_type : <98>
DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0)
<2><7f>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : b
DW_AT_decl_file : 1
DW_AT_decl_line : 4
DW_AT_type : <9f>
DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4)
<2><8b>: Abbrev Number: 3 (DW_TAG_member)
DW_AT_name : c
DW_AT_decl_file : 1
DW_AT_decl_line : 5
DW_AT_type : <a8>
DW_AT_data_member_location: 2 byte block: 23 8 (DW_OP_plus_uconst: 8)
<1><98>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
<1><9f>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : float
DW_AT_byte_size : 4
DW_AT_encoding : 4 (float)
<1><a8>: Abbrev Number: 5 (DW_TAG_array_type)
DW_AT_sibling : <b8>
DW_AT_type : <c8>
<2><b1>: Abbrev Number: 6 (DW_TAG_subrange_type)
DW_AT_type : <b8>
DW_AT_upper_bound : 9
<1><b8>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : unsigned int
DW_AT_byte_size : 4
DW_AT_encoding : 7 (unsigned)
<1><c8>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : char
DW_AT_byte_size : 1
DW_AT_encoding : 6 (signed char)
<1><d0>: Abbrev Number: 7 (DW_TAG_variable)
DW_AT_name : S
DW_AT_decl_file : 1
DW_AT_decl_line : 7
DW_AT_type : <e0>
DW_AT_external : 1
DW_AT_location : 5 byte block: 3 0 0 0 0 (DW_OP_addr: 0)
<1><e0>: Abbrev Number: 8 (DW_TAG_volatile_type)
DW_AT_type : <62>
$
Note that we've got (making up some notation, but I think it's clear
enough):
variable "S" {
type: &volatile_type {
type: &structure_type "s_struct" { ... }
}
}
Which is exactly what it should be: a volatile qualifier applied to a
structure type. The DWARF info should not contain a separate instance
of s_struct with volatile qualifiers propagated down to all its
members; that's GDB's job.
But as we've agreed before, the debug info for the array case you
originally posted is wrong:
$ cat volatile-array.c
volatile int A[10];
$ gcc -g -c volatile-array.c
$ readelf -wi volatile-array.o
The section .debug_info contains:
Compilation Unit @ offset 0x0:
Length: 154
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0
DW_AT_low_pc : 0
DW_AT_producer : GNU C 4.1.1 20060525 (Red Hat 4.1.1-1)
DW_AT_language : 1 (ANSI C)
DW_AT_name : volatile-array.c
DW_AT_comp_dir : /home/jimb/play
<1><61>: Abbrev Number: 2 (DW_TAG_array_type)
DW_AT_sibling : <71>
DW_AT_type : <81>
<2><6a>: Abbrev Number: 3 (DW_TAG_subrange_type)
DW_AT_type : <71>
DW_AT_upper_bound : 9
<1><71>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : unsigned int
DW_AT_byte_size : 4
DW_AT_encoding : 7 (unsigned)
<1><81>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
<1><88>: Abbrev Number: 5 (DW_TAG_variable)
DW_AT_name : A
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_type : <98>
DW_AT_external : 1
DW_AT_location : 5 byte block: 3 0 0 0 0 (DW_OP_addr: 0)
<1><98>: Abbrev Number: 6 (DW_TAG_volatile_type)
DW_AT_type : <61>
$
The DWARF type should reflect 'volatile' applied to the element type,
as it's written in the C code:
variable "A" {
type: &array_type {
type: &volatile_type {
type: &base_type "int" { ... }
}
}
}
whereas the DWARF above is:
variable "A" {
type: &volatile_type {
type: &array_type {
type: base_type "int" { ... }
}
}
}
> For GCC to fix the problem, it need to rewrite the type
> definition for the type of S, along these lines:
>
> typedef volatile int v_int;
> typedef volatile float v_float;
> typedef volatile char v_char;
> struct v_s_struct
> {
> v_int a;
> v_float b;
> v_char c[10];
> };
> typedef volatile struct v_s_struct v_s_t;
> v_s_t S;
>
> Typedefs above are used to illustrate that "volatile" must
> be factored to the lowest level types of the components,
> and must also appear at the struct level to accommodate
> operations on the entire structure.
Just to be clear: GCC should *not* perform the transformation you're
suggesting here and record the result in the DWARF info. GDB should
propagate the qualifiers itself.
^ permalink raw reply [flat|nested] 13+ messages in thread* RE: how to support C type qualifiers applied to arrays?
2006-12-15 22:36 ` Jim Blandy
@ 2006-12-19 19:09 ` Gary Funck
2006-12-20 2:40 ` Gary Funck
1 sibling, 0 replies; 13+ messages in thread
From: Gary Funck @ 2006-12-19 19:09 UTC (permalink / raw)
To: gdb
Cc: 'Daniel Jacobowitz', 'Jim Wilson', 'Jim Blandy'
Jim Blandy wrote:
>
> "Gary Funck" <gary@intrepid.com> writes:
> > The main difficulty is that GCC doesn't create new qualified
> > types for declarations. Rather, it sets TREE_READONLY()
> > and TREE_THIS_VOLATILE() in the DECL node for declarations
> > such as:
> >
> > volatile int A[10];
>
> Ugh. That's a shame. Can't dwarf2out.c fix things up as it builds
> the tree of struct die_structs from the GCC 'tree' type tree?
In theory, it should be possible. I worked on this a bit, but I think
to do it right, this fix will require contribution/direction from someone
more conversant in the GCC front-end, and more knowledgeable about how
the other language front-ends use both the DWARF 2 generation
routines, and the extent to which they depend upon the type information
remaining in its current form.
Three approaches to fixing the front end to create
appropriate DWARF 2 information come to mind:
(1) Change the GCC front-end, so that when it creates
type information and associates the type information
with a declaration that it fully qualifies the type definition,
in a way that preserves language semantics, yet also ensures
that the correct DWARF 2 information is generated for qualified
types.
(2) Create the fully qualified type definition in dwarf2out.c
(probably in routines that handle DECL items such as
gen_formal_parameter_die(), gen_variable_die() and gen_field_die()).
There are two likely sub-approaches: (i) keep this fully
qualified type definition on the side, parallel to the existing
type definition structure, or (ii) smash the new fully qualified
type into the DECL node's TREE_TYPE() value. Keeping a
parallel definition may be difficult because various parts
of dwarfout.c may need to refer back to the DECL node's type
value, and all places that do this will have to be found and fixed.
Cross-type references and typedef's create another set of problems.
Rewriting the declaration's type value is the most straightforward,
but runs the risk of violating various assumptions made by the
language front-ends, and will require a rather elaborate "deep copy"
mechanism to make sure the fix up is done correctly.
(3) Run a final pass over the internal DWARF tree built within
dwarfout.c to fix up the type qualifiers, basically propagating
the const_ and volatile_ qualifiers down to lower levels as
required. This is probably doable, but will slow down DWARF
generation for all compilations, even if most compilations
seldom use "const" and "volatile" (and other qualifiers, such
as UPC's "shared", "strict", and "relaxed"). In this case, it
seems that dwarf2out.c is fixing representation
issues that more correctly should be solved in the front-end.
Given the tradeoffs, choice (1) above, where the type description
is fully qualified at the time the type is bound to the DECL item,
seems more correct, but may impact the correct operation of
the various language front-ends and therefore will require more
care and more study. Choice (2) is perhaps a bad compromise,
and choice (3) is likely workable, but kludgy.
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: how to support C type qualifiers applied to arrays?
2006-12-15 22:36 ` Jim Blandy
2006-12-19 19:09 ` Gary Funck
@ 2006-12-20 2:40 ` Gary Funck
2006-12-27 2:12 ` Jim Blandy
1 sibling, 1 reply; 13+ messages in thread
From: Gary Funck @ 2006-12-20 2:40 UTC (permalink / raw)
To: gdb
Cc: 'Daniel Jacobowitz', 'Jim Wilson', 'Jim Blandy'
> From: Jim Blandy
> Sent: Friday, December 15, 2006 2:37 PM
>
> "Gary Funck" <gary@intrepid.com> writes:
> > Here, GCC sets TREE_THIS_VOLATILE in the DECL node of S,
> > but does not attempt to clone the type description of
> > s_struct, and to populate the volatile qualifier across all
> > contained member types. This works for GCC because it
> > propagates the qualifiers as it evaluates expressions.
> > Thus when evaluating S.c[10], GCC starts with the knowledge
> > that S is volatile, thus S.c is volatile, and S.c[1] is
> > volatile.
>
> Okay --- this is a different problem altogether. This one is indeed
> GDB's fault: referring to a field of a volatile- or const-qualified
> structure should get you a member with the same qualifiers.
> [...]
> > Typedefs above are used to illustrate that "volatile" must
> > be factored to the lowest level types of the components,
> > and must also appear at the struct level to accommodate
> > operations on the entire structure.
>
> Just to be clear: GCC should *not* perform the transformation you're
> suggesting here and record the result in the DWARF info. GDB should
> propagate the qualifiers itself.
This leads to the next question: how difficult will it be to
teach GDB to properly track type qualifiers when evaluating
expressions? Which files/functions will likely need to be
changed? Are there mechanisms within GDB already that track
various value attributes along with the expression values
themselves?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: how to support C type qualifiers applied to arrays?
2006-12-20 2:40 ` Gary Funck
@ 2006-12-27 2:12 ` Jim Blandy
0 siblings, 0 replies; 13+ messages in thread
From: Jim Blandy @ 2006-12-27 2:12 UTC (permalink / raw)
To: Gary Funck; +Cc: gdb, 'Daniel Jacobowitz', 'Jim Wilson'
"Gary Funck" <gary@intrepid.com> writes:
>> From: Jim Blandy
>> Sent: Friday, December 15, 2006 2:37 PM
>>
>> "Gary Funck" <gary@intrepid.com> writes:
>> > Here, GCC sets TREE_THIS_VOLATILE in the DECL node of S,
>> > but does not attempt to clone the type description of
>> > s_struct, and to populate the volatile qualifier across all
>> > contained member types. This works for GCC because it
>> > propagates the qualifiers as it evaluates expressions.
>> > Thus when evaluating S.c[10], GCC starts with the knowledge
>> > that S is volatile, thus S.c is volatile, and S.c[1] is
>> > volatile.
>>
>> Okay --- this is a different problem altogether. This one is indeed
>> GDB's fault: referring to a field of a volatile- or const-qualified
>> structure should get you a member with the same qualifiers.
>> [...]
>> > Typedefs above are used to illustrate that "volatile" must
>> > be factored to the lowest level types of the components,
>> > and must also appear at the struct level to accommodate
>> > operations on the entire structure.
>>
>> Just to be clear: GCC should *not* perform the transformation you're
>> suggesting here and record the result in the DWARF info. GDB should
>> propagate the qualifiers itself.
>
> This leads to the next question: how difficult will it be to
> teach GDB to properly track type qualifiers when evaluating
> expressions? Which files/functions will likely need to be
> changed? Are there mechanisms within GDB already that track
> various value attributes along with the expression values
> themselves?
I think that should be a pretty straightforward change to
value_primitive_field, value_subscripted_rvalue, and probably
value_coerce_array.
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: how to support C type qualifiers applied to arrays?
2006-12-14 20:22 ` Gary Funck
2006-12-15 22:36 ` Jim Blandy
@ 2007-01-01 22:16 ` Jim Wilson
2007-01-09 17:01 ` Gary Funck
1 sibling, 1 reply; 13+ messages in thread
From: Jim Wilson @ 2007-01-01 22:16 UTC (permalink / raw)
To: Gary Funck; +Cc: gdb, 'Daniel Jacobowitz'
On Thu, 2006-12-14 at 12:22 -0800, Gary Funck wrote:
> The main difficulty is that GCC doesn't create new qualified
> types for declarations. Rather, it sets TREE_READONLY()
> and TREE_THIS_VOLATILE() in the DECL node for declarations
> such as:
> volatile int A[10];
If you look at the types created by the C front end, they are OK.
c_build_qualified_type knows how to handle an array correctly.
The problem arises in the DWARF2 output code. gen_type_die calls
type_main_variant for all types other than vector types, which strips
off the const and volatile type modifiers. Then it clumsily tries to
put them back later in gen_variable_die, except that for array types, it
puts them back in the wrong place.
This seems to answer the question I asked long ago. Why are we trying
to put back qualifiers from the decl? Because gen_type_die stripped
them off. This seems wrong.
If we fix gen_type_die to stop calling type_main_variant, and if we fix
gen_variable_die to stop adding back the type qualifiers, then I get the
right result. So I think I was on the right track before, we just need
another little change to gen_type_die in addition to what I already
described.
I haven't investigated this in detail yet. There may be other parts of
the code that expect to see a type main variant here, so we might need
other cascading fixes. This still seems fixable to me though.
--
Jim Wilson, GNU Tools Support, http://www.specifix.com
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: how to support C type qualifiers applied to arrays?
2007-01-01 22:16 ` Jim Wilson
@ 2007-01-09 17:01 ` Gary Funck
0 siblings, 0 replies; 13+ messages in thread
From: Gary Funck @ 2007-01-09 17:01 UTC (permalink / raw)
To: gdb; +Cc: 'Jim Wilson'
Jim Wilson wrote (in part):
> This seems to answer the question I asked long ago. Why are we trying
> to put back qualifiers from the decl? Because gen_type_die stripped
> them off. This seems wrong.
>
It seems that the use of type_main_variant()
dates back to the original port of the DWARF 1 generator
to the DWARF 2 implementation. I didn't try understanding the
DWARF 1 generator in detail, but it seemed that the use of the
type's main variant helped limit the number of unique type dies
that were generated. In any event, it doesn't appear that there
is a compelling reason to continue to use the type_main_variant()
for DWARF 2 generatiion, especially in light of the fact that
in some cases the DWARF 2 information is incorrect in the current
implmentation.
There are of course the risks that you mentioned
in your reply that there may now be implicit assumptions made
by the various clients (C, C++, Fortran, Ada, for example)
regarding dependencies upon the type_main_variant(), but we
may have to deal with those issues as they arise.
> If we fix gen_type_die to stop calling type_main_variant, and
> if we fix
> gen_variable_die to stop adding back the type qualifiers,
> then I get the
> right result. So I think I was on the right track before, we
> just need
> another little change to gen_type_die in addition to what I already
> described.
I'll give this a try, and follow up.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-01-09 17:01 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-11-27 22:42 how to support C type qualifiers applied to arrays? Gary Funck
2006-11-27 23:10 ` Daniel Jacobowitz
2006-11-27 23:30 ` Jim Blandy
2006-11-27 23:52 ` Daniel Jacobowitz
2006-11-27 23:45 ` Joseph S. Myers
2006-11-27 23:55 ` Daniel Jacobowitz
2006-12-14 20:22 ` Gary Funck
2006-12-15 22:36 ` Jim Blandy
2006-12-19 19:09 ` Gary Funck
2006-12-20 2:40 ` Gary Funck
2006-12-27 2:12 ` Jim Blandy
2007-01-01 22:16 ` Jim Wilson
2007-01-09 17:01 ` Gary Funck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox