From efd9eb2979c1d01c2bea341e5faf1a682c104ff4 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Tue, 21 Aug 2018 07:39:29 +0000 Subject: [PATCH] [debug] Add debug and earlydebug dumps With the introduction of early debug, we've added a phase in the compiler which produces information which is not visible, unless we run the compiler in the debugger and call debug_dwarf from dwarf2out_early_finish or some such. This patch adds dumping of "early" and "final" debug info, into .earlydebug and .debug dump files, enabled by -fdump-earlydebug and -fdumpdebug, such that we can follow f.i. the upper bound of a vla type from early debug: ... DW_AT_upper_bound: location descriptor: (0x7f0d645b7550) DW_OP_GNU_variable_value , 0 ... to final debug: ... DW_AT_upper_bound: location descriptor: (0x7f0d645b7550) DW_OP_fbreg 18446744073709551592, 0 (0x7f0d645b7a00) DW_OP_deref 8, 0 ... to -dA annotated assembly file: ... .uleb128 0x3 # DW_AT_upper_bound .byte 0x91 # DW_OP_fbreg .sleb128 -24 .byte 0x6 # DW_OP_deref ... The .debug file shows the same information as the annotated assembly, but in the same format as the "early" debug info. Bootstrapped and reg-tested on x86_64. 2018-08-21 Tom de Vries * cgraph.h (debuginfo_early_init, debuginfo_init, debuginfo_fini) (debuginfo_start, debuginfo_stop, debuginfo_early_start) (debuginfo_early_stop): Declare. * cgraphunit.c (debuginfo_early_init, debuginfo_init, debuginfo_fini) (debuginfo_start, debuginfo_stop, debuginfo_early_start) (debuginfo_early_stop): New function. (symbol_table::finalize_compilation_unit): Call debuginfo_early_start and debuginfo_early_stop. * dwarf2out.c (dwarf2out_finish, dwarf2out_early_finish): Dump dwarf. * toplev.c (compile_file): Call debuginfo_start and debuginfo_stop. (general_init): Call debuginfo_early_init. (finalize): Call debuginfo_fini. (do_compile): Call debuginfo_init. * doc/invoke.texi (@gccoptlist): Add -fdump-debug and -fdump-early-debug. (@item -fdump-debug, @item -fdump-earlydebug): Add. * lto.c (lto_main): Call debuginfo_early_start and debuginfo_early_stop. * gcc.c-torture/unsorted/dump-noaddr.x: Use -gno-record-gcc-switches to avoid mismatch in .debug and .earlydebug dump files. From-SVN: r263687 --- gcc/ChangeLog | 19 +++++ gcc/cgraph.h | 8 ++ gcc/cgraphunit.c | 85 +++++++++++++++++++ gcc/doc/invoke.texi | 11 +++ gcc/dwarf2out.c | 18 +++- gcc/lto/ChangeLog | 5 ++ gcc/lto/lto.c | 2 + gcc/testsuite/ChangeLog | 5 ++ .../gcc.c-torture/unsorted/dump-noaddr.x | 4 +- gcc/toplev.c | 5 ++ 10 files changed, 159 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb9c1518062..47dd9eaa4ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2018-08-21 Tom de Vries + + * cgraph.h (debuginfo_early_init, debuginfo_init, debuginfo_fini) + (debuginfo_start, debuginfo_stop, debuginfo_early_start) + (debuginfo_early_stop): Declare. + * cgraphunit.c (debuginfo_early_init, debuginfo_init, debuginfo_fini) + (debuginfo_start, debuginfo_stop, debuginfo_early_start) + (debuginfo_early_stop): New function. + (symbol_table::finalize_compilation_unit): Call debuginfo_early_start + and debuginfo_early_stop. + * dwarf2out.c (dwarf2out_finish, dwarf2out_early_finish): Dump dwarf. + * toplev.c (compile_file): Call debuginfo_start and debuginfo_stop. + (general_init): Call debuginfo_early_init. + (finalize): Call debuginfo_fini. + (do_compile): Call debuginfo_init. + * doc/invoke.texi (@gccoptlist): Add -fdump-debug and + -fdump-early-debug. + (@item -fdump-debug, @item -fdump-earlydebug): Add. + 2018-08-21 Tom de Vries * dwarf2out.c (print_dw_val, print_loc_descr, print_die): Handle diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a8b1b4cb3c3..2b00f0165fa 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -25,6 +25,14 @@ along with GCC; see the file COPYING3. If not see #include "ipa-ref.h" #include "plugin-api.h" +extern void debuginfo_early_init (void); +extern void debuginfo_init (void); +extern void debuginfo_fini (void); +extern void debuginfo_start (void); +extern void debuginfo_stop (void); +extern void debuginfo_early_start (void); +extern void debuginfo_early_stop (void); + class ipa_opt_pass_d; typedef ipa_opt_pass_d *ipa_opt_pass; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 208798f0dc7..ec490d75bd1 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2641,6 +2641,89 @@ symbol_table::compile (void) } } +/* Earlydebug dump file, flags, and number. */ + +static int debuginfo_early_dump_nr; +static FILE *debuginfo_early_dump_file; +static dump_flags_t debuginfo_early_dump_flags; + +/* Debug dump file, flags, and number. */ + +static int debuginfo_dump_nr; +static FILE *debuginfo_dump_file; +static dump_flags_t debuginfo_dump_flags; + +/* Register the debug and earlydebug dump files. */ + +void +debuginfo_early_init (void) +{ + gcc::dump_manager *dumps = g->get_dumps (); + debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", "earlydebug", + "earlydebug", DK_tree, + OPTGROUP_NONE, + false); + debuginfo_dump_nr = dumps->dump_register (".debug", "debug", + "debug", DK_tree, + OPTGROUP_NONE, + false); +} + +/* Initialize the debug and earlydebug dump files. */ + +void +debuginfo_init (void) +{ + gcc::dump_manager *dumps = g->get_dumps (); + debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL); + debuginfo_dump_flags = dumps->get_dump_file_info (debuginfo_dump_nr)->pflags; + debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL); + debuginfo_early_dump_flags + = dumps->get_dump_file_info (debuginfo_early_dump_nr)->pflags; +} + +/* Finalize the debug and earlydebug dump files. */ + +void +debuginfo_fini (void) +{ + if (debuginfo_dump_file) + dump_end (debuginfo_dump_nr, debuginfo_dump_file); + if (debuginfo_early_dump_file) + dump_end (debuginfo_early_dump_nr, debuginfo_early_dump_file); +} + +/* Set dump_file to the debug dump file. */ + +void +debuginfo_start (void) +{ + set_dump_file (debuginfo_dump_file); +} + +/* Undo setting dump_file to the debug dump file. */ + +void +debuginfo_stop (void) +{ + set_dump_file (NULL); +} + +/* Set dump_file to the earlydebug dump file. */ + +void +debuginfo_early_start (void) +{ + set_dump_file (debuginfo_early_dump_file); +} + +/* Undo setting dump_file to the earlydebug dump file. */ + +void +debuginfo_early_stop (void) +{ + set_dump_file (NULL); +} /* Analyze the whole compilation unit once it is parsed completely. */ @@ -2696,7 +2779,9 @@ symbol_table::finalize_compilation_unit (void) /* Clean up anything that needs cleaning up after initial debug generation. */ + debuginfo_early_start (); (*debug_hooks->early_finish) (main_input_filename); + debuginfo_early_stop (); } /* Finally drive the pass manager. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f8287153be1..99849ec6467 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -566,6 +566,7 @@ Objective-C and Objective-C++ Dialects}. -fdisable-rtl-@var{pass-name}=@var{range-list} @gol -fdisable-tree-@var{pass_name} @gol -fdisable-tree-@var{pass-name}=@var{range-list} @gol +-fdump-debug -fdump-earlydebug @gol -fdump-noaddr -fdump-unnumbered -fdump-unnumbered-links @gol -fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol -fdump-final-insns@r{[}=@var{file}@r{]} @gol @@ -13777,6 +13778,16 @@ Just generate RTL for a function instead of compiling it. Usually used with @option{-fdump-rtl-expand}. @end table +@item -fdump-debug +@opindex fdump-debug +Dump debugging information generated during the debug +generation phase. + +@item -fdump-earlydebug +@opindex fdump-earlydebug +Dump debugging information generated during the early debug +generation phase. + @item -fdump-noaddr @opindex fdump-noaddr When doing debugging dumps, suppress address output. This makes it more diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index ffb332a358d..fb71ff349fa 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -31112,7 +31112,7 @@ reset_dies (dw_die_ref die) and generate the DWARF-2 debugging info. */ static void -dwarf2out_finish (const char *) +dwarf2out_finish (const char *filename) { comdat_type_node *ctnode; dw_die_ref main_comp_unit_die; @@ -31193,6 +31193,12 @@ dwarf2out_finish (const char *) resolve_addr (comp_unit_die ()); move_marked_base_types (); + if (dump_file) + { + fprintf (dump_file, "DWARF for %s\n", filename); + print_die (comp_unit_die (), dump_file); + } + /* Initialize sections and labels used for actual assembler output. */ unsigned generation = init_sections_and_labels (false); @@ -31888,6 +31894,11 @@ dwarf2out_early_finish (const char *filename) if (in_lto_p) { early_dwarf_finished = true; + if (dump_file) + { + fprintf (dump_file, "LTO EARLY DWARF for %s\n", filename); + print_die (comp_unit_die (), dump_file); + } return; } @@ -31965,6 +31976,11 @@ dwarf2out_early_finish (const char *filename) /* The early debug phase is now finished. */ early_dwarf_finished = true; + if (dump_file) + { + fprintf (dump_file, "EARLY DWARF for %s\n", filename); + print_die (comp_unit_die (), dump_file); + } /* Do not generate DWARF assembler now when not producing LTO bytecode. */ if ((!flag_generate_lto && !flag_generate_offload) diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index eb239972d9e..a92317cb774 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2018-08-21 Tom de Vries + + * lto.c (lto_main): Call debuginfo_early_start and + debuginfo_early_stop. + 2018-07-20 Martin Sebor PR middle-end/82063 diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 8db280ecefc..10618896022 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -3419,7 +3419,9 @@ lto_main (void) lto_promote_statics_nonwpa (); /* Annotate the CU DIE and mark the early debug phase as finished. */ + debuginfo_early_start (); debug_hooks->early_finish (""); + debuginfo_early_stop (); /* Let the middle end know that we have read and merged all of the input files. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af8615607fb..0a420304716 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-21 Tom de Vries + + * gcc.c-torture/unsorted/dump-noaddr.x: Use -gno-record-gcc-switches + to avoid mismatch in .debug and .earlydebug dump files. + 2018-08-20 Michael Meissner PR target/87033 diff --git a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x index e86f36a1861..0e4298ad3d7 100644 --- a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x +++ b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x @@ -11,10 +11,10 @@ proc dump_compare { src options } { foreach option $option_list { file delete -force $tmpdir/dump1 file mkdir $tmpdir/dump1 - c-torture-compile $src "$option $options -dumpbase dump1/$dumpbase -DMASK=1 -x c --param ggc-min-heapsize=1 -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" + c-torture-compile $src "$option $options -dumpbase dump1/$dumpbase -DMASK=1 -x c --param ggc-min-heapsize=1 -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr -gno-record-gcc-switches" file delete -force $tmpdir/dump2 file mkdir $tmpdir/dump2 - c-torture-compile $src "$option $options -dumpbase dump2/$dumpbase -DMASK=2 -x c -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" + c-torture-compile $src "$option $options -dumpbase dump2/$dumpbase -DMASK=2 -x c -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr -gno-record-gcc-switches" foreach dump1 [lsort [glob -nocomplain $tmpdir/dump1/*]] { set dump2 "$tmpdir/dump2/[file tail $dump1]" set dumptail "gcc.c-torture/unsorted/[file tail $dump1]" diff --git a/gcc/toplev.c b/gcc/toplev.c index 2789d71b24f..9fb83d4e43f 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -529,7 +529,9 @@ compile_file (void) dwarf2out_frame_finish (); #endif + debuginfo_start (); (*debug_hooks->finish) (main_input_filename); + debuginfo_stop (); timevar_pop (TV_SYMOUT); /* Output some stuff at end of file if nec. */ @@ -1187,6 +1189,7 @@ general_init (const char *argv0, bool init_signals) symtab = new (ggc_cleared_alloc ()) symbol_table (); statistics_early_init (); + debuginfo_early_init (); finish_params (); } @@ -2081,6 +2084,7 @@ finalize (bool no_backend) if (!no_backend) { statistics_fini (); + debuginfo_fini (); g->get_passes ()->finish_optimization_passes (); @@ -2158,6 +2162,7 @@ do_compile () init_final (main_input_filename); coverage_init (aux_base_name); statistics_init (); + debuginfo_init (); invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL); timevar_stop (TV_PHASE_SETUP); -- 2.30.2