This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

DW_TAG_variable for both decl and defn?


In kernel-debuginfo-2.6.33.6-147.fc13.x86_64
	/usr/lib/debug/lib/modules/2.6.33.6-147.fc13.x86_64/vmlinux 
 Compilation unit at offset 63884337:
 Version: 3, Abbreviation section offset: 1655619, Address size: 8, Offset size: 4
 [3cecc3c]  compile_unit
           producer             (strp) "GNU C 4.4.4 20100630 (Red Hat 4.4.4-10)"
           language             (data1) ISO C89 (1)
           name                 (strp) "net/ipv4/tcp.c"
           comp_dir             (strp) "/usr/src/debug/kernel-2.6.33/linux-2.6.33.x86_64"

we see:

 [3d0b497]    variable
             name                 (strp) "tcp_memory_pressure"
             decl_file            (data1) 10
             decl_line            (data1) 247
             type                 (ref4) [3ceccfc]
             external             (flag) Yes
             declaration          (flag) Yes

(extern decl in header file) and later in the same CU:

 [3d0c424]    variable
             name                 (strp) "tcp_memory_pressure"
             decl_file            (data1) 1
             decl_line            (data2) 318
             type                 (ref4) [3ceccfc]
             external             (flag) Yes
             location             (block1)               [   0] addr 0xffffffff81b8cb04

(global defn in this CU's main source file).

I guess it's kosher enough to have one DIE for the declaration and one for
the definition.  But it was a surprise to see this happen.  In a simple
test case:

	extern int global_var;

	static int static_var;

	static int static_var = 123;

	int global_var = 456;

(with plain -g) I only get one DW_TAG_variable for each.

So I would like to understand under what conditions GCC does (or should?)
generate two entries in cases like these.

IMHO, it would be nice, if you're going to have both a decl and a defn,
for the defn to have DW_AT_specification pointing to the decl (even for C).
But that's a tangential idea.

We noticed this with systemtap, because dwarf_getscopevar (which it uses)
stops at the first matching name.  So it found the declaration DIE and said
"this has no known location" (i.e. punt to methods for extern decls of
things defined in other CUs).  This is fine for this kind of case, since we
do have those methods in systemtap (it looks up an ELF symbol to resolve
the global between CUs).

However, if it ever generated two DIEs like that for a static variable,
this would break systemtap as things stand today (if the DW_AT_declaration
one appears first in the CU's DIE list).

If that is how it's going to be, then perhaps dwarf_getscopevar should do
something like keep looking until it sees a match without DW_AT_declaration,
only giving the (first? last?) DW_AT_declaration match if there is no later
non-declaration DIE.

Petr, a check related to this is a to-do item for dwarflint high-level checks.

If you think (as I suspect) that it's just a bug for there to be two DIEs
for the same variable, then I have the reproducer:

1	extern int global_var;
2
3	extern __typeof (global_var) global_var;
4
5	int global_var = 456;

Through some macro magic, this is the essence of what's happening in the
kernel case.  The DW_AT_declaration entry emitted is for the first decl
(line 1).  I'm guessing that the __typeof magic in the line 3 decl confuses
it somehow into thinking that the extern on line 1 and the defn on line 5
don't go together, so line 5 fails to trump line 1 as it ordinarily would.
(Perhaps this would also happen if it redeclared it with __attribute__ or
something, though I haven't found another case in things I've tried.)


Thanks,
Roland

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]