GCC stack backtraces
Pedro Larroy
pedro.larroy.lists@gmail.com
Fri Sep 14 11:02:00 GMT 2012
If you link with -rdynamic you can show a backtrace with something
like the attached code.
On Wed, Aug 29, 2012 at 9:22 AM, Ian Lance Taylor <iant@google.com> wrote:
> I've spent the last couple of days working on a stack backtrace library.
>
> It uses the GCC unwind interface to collect a stack trace, and parses
> DWARF debug info to get file/line/function information. (Of course it's
> silly to write yet another DWARF reader, but I didn't find an existing
> reader that seemed wholly suitable.) The code currently only works for
> ELF/DWARF, but it's designed to support other object file and debug
> formats should anybody care to write them. Since its use in GCC would
> be purely for GCC developers, it's not essential that it be fully
> portable.
>
>
> I picked a random PR that causes an ICE. Here is the final output of
> g++ -c foo.cc:
>
> foo.cc:6:6: internal compiler error: in cp_lexer_new_from_tokens, at cp/parser.c:638
> 0xed6e77 diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*)
> ../../trunk/gcc/diagnostic.c:700
> 0xed7c2f internal_error(char const*, ...)
> ../../trunk/gcc/diagnostic.c:1003
> 0xed6703 fancy_abort(char const*, int, char const*)
> ../../trunk/gcc/diagnostic.c:1057
> 0x5bc3ee cp_lexer_new_from_tokens
> ../../trunk/gcc/cp/parser.c:638
> 0x5bc3ee cp_parser_push_lexer_for_tokens
> ../../trunk/gcc/cp/parser.c:3293
> 0x5c5510 cp_parser_late_parsing_for_member
> ../../trunk/gcc/cp/parser.c:21741
> 0x5c5510 cp_parser_class_specifier_1
> ../../trunk/gcc/cp/parser.c:18210
> 0x5c5510 cp_parser_class_specifier
> ../../trunk/gcc/cp/parser.c:18234
> 0x5c5510 cp_parser_type_specifier
> ../../trunk/gcc/cp/parser.c:13393
> 0x5dd56d cp_parser_decl_specifier_seq
> ../../trunk/gcc/cp/parser.c:10734
> 0x5e00d7 cp_parser_single_declaration
> ../../trunk/gcc/cp/parser.c:21344
> 0x5e1211 cp_parser_template_declaration_after_export
> ../../trunk/gcc/cp/parser.c:21231
> 0x5ea9f9 cp_parser_declaration
> ../../trunk/gcc/cp/parser.c:10186
> 0x5e9507 cp_parser_declaration_seq_opt
> ../../trunk/gcc/cp/parser.c:10108
> 0x5eae92 cp_parser_translation_unit
> ../../trunk/gcc/cp/parser.c:3760
> 0x5eae92 c_parse_file()
> ../../trunk/gcc/cp/parser.c:27585
> 0x6ed0c4 c_common_parse_file()
> ../../trunk/gcc/c-family/c-opts.c:1137
> 0xa2017b compile_file
> ../../trunk/gcc/toplev.c:546
> 0xa21d89 do_compile
> ../../trunk/gcc/toplev.c:1863
> 0xa21d89 toplev_main(int, char**)
> ../../trunk/gcc/toplev.c:1939
> 0x7fb0a50d8c4c ???
> ???:0
> 0x4c6db8 ???
> ???:0
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <http://gcc.gnu.org/bugs.html> for instructions.
>
>
> So, big deal. You can get a stack backtrace from gdb anyhow.
>
> For a more interesting use I hacked ggc-common.c to collect detailed
> statistics when used with -fmem-report. This gives us data similar to,
> and better than, that you get when you configure GCC with
> --enable-gather-detailed-mem-stats. However, with this approach you do
> not need to recompile GCC. Running this modified GCC with -fmem-report
> -O2 -g combine.ii took 36 seconds. The full report is too large to
> attach here, but here are the last few entries of the ggc-common.c.
> Note that I spent exactly 0 seconds making the report pretty.
>
> 0xbf1151 ../../trunk/gcc/tree.c:7607 build_function_type(tree_node*, tree_node*)
> 0x50f1c0 ../../trunk/gcc/cp/decl.c:9346 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq const*, decl_context, int, tree_node**)
> 0x514a75 ../../trunk/gcc/cp/decl.c:4366 start_decl(cp_declarator const*, cp_decl_specifier_seq*, int, tree_node*, tree_node*, tree_node**)
> 0x5dbeca ../../trunk/gcc/cp/parser.c:15720 cp_parser_init_declarator
> 0x5de4ba ../../trunk/gcc/cp/parser.c:10445 cp_parser_simple_declaration
> 0x5e6337 ../../trunk/gcc/cp/parser.c:10326 cp_parser_block_declaration
> 0x5ea8fb ../../trunk/gcc/cp/parser.c:10222 cp_parser_declaration
> 0x5e9507 ../../trunk/gcc/cp/parser.c:10108 cp_parser_declaration_seq_opt
> 0x5eae92 ../../trunk/gcc/cp/parser.c:3760 cp_parser_translation_unit
> 0x5eae92 ../../trunk/gcc/cp/parser.c:27585 c_parse_file()
> 0x6ed0c4 ../../trunk/gcc/c-family/c-opts.c:1137 c_common_parse_file()
> 0xa2017b ../../trunk/gcc/toplev.c:546 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 611352: 1.0% 0: 0.0% 181776: 0.6% 0: 0.0% 4721
> 0xbf342f ../../trunk/gcc/tree.c:1224 build_int_cst_wide(tree_node*, unsigned long, long)
> 0xbf37a5 ../../trunk/gcc/tree.c:1065 double_int_to_tree(tree_node*, double_int)
> 0xbf37ea ../../trunk/gcc/tree.c:1042 build_int_cst(tree_node*, long)
> 0xa19fee ../../trunk/gcc/stor-layout.c:2545 set_min_and_max_values_for_integral_type(tree_node*, int, bool)
> 0x502788 ../../trunk/gcc/cp/decl.c:12345 finish_enum_value_list(tree_node*)
> 0x5d53d4 ../../trunk/gcc/cp/parser.c:14609 cp_parser_enum_specifier
> 0x5c4c1d ../../trunk/gcc/cp/parser.c:13365 cp_parser_type_specifier
> 0x5dd56d ../../trunk/gcc/cp/parser.c:10734 cp_parser_decl_specifier_seq
> 0x5de309 ../../trunk/gcc/cp/parser.c:10377 cp_parser_simple_declaration
> 0x5e6337 ../../trunk/gcc/cp/parser.c:10326 cp_parser_block_declaration
> 0x5ea8fb ../../trunk/gcc/cp/parser.c:10222 cp_parser_declaration
> 0x5e9507 ../../trunk/gcc/cp/parser.c:10108 cp_parser_declaration_seq_opt
> 0x5eae92 ../../trunk/gcc/cp/parser.c:3760 cp_parser_translation_unit
> 0x5eae92 ../../trunk/gcc/cp/parser.c:27585 c_parse_file()
> 0x6ed0c4 ../../trunk/gcc/c-family/c-opts.c:1137 c_common_parse_file()
> 0xa2017b ../../trunk/gcc/toplev.c:546 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 0: 0.0% 0: 0.0% 837344: 2.8% 276192:16.2% 137
> 0xc147e7 ../../trunk/gcc/var-tracking.c:8568 emit_note_insn_var_location
> 0xf18f08 ../../trunk/libiberty/hashtab.c:784 htab_traverse
> 0xc22ea7 ../../trunk/gcc/var-tracking.c:8756 emit_notes_for_changes
> 0xc23054 ../../trunk/gcc/var-tracking.c:8870 emit_notes_for_differences
> 0xc23054 ../../trunk/gcc/var-tracking.c:9245 vt_emit_notes
> 0xc23b49 ../../trunk/gcc/var-tracking.c:10048 variable_tracking_main_1
> 0xc23b49 ../../trunk/gcc/var-tracking.c:10062 variable_tracking_main()
> 0x97de5e ../../trunk/gcc/passes.c:2157 execute_one_pass(opt_pass*)
> 0x97e214 ../../trunk/gcc/passes.c:2212 execute_pass_list(opt_pass*)
> 0x97e226 ../../trunk/gcc/passes.c:2213 execute_pass_list(opt_pass*)
> 0x97e226 ../../trunk/gcc/passes.c:2213 execute_pass_list(opt_pass*)
> 0x7782d7 ../../trunk/gcc/cgraphunit.c:1609 expand_function
> 0x77a179 ../../trunk/gcc/cgraphunit.c:1714 expand_all_functions
> 0x77a179 ../../trunk/gcc/cgraphunit.c:2012 compile()
> 0x77a774 ../../trunk/gcc/cgraphunit.c:2089 finalize_compilation_unit()
> 0x5aa0ba ../../trunk/gcc/cp/decl2.c:4024 cp_write_global_declarations()
> 0xa201c4 ../../trunk/gcc/toplev.c:560 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 872704: 1.5% 0: 0.0% 0: 0.0% 0: 0.0% 13636
> 0xbf03e8 ../../trunk/gcc/tree.c:4093 build_decl_stat(unsigned int, tree_code, tree_node*, tree_node*)
> 0x5bb085 ../../trunk/gcc/cp/lex.c:532 build_lang_decl_loc(unsigned int, tree_code, tree_node*, tree_node*)
> 0x516729 ../../trunk/gcc/cp/decl.c:7175 grokfndecl
> 0x5129fd ../../trunk/gcc/cp/decl.c:10394 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq const*, decl_context, int, tree_node**)
> 0x514a75 ../../trunk/gcc/cp/decl.c:4366 start_decl(cp_declarator const*, cp_decl_specifier_seq*, int, tree_node*, tree_node*, tree_node**)
> 0x5dbeca ../../trunk/gcc/cp/parser.c:15720 cp_parser_init_declarator
> 0x5de4ba ../../trunk/gcc/cp/parser.c:10445 cp_parser_simple_declaration
> 0x5e6337 ../../trunk/gcc/cp/parser.c:10326 cp_parser_block_declaration
> 0x5ea8fb ../../trunk/gcc/cp/parser.c:10222 cp_parser_declaration
> 0x5e9507 ../../trunk/gcc/cp/parser.c:10108 cp_parser_declaration_seq_opt
> 0x5eae92 ../../trunk/gcc/cp/parser.c:3760 cp_parser_translation_unit
> 0x5eae92 ../../trunk/gcc/cp/parser.c:27585 c_parse_file()
> 0x6ed0c4 ../../trunk/gcc/c-family/c-opts.c:1137 c_common_parse_file()
> 0xa2017b ../../trunk/gcc/toplev.c:546 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 0: 0.0% 864: 0.0% 1348128: 4.5% 149888: 8.8% 4684
> 0xb86a21 ../../trunk/gcc/tree-ssanames.c:140 make_ssa_name_fn(function*, tree_node*, gimple_statement_d*)
> 0xa7a3c1 ../../trunk/gcc/tree-flow-inline.h:1144 make_ssa_name
> 0xa7a3c1 ../../trunk/gcc/tree-into-ssa.c:1396 rewrite_stmt
> 0xa7a3c1 ../../trunk/gcc/tree-into-ssa.c:1471 rewrite_enter_block
> 0xe275fa ../../trunk/gcc/domwalk.c:188 walk_dominator_tree(dom_walk_data*, basic_block_def*)
> 0xa7bc70 ../../trunk/gcc/tree-into-ssa.c:2265 rewrite_blocks
> 0xa7bf97 ../../trunk/gcc/tree-into-ssa.c:2432 rewrite_into_ssa
> 0x97de5e ../../trunk/gcc/passes.c:2157 execute_one_pass(opt_pass*)
> 0x97e214 ../../trunk/gcc/passes.c:2212 execute_pass_list(opt_pass*)
> 0x97d37c ../../trunk/gcc/passes.c:1702 do_per_function_toporder(void (*)(void*), void*)
> 0x97e6ab ../../trunk/gcc/passes.c:2526 execute_ipa_pass_list(opt_pass*)
> 0x779fe1 ../../trunk/gcc/cgraphunit.c:1838 ipa_passes
> 0x779fe1 ../../trunk/gcc/cgraphunit.c:1961 compile()
> 0x77a774 ../../trunk/gcc/cgraphunit.c:2089 finalize_compilation_unit()
> 0x5aa0ba ../../trunk/gcc/cp/decl2.c:4024 cp_write_global_declarations()
> 0xa201c4 ../../trunk/gcc/toplev.c:560 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 1005760: 1.7% 0: 0.0% 359680: 1.2% 0: 0.0% 17068
> 0xa1ca7d ../../trunk/gcc/stringpool.c:75 alloc_node
> 0xef2dc7 ../../trunk/libcpp/symtab.c:158 ht_lookup_with_hash(ht*, unsigned char const*, unsigned long, unsigned int, ht_lookup_option)
> 0xee88de ../../trunk/libcpp/lex.c:1232 lex_identifier
> 0xeeadcf ../../trunk/libcpp/lex.c:2205 _cpp_lex_direct
> 0xeeb96b ../../trunk/libcpp/lex.c:1974 _cpp_lex_token
> 0xeefce7 ../../trunk/libcpp/macro.c:2357 cpp_get_token_1
> 0x6e6622 ../../trunk/gcc/c-family/c-lex.c:299 c_lex_with_flags(tree_node**, unsigned int*, unsigned char*, int)
> 0x5bf66f ../../trunk/gcc/cp/parser.c:719 cp_lexer_get_preprocessor_token
> 0x5ead40 ../../trunk/gcc/cp/parser.c:598 cp_lexer_new_main
> 0x5ead40 ../../trunk/gcc/cp/parser.c:3216 cp_parser_new
> 0x5ead40 ../../trunk/gcc/cp/parser.c:27582 c_parse_file()
> 0x6ed0c4 ../../trunk/gcc/c-family/c-opts.c:1137 c_common_parse_file()
> 0xa2017b ../../trunk/gcc/toplev.c:546 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 16016: 0.0% 0: 0.0% 1564728: 5.2% 0: 0.0% 17963
> 0xbf03e8 ../../trunk/gcc/tree.c:4093 build_decl_stat(unsigned int, tree_code, tree_node*, tree_node*)
> 0x59de96 ../../trunk/gcc/cp/decl2.c:181 cp_build_parm_decl(tree_node*, tree_node*)
> 0x5133de ../../trunk/gcc/cp/decl.c:10054 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq const*, decl_context, int, tree_node**)
> 0x5defbc ../../trunk/gcc/cp/parser.c:17116 cp_parser_parameter_declaration_list
> 0x5df444 ../../trunk/gcc/cp/parser.c:17030 cp_parser_parameter_declaration_clause
> 0x5d6aee ../../trunk/gcc/cp/parser.c:16090 cp_parser_direct_declarator
> 0x5d6aee ../../trunk/gcc/cp/parser.c:15961 cp_parser_declarator
> 0x5dbb67 ../../trunk/gcc/cp/parser.c:15537 cp_parser_init_declarator
> 0x5de4ba ../../trunk/gcc/cp/parser.c:10445 cp_parser_simple_declaration
> 0x5e6337 ../../trunk/gcc/cp/parser.c:10326 cp_parser_block_declaration
> 0x5ea8fb ../../trunk/gcc/cp/parser.c:10222 cp_parser_declaration
> 0x5e9507 ../../trunk/gcc/cp/parser.c:10108 cp_parser_declaration_seq_opt
> 0x5eae92 ../../trunk/gcc/cp/parser.c:3760 cp_parser_translation_unit
> 0x5eae92 ../../trunk/gcc/cp/parser.c:27585 c_parse_file()
> 0x6ed0c4 ../../trunk/gcc/c-family/c-opts.c:1137 c_common_parse_file()
> 0xa2017b ../../trunk/gcc/toplev.c:546 compile_file
> 0xa21d89 ../../trunk/gcc/toplev.c:1863 do_compile
> 0xa21d89 ../../trunk/gcc/toplev.c:1939 toplev_main(int, char**)
> 0x7f4044f36c4c ???:0 ???
> 0x4c6db8 ???:0 ???
> 32640: 0.1% 0: 0.0% 1555328: 5.2% 0: 0.0% 12406
> Total 59553548 38936868 29879567 1701879 1921781
> Garbage Freed Leak Overhead Times
>
>
>
> As you can see, this gives us the opportunity for some fairly detailed
> analysis of where we are allocating memory, without requiring the
> compiler to be recompiled, and without taking an inordinate amount of
> time.
>
>
> I expect to use this code not just for GCC proper, but also for libgo
> (currently libgo uses Go code to parse DWARF, but that is not very
> satisfactory as that code is only available if it has been imported into
> the program). So I put it under a BSD license, although that is open
> for discussion. Also in case it finds more uses elsewhere I wrote it in
> reasonably portable C rather than C++.
>
>
> I've attached two patches. The first is the patch for the libbacktrace
> library, plus the changes to the top level configure.ac and
> Makefile.def. The second is the changes to GCC proper that I used to
> generate the above dumps. The second patch is just quick and dirty work
> to see if the library could work well.
>
>
> Does this seem like something we could usefully add to GCC? Does
> anybody see any big problems with it?
>
> The library is not quite ready to commit, but it's quite close. It just
> needs a bit more testing in uncommon build environments, i.e., anything
> other than x86_64 GNU/Linux, to make sure that it at least builds and
> does not crash even when it can't get a backtrace.
>
> Ian
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bt.cc
Type: application/octet-stream
Size: 1351 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20120914/9426425c/attachment.obj>
More information about the Gcc
mailing list