4c2ad1
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
4c2ad1
From: Fedora GDB patches <invalid@email.com>
4c2ad1
Date: Fri, 27 Oct 2017 21:07:50 +0200
4c2ad1
Subject: gdb-bz533176-fortran-omp-step.patch
4c2ad1
4c2ad1
;; Fix stepping with OMP parallel Fortran sections (BZ 533176).
4c2ad1
;;=push+jan: It requires some better DWARF annotations.
4c2ad1
4c2ad1
https://bugzilla.redhat.com/show_bug.cgi?id=533176#c4
4c2ad1
4c2ad1
I find it a bug in DWARF and gdb behaves correctly according to it.  From the
4c2ad1
current DWARF's point of view the is a function call which you skip by "next".
4c2ad1
4c2ad1
If you hide any /usr/lib/debug such as using:
4c2ad1
gdb -nx -ex 'set debug-file-directory /qwe' -ex 'file ./tpcommon_gfortran44'
4c2ad1
and use "step" command instead of "next" there it will work.
4c2ad1
(You need to hide debuginfo from libgomp as you would step into libgomp sources
4c2ad1
to maintain the threads for execution.)
4c2ad1
4c2ad1
There should be some DWARF extension for it, currently tried to detect
4c2ad1
substring ".omp_fn." as this function is called "MAIN__.omp_fn.0" and do not
4c2ad1
consider such sub-function as a skippable by "next".
4c2ad1
4c2ad1
Another problem is that with "set scheduler-locking" being "off" (default
4c2ad1
upstream) or "step" (default in F/RHEL) the simultaneous execution of the
4c2ad1
threads is inconvenient.  Setting it to "on" will lockup the debugging as the
4c2ad1
threads need to get synchronized at some point.  This is a more general
4c2ad1
debugging problem of GOMP outside of the scope of this Bug.
4c2ad1
4c2ad1
diff --git a/gdb/infrun.c b/gdb/infrun.c
4c2ad1
--- a/gdb/infrun.c
4c2ad1
+++ b/gdb/infrun.c
4c2ad1
@@ -6695,6 +6695,16 @@ process_event_stop_test (struct execution_control_state *ecs)
4c2ad1
 
4c2ad1
       if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
4c2ad1
 	{
4c2ad1
+	  struct symbol *stop_fn = find_pc_function (stop_pc);
4c2ad1
+	  struct minimal_symbol *stopf = lookup_minimal_symbol_by_pc (stop_pc).minsym;
4c2ad1
+
4c2ad1
+	  if ((stop_fn == NULL
4c2ad1
+	       || strstr (SYMBOL_LINKAGE_NAME (stop_fn), ".omp_fn.") == NULL)
4c2ad1
+	      /* gcc-4.7.2-9.fc19.x86_64 uses a new format.  */
4c2ad1
+	      && (stopf == NULL
4c2ad1
+		  || strstr (MSYMBOL_LINKAGE_NAME (stopf), "._omp_fn.") == NULL))
4c2ad1
+{	/* ".omp_fn." */
4c2ad1
+
4c2ad1
 	  /* We're doing a "next".
4c2ad1
 
4c2ad1
 	     Normal (forward) execution: set a breakpoint at the
4c2ad1
@@ -6728,6 +6738,7 @@ process_event_stop_test (struct execution_control_state *ecs)
4c2ad1
 
4c2ad1
 	  keep_going (ecs);
4c2ad1
 	  return;
4c2ad1
+}	/* ".omp_fn." */
4c2ad1
 	}
4c2ad1
 
4c2ad1
       /* If we are in a function call trampoline (a stub between the
4c2ad1
diff --git a/gdb/testsuite/gdb.fortran/omp-step.exp b/gdb/testsuite/gdb.fortran/omp-step.exp
4c2ad1
new file mode 100644
4c2ad1
--- /dev/null
4c2ad1
+++ b/gdb/testsuite/gdb.fortran/omp-step.exp
4c2ad1
@@ -0,0 +1,31 @@
4c2ad1
+# Copyright 2009 Free Software Foundation, Inc.
4c2ad1
+
4c2ad1
+# This program is free software; you can redistribute it and/or modify
4c2ad1
+# it under the terms of the GNU General Public License as published by
4c2ad1
+# the Free Software Foundation; either version 3 of the License, or
4c2ad1
+# (at your option) any later version.
4c2ad1
+#
4c2ad1
+# This program is distributed in the hope that it will be useful,
4c2ad1
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4c2ad1
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4c2ad1
+# GNU General Public License for more details.
4c2ad1
+#
4c2ad1
+# You should have received a copy of the GNU General Public License
4c2ad1
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
4c2ad1
+
4c2ad1
+set testfile "omp-step"
4c2ad1
+set srcfile ${testfile}.f90
4c2ad1
+if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f90 additional_flags=-fopenmp}] } {
4c2ad1
+    return -1
4c2ad1
+}
4c2ad1
+
4c2ad1
+if ![runto [gdb_get_line_number "start-here"]] {
4c2ad1
+    perror "Couldn't run to start-here"
4c2ad1
+    return 0
4c2ad1
+}
4c2ad1
+
4c2ad1
+gdb_test "next" {!\$omp parallel} "step closer"
4c2ad1
+gdb_test "next" {a\(omp_get_thread_num\(\) \+ 1\) = 1} "step into omp"
4c2ad1
+
4c2ad1
+gdb_breakpoint [gdb_get_line_number "success"]
4c2ad1
+gdb_continue_to_breakpoint "success" ".*success.*"
4c2ad1
diff --git a/gdb/testsuite/gdb.fortran/omp-step.f90 b/gdb/testsuite/gdb.fortran/omp-step.f90
4c2ad1
new file mode 100644
4c2ad1
--- /dev/null
4c2ad1
+++ b/gdb/testsuite/gdb.fortran/omp-step.f90
4c2ad1
@@ -0,0 +1,32 @@
4c2ad1
+! Copyright 2009 Free Software Foundation, Inc.
4c2ad1
+
4c2ad1
+! This program is free software; you can redistribute it and/or modify
4c2ad1
+! it under the terms of the GNU General Public License as published by
4c2ad1
+! the Free Software Foundation; either version 3 of the License, or
4c2ad1
+! (at your option) any later version.
4c2ad1
+!
4c2ad1
+! This program is distributed in the hope that it will be useful,
4c2ad1
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
4c2ad1
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4c2ad1
+! GNU General Public License for more details.
4c2ad1
+!
4c2ad1
+! You should have received a copy of the GNU General Public License
4c2ad1
+! along with this program.  If not, see <http://www.gnu.org/licenses/>.
4c2ad1
+
4c2ad1
+      use omp_lib
4c2ad1
+      integer nthreads, i, a(1000)
4c2ad1
+      nthreads = omp_get_num_threads()
4c2ad1
+      if (nthreads .gt. 1000) call abort
4c2ad1
+
4c2ad1
+      do i = 1, nthreads
4c2ad1
+          a(i) = 0
4c2ad1
+      end do
4c2ad1
+      print *, "start-here"
4c2ad1
+!$omp parallel
4c2ad1
+      a(omp_get_thread_num() + 1) = 1
4c2ad1
+!$omp end parallel
4c2ad1
+      do i = 1, nthreads
4c2ad1
+          if (a(i) .ne. 1) call abort
4c2ad1
+      end do
4c2ad1
+      print *, "success"
4c2ad1
+      end