Bug 29635 - debug info of modules
Summary: debug info of modules
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: wrong-debug
: 37133 (view as bug list)
Depends on:
Blocks: 24546
  Show dependency treegraph
 
Reported: 2006-10-29 14:02 UTC by Francois-Xavier Coudert
Modified: 2009-05-29 08:51 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-10-29 14:04:03


Attachments
gcc44-pr29635.patch (3.09 KB, patch)
2008-08-15 18:29 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2006-10-29 14:02:25 UTC
$ cat a.f90 
module foo
  integer i
end module foo

use foo
print *, i
end
$ ifort -g -c a.f90 
$ readelf -wi a.o  
The section .debug_info contains:

  Compilation Unit @ offset 0x0:
   Length:        167
   Version:       2
   Abbrev Offset: 0
   Pointer Size:  4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
     DW_AT_comp_dir    : /tmp
     DW_AT_language    : 14     (Fortran 95)
     DW_AT_name        : a.f90
     DW_AT_producer    : Intel (R) Fortran Compiler Fixes RangesRelative

     DW_AT_stmt_list   : 0
 <1><4d>: Abbrev Number: 2 (DW_TAG_module)
     DW_AT_decl_line   : 1
     DW_AT_decl_column : 7
     DW_AT_decl_file   : 1
     DW_AT_name        : FOO
 <2><55>: Abbrev Number: 3 (DW_TAG_variable)
     DW_AT_decl_line   : 2
     DW_AT_decl_column : 11
     DW_AT_decl_file   : 1
     DW_AT_accessibility: 1     (public)
     DW_AT_name        : i
     DW_AT_type        : <68>
     DW_AT_location    : 5 byte block: 3 0 0 0 0        (DW_OP_addr: 0)
     DW_AT_external    : 1
 <1><68>: Abbrev Number: 4 (DW_TAG_base_type)
     DW_AT_byte_size   : 4
     DW_AT_encoding    : 5      (signed)
     DW_AT_name        : INTEGER(4)
 <1><76>: Abbrev Number: 4 (DW_TAG_base_type)
     DW_AT_byte_size   : 0
     DW_AT_encoding    : 5      (signed)
     DW_AT_name        : void
 <1><7e>: Abbrev Number: 5 (DW_TAG_subprogram)
     DW_AT_decl_line   : 6
     DW_AT_decl_column : 1
     DW_AT_decl_file   : 1
     DW_AT_calling_convention: 2        (program)
     DW_AT_accessibility: 1     (public)
     DW_AT_name        : main$a_$BLK
     DW_AT_type        : <76>
     DW_AT_prototyped  : 0
     DW_AT_high_pc     : 0x6a
     DW_AT_low_pc      : 0x6
     DW_AT_external    : 1
 <2><9e>: Abbrev Number: 6 (DW_TAG_imported_declaration)
     DW_AT_decl_line   : 6
     DW_AT_decl_column : 1
     DW_AT_decl_file   : 1
     DW_AT_import      : <55>
Comment 1 Francois-Xavier Coudert 2007-01-02 14:35:01 UTC
Steven, any news from your Fortran debug info work?
Comment 2 stevenb.gcc@gmail.com 2007-01-02 15:27:25 UTC
Subject: Re:  debug info of modules

I'm waiting for my gdb assignment to be finished.  This will probably
be work for Q2 2007.
Comment 3 Daniel Franke 2007-08-11 22:08:11 UTC
gfortran seems to lack the following information:

 1. DW_TAG_module
    to describe the module at hand
 2. DW_TAG_imported_declaration/DW_TAG_imported_module/DW_AT_import
    to describe use-associated variables (dwarf2, sec. 4.3; dwarf3, sec. 3.2.3 and 3.2.4)

The former is generated by ifort, the latter is not.

As dwarf3, sec 3.2, indicates similarities of modules to C++ namespaces, it could be worth a try to see how it is implemented over there. The equivalent C++-code:

