Message ID | alpine.LSU.2.11.1508191531490.19998@zhemvz.fhfr.qr |
---|---|
State | New |
Headers | show |
On 08/19/2015 06:45 AM, Richard Biener wrote: [copying gdb folks] > On Tue, 18 Aug 2015, Aldy Hernandez wrote: > >> On 08/18/2015 07:20 AM, Richard Biener wrote: [snip] > The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu > as well as gdb testing. Twice unpatched, twice patched - results seem > to be somewhat unstable!? I even refrained from using any -j with > make check-gdb... maybe it's just contrib/test_summary not coping well > with gdb? any hints? Difference between unpatched run 1 & 2 is > for example > > --- results.unpatched 2015-08-19 15:08:36.152899926 +0200 > +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200 > @@ -209,7 +209,6 @@ > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3, > fc4) > FAIL: gdb.cp/inherit.exp: print g_vD > FAIL: gdb.cp/inherit.exp: print g_vE > FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)' > @@ -238,6 +237,7 @@ > UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings > FAIL: gdb.fortran/whatis_type.exp: run to MAIN__ > WARNING: remote_expect statement without a default case?! > +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > @@ -362,12 +362,12 @@ > === gdb Summary === > > -# of expected passes 30881 > +# of expected passes 30884 > # of unexpected failures 284 > # of unexpected successes 2 > -# of expected failures 85 > +# of expected failures 83 > # of unknown successes 2 > -# of known failures 60 > +# of known failures 59 > # of unresolved testcases 6 > # of untested testcases 32 > # of unsupported tests 165 > > the sames changes randomly appear/disappear in the patched case. > Otherwise patched/unpatched agree. This is somewhat expected. Well, at least I never found a good explanation. Some tests seemed to be thread related and inconsistent. Others, I have no idea. After running the tests enough times I got a feeling of which tests would always pass, and use those as reference. It was confusing at first. Perhaps the GDB folks could shed some light? I've found them very helpful. Also, -j made things worse. I never used it. Aldy
On 08/19/2015 02:55 PM, Aldy Hernandez wrote: > On 08/19/2015 06:45 AM, Richard Biener wrote: > > [copying gdb folks] Thanks. > >> On Tue, 18 Aug 2015, Aldy Hernandez wrote: >> >>> On 08/18/2015 07:20 AM, Richard Biener wrote: > > [snip] > >> The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu >> as well as gdb testing. Twice unpatched, twice patched - results seem >> to be somewhat unstable!? I even refrained from using any -j with >> make check-gdb... maybe it's just contrib/test_summary not coping well >> with gdb? any hints? Difference between unpatched run 1 & 2 is >> for example >> >> --- results.unpatched 2015-08-19 15:08:36.152899926 +0200 >> +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200 >> @@ -209,7 +209,6 @@ >> WARNING: remote_expect statement without a default case?! >> WARNING: remote_expect statement without a default case?! >> WARNING: remote_expect statement without a default case?! >> -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3, >> fc4) if {![target_info exists gdb,skip_float_tests]} { gdb_test_stdio "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)" \ "find_max\\(.*\\) returns 17\\.000000\[ \r\n\]+" \ ".\[0-9\]+ = 17" \ "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)" } # Test _Complex type here if supported. if [support_complex_tests] { global gdb_prompt set test "print find_max_float_real(4, fc1, fc2, fc3, fc4)" gdb_test $test ".*= 4 \\+ 4 \\* I" $test >> FAIL: gdb.cp/inherit.exp: print g_vD >> FAIL: gdb.cp/inherit.exp: print g_vE >> FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)' >> @@ -238,6 +237,7 @@ >> UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings >> FAIL: gdb.fortran/whatis_type.exp: run to MAIN__ >> WARNING: remote_expect statement without a default case?! >> +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt # Prime the system gdb_test_stdio "call complaint (&symfile_complaints, \"Register a complaint\")" \ "During symbol reading, Register a complaint." # Check that the complaint was inserted and where gdb_test "print symfile_complaints->root->fmt" \ ".\[0-9\]+ =.*\"Register a complaint\"" So in both cases, there was a "gdb_test_stdio" test just before the test that failed. gdb_test_stdio is new, and it expects output from two different spawn ids simultaneously. Sounds like it still needs fixing... I'll guess that Richard has a much faster machine than my getting-old laptop, which exposes races that I didn't trip on... > This is somewhat expected. Well, at least I never found a good > explanation. Some tests seemed to be thread related and inconsistent. > Others, I have no idea. > Indeed there are still some threading tests that unfortunately still cause intermittent fails. We've been fixing them but it's a slow process. Judging by the GDB build bots, x86_64 GNU/Linux testing seems to be mostly stable though. There's one DejaGNU issue that is consistently causing trouble -- see below. > After running the tests enough times I got a feeling of which tests > would always pass, and use those as reference. It was confusing at > first. Perhaps the GDB folks could shed some light? I've found them very > helpful. > > Also, -j made things worse. I never used it. It gets much better if you use git master DejaGNU, to pick this up: http://lists.gnu.org/archive/html/dejagnu/2015-07/msg00005.html Thanks, Pedro Alves
On Wed, 19 Aug 2015, Richard Biener wrote: > On Tue, 18 Aug 2015, Aldy Hernandez wrote: > > > On 08/18/2015 07:20 AM, Richard Biener wrote: > > > > > > This starts a series of patches (still in development) to refactor > > > dwarf2out.c to better cope with early debug (and LTO debug). > > > > Awesome! Thanks. > > > > > Aldyh, what other testing did you usually do for changes? Run > > > the gdb testsuite against the new compiler? Anything else? > > > > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada, > > though the latter is mostly useful while you iron out bugs initially. I found > > that ultimately, the best test was C++. > > I see. > > > Pre merge I also bootstrapped the compiler and compared .debug* section sizes > > in object files to make sure things were within reason. > > > > > + > > > +static void > > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED) > > > +{ > > > + if (write_symbols == VMS_AND_DWARF2_DEBUG) > > > + (*dwarf2_debug_hooks.early_finish) (filename); > > > +} > > > > You can get rid of ATTRIBUTE_UNUSED now. > > Done. I've also refrained from moving > > gen_scheduled_generic_parms_dies (); > gen_remaining_tmpl_value_param_die_attribute (); > > for now as that causes regressions I have to investigate. Tricky beast ;) For g++.dg/debug/dwarf2/template-func-params-3.C we run into the issue that when doing early dwarf the rtl_for_decl_init (&bleh) call will fail because it ends up asking 15809 && ! walk_tree (&init, reference_to_unused, NULL, NULL) which uses TREE_ASM_WRITTEN to see of 'bleh' was emitted or not. That's not going to work at this stage - we even have no idea whether 'bleh' is going to survive IPA or not (might be inlined). With LTO it gets even tricker as we only see a subset of the whole program (or original TU) at LTRANS stage. So it somehow looks like late dwarf thing for this kind of symbolic constants - but it _also_ looks like a very bad dwarf representation to me (going through RTL is bad enough, heh). We expect DW_OP_addr and a reference to _Z4blehv as follows: .byte 0x3 # DW_OP_addr .quad _Z4blehv but I wonder if DWARF has something better so we can refer to _Z4blehv by means of the DIE for its declaration (so the debugger can resolve the constant value)? That would allow the debugger to print &bleh even if bleh was optimized out (it just would have to print <optimized out> for the actual address). So what I'll do is have two phases of gen_remaining_tmpl_value_param_die_attribute (gen_scheduled_generic_parms_dies doesn't have a similar issue AFAICS), during early-debug add those we can, retaining those we can only handle late (just checking the return value of tree_add_const_value_attribute). For LTO the remaining ones will be dropped on the floor (or we'd have to stream them somehow) unless we can change the DWARF representation of these symbolic constants. Thanks, Richard.
On Wed, 19 Aug 2015, Richard Biener wrote: > On Tue, 18 Aug 2015, Aldy Hernandez wrote: > > > On 08/18/2015 07:20 AM, Richard Biener wrote: > > > > > > This starts a series of patches (still in development) to refactor > > > dwarf2out.c to better cope with early debug (and LTO debug). > > > > Awesome! Thanks. > > > > > Aldyh, what other testing did you usually do for changes? Run > > > the gdb testsuite against the new compiler? Anything else? > > > > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada, > > though the latter is mostly useful while you iron out bugs initially. I found > > that ultimately, the best test was C++. > > I see. > > > Pre merge I also bootstrapped the compiler and compared .debug* section sizes > > in object files to make sure things were within reason. > > > > > + > > > +static void > > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED) > > > +{ > > > + if (write_symbols == VMS_AND_DWARF2_DEBUG) > > > + (*dwarf2_debug_hooks.early_finish) (filename); > > > +} > > > > You can get rid of ATTRIBUTE_UNUSED now. > > Done. I've also refrained from moving > > gen_scheduled_generic_parms_dies (); > gen_remaining_tmpl_value_param_die_attribute (); > > for now as that causes regressions I have to investigate. So I thought gen_scheduled_generic_parms_dies was fine but it exposes a hole in /* Generate early debug for global variables. Any local variables will be handled by either handling reachable functions from finalize_compilation_unit (and by consequence, locally scoped symbols), or by rest_of_type_compilation below. ... && !decl_type_context (decl)) (*debug_hooks->early_global_decl) (decl); for __timepunct_cache::_S_timezones where through the rest_of_type_compilation we quickly finish processing __timepunct_cache as it is TYPE_DECL_SUPPRESS_DEBUG (so ->type_decl exits w/o doing anything). So we fail to generate a type DIE for the global which causes us, at late_global_decl time (we do output this global var) ends up doing #12 0x0000000000b831f1 in gen_decl_die (decl=0x7ffff5650a20, origin=0x0, context_die=0x7ffff62ab000) at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:21535 21532 /* And its containing type. */ 21533 class_origin = decl_class_context (decl_or_origin); 21534 if (class_origin != NULL_TREE) 21535 gen_type_die_for_member (class_origin, decl_or_origin, context_die); and thus create the type DIE for __timepunct_cache late. This is a hole in current early-debug. IMHO we should force early_global_decl even for globals in decl_type_context () or at least for a type DIE to be created for TYPE_DECL_SUPPRESS_DEBUG type decls. Jason, any advice on this? I note /* In a TYPE_DECL nonzero means the detail info about this type is not dumped into stabs. Instead it will generate cross reference ('x') of names. This uses the same flag as DECL_EXTERNAL. */ #define TYPE_DECL_SUPPRESS_DEBUG(NODE) \ (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1) refering to STABS and "This uses the same flag as DECL_EXTERNAL" so maybe this is just bad co-incidence? DECL_EXTERNAL doesn't check it operates on a non-TYPE_DECL. So without knowing that the flag is supposed to be doing in DWARF (also the desired effect on any of its static members) I can only suggest we maybe do not want any debug info for __timepunct_cache::_S_timezones at all? Thanks, Richard.
On Wed, 19 Aug 2015, Richard Biener wrote: > On Tue, 18 Aug 2015, Aldy Hernandez wrote: > > > On 08/18/2015 07:20 AM, Richard Biener wrote: > > > > > > This starts a series of patches (still in development) to refactor > > > dwarf2out.c to better cope with early debug (and LTO debug). > > > > Awesome! Thanks. > > > > > Aldyh, what other testing did you usually do for changes? Run > > > the gdb testsuite against the new compiler? Anything else? > > > > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada, > > though the latter is mostly useful while you iron out bugs initially. I found > > that ultimately, the best test was C++. > > I see. > > > Pre merge I also bootstrapped the compiler and compared .debug* section sizes > > in object files to make sure things were within reason. > > > > > + > > > +static void > > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED) > > > +{ > > > + if (write_symbols == VMS_AND_DWARF2_DEBUG) > > > + (*dwarf2_debug_hooks.early_finish) (filename); > > > +} > > > > You can get rid of ATTRIBUTE_UNUSED now. > > Done. I've also refrained from moving > > gen_scheduled_generic_parms_dies (); > gen_remaining_tmpl_value_param_die_attribute (); > > for now as that causes regressions I have to investigate. > > The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu > as well as gdb testing. Twice unpatched, twice patched - results seem > to be somewhat unstable!? I even refrained from using any -j with > make check-gdb... maybe it's just contrib/test_summary not coping well > with gdb? any hints? Difference between unpatched run 1 & 2 is > for example > > --- results.unpatched 2015-08-19 15:08:36.152899926 +0200 > +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200 > @@ -209,7 +209,6 @@ > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3, > fc4) > FAIL: gdb.cp/inherit.exp: print g_vD > FAIL: gdb.cp/inherit.exp: print g_vE > FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)' > @@ -238,6 +237,7 @@ > UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings > FAIL: gdb.fortran/whatis_type.exp: run to MAIN__ > WARNING: remote_expect statement without a default case?! > +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > WARNING: remote_expect statement without a default case?! > @@ -362,12 +362,12 @@ > === gdb Summary === > > -# of expected passes 30881 > +# of expected passes 30884 > # of unexpected failures 284 > # of unexpected successes 2 > -# of expected failures 85 > +# of expected failures 83 > # of unknown successes 2 > -# of known failures 60 > +# of known failures 59 > # of unresolved testcases 6 > # of untested testcases 32 > # of unsupported tests 165 > > the sames changes randomly appear/disappear in the patched case. > Otherwise patched/unpatched agree. > > Ok? Jason, are you willing to review these refactoring patches or can I invoke my middle-end maintainer powers to remove some of this noise from the LTO parts? Thanks, Richard. > Thanks, > Richard. > > 2015-08-18 Richard Biener <rguenther@suse.de> > > * debug.h (gcc_debug_hooks::early_finish): Add filename argument. > * dbxout.c (dbx_debug_hooks): Adjust. > * debug.c (do_nothing_hooks): Likewise. > * sdbout.c (sdb_debug_hooks): Likewise. > * vmsdbgout.c (vmsdbgout_early_finish): New function dispatching > to dwarf2out variant if needed. > (vmsdbg_debug_hooks): Adjust. > * dwarf2out.c (dwarf2_line_hooks): Adjust. > (flush_limbo_die_list): New function. > (dwarf2out_finish): Call flush_limbo_die_list instead of > dwarf2out_early_finish. Assert there are no deferred asm-names. > Move early stuff ... > (dwarf2out_early_finish): ... here. > * cgraphunit.c (symbol_table::finalize_compilation_unit): > Call early_finish with main_input_filename argument. > > > Index: gcc/cgraphunit.c > =================================================================== > --- gcc/cgraphunit.c (revision 226966) > +++ gcc/cgraphunit.c (working copy) > @@ -2490,7 +2490,7 @@ symbol_table::finalize_compilation_unit > > /* Clean up anything that needs cleaning up after initial debug > generation. */ > - (*debug_hooks->early_finish) (); > + (*debug_hooks->early_finish) (main_input_filename); > > /* Finally drive the pass manager. */ > compile (); > Index: gcc/dbxout.c > =================================================================== > --- gcc/dbxout.c (revision 226966) > +++ gcc/dbxout.c (working copy) > @@ -354,7 +354,7 @@ const struct gcc_debug_hooks dbx_debug_h > { > dbxout_init, > dbxout_finish, > - debug_nothing_void, > + debug_nothing_charstar, > debug_nothing_void, > debug_nothing_int_charstar, > debug_nothing_int_charstar, > Index: gcc/debug.c > =================================================================== > --- gcc/debug.c (revision 226966) > +++ gcc/debug.c (working copy) > @@ -28,7 +28,7 @@ const struct gcc_debug_hooks do_nothing_ > { > debug_nothing_charstar, > debug_nothing_charstar, > - debug_nothing_void, /* early_finish */ > + debug_nothing_charstar, /* early_finish */ > debug_nothing_void, > debug_nothing_int_charstar, > debug_nothing_int_charstar, > Index: gcc/debug.h > =================================================================== > --- gcc/debug.h (revision 226966) > +++ gcc/debug.h (working copy) > @@ -31,7 +31,7 @@ struct gcc_debug_hooks > void (* finish) (const char *main_filename); > > /* Run cleanups necessary after early debug generation. */ > - void (* early_finish) (void); > + void (* early_finish) (const char *main_filename); > > /* Called from cgraph_optimize before starting to assemble > functions/variables/toplevel asms. */ > Index: gcc/dwarf2out.c > =================================================================== > --- gcc/dwarf2out.c (revision 226966) > +++ gcc/dwarf2out.c (working copy) > @@ -2420,7 +2420,7 @@ build_cfa_aligned_loc (dw_cfa_location * > > static void dwarf2out_init (const char *); > static void dwarf2out_finish (const char *); > -static void dwarf2out_early_finish (void); > +static void dwarf2out_early_finish (const char *); > static void dwarf2out_assembly_start (void); > static void dwarf2out_define (unsigned int, const char *); > static void dwarf2out_undef (unsigned int, const char *); > @@ -2494,7 +2494,7 @@ const struct gcc_debug_hooks dwarf2_line > { > dwarf2out_init, > debug_nothing_charstar, > - debug_nothing_void, > + debug_nothing_charstar, > debug_nothing_void, > debug_nothing_int_charstar, > debug_nothing_int_charstar, > @@ -25128,47 +25128,81 @@ optimize_location_lists (dw_die_ref die) > optimize_location_lists_1 (die, &htab); > } > > +/* Traverse the limbo die list, and add parent/child links. The only > + dies without parents that should be here are concrete instances of > + inline functions, and the comp_unit_die. We can ignore the comp_unit_die. > + For concrete instances, we can get the parent die from the abstract > + instance. */ > + > +static void > +flush_limbo_die_list (void) > +{ > + limbo_die_node *node, *next_node; > + > + for (node = limbo_die_list; node; node = next_node) > + { > + dw_die_ref die = node->die; > + next_node = node->next; > + > + if (die->die_parent == NULL) > + { > + dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); > + > + if (origin && origin->die_parent) > + add_child_die (origin->die_parent, die); > + else if (is_cu_die (die)) > + ; > + else if (seen_error ()) > + /* It's OK to be confused by errors in the input. */ > + add_child_die (comp_unit_die (), die); > + else > + { > + /* In certain situations, the lexical block containing a > + nested function can be optimized away, which results > + in the nested function die being orphaned. Likewise > + with the return type of that nested function. Force > + this to be a child of the containing function. > + > + It may happen that even the containing function got fully > + inlined and optimized out. In that case we are lost and > + assign the empty child. This should not be big issue as > + the function is likely unreachable too. */ > + gcc_assert (node->created_for); > + > + if (DECL_P (node->created_for)) > + origin = get_context_die (DECL_CONTEXT (node->created_for)); > + else if (TYPE_P (node->created_for)) > + origin = scope_die_for (node->created_for, comp_unit_die ()); > + else > + origin = comp_unit_die (); > + > + add_child_die (origin, die); > + } > + } > + } > + > + limbo_die_list = NULL; > +} > + > /* Output stuff that dwarf requires at the end of every file, > and generate the DWARF-2 debugging info. */ > > static void > -dwarf2out_finish (const char *filename) > +dwarf2out_finish (const char *) > { > comdat_type_node *ctnode; > dw_die_ref main_comp_unit_die; > > /* Flush out any latecomers to the limbo party. */ > - dwarf2out_early_finish (); > + flush_limbo_die_list (); > > - /* PCH might result in DW_AT_producer string being restored from the > - header compilation, so always fill it with empty string initially > - and overwrite only here. */ > - dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer); > - producer_string = gen_producer_string (); > - producer->dw_attr_val.v.val_str->refcount--; > - producer->dw_attr_val.v.val_str = find_AT_string (producer_string); > + /* We shouldn't have any symbols with delayed asm names for > + DIEs generated after early finish. */ > + gcc_assert (deferred_asm_name == NULL); > > gen_scheduled_generic_parms_dies (); > gen_remaining_tmpl_value_param_die_attribute (); > > - /* Add the name for the main input file now. We delayed this from > - dwarf2out_init to avoid complications with PCH. > - For LTO produced units use a fixed artificial name to avoid > - leaking tempfile names into the dwarf. */ > - if (!in_lto_p) > - add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); > - else > - add_name_attribute (comp_unit_die (), "<artificial>"); > - if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir) > - add_comp_dir_attribute (comp_unit_die ()); > - else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) > - { > - bool p = false; > - file_table->traverse<bool *, file_table_relative_p> (&p); > - if (p) > - add_comp_dir_attribute (comp_unit_die ()); > - } > - > #if ENABLE_ASSERT_CHECKING > { > dw_die_ref die = comp_unit_die (), c; > @@ -25482,9 +25516,9 @@ dwarf2out_finish (const char *filename) > has run. */ > > static void > -dwarf2out_early_finish (void) > +dwarf2out_early_finish (const char *filename) > { > - limbo_die_node *node, *next_node; > + limbo_die_node *node; > > /* Add DW_AT_linkage_name for all deferred DIEs. */ > for (node = deferred_asm_name; node; node = node->next) > @@ -25502,57 +25536,35 @@ dwarf2out_early_finish (void) > } > deferred_asm_name = NULL; > > - /* Traverse the limbo die list, and add parent/child links. The only > - dies without parents that should be here are concrete instances of > - inline functions, and the comp_unit_die. We can ignore the comp_unit_die. > - For concrete instances, we can get the parent die from the abstract > - instance. > - > - The point here is to flush out the limbo list so that it is empty > + /* The point here is to flush out the limbo list so that it is empty > and we don't need to stream it for LTO. */ > - for (node = limbo_die_list; node; node = next_node) > - { > - dw_die_ref die = node->die; > - next_node = node->next; > - > - if (die->die_parent == NULL) > - { > - dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); > - > - if (origin && origin->die_parent) > - add_child_die (origin->die_parent, die); > - else if (is_cu_die (die)) > - ; > - else if (seen_error ()) > - /* It's OK to be confused by errors in the input. */ > - add_child_die (comp_unit_die (), die); > - else > - { > - /* In certain situations, the lexical block containing a > - nested function can be optimized away, which results > - in the nested function die being orphaned. Likewise > - with the return type of that nested function. Force > - this to be a child of the containing function. > + flush_limbo_die_list (); > > - It may happen that even the containing function got fully > - inlined and optimized out. In that case we are lost and > - assign the empty child. This should not be big issue as > - the function is likely unreachable too. */ > - gcc_assert (node->created_for); > - > - if (DECL_P (node->created_for)) > - origin = get_context_die (DECL_CONTEXT (node->created_for)); > - else if (TYPE_P (node->created_for)) > - origin = scope_die_for (node->created_for, comp_unit_die ()); > - else > - origin = comp_unit_die (); > + /* PCH might result in DW_AT_producer string being restored from the > + header compilation, so always fill it with empty string initially > + and overwrite only here. */ > + dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer); > + producer_string = gen_producer_string (); > + producer->dw_attr_val.v.val_str->refcount--; > + producer->dw_attr_val.v.val_str = find_AT_string (producer_string); > > - add_child_die (origin, die); > - } > - } > + /* Add the name for the main input file now. We delayed this from > + dwarf2out_init to avoid complications with PCH. > + For LTO produced units use a fixed artificial name to avoid > + leaking tempfile names into the dwarf. */ > + if (!in_lto_p) > + add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); > + else > + add_name_attribute (comp_unit_die (), "<artificial>"); > + if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir) > + add_comp_dir_attribute (comp_unit_die ()); > + else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) > + { > + bool p = false; > + file_table->traverse<bool *, file_table_relative_p> (&p); > + if (p) > + add_comp_dir_attribute (comp_unit_die ()); > } > - > - limbo_die_list = NULL; > } > > /* Reset all state within dwarf2out.c so that we can rerun the compiler > Index: gcc/sdbout.c > =================================================================== > --- gcc/sdbout.c (revision 226966) > +++ gcc/sdbout.c (working copy) > @@ -278,7 +278,7 @@ const struct gcc_debug_hooks sdb_debug_h > { > sdbout_init, /* init */ > sdbout_finish, /* finish */ > - debug_nothing_void, /* early_finish */ > + debug_nothing_charstar, /* early_finish */ > debug_nothing_void, /* assembly_start */ > debug_nothing_int_charstar, /* define */ > debug_nothing_int_charstar, /* undef */ > Index: gcc/vmsdbgout.c > =================================================================== > --- gcc/vmsdbgout.c (revision 226966) > +++ gcc/vmsdbgout.c (working copy) > @@ -147,6 +147,7 @@ static int write_srccorrs (int); > > static void vmsdbgout_init (const char *); > static void vmsdbgout_finish (const char *); > +static void vmsdbgout_early_finish (const char *); > static void vmsdbgout_assembly_start (void); > static void vmsdbgout_define (unsigned int, const char *); > static void vmsdbgout_undef (unsigned int, const char *); > @@ -174,7 +175,7 @@ static void vmsdbgout_abstract_function > const struct gcc_debug_hooks vmsdbg_debug_hooks > = {vmsdbgout_init, > vmsdbgout_finish, > - debug_nothing_void, > + vmsdbgout_early_finish, > vmsdbgout_assembly_start, > vmsdbgout_define, > vmsdbgout_undef, > @@ -1552,7 +1553,17 @@ vmsdbgout_abstract_function (tree decl) > VMS Debug debugging info. */ > > static void > -vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED) > +vmsdbgout_early_finish (const char *filename) > +{ > + if (write_symbols == VMS_AND_DWARF2_DEBUG) > + (*dwarf2_debug_hooks.early_finish) (filename); > +} > + > +/* Output stuff that Debug requires at the end of every file and generate the > + VMS Debug debugging info. */ > + > +static void > +vmsdbgout_finish (const char *filename) > { > unsigned int i, ifunc; > int totsize; >
--- results.unpatched 2015-08-19 15:08:36.152899926 +0200 +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200 @@ -209,7 +209,6 @@ WARNING: remote_expect statement without a default case?! WARNING: remote_expect statement without a default case?! WARNING: remote_expect statement without a default case?! -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3, fc4) FAIL: gdb.cp/inherit.exp: print g_vD FAIL: gdb.cp/inherit.exp: print g_vE FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)' @@ -238,6 +237,7 @@ UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings FAIL: gdb.fortran/whatis_type.exp: run to MAIN__ WARNING: remote_expect statement without a default case?! +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt WARNING: remote_expect statement without a default case?! WARNING: remote_expect statement without a default case?! WARNING: remote_expect statement without a default case?! @@ -362,12 +362,12 @@ === gdb Summary === -# of expected passes 30881 +# of expected passes 30884 # of unexpected failures 284 # of unexpected successes 2 -# of expected failures 85 +# of expected failures 83 # of unknown successes 2 -# of known failures 60 +# of known failures 59 # of unresolved testcases 6 # of untested testcases 32 # of unsupported tests 165 the sames changes randomly appear/disappear in the patched case. Otherwise patched/unpatched agree. Ok? Thanks, Richard. 2015-08-18 Richard Biener <rguenther@suse.de> * debug.h (gcc_debug_hooks::early_finish): Add filename argument. * dbxout.c (dbx_debug_hooks): Adjust. * debug.c (do_nothing_hooks): Likewise. * sdbout.c (sdb_debug_hooks): Likewise. * vmsdbgout.c (vmsdbgout_early_finish): New function dispatching to dwarf2out variant if needed. (vmsdbg_debug_hooks): Adjust. * dwarf2out.c (dwarf2_line_hooks): Adjust. (flush_limbo_die_list): New function. (dwarf2out_finish): Call flush_limbo_die_list instead of dwarf2out_early_finish. Assert there are no deferred asm-names. Move early stuff ... (dwarf2out_early_finish): ... here. * cgraphunit.c (symbol_table::finalize_compilation_unit): Call early_finish with main_input_filename argument. Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 226966) +++ gcc/cgraphunit.c (working copy) @@ -2490,7 +2490,7 @@ symbol_table::finalize_compilation_unit /* Clean up anything that needs cleaning up after initial debug generation. */ - (*debug_hooks->early_finish) (); + (*debug_hooks->early_finish) (main_input_filename); /* Finally drive the pass manager. */ compile (); Index: gcc/dbxout.c =================================================================== --- gcc/dbxout.c (revision 226966) +++ gcc/dbxout.c (working copy) @@ -354,7 +354,7 @@ const struct gcc_debug_hooks dbx_debug_h { dbxout_init, dbxout_finish, - debug_nothing_void, + debug_nothing_charstar, debug_nothing_void, debug_nothing_int_charstar, debug_nothing_int_charstar, Index: gcc/debug.c =================================================================== --- gcc/debug.c (revision 226966) +++ gcc/debug.c (working copy) @@ -28,7 +28,7 @@ const struct gcc_debug_hooks do_nothing_ { debug_nothing_charstar, debug_nothing_charstar, - debug_nothing_void, /* early_finish */ + debug_nothing_charstar, /* early_finish */ debug_nothing_void, debug_nothing_int_charstar, debug_nothing_int_charstar, Index: gcc/debug.h =================================================================== --- gcc/debug.h (revision 226966) +++ gcc/debug.h (working copy) @@ -31,7 +31,7 @@ struct gcc_debug_hooks void (* finish) (const char *main_filename); /* Run cleanups necessary after early debug generation. */ - void (* early_finish) (void); + void (* early_finish) (const char *main_filename); /* Called from cgraph_optimize before starting to assemble functions/variables/toplevel asms. */ Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 226966) +++ gcc/dwarf2out.c (working copy) @@ -2420,7 +2420,7 @@ build_cfa_aligned_loc (dw_cfa_location * static void dwarf2out_init (const char *); static void dwarf2out_finish (const char *); -static void dwarf2out_early_finish (void); +static void dwarf2out_early_finish (const char *); static void dwarf2out_assembly_start (void); static void dwarf2out_define (unsigned int, const char *); static void dwarf2out_undef (unsigned int, const char *); @@ -2494,7 +2494,7 @@ const struct gcc_debug_hooks dwarf2_line { dwarf2out_init, debug_nothing_charstar, - debug_nothing_void, + debug_nothing_charstar, debug_nothing_void, debug_nothing_int_charstar, debug_nothing_int_charstar, @@ -25128,47 +25128,81 @@ optimize_location_lists (dw_die_ref die) optimize_location_lists_1 (die, &htab); } +/* Traverse the limbo die list, and add parent/child links. The only + dies without parents that should be here are concrete instances of + inline functions, and the comp_unit_die. We can ignore the comp_unit_die. + For concrete instances, we can get the parent die from the abstract + instance. */ + +static void +flush_limbo_die_list (void) +{ + limbo_die_node *node, *next_node; + + for (node = limbo_die_list; node; node = next_node) + { + dw_die_ref die = node->die; + next_node = node->next; + + if (die->die_parent == NULL) + { + dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); + + if (origin && origin->die_parent) + add_child_die (origin->die_parent, die); + else if (is_cu_die (die)) + ; + else if (seen_error ()) + /* It's OK to be confused by errors in the input. */ + add_child_die (comp_unit_die (), die); + else + { + /* In certain situations, the lexical block containing a + nested function can be optimized away, which results + in the nested function die being orphaned. Likewise + with the return type of that nested function. Force + this to be a child of the containing function. + + It may happen that even the containing function got fully + inlined and optimized out. In that case we are lost and + assign the empty child. This should not be big issue as + the function is likely unreachable too. */ + gcc_assert (node->created_for); + + if (DECL_P (node->created_for)) + origin = get_context_die (DECL_CONTEXT (node->created_for)); + else if (TYPE_P (node->created_for)) + origin = scope_die_for (node->created_for, comp_unit_die ()); + else + origin = comp_unit_die (); + + add_child_die (origin, die); + } + } + } + + limbo_die_list = NULL; +} + /* Output stuff that dwarf requires at the end of every file, and generate the DWARF-2 debugging info. */ static void -dwarf2out_finish (const char *filename) +dwarf2out_finish (const char *) { comdat_type_node *ctnode; dw_die_ref main_comp_unit_die; /* Flush out any latecomers to the limbo party. */ - dwarf2out_early_finish (); + flush_limbo_die_list (); - /* PCH might result in DW_AT_producer string being restored from the - header compilation, so always fill it with empty string initially - and overwrite only here. */ - dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer); - producer_string = gen_producer_string (); - producer->dw_attr_val.v.val_str->refcount--; - producer->dw_attr_val.v.val_str = find_AT_string (producer_string); + /* We shouldn't have any symbols with delayed asm names for + DIEs generated after early finish. */ + gcc_assert (deferred_asm_name == NULL); gen_scheduled_generic_parms_dies (); gen_remaining_tmpl_value_param_die_attribute (); - /* Add the name for the main input file now. We delayed this from - dwarf2out_init to avoid complications with PCH. - For LTO produced units use a fixed artificial name to avoid - leaking tempfile names into the dwarf. */ - if (!in_lto_p) - add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); - else - add_name_attribute (comp_unit_die (), "<artificial>"); - if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir) - add_comp_dir_attribute (comp_unit_die ()); - else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) - { - bool p = false; - file_table->traverse<bool *, file_table_relative_p> (&p); - if (p) - add_comp_dir_attribute (comp_unit_die ()); - } - #if ENABLE_ASSERT_CHECKING { dw_die_ref die = comp_unit_die (), c; @@ -25482,9 +25516,9 @@ dwarf2out_finish (const char *filename) has run. */ static void -dwarf2out_early_finish (void) +dwarf2out_early_finish (const char *filename) { - limbo_die_node *node, *next_node; + limbo_die_node *node; /* Add DW_AT_linkage_name for all deferred DIEs. */ for (node = deferred_asm_name; node; node = node->next) @@ -25502,57 +25536,35 @@ dwarf2out_early_finish (void) } deferred_asm_name = NULL; - /* Traverse the limbo die list, and add parent/child links. The only - dies without parents that should be here are concrete instances of - inline functions, and the comp_unit_die. We can ignore the comp_unit_die. - For concrete instances, we can get the parent die from the abstract - instance. - - The point here is to flush out the limbo list so that it is empty + /* The point here is to flush out the limbo list so that it is empty and we don't need to stream it for LTO. */ - for (node = limbo_die_list; node; node = next_node) - { - dw_die_ref die = node->die; - next_node = node->next; - - if (die->die_parent == NULL) - { - dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); - - if (origin && origin->die_parent) - add_child_die (origin->die_parent, die); - else if (is_cu_die (die)) - ; - else if (seen_error ()) - /* It's OK to be confused by errors in the input. */ - add_child_die (comp_unit_die (), die); - else - { - /* In certain situations, the lexical block containing a - nested function can be optimized away, which results - in the nested function die being orphaned. Likewise - with the return type of that nested function. Force - this to be a child of the containing function. + flush_limbo_die_list (); - It may happen that even the containing function got fully - inlined and optimized out. In that case we are lost and - assign the empty child. This should not be big issue as - the function is likely unreachable too. */ - gcc_assert (node->created_for); - - if (DECL_P (node->created_for)) - origin = get_context_die (DECL_CONTEXT (node->created_for)); - else if (TYPE_P (node->created_for)) - origin = scope_die_for (node->created_for, comp_unit_die ()); - else - origin = comp_unit_die (); + /* PCH might result in DW_AT_producer string being restored from the + header compilation, so always fill it with empty string initially + and overwrite only here. */ + dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer); + producer_string = gen_producer_string (); + producer->dw_attr_val.v.val_str->refcount--; + producer->dw_attr_val.v.val_str = find_AT_string (producer_string); - add_child_die (origin, die); - } - } + /* Add the name for the main input file now. We delayed this from + dwarf2out_init to avoid complications with PCH. + For LTO produced units use a fixed artificial name to avoid + leaking tempfile names into the dwarf. */ + if (!in_lto_p) + add_name_attribute (comp_unit_die (), remap_debug_filename (filename)); + else + add_name_attribute (comp_unit_die (), "<artificial>"); + if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir) + add_comp_dir_attribute (comp_unit_die ()); + else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) + { + bool p = false; + file_table->traverse<bool *, file_table_relative_p> (&p); + if (p) + add_comp_dir_attribute (comp_unit_die ()); } - - limbo_die_list = NULL; } /* Reset all state within dwarf2out.c so that we can rerun the compiler Index: gcc/sdbout.c =================================================================== --- gcc/sdbout.c (revision 226966) +++ gcc/sdbout.c (working copy) @@ -278,7 +278,7 @@ const struct gcc_debug_hooks sdb_debug_h { sdbout_init, /* init */ sdbout_finish, /* finish */ - debug_nothing_void, /* early_finish */ + debug_nothing_charstar, /* early_finish */ debug_nothing_void, /* assembly_start */ debug_nothing_int_charstar, /* define */ debug_nothing_int_charstar, /* undef */ Index: gcc/vmsdbgout.c =================================================================== --- gcc/vmsdbgout.c (revision 226966) +++ gcc/vmsdbgout.c (working copy) @@ -147,6 +147,7 @@ static int write_srccorrs (int); static void vmsdbgout_init (const char *); static void vmsdbgout_finish (const char *); +static void vmsdbgout_early_finish (const char *); static void vmsdbgout_assembly_start (void); static void vmsdbgout_define (unsigned int, const char *); static void vmsdbgout_undef (unsigned int, const char *); @@ -174,7 +175,7 @@ static void vmsdbgout_abstract_function const struct gcc_debug_hooks vmsdbg_debug_hooks = {vmsdbgout_init, vmsdbgout_finish, - debug_nothing_void, + vmsdbgout_early_finish, vmsdbgout_assembly_start, vmsdbgout_define, vmsdbgout_undef, @@ -1552,7 +1553,17 @@ vmsdbgout_abstract_function (tree decl) VMS Debug debugging info. */ static void -vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED) +vmsdbgout_early_finish (const char *filename) +{ + if (write_symbols == VMS_AND_DWARF2_DEBUG) + (*dwarf2_debug_hooks.early_finish) (filename); +} + +/* Output stuff that Debug requires at the end of every file and generate the + VMS Debug debugging info. */ + +static void +vmsdbgout_finish (const char *filename) { unsigned int i, ifunc; int totsize;