Blame SOURCES/gdb-bz533176-fortran-omp-step.patch

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