Variables in Fortran modules compiled in -fPIC shared libraries will get unique address by a copy relocation to the main executable. Still .debug_info of the library contains absolute DW_AT_location of the variable - without any indirection through the GOT vector. Debugger will then print the variable location not in active use. Current FSF GDB cannot resolve these variables but it was found by a new patch for modules: http://sourceware.org/gdb/wiki/ArcherBranchManagement archer-jankratochvil-fortran-module Assuming no DW_AT_location should exist for such variables. DW_AT_declaration should be present there as such variables are NOT optimized-out. Or DW_AT_location using DW_FORM_block* indirecting GOT could be present? For C the problem does not happen with GCC as it will put there _two_ DIEs and the first one is just a declaration. Current FSF GDB ignores any non-first DIEs for a named object. Still the second invalid DIE is redundant + invalid even in the C case. GNU Fortran (GCC) 4.4.0 20090427 (Red Hat 4.4.0-3) GNU Fortran (GCC) 4.5.0 20090501 (experimental) ------------------------------------------------------------------------------ cat >lib.f90 <<EOH module lib integer :: var = 1 end module lib EOH cat >main.f90 <<EOH use lib if (var .ne. 1) call abort end EOH F="gfortran -Wall -g"; $F -o lib.so -shared -fPIC lib.f90; $F -o main main.f90 ./lib.so $ nm -D lib.so | grep var 0000000000200798 D __lib_MOD_var $ nm -D main | grep var 0000000000600c38 B __lib_MOD_var $ readelf -a lib.so | approx-grep var Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [21] .data PROGBITS 0000000000200798 00000798 0000000000000004 0000000000000000 WA 0 0 4 Symbol table '.dynsym' contains 11 entries: Num: Value Size Type Bind Vis Ndx Name 9: 0000000000200798 4 OBJECT GLOBAL DEFAULT 21 __lib_MOD_var Symbol table '.symtab' contains 57 entries: Num: Value Size Type Bind Vis Ndx Name 50: 0000000000200798 4 OBJECT GLOBAL DEFAULT 21 __lib_MOD_var $ readelf -a main | approx-grep var Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [25] .bss NOBITS 0000000000600c38 00000c34 0000000000000018 0000000000000000 WA 0 0 8 Relocation section '.rela.dyn' at offset 0x560 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000600c38 000c00000005 R_X86_64_COPY 0000000000600c38 __lib_MOD_var + 0 Symbol table '.dynsym' contains 14 entries: Num: Value Size Type Bind Vis Ndx Name 12: 0000000000600c38 4 OBJECT GLOBAL DEFAULT 25 __lib_MOD_var Symbol table '.symtab' contains 77 entries: Num: Value Size Type Bind Vis Ndx Name 59: 0000000000600c38 4 OBJECT GLOBAL DEFAULT 25 __lib_MOD_var $ readelf -wi lib.so | approx-grep var <1><2d>: Abbrev Number: 2 (DW_TAG_module) <2e> DW_AT_name : lib <2><38>: Abbrev Number: 3 (DW_TAG_variable) <39> DW_AT_name : var <3f> DW_AT_type : <0x4f> <43> DW_AT_external : 1 <44> DW_AT_location : 9 byte block: 3 98 7 20 0 0 0 0 0 (DW_OP_addr: 200798) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid DW_AT_location $ readelf -wi main | approx-grep var <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram) <2f> DW_AT_name : (indirect string, offset: 0x9): MAIN__ <2><50>: Abbrev Number: 4 (DW_TAG_imported_module) <53> DW_AT_import : <0x58> [Abbrev Number: 5 (DW_TAG_module)] <1><58>: Abbrev Number: 5 (DW_TAG_module) <59> DW_AT_name : lib <5d> DW_AT_declaration : 1 cat >clib.c <<EOH int var = 1; int func (void) { return var; } EOH cat >cmain.c <<EOH extern int var; extern int func (void); int main (void) { var = 2; return var == func () ? 0 : 1; } EOH C="gcc -Wall -g"; $C -o clib.so -shared -fPIC clib.c; $C -o cmain cmain.c ./clib.so $ nm -D clib.so | grep var 0000000000200800 D var $ nm -D cmain | grep var 00000000006009c0 B var $ readelf -wi clib.so | approx-grep var <1><55>: Abbrev Number: 4 (DW_TAG_variable) <56> DW_AT_name : var <5c> DW_AT_type : <0x4e> <60> DW_AT_external : 1 <61> DW_AT_declaration : 1 <1><62>: Abbrev Number: 5 (DW_TAG_variable) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ redundant+invalid DIE <63> DW_AT_name : var <69> DW_AT_type : <0x4e> <6d> DW_AT_external : 1 <6e> DW_AT_location : 9 byte block: 3 0 8 20 0 0 0 0 0 (DW_OP_addr: 200800) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid DW_AT_location
I'd say this is actually a ld bug, not GCC. GCC emits: .uleb128 0x3 # (DIE (0x38) DW_TAG_variable) .ascii "var\0" # DW_AT_name .byte 0x1 # DW_AT_decl_file (pr40040lib.f90) .byte 0x2 # DW_AT_decl_line .long 0x4f # DW_AT_type .byte 0x1 # DW_AT_external .byte 0x9 # DW_AT_location .byte 0x3 # DW_OP_addr .quad __pr40040lib_MOD_var and the relocation is preserved even by gas, .rela.debug_info has: 6: 0000000000200738 4 OBJECT GLOBAL DEFAULT 19 __pr40040lib_MOD_var But then ld resolves all relocations in .rela.debug_info locally and throws away that section, while perhaps best would be to drop most of the relocations from that section and keep only some, against overridable objects. Still the question is if .rela.debug_info won't be too large for practical uses. If DW_AT_location isn't provided, how would gdb find that address out? Using DW_AT_MIPS_linkage_name (currently not emitted) and symbol lookup?
(In reply to comment #1) > If DW_AT_location isn't provided, how would gdb find that address out? Using > DW_AT_MIPS_linkage_name (currently not emitted) and symbol lookup? The GDB patch now assembles the symbol name from its parent DW_TAG_module as `__modulename_MOD_varname'. As GDB also has to know the C++ mangling rules I believe this Fortran mangling is can be also used from GDB. If GDB should never guess the fully qualified names I will have to file at least one more GCC fortran debug/ PR for DW_TAG_imported_declaration which already uses only DW_TAG_variable with DW_AT_declaration and no DW_AT_location.
(In reply to comment #2) > The GDB patch now assembles the symbol name from its parent DW_TAG_module as > `__modulename_MOD_varname'. As GDB also has to know the C++ mangling rules I > believe this Fortran mangling is can be also used from GDB. Note: The Fortran mangling is highly compiler dependent. Intel's ifort uses "modulename_mp_varname_", sunf95 uses "modulename.varname_", and g95 and NAG f95 use "modulename_MP_varname" (however, the latter two don't create DW_TAG_module - g95 is based on gcc 4.0.x and NAG f95 uses the system's C compiler).
Hmm. I am concerned by the idea of relocs for DWARF sections in final-linked objects. That is a hassle that consumers have not had to handle before. (AFAIK only consumers that handle ET_REL pseudo-final objects such as Linux kernel .ko modules cope with reloc sections at all.) I think what's ideal in the abstract is that the location expression indicates how the variable is really accessed, i.e. loading the address from the GOT or whatever it really does. That might not always be possible in the defining declaration. e.g., when the definition is in a CU where there are no accesses, perhaps it can't tell whether other CUs will be using direct addressing (e.g. @GOTOFF) or GOT-indirect. I read DWARF 3 section 4.1 item 4 to suggest that there should be a defining DW_TAG_variable whose DW_AT_location can be the "base" one, i.e. direct address in the definer, plus non-defining DW_TAG_variable (with DW_AT_declaration) DIEs whose DW_AT_location expressions indicate how the variable is accessed in each scope using it. So, in the "main program" CU the DW_TAG_variable should have DW_AT_declaration, DW_AT_external, and a DW_AT_location describing the main program's copy (or its GOT lookup if PIC). In the non-defining accessing CUs in a DSO, there should be a similar DIE whose DW_AT_location describes that DSO's GOT lookup, etc. If the defining CU also contains accesses, then the defining DW_TAG_variable's DW_AT_location would describe the GOT access if that's what that CU uses, and then no DIE anywhere would have the direct address location expression for the DSO initializer/copy. I don't know how ready GDB et al are to cope with this, but it seems like the "correct" route to me. They'd have to find the right DIE for the scope of the access, so it has the appropriate location expression. For "blind" global lookups, it would have to be sure to use the "dominating" DIE, i.e. choose one somewhere in the main program before the defining definition in the DSO.
(In reply to comment #4) > I don't know how ready GDB et al are to cope with this, (For GDB the local definitions containing an address expression are even less problematic than the current declarations requiring mangled symbols resolving.)
What is actually the status of this PR? I read through it twice and I still do not know whether this is a GCC bug or a GNU ld bug - and, if the former, how it is supposed to be fixed.
Created attachment 20436 [details] Preliminary GDB patch. Tobias, could you add DW_AT_MIPS_linkage name? You say in Comment 3 the debugger cannot guess the linkage name from DW_AT_namespace hierarchy as it is not standardized across Fortran compilers. If DW_AT_external is true the GDB patch ignores DW_AT_location and relies on the ELF symbols which would work. It should IMHO follow Roland's Re: Cross-CU C++ DIE references vs. mangling http://sourceware.org/ml/archer/2010-q1/msg00092.html
Please treat DW_AT_linkage_name the same as DW_AT_MIPS_linkage_name, for -gdwarf-4 the patch I've posted yesterday emits the former rather than latter. Currently the addition of DW_AT_{,MIPS_}linkage_name is guarded with && !is_fortran () that would probably need to go away. BTW, should DW_AT_{,MIPS_}linkage_name be also present on DW_TAG_common_block? If yes, we need to file a request similar to http://dwarfstd.org/ShowIssue.php?issue=100419.4&type=open for DW_AT_linkage_name to be allowed on DW_TAG_common_block.
(In reply to comment #8) > BTW, should DW_AT_{,MIPS_}linkage_name be also present on DW_TAG_common_block? [...] > for DW_AT_linkage_name to be allowed on DW_TAG_common_block. For DW_TAG_common_block: + /* SYMBOL_VALUE_ADDRESS never gets used as all its fields are static. */ There is only important the user-visible DW_AT_name of DW_TAG_common_block. Then there are child DIEs DW_TAG_variable. Good point there should be DW_AT_*linkage_name present the same way as normal variables should have it. http://cvs.fedoraproject.org/viewvc/rpms/gdb/F-13/gdb-fortran-common.patch?content-type=text%2Fplain&view=co <2><4a>: Abbrev Number: 3 (DW_TAG_common_block) <4b> DW_AT_name : (indirect string, offset: 0xd3): fo_o <51> DW_AT_location : 9 byte block: 3 50 c 60 0 0 0 0 0 (DW_OP_addr: 600c50) <3><5f>: Abbrev Number: 4 (DW_TAG_variable) <60> DW_AT_name : ix <65> DW_AT_type : <0x114> <69> DW_AT_external : 1 <6a> DW_AT_location : 9 byte block: 3 50 c 60 0 0 0 0 0 (DW_OP_addr: 600c50)
BTW, gcc stopped emitting with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129882 - PR10220 commit. Unfortunately that change isn't even mentioned in the ChangeLog entry nor I could find any discussions about it on the mailing list from that time.
(In reply to comment #10) > Unfortunately that change isn't even mentioned in the ChangeLog entry nor I > could find any discussions about it on the mailing list from that time. In the bugzilla PR you reference, there are links to the gcc-patches thread: http://gcc.gnu.org/ml/gcc-patches/2007-11/msg00120.html which itself refers to a thread on the gdb list: http://www.sourceware.org/ml/gdb/2007-10/msg00205.html Now, if you're refering to this hunk of the change: --- trunk/gcc/dwarf2out.c 2007/11/04 04:34:47 129881 +++ trunk/gcc/dwarf2out.c 2007/11/04 14:43:45 129882 @@ -11356,7 +11356,8 @@ && TREE_PUBLIC (decl) && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) && !DECL_ABSTRACT (decl) - && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))) + && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) + && !is_fortran ()) add_AT_string (die, DW_AT_MIPS_linkage_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); } well, it looks like it wasn't approved, so I wouldn't be surprised if it's just a something I had testing in my tree that I inadvertently committed at the time. Sorry about that.
Yeah, that's exactly the hunk I'm referring to. The gdb patch Jan provided relies on DW_AT_MIPS_linkage_name (or DW_AT_linkage_name hopefully for DWARF4) to be provided. While for most normal Fortran identifiers when modules aren't involved most implementations agree on appending _ at the end, for objects/functions in modules the mangling differs between implementations and certainly isn't something debug info consumers should hardcode.
I have googled the gcc.gnu.org domain for my name and DW_AT_MIPS_linkage_name, and came up with nothing relevant. So, I never proposed or sought to get this part approved, which confirms it's probably just human error. I am no longer a Fortran maintainer, but I'm sure the reversion will be easily approved.
Subject: Bug 40040 Author: jakub Date: Wed Apr 21 16:48:41 2010 New Revision: 158612 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=158612 Log: PR debug/40040 * dwarf2out.c (add_name_and_src_coords_attributes): Add DW_AT_{,MIPS_}linkage_name even for Fortran decls. Modified: trunk/gcc/ChangeLog trunk/gcc/dwarf2out.c
Is this fixed by revision 158612? If yes, please close this PR as FIXED.
(In reply to Dominique d'Humieres from comment #15) > Is this fixed by revision 158612? If yes, please close this PR as FIXED. No reply, guessing it was.