From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12496 invoked by alias); 16 Mar 2009 20:20:58 -0000 Received: (qmail 12487 invoked by uid 22791); 16 Mar 2009 20:20:56 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 Mar 2009 20:20:49 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2GKKkgi017685 for ; Mon, 16 Mar 2009 16:20:46 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2GKKk9A011206 for ; Mon, 16 Mar 2009 16:20:46 -0400 Received: from host0.dyn.jankratochvil.net (sebastian-int.corp.redhat.com [172.16.52.221]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n2GKKiLj023435 for ; Mon, 16 Mar 2009 16:20:45 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id n2GKKfmG001960 for ; Mon, 16 Mar 2009 21:20:43 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.2/Submit) id n2GKKfnK001954 for gdb-patches@sourceware.org; Mon, 16 Mar 2009 21:20:41 +0100 Date: Mon, 16 Mar 2009 21:15:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch/rfc] Recognize non-DW_AT_location symbols Message-ID: <20090316202040.GA27070@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00283.txt.bz2 Hi, this patch is far from a perfect solution but it would be fine to check it in if there is an approval as this patch is a regression-free GDB improvement: for: echo 'int main () { int x = 42; return x; }' | gcc -Wall -O2 -g -x c - current GDB prints: (gdb) p x No symbol "x" in current context. (gdb) ptype x No symbol "x" in current context. while patched GDB prints: (gdb) p x $1 = (gdb) ptype x type = int It can also happen for gcc-4.4 -O0 -g but that is more its bug (PR debug/39474). With the current -O2 debugging situation I find the `No symbol ...' statements even more confusing than pragmatic . Still this patch is just a fixup of the current incorrect GDB parsing code, the proper solution should rewrite it from scratch. But it has no regressions on x86_64-unknown-linux-gnu so it is at least an improvement. Existing problems even with this patch: * zero-length DW_AT_location should be the same as missing DW_AT_location. https://fedorahosted.org/pipermail/elfutils-devel/2009-March/000180.html GCC seems to use zero-length DW_AT_location for optimized-out variables and no DW_AT_location if it fails to provide it for whatever reason. But not always. If GDB would always use zero-length DW_AT_location for optimized-out symbols vs. no DW_AT_location for non-defining declarations this GDB patch would not be needed as this is the current (DWARF-noncompliant) GDB expectation. * Missing DWARF3 2.13.2 Declarations Completing Non-Defining Declarations: Current ignorance of LOC_OPTIMIZED_OUT symbols was used for C++ symbols completion. Fixing the LOC_OPTIMIZED_OUT symbols presents break C++ symbols completion as the code then recognizes the first instance of the symbol (even if it is LOC_OPTIMIZED_OUT) thus ignoring its later completion such as for: <3><247>: Abbrev Number: 18 (DW_TAG_variable) <248> DW_AT_name : cX <24d> DW_AT_type : <0xca> <251> DW_AT_declaration : 1 <1><5c5>: Abbrev Number: 37 (DW_TAG_variable) <5c6> DW_AT_specification: <0x247> <5ca> DW_AT_const_value : 6 The insert_symbol_hashed() part of the patch fixes up this specific case to have no testsuite regressions on gcc. Still a more general fix should be made. * For external variables it still prints Address of symbol "foo" is unknown. while it should print because (read_var_value ) should return not_lval+set_value_optimized_out but providing such patch causes regression on other GDB C++ support code. * The updated testcase is probably incompatible with Alpha (larger than 32bit file addresses), also it should test more types of symbol placements, `main' range is not correct, CU range is not correct etc. Updated patch fixes for current GDB its new testcases: FAIL: gdb.dwarf2/dw2-noloc.exp: print noloc_local (file-scope optimized-out) FAIL: gdb.dwarf2/dw2-noloc.exp: ptype noloc_local FAIL: gdb.dwarf2/dw2-noloc.exp: print noloc_local2 (function-scope optimized-out) FAIL: gdb.dwarf2/dw2-noloc.exp: ptype noloc_local2 Thanks, Jan gdb/ 2009-03-16 Jan Kratochvil Recognize missing DW_AT_location as . * dictionary.c (insert_symbol_hashed): New variables `iterp', `iter'. Remove non-defining declaration completed by later declarations. * dwarf2read.c (new_symbol ): Call add_symbol_to_list. gdb/testsuite/ 2009-03-16 Jan Kratochvil * gdb.dwarf2/dw2-noloc.exp: Compile main.c with nodebug. (print noloc): Rename to ... (print noloc_unresolvable): ... here. (print hasloc_direct, print hasloc_resolvable, print noloc_local) (print hasloc_direct2, print hasloc_resolvable2) (print noloc_unresolvable2, print noloc_local2): New. * gdb.dwarf2/dw2-noloc.S (main_end, hasloc_resolvable) (hasloc_resolvable2): New. (DW_AT_high_pc): Change it to `main_end'. (noloc): Rename to ... (noloc_unresolvable): ... here. (hasloc_direct, hasloc_resolvable, noloc_local, hasloc_direct2) (hasloc_resolvable2, noloc_unresolvable2, noloc_local2): New. --- gdb/dictionary.c 3 Jan 2009 05:57:51 -0000 1.10 +++ gdb/dictionary.c 16 Mar 2009 18:18:49 -0000 @@ -670,10 +670,34 @@ insert_symbol_hashed (struct dictionary struct symbol *sym) { unsigned int hash_index; - struct symbol **buckets = DICT_HASHED_BUCKETS (dict); + struct symbol **buckets = DICT_HASHED_BUCKETS (dict), **iterp, *iter; hash_index = (msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) % DICT_HASHED_NBUCKETS (dict)); + + /* Remove non-defining declaration completed by later declarations + (DWARF3 2.13.2). As there may be multiple symbols of the same + SYMBOL_SEARCH_NAME but different SYMBOL_CLASS replace only those that have + lower validity (in the order of LOC* > LOC_UNRESOLVED > LOC_OPTIMIZED_OUT). + + dict_create_linear should also contain such code but the C++ declarations + completing in practice exists only for file/global symbols which are being + indexed only using this function insert_symbol_hashed. + + As this function is called in a reverse order than the placement of the + symbols in the inferior the RETURN statement will ensure the symbol gets + replaced. */ + + if (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT + || SYMBOL_CLASS (sym) == LOC_UNRESOLVED) + for (iterp = &buckets[hash_index]; (iter = *iterp) != NULL; + iterp = &iter->hash_next) + if (strcmp (SYMBOL_SEARCH_NAME (iter), SYMBOL_SEARCH_NAME (sym)) == 0 + && (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT + || (SYMBOL_CLASS (sym) == LOC_UNRESOLVED + && SYMBOL_CLASS (iter) == LOC_OPTIMIZED_OUT))) + return; + sym->hash_next = buckets[hash_index]; buckets[hash_index] = sym; } --- gdb/dwarf2read.c 9 Mar 2009 18:53:48 -0000 1.296 +++ gdb/dwarf2read.c 16 Mar 2009 18:18:53 -0000 @@ -7658,6 +7658,11 @@ new_symbol (struct die_info *die, struct SYMBOL_CLASS (sym) = LOC_UNRESOLVED; add_symbol_to_list (sym, &global_symbols); } + else + { + /* Use the default LOC_OPTIMIZED_OUT class. */ + add_symbol_to_list (sym, cu->list_in_scope); + } } break; case DW_TAG_formal_parameter: --- gdb/testsuite/gdb.dwarf2/dw2-noloc.S 3 Jan 2009 05:58:04 -0000 1.4 +++ gdb/testsuite/gdb.dwarf2/dw2-noloc.S 16 Mar 2009 18:18:54 -0000 @@ -26,6 +26,15 @@ func_cu1: .size func_cu1, .-func_cu1 .Lend_text1: + .equ main_end, main + 0x100 /* Just an estimate. */ + + .data + .globl hasloc_resolvable + .globl hasloc_resolvable2 +hasloc_resolvable: +hasloc_resolvable2: + .4byte 1234567890 + /* Debug information */ .section .debug_info @@ -40,7 +49,7 @@ func_cu1: /* CU die */ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ .4byte .Lline1_begin /* DW_AT_stmt_list */ - .4byte .Lend_text1 /* DW_AT_high_pc */ + .4byte main_end /* DW_AT_high_pc */ .4byte .Lbegin_text1 /* DW_AT_low_pc */ .ascii "file1.txt\0" /* DW_AT_name */ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ @@ -64,11 +73,65 @@ func_cu1: .byte 4 /* DW_AT_byte_size */ .byte 5 /* DW_AT_encoding */ - .uleb128 4 /* Abbrev: DW_TAG_variable */ - .ascii "noloc\0" /* DW_AT_name */ + .uleb128 7 /* Abbrev: DW_TAG_variable (location) */ + .ascii "hasloc_direct\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: + .byte 3 /* DW_OP_addr */ + .4byte hasloc_resolvable /* */ +2: + + .uleb128 4 /* Abbrev: DW_TAG_variable (extern) */ + .ascii "hasloc_resolvable\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .byte 1 /* DW_AT_external */ + + .uleb128 4 /* Abbrev: DW_TAG_variable (extern) */ + .ascii "noloc_unresolvable\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .byte 1 /* DW_AT_external */ + + .uleb128 5 /* Abbrev: DW_TAG_variable (local) */ + .ascii "noloc_local\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + + /* main */ + .uleb128 6 /* Abbrev: DW_TAG_subprogram */ + .byte 1 /* DW_AT_decl_file */ + .byte 2 /* DW_AT_decl_line */ + .ascii "main\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .4byte main /* DW_AT_low_pc */ + .4byte main_end /* DW_AT_high_pc */ + .byte 1 /* DW_AT_frame_base: length */ + .byte 0x55 /* DW_AT_frame_base: DW_OP_reg5 */ + + .uleb128 7 /* Abbrev: DW_TAG_variable (location) */ + .ascii "hasloc_direct2\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: + .byte 3 /* DW_OP_addr */ + .4byte hasloc_resolvable /* */ +2: + + .uleb128 4 /* Abbrev: DW_TAG_variable (extern) */ + .ascii "hasloc_resolvable2\0" /* DW_AT_name */ .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ .byte 1 /* DW_AT_external */ + .uleb128 4 /* Abbrev: DW_TAG_variable (extern) */ + .ascii "noloc_unresolvable2\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .byte 1 /* DW_AT_external */ + + .uleb128 5 /* Abbrev: DW_TAG_variable (local) */ + .ascii "noloc_local2\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + + .byte 0 /* End of children of main */ + .byte 0 /* End of children of CU */ .Lcu1_end: @@ -128,7 +191,7 @@ func_cu1: .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ - .uleb128 4 /* Abbrev code */ + .uleb128 4 /* Abbrev code (extern) */ .uleb128 0x34 /* DW_TAG_variable */ .byte 0 /* has_children */ .uleb128 0x3 /* DW_AT_name */ @@ -140,6 +203,48 @@ func_cu1: .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ + .uleb128 5 /* Abbrev code (local) */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 6 /* Abbrev code */ + .uleb128 0x2e /* DW_TAG_subprogram */ + .byte 1 /* has_children */ + .uleb128 0x3a /* DW_AT_decl_file */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3b /* DW_AT_decl_line */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x40 /* DW_AT_frame_base */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 7 /* Abbrev code (location) */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2 /* DW_AT_location */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ .byte 0x0 /* Terminator */ --- gdb/testsuite/gdb.dwarf2/dw2-noloc.exp 3 Jan 2009 05:58:04 -0000 1.4 +++ gdb/testsuite/gdb.dwarf2/dw2-noloc.exp 16 Mar 2009 18:18:54 -0000 @@ -28,7 +28,7 @@ set testfile "dw2-noloc" set srcfile ${testfile}.S set binfile ${objdir}/${subdir}/${testfile}.x -if { [gdb_compile "${srcdir}/${subdir}/main.c" "main.o" object {debug}] != "" } { +if { [gdb_compile "${srcdir}/${subdir}/main.c" "main.o" object {nodebug}] != "" } { return -1 } @@ -45,4 +45,30 @@ gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} -gdb_test "print noloc" "Address of symbol \"noloc\" is unknown." "print noloc" +gdb_test "print hasloc_direct" "= 1234567890" +gdb_test "ptype hasloc_direct" "type = int" + +gdb_test "print hasloc_resolvable" "= 1234567890" +gdb_test "ptype hasloc_resolvable" "type = int" + +gdb_test "print noloc_unresolvable" "Address of symbol \"noloc_unresolvable\" is unknown\\." +gdb_test "ptype noloc_unresolvable" "type = int" + +gdb_test "print noloc_local" "= " +gdb_test "ptype noloc_local" "type = int" + +if ![runto_main] { + return -1 +} + +gdb_test "print hasloc_direct2" "= 1234567890" +gdb_test "ptype hasloc_direct2" "type = int" + +gdb_test "print hasloc_resolvable2" "= 1234567890" +gdb_test "ptype hasloc_resolvable2" "type = int" + +gdb_test "print noloc_unresolvable2" "Address of symbol \"noloc_unresolvable2\" is unknown\\." +gdb_test "ptype noloc_unresolvable2" "type = int" + +gdb_test "print noloc_local2" "= " +gdb_test "ptype noloc_local2" "type = int"