Hi Guys,
There is a problem with unit-at-a-time compilation and DWARF debug
info generation. Consider this small test case which has been
derived from GDB's observer.c source file:
int observer_test_first_observer = 0;
int observer_test_second_observer = 0;
int observer_test_third_observer = 0;
void observer_test_first_notification_function (void)
{
observer_test_first_observer++;
}
void observer_test_second_notification_function (void)
{
observer_test_second_observer++;
}
void observer_test_third_notification_function (void)
{
observer_test_third_observer++;
}
When compiled with the current mainline gcc sources for an x86
native target and with "-g -O2 -dA" on the command line the
following debug info is produced:
[snip]
.long .LASF0 # DW_AT_name: "observer_test_first_observer"
.byte 0x1 # DW_AT_decl_file
.byte 0x1 # DW_AT_decl_line
.long 0x37 # DW_AT_type
.byte 0x1 # DW_AT_external
.byte 0x5 # DW_AT_location
.byte 0x3 # DW_OP_addr
.long observer_test_first_observer
.uleb128 0x3 # (DIE (0x37) DW_TAG_base_type)
.ascii "int\0" # DW_AT_name
.byte 0x4 # DW_AT_byte_size
.byte 0x5 # DW_AT_encoding
.uleb128 0x4 # (DIE (0x3e) DW_TAG_variable)
.long .LASF1 # DW_AT_name: "observer_test_second_observer"
.byte 0x1 # DW_AT_decl_file
.byte 0x2 # DW_AT_decl_line
.long 0x37 # DW_AT_type
.byte 0x1 # DW_AT_external
.byte 0x0 # DW_AT_const_value
[snip]
Note how observer_test_first_observer is correctly defined as having
a DW_AT_location and a DW_OP_addr whereas
observer_test_second_observer is incorrectly defined as having a
DW_AT_const_value. ie the debug info is saying that it is a
variable without a location in memory.
The reason for this behaviour is that the debug information is being
written out before the variables have been fully resolved. In
particular DECL_SET() for the second and third observer functions is
NULL when the debug info is generated, which is why they are being
given the DW_AT_const_value attribute.
In trying to solve this I found that switching the order of the
calls to lang_hooks.decls.final_write_globals() and
cgraph_varpool_assemble_pending_decls() in compile_file() worked,
and this seemed to be intuitively correct. But when I reran the gcc
testsuite I found that the change introduced a regression:
gcc.dg/varpool-1.c now had the variable
"unnecessary_static_initialized_variable" still defined at the end
of compilation.
I have investigated some more but not gotten much further, so I am
asking for help. Can anyone suggest where the conflict between
generating the debug info and deciding if the variable is going to
be emitted should really be resolved ?
Cheers
Nick