Bug 844959 - common block thread private variables out of scope inside OpenMP parallel region
common block thread private variables out of scope inside OpenMP parallel re...
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: gcc (Show other bugs)
7.0
All Linux
medium Severity medium
: rc
: ---
Assigned To: Jakub Jelinek
Miroslav Franc
: Patch
Depends On: 533183
Blocks: 1113520 1158876 1258713 1025729
  Show dependency treegraph
 
Reported: 2012-08-01 07:11 EDT by Marek Polacek
Modified: 2016-01-31 21:27 EST (History)
14 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Previously, the OpenMP artificial functions generated by the compiler did not have the DW_AT_name attribute. Because of this, it was not possible to print variables residing in an OpenMP region in the GNU debugger. This has been fixed in such a way that DW_AT_name is properly set and now it is possible to print variables even in OpenMP regions.
Story Points: ---
Clone Of: 533183
: 1025729 1158876 (view as bug list)
Environment:
Last Closed: 2015-03-05 02:04:21 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Comment 2 Jakub Jelinek 2012-08-17 09:36:04 EDT
Has the testcase ever worked right with any gcc/gdb combination?  From what I can see, the IMHO right debug info is provided by all of 4.4-RH, 4.7-RH and 4.8, namely that istart is in the outer function (correct) when inside of the OpenMP region, and that transforms the problem from the Fortran common issue to something like:
int
main ()
{
  static int i;
  int j = 1;
  int k;
  #pragma omp parallel num_threads(2)
  {
    k = 2;
    __builtin_printf ("%d\n", k);
  }
  return 0;
}
where one would also expect to be able to print i and j while in the OpenMP region.  I guess we should eventually change the OpenMP generated code to call the body function directly even in the initial thread, then we can do magic with the backtrace.
Comment 3 Marek Polacek 2012-08-17 13:16:38 EDT
Hmm.  It "works" e.g. on RHEL5 with 
libgomp-4.4.6-3.el5.1
gdb-7.0.1-42.el5
gcc-4.1.2-52.el5
gcc-gfortran-4.1.2-52.el5
also with 
gcc44-4.4.6-3.el5.1
gcc44-gfortran-4.4.6-3.el5.1

and also on RHEL6 (libgomp is essentially the same).

What the test does is basically

# cat tpcommon-init.f
      program correct
      use omp_lib
      integer iarray(100), N, nthreads, iam, chunk, istart, iend
      common /bounds/ istart, iend
!$omp threadprivate(/bounds/)

      N = 100
      istart = 1
!$omp parallel private(nthreads, iam, chunk)

      ! Compute the subset of iterations executed by each thread
      nthreads = omp_get_num_threads()
      iam = omp_get_thread_num()
      chunk = (N + nthreads - 1)/nthreads
      istart = iam * chunk + 1
      iend = min((iam + 1) * chunk, N)
      print *, nthreads, iam, chunk, istart, iend

      call work(iarray)
!$omp end parallel
      print *
      print *, iarray
      PRINT *, "Hello, World."
      end

      subroutine work(iarray)

      ! Subroutine to operate on a thread's portion of the array "iarray"
      integer iarray(100), istart, iend, i
      common /bounds/ istart, iend
!$omp threadprivate(/bounds/)

      do i = istart, iend
          iarray(i) = i * i
      enddo
      return
      end

# gfortran -fopenmp -g -O0 -o tpcommon-init tpcommon-init.f
then in
# gdb ./tpcommon-init
b 30
b 26
r
n
c
p istart

and checks whether at this point we don't get
"No symbol "istart" in current context."

It's possible that the test is flawed, I think it'd be better to use the C testcase in the first place, but I didn't write this one.  It just began to fail on RHEL7.
Comment 4 Marek Polacek 2012-08-17 13:17:23 EDT
(Or it is a GDB bug.)
Comment 5 Marek Polacek 2012-08-17 13:23:44 EDT
Argh, actually with abovementioned it works even on F16, but with this testcase it shows "No symbol "istart" in current context.":

! "Parallel Programming in OpenMP" ISBN 1-55860-671-8
! Copyright 2001 by Academic Press
! Example 4.7 (pp 104-105) with slight modifications

! AIX:
!   xlf90    -qsmp=noopt -g -O0 -o tpcommon_64_xlf90_9.1.0.3-qsmp=noopt-g-O0 \
!     tpcommon.f
!
! Linux x86:
!   pgf95    -mp         -g -O0 -o tpcommon_pgf95_6.2-3-mp-g-O0              \
!     tpcommon.f
!   gfortran -fopenmp    -g -O0 -o tpcommon_gfortran tpcommon.f
!   ifort    -openmp     -g -O0 -o tpcommon_ifort_10.0.013-openmp-g-O0       \
!     tpcommon.f
!   pathf90  -mp         -g -O0 -o tpcommon_pathf90_2.5-mp-g-O0              \
!     tpcommon.f
!   setenv PSC_OMP_STACK_SIZE 100000

      program correct
      use omp_lib
      integer iarray(100), N, nthreads, iam, chunk, istart, iend
      common /bounds/ istart, iend
