public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Fixes and improvements for the starting function
@ 2023-03-28 16:06 Maciej W. Rozycki
  2023-03-28 16:06 ` [PATCH 1/3] GDB: Favor full symbol main name for backtrace stop Maciej W. Rozycki
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Maciej W. Rozycki @ 2023-03-28 16:06 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt

Hi,

 Here is a small patch series to fix and improve the handling of the 
starting (aka main) function of the program, specifically for Fortran.

 They have been regression-tested with the `x86_64-linux-gnu' native 
configuration and GCC versions 11.3.0 and 4.4.7.  See individual change 
descriptions for details.

 OK to apply?

  Maciej

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] GDB: Favor full symbol main name for backtrace stop
  2023-03-28 16:06 [PATCH 0/3] Fixes and improvements for the starting function Maciej W. Rozycki
@ 2023-03-28 16:06 ` Maciej W. Rozycki
  2023-03-28 16:06 ` [PATCH 2/3] GDB: Bring back the handling of DW_CC_program Maciej W. Rozycki
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Maciej W. Rozycki @ 2023-03-28 16:06 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt

From: Richard Bunt <richard.bunt@linaro.org>

In the case where a Fortran program has a program name of "main" and 
there is also a minimal symbol called main, such as with programs built 
with GCC version 4.4.7 or below, the backtrace will erroneously stop at 
the minimal symbol rather than the user specified main, e.g.:

(gdb) bt
#0  bar () at .../gdb/testsuite/gdb.fortran/backtrace.f90:17
#1  0x0000000000402556 in foo () at .../gdb/testsuite/gdb.fortran/backtrace.f90:21
#2  0x0000000000402575 in main () at .../gdb/testsuite/gdb.fortran/backtrace.f90:31
#3  0x00000000004025aa in main ()
(gdb) FAIL: gdb.fortran/backtrace.exp: bt

This patch fixes this issue by increasing the precedence of the full 
symbol when the language of the current frame is Fortran.

Newer versions of GCC transform the program name to "MAIN__" in this 
case, avoiding the problem.

Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
---
 gdb/frame.c                             |   25 ++++++++++++---------
 gdb/testsuite/gdb.fortran/backtrace.exp |   38 ++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/backtrace.f90 |   32 ++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 10 deletions(-)

