Bug 844959
| Summary: | common block thread private variables out of scope inside OpenMP parallel region | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Marek Polacek <mpolacek> | |
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> | |
| Status: | CLOSED ERRATA | QA Contact: | Miroslav Franc <mfranc> | |
| Severity: | medium | Docs Contact: | ||
| Priority: | medium | |||
| Version: | 7.0 | CC: | cww, jan.kratochvil, law, mfranc, mnewsome, mpetlan, ohudlick, patrickm, pmuller, roland, rth, sergiodj, tao, woodard | |
| Target Milestone: | rc | Keywords: | Patch | |
| Target Release: | --- | |||
| Hardware: | All | |||
| OS: | Linux | |||
| Whiteboard: | ||||
| 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 07:04:21 UTC | Type: | --- | |
| Regression: | --- | Mount Type: | --- | |
| Documentation: | --- | CRM: | ||
| Verified Versions: | Category: | --- | ||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
| Cloudforms Team: | --- | Target Upstream Version: | ||
| Embargoed: | ||||
| Bug Depends On: | 533183 | |||
| Bug Blocks: | 1025729, 1113520, 1158876, 1258713 | |||
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.
(Or it is a GDB bug.) 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
(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 (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. Not sure if you test it with FSF or Fedora/RHEL GDBs, the latter have replaced support for Fortran common blocks. (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) (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. 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 |
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.