$> cat a.cpp
#include <cstdio>

namespace foo {
  int i = 42;
}

int main() {
  using namespace foo;

  printf("%d\n", i);
  return 0;
}

$> g++ -g a.cpp
$> readelf 
[...]
 <1><ad3>: Abbrev Number: 29 (DW_TAG_subprogram)
     DW_AT_external    : 1
     DW_AT_name        : main
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 17
     DW_AT_type        : <109>
     DW_AT_low_pc      : 0x8048484
     DW_AT_high_pc     : 0x80484b8
     DW_AT_frame_base  : 0      (location list)
     DW_AT_sibling     : <af8>
 <2><af0>: Abbrev Number: 30 (DW_TAG_imported_module)
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 18
     DW_AT_import      : <af8>
 <1><af8>: Abbrev Number: 4 (DW_TAG_namespace)
     DW_AT_name        : foo
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 13
     DW_AT_sibling     : <b1a>
 <2><b03>: Abbrev Number: 31 (DW_TAG_variable)
     DW_AT_name        : i
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 14
     DW_AT_MIPS_linkage_name: _ZN3foo1iE
     DW_AT_type        : <109>
     DW_AT_external    : 1
     DW_AT_declaration : 1
 <1><b1a>: Abbrev Number: 32 (DW_TAG_variable)
     DW_AT_specification: <b03>
     DW_AT_location    : 5 byte block: 3 ec 96 4 8      (DW_OP_addr: 80496ec)
[...]

Steven, are you (still) working on this?
Comment 4 stevenb.gcc@gmail.com 2007-08-12 10:36:00 UTC
Subject: Re:  debug info of modules

This is still on my TODO-list, but not for GCC 4.3.
Comment 5 Jakub Jelinek 2008-08-15 18:29:26 UTC
Created attachment 16077 [details]
gcc44-pr29635.patch

Initial patch, which generates DW_TAG_module in the compilation unit that defines
the module and puts all module procedures, variables, DW_TAG_common_blocks and derived types as children of that DIE.