gdb-richard-favour-full-symbol-main-name-for-backtrace-stop.diff
Index: src/gdb/frame.c
===================================================================
--- src.orig/gdb/frame.c
+++ src/gdb/frame.c
@@ -2542,29 +2542,34 @@ inside_main_func (frame_info_ptr this_fr
   bound_minimal_symbol msymbol
     = lookup_minimal_symbol (name, NULL,
 			     current_program_space->symfile_object_file);
-  if (msymbol.minsym == nullptr)
+
+  if (msymbol.minsym != nullptr)
+    sym_addr = msymbol.value_address ();
+
+  /* Favor a full symbol in Fortran, for the case where the Fortran main
+     is also called "main".  */
+  if (msymbol.minsym == nullptr
+      || get_frame_language (this_frame) == language_fortran)
     {
       /* 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;
 
       /* We might have found some unrelated symbol.  For example, the
 	 Rust compiler can emit both a subprogram and a namespace with
 	 the same name in the same scope; and due to how gdb's symbol
 	 tables currently work, we can't request the one we'd
 	 prefer.  */
-      if (bs.symbol->aclass () != LOC_BLOCK)
+      if (bs.symbol != nullptr && bs.symbol->aclass () == LOC_BLOCK)
+	{
+	  const struct block *block = bs.symbol->value_block ();
+	  gdb_assert (block != nullptr);
+	  sym_addr = block->start ();
+	}
+      else if (msymbol.minsym == nullptr)
 	return false;
-
-      const struct block *block = bs.symbol->value_block ();
-      gdb_assert (block != nullptr);
-      sym_addr = block->start ();
     }
-  else
-    sym_addr = msymbol.value_address ();
 
   /* Convert any function descriptor addresses into the actual function
      code address.  */
Index: src/gdb/testsuite/gdb.fortran/backtrace.exp
===================================================================
--- /dev/null
+++ src/gdb/testsuite/gdb.fortran/backtrace.exp
@@ -0,0 +1,38 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require allow_fortran_tests
+
+load_lib fortran.exp
+
+standard_testfile .f90
+
+if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}]} {
+    return -1
+}
+
+if {![fortran_runto_main]} {
+    perror "Could not run to main."
+    return
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here"]
+gdb_continue_to_breakpoint "continue to bar"
+
+gdb_test "bt" \
+    [multi_line \
+	 "#0\[ \t\]*bar \\(\\) at \[^\r\n\]+" \
+	 "#1\[ \t\]*$hex in foo \\(\\) at \[^\r\n\]+" \
+	 "#2\[ \t\]*$hex in \(?:MAIN__\|main\) \\(\\) at \[^\r\n\]+" ]
Index: src/gdb/testsuite/gdb.fortran/backtrace.f90
===================================================================
--- /dev/null
+++ src/gdb/testsuite/gdb.fortran/backtrace.f90
@@ -0,0 +1,32 @@
+! Copyright 2023 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+subroutine bar ()
+  return                ! Break here
+end subroutine bar
+
+subroutine foo ()
+  call bar ()
+end subroutine foo
+
+program main
+  interface
+    subroutine bar ()
+    end subroutine bar
+    subroutine foo ()
+    end subroutine foo
+  end interface
+  call foo ()
+end program main

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/3] GDB: Bring back the handling of DW_CC_program
  2023-03-28 16:06 [PATCH 0/3] Fixes and improvements for the starting function Maciej W. Rozycki
  2023-03-28 16:06 ` [PATCH 1/3] GDB: Favor full symbol main name for backtrace stop Maciej W. Rozycki
@ 2023-03-28 16:06 ` Maciej W. Rozycki
  2023-03-28 16:07 ` [PATCH 3/3] GDB: Add `info main' command Maciej W. Rozycki
  2023-03-28 17:04 ` [PATCH 0/3] Fixes and improvements for the starting function Eli Zaretskii
  3 siblings, 0 replies; 6+ messages in thread
From: Maciej W. Rozycki @ 2023-03-28 16:06 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt

Fix a functional regression and restore the handling of DW_CC_program 
code of DW_AT_calling_convention attribute for determining the name of 
the starting function of the program where the DW_AT_main_subprogram 
attribute has not been provided, such as with Fortran code compiled with 
GCC versions 4.5.4 and below, or where DWARF version 3 or below has been 
requested.  Without it "main" is considered the starting function.  Cf. 
GCC PR fortran/43414.

Original code was removed with commit 6209cde4ddb8 ("Delete DWARF 
psymtab code"), and then an update to complement commit 81873cc81eff 
("[gdb/symtab] Support DW_AT_main_subprogram with -readnow.") has also 
been included here.
---
NB this was discovered with and is covered by the test case included with 
3/3; it has been verified to trigger with GCC 4.4.7 and will likely also 
with other configurations.
---
 gdb/dwarf2/read.c |   19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

gdb-main-name-dw-cc-program.diff
Index: src/gdb/dwarf2/read.c
===================================================================
--- src.orig/gdb/dwarf2/read.c
+++ src/gdb/dwarf2/read.c
@@ -9994,6 +9994,18 @@ inherit_abstract_dies (struct die_info *
     compute_delayed_physnames (origin_cu);
 }
 
+/* Return TRUE if the given DIE is the program's "main".  */
+
+static bool
+dwarf2_func_is_main_p (struct die_info *die, struct dwarf2_cu *cu)
+{
+  if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
+    return true;
+  struct attribute *attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
+  return (attr != nullptr
+	  && attr->constant_value (DW_CC_normal) == DW_CC_program);
+}
+
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -10084,7 +10096,7 @@ read_func_scope (struct die_info *die, s
   newobj = cu->get_builder ()->push_context (0, lowpc);
   newobj->name = new_symbol (die, read_type_die (die, cu), cu, templ_func);
 
-  if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
+  if (dwarf2_func_is_main_p (die, cu))
     set_objfile_main_name (objfile, newobj->name->linkage_name (),
 			   cu->lang ());
 
@@ -16141,6 +16153,11 @@ cooked_indexer::scan_attributes (dwarf2_
 	    *flags |= IS_MAIN;
 	  break;
 
+	case DW_AT_calling_convention:
+	  if (attr.constant_value (DW_CC_normal) == DW_CC_program)
+	    *flags |= IS_MAIN;
+	  break;
+
 	case DW_AT_declaration:
 	  is_declaration = attr.as_boolean ();
 	  break;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/3] GDB: Add `info main' command
  2023-03-28 16:06 [PATCH 0/3] Fixes and improvements for the starting function Maciej W. Rozycki
  2023-03-28 16:06 ` [PATCH 1/3] GDB: Favor full symbol main name for backtrace stop Maciej W. Rozycki
  2023-03-28 16:06 ` [PATCH 2/3] GDB: Bring back the handling of DW_CC_program Maciej W. Rozycki
@ 2023-03-28 16:07 ` Maciej W. Rozycki
  2023-03-28 17:04 ` [PATCH 0/3] Fixes and improvements for the starting function Eli Zaretskii
  3 siblings, 0 replies; 6+ messages in thread
From: Maciej W. Rozycki @ 2023-03-28 16:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Richard Bunt

From: Richard Bunt <richard.bunt@linaro.org>

Allow consumers of GDB to extract the name of the main method.  This is
most useful for Fortran programs which have a variable main method.

