From 9370fd51ebfca8a8acacaecb92c57ee54f4f8382 Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Thu, 8 Oct 2020 12:28:19 +0100 Subject: [PATCH] gdb: detect main function even when there's no matching msymbol Currently, GDB will only stop the backtrace at the main function if there is a minimal symbol with the matching name. In Fortran programs compiled with gfortran this is not the case. The main function is present in the DWARF, and as marked as DW_AT_main_subprogram, but there's no minimal symbol. This commit extends `inside_main_func` to check the full symbols if no matching minimal symbol is found. There's an updated test case that covers this change. gdb/ChangeLog: * frame.c (inside_main_func): Check full symbols as well as minimal symbols. gdb/testsuite/ChangeLog: * gdb.fortran/mixed-lang-stack.exp (run_tests): Update expected output of backtrace. --- gdb/ChangeLog | 5 ++++ gdb/frame.c | 30 ++++++++++++++----- gdb/testsuite/ChangeLog | 5 ++++ .../gdb.fortran/mixed-lang-stack.exp | 3 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index de66f5aae79..26623c6067c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-10-11 Andrew Burgess + + * frame.c (inside_main_func): Check full symbols as well as + minimal symbols. + 2020-10-09 Joel Brobecker * ada-lang.c (advance_wild_match): Rewrite the function's diff --git a/gdb/frame.c b/gdb/frame.c index 5ae8611a8e6..b4af734c2ee 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -2295,19 +2295,33 @@ inside_main_func (frame_info *this_frame) if (symfile_objfile == nullptr) return false; + CORE_ADDR sym_addr; + const char *name = main_name (); bound_minimal_symbol msymbol - = lookup_minimal_symbol (main_name (), NULL, symfile_objfile); + = lookup_minimal_symbol (name, NULL, symfile_objfile); if (msymbol.minsym == nullptr) - return false; + { + /* In some language (for example Fortran) there will be no minimal + symbol with the name of the main function. In this case we should + search the full symbols to see if we can find a match. */ + struct block_symbol bs = lookup_symbol (name, NULL, VAR_DOMAIN, 0); + if (bs.symbol == nullptr) + return false; + + const struct block *block = SYMBOL_BLOCK_VALUE (bs.symbol); + gdb_assert (block != nullptr); + sym_addr = BLOCK_START (block); + } + else + sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol); - /* Make certain that the code, and not descriptor, address is - returned. */ - CORE_ADDR maddr + /* Convert any function descriptor addresses into the actual function + code address. */ + sym_addr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame), - BMSYMBOL_VALUE_ADDRESS (msymbol), - current_top_target ()); + sym_addr, current_top_target ()); - return maddr == get_frame_func (this_frame); + return sym_addr == get_frame_func (this_frame); } /* Test whether THIS_FRAME is inside the process entry point function. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d7e80954b1d..2e8efd93746 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-10-11 Andrew Burgess + + * gdb.fortran/mixed-lang-stack.exp (run_tests): Update expected + output of backtrace. + 2020-10-09 Tom Tromey * gdb.ada/scalar_storage/storage.adb (Another_Range): New type. diff --git a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp index edf2508537d..8d1f2bc0123 100644 --- a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp +++ b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp @@ -73,8 +73,7 @@ proc run_tests { lang } { "#6\\s+$hex in mixed_func_1c \\(\[^\r\n\]+\\) at \[^\r\n\]+" \ "#7\\s+$hex in mixed_func_1b \\($1b_args\\) at \[^\r\n\]+" \ "#8\\s+$hex in mixed_func_1a \\(\\) at \[^\r\n\]+" \ - "#9\\s+$hex in mixed_stack_main \\(\\) at \[^\r\n\]+" \ - "#10\\s+$hex in main \\(\[^\r\n\]+\\) at .*" ] + "#9\\s+$hex in mixed_stack_main \\(\\) at \[^\r\n\]+" ] gdb_test "bt -frame-arguments all" $bt_stack # Check the language for frame #0. -- 2.30.2