ATM it uses the same weird double DIE way as C++ namespaces use (one DIE in
DW_TAG_namespace (resp. DW_TAG_module in Fortran) with DW_AT_declaration 1
and another outside of the namespace/module with DW_AT_specification.

Any ideas why does C++ do this?

To emit proper DW_TAG_imported_{declaration,module} DIEs there is much more work.
One problem is that Fortran FE rereads the *.mod each time a USE statement is seen, so finding the same NAMESPACE_DECL is harder (we'd need to add some data structure mapping a module name to the NAMESPACE_DECL).  If we have that,
for non-renaming USE or USE, ONLY it is easy (at least in the same CU as the module definition), but for renaming we'd need to extend the API of the imported_module_or_decl debug_hook.  The USE modx, a=>b, c=>d
renaming also needs the DW_TAG_imported_declaration's with the renamings to
be children of DW_TAG_imported_module.  I think the renaming is visible from
the symtree (the renamed name is in symtree->name, original in symtree->n.sym->name).  Another problem are USE statements in different compilation unit from the one that defines the module.  We probably can't output
a reference to DW_TAG_module from a different .o file, so we'd need to emit DW_TAG_module in that case too, but can we just put into it just the module variables, procedures etc. that are used in the CU?  I'm afraid module loading throws away stuff that is not needed.
Comment 6 Jakub Jelinek 2008-08-15 20:19:11 UTC
*** Bug 37133 has been marked as a duplicate of this bug. ***
Comment 7 Jakub Jelinek 2008-08-18 08:11:41 UTC
To expand on the duplicate DIE issue in C++, say:
namespace N
{
  int i;
}
int foo ()
{
  using N::i;
  return i;
}
emits:
        .uleb128 0x3    # (DIE (0x55) DW_TAG_imported_declaration)
        .byte   0x1     # DW_AT_decl_file (mno2.C)
        .byte   0x7     # DW_AT_decl_line
        .long   0x6d    # DW_AT_import
in foo (correct) and then:
        .uleb128 0x5    # (DIE (0x64) DW_TAG_namespace)
        .ascii "N\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file (mno2.C)
        .byte   0x2     # DW_AT_decl_line
        .long   0x8c    # DW_AT_sibling
        .uleb128 0x6    # (DIE (0x6d) DW_TAG_variable)
        .ascii "i\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file (mno2.C)
        .byte   0x3     # DW_AT_decl_line
        .long   .LASF0  # DW_AT_MIPS_linkage_name: "_ZN1N1iE"
        .long   0x5d    # DW_AT_type
        .byte   0x1     # DW_AT_external
        .byte   0x1     # DW_AT_declaration
        .uleb128 0x6    # (DIE (0x7c) DW_TAG_variable)
        .ascii "i\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file (mno2.C)
        .byte   0x3     # DW_AT_decl_line
        .long   .LASF0  # DW_AT_MIPS_linkage_name: "_ZN1N1iE"
        .long   0x5d    # DW_AT_type
        .byte   0x1     # DW_AT_external
        .byte   0x1     # DW_AT_declaration
        .byte   0x0     # end of children of DIE 0x64
        .uleb128 0x7    # (DIE (0x8c) DW_TAG_variable)
        .long   0x7c    # DW_AT_specification
        .byte   0x9     # DW_AT_location
        .byte   0x3     # DW_OP_addr
        .quad   _ZN1N1iE
        .byte   0x0     # end of children of DIE 0xb
Note not just 2, but 3, 2 DW_AT_declaration inside and one DW_AT_specification DIE outside of the namespace.  If extern int i; is used instead, then the DW_AT_specification is missing.
Comment 8 Jakub Jelinek 2008-08-18 08:43:10 UTC
Looking at the original namespace support in dwarf2out patches I found the declaration in the namespace and specification in CU is being done for compatibility with (at that time) existing debuggers.  I'm not sure if we need to do the same for Fortran (maybe not, what does gdb do with DW_TAG_module?) or if we couldn't drop compatibility hacks for more than 5 years old dwarf2 debuggers by now even for C++.  The duplicate declaration DIEs are still unexpected.
Comment 9 Daniel Jacobowitz 2008-08-18 12:38:52 UTC
Interesting, I didn't know this was for the benefit of some debugger.  I don't think GDB has needed it in several years.  If things work with GDB 6.8 and without these DIEs, I think it's safe to combine the declaration and the reference to it.

(It's not right to call a DIE with DW_AT_specification a specification; the target of the attribute is the specification.)
Comment 10 Jakub Jelinek 2008-08-29 18:42:35 UTC
Subject: Bug 29635

Author: jakub
Date: Fri Aug 29 18:41:19 2008
New Revision: 139773

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=139773
Log:
	PR fortran/29635
	PR fortran/23057
	* debug.h (struct gcc_debug_hooks): Add NAME and CHILD
	arguments to imported_module_or_decl.
	(debug_nothing_tree_tree): Removed.
	(debug_nothing_tree_tree_tree_bool): New prototype.
	* debug.c (do_nothing_debug_hooks): Adjust.
	(debug_nothing_tree_tree): Removed.
	(debug_nothing_tree_tree_tree_bool): New function.
	* dwarf2out.c (is_symbol_die): Handle DW_TAG_module.
	(gen_variable_die): Put all common vars for the
	same COMMON block under one DW_TAG_common_block.
	(declare_in_namespace): Return new context_die, for Fortran
	return the module DIE instead of adding extra declarations into
	the namespace.
	(gen_type_die_with_usage): Adjust declare_in_namespace caller.
	(gen_namespace_die): If is_fortran (), generate DW_TAG_module
	instead of DW_TAG_namespace.  If DECL_EXTERNAL is set, add
	DW_AT_declaration.
	(dwarf2out_global_decl): Don't skip Fortran global vars.
	(gen_decl_die): Likewise.  Adjust declare_in_namespace callers.
	(dwarf2out_imported_module_or_decl): Add NAME and CHILD arguments.
	If NAME is non-NULL, add DW_AT_name.  If CHILD is non-NULL, put
	DW_TAG_imported_declaration as child of previous
	DW_TAG_imported_module.
	* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Adjust.
	* sdbout.c (sdb_debug_hooks): Likewise.
	* vmsdbgout.c (vmsdbg_debug_hooks): Likewise.

	* name-lookup.c (do_using_directive, cp_emit_debug_info_for_using):
	Adjust debug_hooks->imported_module_or_decl callers.

	* f95-lang.c (gfc_init_ts): New function.
	(LANG_HOOKS_INIT_TS): Define.
	* gfortran.h (gfc_use_rename): New type, moved from module.c.
	(gfc_get_use_rename): New macro, moved from module.c.
	(gfc_use_list): New type.
	(gfc_get_use_list): New macro.
	(gfc_namespace): Add use_stmts field.
	(gfc_free_use_stmts): New prototype.
	* Make-lang.in (fortran/trans-decl.o): Depend on debug.h.
	* module.c (gfc_use_rename, gfc_get_use_rename): Moved to
	gfortran.h.
	(gfc_use_module): Chain the USE statement info to
	ns->use_stmts.
	(gfc_free_use_stmts): New function.
	* symbol.c (gfc_free_namespace): Call gfc_free_use_stmts.
	* trans.h (struct module_htab_entry): New type.
	(gfc_find_module, gfc_module_add_decl): New functions.
	* trans.c (gfc_generate_module_code): Create NAMESPACE_DECL for
	the module, adjust DECL_CONTEXTs of module procedures and
	call gfc_module_add_decl for them.
	* trans-common.c (build_common_decl): Set DECL_IGNORED_P
	on the common variable.
	(create_common): Set DECL_IGNORED_P for use associated vars.
	* trans-decl.c: Include debug.h.
	(gfc_get_symbol_decl): Set DECL_IGNORED_P on use_assoc vars from
	modules.
	(build_function_decl): Allow current_function_decl's context
	to be a NAMESPACE_DECL.
	(module_htab, cur_module): New variables.
	(module_htab_do_hash, module_htab_eq, module_htab_decls_hash,
	module_htab_decls_eq, gfc_find_module, gfc_module_add_decl): New
	functions.
	(gfc_create_module_variable): Adjust DECL_CONTEXTs of module
	variables and types and call gfc_module_add_decl for them.
	(gfc_generate_module_vars): Temporarily set cur_module.
	(gfc_trans_use_stmts): New function.
	(gfc_generate_function_code): Call it.
	(gfc_generate_block_data): Set DECL_IGNORED_P on decl.
	* trans-types.c (gfc_get_derived_type): Adjust DECL_CONTEXT
	and TYPE_CONTEXT of module derived types.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/name-lookup.c
    trunk/gcc/dbxout.c
    trunk/gcc/debug.c
    trunk/gcc/debug.h
    trunk/gcc/dwarf2out.c
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/Make-lang.in
    trunk/gcc/fortran/f95-lang.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/symbol.c
    trunk/gcc/fortran/trans-common.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/sdbout.c
    trunk/gcc/vmsdbgout.c

Comment 11 Daniel Franke 2009-04-10 21:38:43 UTC
Jakub, is anything left to do? Can this one be closed?
How about PR24526, is this fixed as well?
Comment 12 Tobias Burnus 2009-05-29 07:44:38 UTC
Jakub, I think this PR is fixed and can be closed. The remaining issue (ld or gcc bug) is tracked in PR 40040. Can we close it?
Comment 13 Jakub Jelinek 2009-05-29 08:51:51 UTC
Closing.