Used by both MAP and DDT e.g. it is used to detect the presence of debug 
information.

Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
---
 gdb/symtab.c                            |   11 ++++++++
 gdb/testsuite/gdb.fortran/info-main.exp |   42 ++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/info-main.f90 |   19 ++++++++++++++
 3 files changed, 72 insertions(+)

gdb-richard-info-main-command.diff
Index: src/gdb/symtab.c
===================================================================
--- src.orig/gdb/symtab.c
+++ src/gdb/symtab.c
@@ -5282,6 +5282,14 @@ info_modules_command (const char *args,
 		      from_tty);
 }
 
+/* Implement the 'info main' command.  */
+
+static void
+info_main_command (const char *args, int from_tty)
+{
+  gdb_printf ("%s\n", main_name ());
+}
+
 static void
 rbreak_command (const char *regexp, int from_tty)
 {
@@ -6873,6 +6881,9 @@ Options:\n\
 		_("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
+  add_info ("main", info_main_command,
+	    _("Get main symbol to identify entry point into program."));
+
   add_basic_prefix_cmd ("module", class_info, _("\
 Print information about modules."),
 			&info_module_cmdlist, 0, &infolist);
Index: src/gdb/testsuite/gdb.fortran/info-main.exp
===================================================================
--- /dev/null
+++ src/gdb/testsuite/gdb.fortran/info-main.exp
@@ -0,0 +1,42 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require allow_fortran_tests
+
+load_lib fortran.exp
+
+standard_testfile .f90
+
+set old_gdbflags $GDBFLAGS
+set GDBFLAGS [string map {"-readnow" ""} "$GDBFLAGS"]
+
+if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}]} {
+    return -1
+}
+
+gdb_test "info main" "simple" "info main prior to start"
+
+if ![fortran_runto_main] {
+    untested "could not run to main"
+    return -1
+}
+
+gdb_test "info main" "simple" "info main post start"
+
+set GDBFLAGS "$GDBFLAGS -readnow"
+clean_restart $testfile
+gdb_test "info main" "simple" "info main with readnow"
+
+set GDBFLAGS $old_gdbflags
Index: src/gdb/testsuite/gdb.fortran/info-main.f90
===================================================================
--- /dev/null
+++ src/gdb/testsuite/gdb.fortran/info-main.f90
@@ -0,0 +1,19 @@
+! Copyright 2023 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 3 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+program simple
+    implicit none
+    print *, "Nothing."
+end program simple

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] Fixes and improvements for the starting function
  2023-03-28 16:06 [PATCH 0/3] Fixes and improvements for the starting function Maciej W. Rozycki
                   ` (2 preceding siblings ...)
  2023-03-28 16:07 ` [PATCH 3/3] GDB: Add `info main' command Maciej W. Rozycki
@ 2023-03-28 17:04 ` Eli Zaretskii
  2023-03-28 17:27   ` Maciej W. Rozycki
  3 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2023-03-28 17:04 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gdb-patches, richard.bunt

> Date: Tue, 28 Mar 2023 17:06:01 +0100 (BST)
> From: "Maciej W. Rozycki" <macro@embecosm.com>
> cc: Richard Bunt <richard.bunt@linaro.org>
> 
> Hi,
> 
>  Here is a small patch series to fix and improve the handling of the 
> starting (aka main) function of the program, specifically for Fortran.
> 
>  They have been regression-tested with the `x86_64-linux-gnu' native 
> configuration and GCC versions 11.3.0 and 4.4.7.  See individual change 
> descriptions for details.
> 
>  OK to apply?

Shouldn't the new command be documented and called out in NEWS?

Thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] Fixes and improvements for the starting function
  2023-03-28 17:04 ` [PATCH 0/3] Fixes and improvements for the starting function Eli Zaretskii
@ 2023-03-28 17:27   ` Maciej W. Rozycki
  0 siblings, 0 replies; 6+ messages in thread
From: Maciej W. Rozycki @ 2023-03-28 17:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, richard.bunt

On Tue, 28 Mar 2023, Eli Zaretskii wrote:

> >  Here is a small patch series to fix and improve the handling of the 
> > starting (aka main) function of the program, specifically for Fortran.
> 
> Shouldn't the new command be documented and called out in NEWS?

 Good point, thanks, I forgot about it.  I'll send v2.

  Maciej

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-03-28 17:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28 16:06 [PATCH 0/3] Fixes and improvements for the starting function Maciej W. Rozycki
2023-03-28 16:06 ` [PATCH 1/3] GDB: Favor full symbol main name for backtrace stop Maciej W. Rozycki
2023-03-28 16:06 ` [PATCH 2/3] GDB: Bring back the handling of DW_CC_program Maciej W. Rozycki
2023-03-28 16:07 ` [PATCH 3/3] GDB: Add `info main' command Maciej W. Rozycki
2023-03-28 17:04 ` [PATCH 0/3] Fixes and improvements for the starting function Eli Zaretskii
2023-03-28 17:27   ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).