diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-10-08 12:28:19 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-10-11 18:35:39 +0100 |
commit | 9370fd51ebfca8a8acacaecb92c57ee54f4f8382 (patch) | |
tree | d36933bddea27597c50b9fa5680dfc7136f369a6 /gdb/frame.c | |
parent | f7c1edaa78ed5ef18ba1e290effd76ecc49884d2 (diff) | |
download | fsf-binutils-gdb-9370fd51ebfca8a8acacaecb92c57ee54f4f8382.zip fsf-binutils-gdb-9370fd51ebfca8a8acacaecb92c57ee54f4f8382.tar.gz fsf-binutils-gdb-9370fd51ebfca8a8acacaecb92c57ee54f4f8382.tar.bz2 |
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.
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/gdb/frame.c b/gdb/frame.c index 5ae8611..b4af734 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. */ |