!$omp threadprivate(/bounds/)

      N = 100
      istart = 1
!$omp parallel private(nthreads, iam, chunk)

      ! Compute the subset of iterations executed by each thread
      nthreads = omp_get_num_threads()
      iam = omp_get_thread_num()
      chunk = (N + nthreads - 1)/nthreads
      istart = iam * chunk + 1
      iend = min((iam + 1) * chunk, N)
      print *, nthreads, iam, chunk, istart, iend

      call work(iarray)
!$omp end parallel
      print *
      print *, iarray
      PRINT *, "Hello, World."
      end

      subroutine work(iarray)

      ! Subroutine to operate on a thread's portion of the array "iarray"
      integer iarray(100), istart, iend, i
      common /bounds/ istart, iend
!$omp threadprivate(/bounds/)

      do i = istart, iend
          iarray(i) = i * i
      enddo
      return
      end
Comment 6 Tom Tromey 2012-08-17 13:58:24 EDT
(In reply to comment #2)
> From what
> I can see, the IMHO right debug info is provided by all of 4.4-RH, 4.7-RH
> and 4.8, namely that istart is in the outer function (correct) when inside
> of the OpenMP region

With the C test case I see that the artificial function generated by
GCC doesn't have a DW_AT_name.
gdb claims that this attribute is required.  I think I agree, DWARF 4
section 3.3 seems pretty definite on this point.
So, gdb skips this function's DIEs.

If I hack around this in gdb, then it works ok:

Breakpoint 1, zardoz () at pr.c:9
9	    k = 2;
(gdb) info local
k = 0

Could GCC just emit a DW_AT_name here?  I'd somewhat prefer that
over a gdb hack.

I didn't try the fortran tests yet.

For the more general case I think we'd need a debuginfo extension.
It's tempting to try to use the nested function approach, with some
attribute saying "check other threads", or maybe a magic local that
points to the "main" thread... but then I think we'd also need a fix for
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53927
Comment 7 Tom Tromey 2012-08-17 14:37:35 EDT
(In reply to comment #6)

> I didn't try the fortran tests yet.

The 'istart' problem seems to be because gdb's support
for common blocks is questionable.
Comment 8 Jan Kratochvil 2012-08-17 14:48:33 EDT
Not sure if you test it with FSF or Fedora/RHEL GDBs, the latter have replaced support for Fortran common blocks.
Comment 9 Tom Tromey 2012-08-20 15:13:34 EDT
(In reply to comment #8)
> Not sure if you test it with FSF or Fedora/RHEL GDBs, the latter have
> replaced support for Fortran common blocks.

Even with the common blocks patches applied, we don't see them in
the artificial function:

(gdb) up
#1  0x0000000000400d69 in zardoz () at f.f90:37
(gdb) p istart
No symbol "istart" in current context.

The problem here is that GCC doesn't emit a DW_TAG_common_block
in the artificial function.  But, I think this is just another instance
of the problem where only variables used in the body of the artificial
function are available there, since we aren't using a static link or
anything similar.

The common block patches for gdb are also incomplete:

(gdb) down
#0  work (iarray=...) at f.f90:51
(gdb) p istart
$4 = 51
(gdb) info common
Contents of F77 COMMON block 'bounds':
istart = <address of value unknown>
iend = <address of value unknown>

I haven't debugged this yet but it does seem weird that read_common_block
uses decode_locdesc.  In this case the location is an expression:

    <176>   DW_AT_location    : 10 byte block: e 0 0 0 0 0 0 0 0 e0 	(DW_OP_const8u: 0 0; DW_OP_GNU_push_tls_address or DW_OP_HP_unknown)
Comment 10 Tom Tromey 2012-08-21 16:55:06 EDT
(In reply to comment #9)

> The common block patches for gdb are also incomplete:
> 
> (gdb) down
> #0  work (iarray=...) at f.f90:51
> (gdb) p istart
> $4 = 51
> (gdb) info common
> Contents of F77 COMMON block 'bounds':
> istart = <address of value unknown>
> iend = <address of value unknown>

I sent some patches for this upstream.
Comment 24 errata-xmlrpc 2015-03-05 02:04:21 EST
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-0320.html

Note You need to log in before you can comment on or make changes to this bug.