[llvm-bugs] [Bug 44891] New: Debugger can't access in-scope variables in OpenMP parallel regions

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Feb 12 21:50:52 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=44891

            Bug ID: 44891
           Summary: Debugger can't access in-scope variables in OpenMP
                    parallel regions
           Product: OpenMP
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Clang Compiler Support
          Assignee: unassignedclangbugs at nondot.org
          Reporter: kevinb at redhat.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 23125
  --> https://bugs.llvm.org/attachment.cgi?id=23125&action=edit
Test case for in-scope variable openmp bug

Overview:

A debugger (either lldb or gdb) is unable to access certain in-scope variables
from within an OpenMP parallel region.  I've attached the test case that I've
written for GDB's test suite.  I could shortened this program for bug reporting
purposes, but ultimately it's worth considering each parallel region in this
file because each of these regions will likely show additional problems with
debugging in-scope variables.

I've tried clang 8 thru 10.0.0; each of these versions are broken.

In the examples below, s1, s3, and i3 are all in scope and should be printable
by the debugger, but are not.

I wanted to use clang 10.0.0 which is found in recent Fedora Rawhide.  These
same problems are also present on Fedora 31 and earlier which use earlier
versions of clang.

Steps to reproduce:

[kev at rawhide-1 tmp]$ clang --version
clang version 10.0.0 (Fedora 10.0.0-0.1.rc1.fc32)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
[kev at rawhide-1 tmp]$ clang -g -fopenmp -o omp-par-scope omp-par-scope.c
[kev at rawhide-1 tmp]$ lldb omp-par-scope
(lldb) target create "omp-par-scope"
Current executable set to '/tmp/omp-par-scope' (x86_64).
(lldb) b 39
Breakpoint 1: where = omp-par-scope`.omp_outlined._debug__ + 164 at
omp-par-scope.c:39:5, address = 0x0000000000401354
(lldb) run
Process 599852 launched: '/tmp/omp-par-scope' (x86_64)
warning: (x86_64) /lib64/libarcher.so unsupported DW_FORM values: 0x1f20 0x1f21
Process 599852 stopped
* thread #2, name = 'omp-par-scope', stop reason = breakpoint 1.1
    frame #0: 0x0000000000401354
omp-par-scope`.omp_outlined._debug__(.global_tid.=0x00007ffff797cba0,
.bound_tid.=0x00007ffff797cb98, i1=0x00007fffffffd61c) at omp-par-scope.c:39:5
   36       i2 = s2 + 10;
   37   
   38       #pragma omp critical
-> 39       printf ("single_scope: thread_num=%d, s1=%d, i1=%d, s2=%d,
i2=%d\n",
   40               thread_num, s1, i1, s2, i2);
   41     }
   42   
(lldb) p s1
error: <user expression 0>:1:1: use of undeclared identifier 's1'
s1
^
(lldb) p s2
(int) $0 = 202
(lldb) p s3
error: <user expression 2>:1:1: use of undeclared identifier 's3'
s3
^
(lldb) p i1
(int) $1 = 11
(lldb) p i2
(int) $2 = 212
(lldb) p i3
error: <user expression 5>:1:1: use of undeclared identifier 'i3'
i3
^

GDB is able to print values for s1 and s3, but they are incorrect. (I haven't
investigated where they're coming from.)  Also note that gdb can't find a value
for i3.

[kev at rawhide-1 tmp]$ gdb -q omp-par-scope
Reading symbols from omp-par-scope...
(gdb) b 39
Breakpoint 1 at 0x401354: file omp-par-scope.c, line 39.
(gdb) run
Starting program: /tmp/omp-par-scope 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff797d780 (LWP 600272)]

Thread 1 "omp-par-scope" hit Breakpoint 1, .omp_outlined._debug__ (
    .global_tid.=0x7fffffffd190, .bound_tid.=0x7fffffffd188, 
    i1=@0x7fffffffd5ec: 11) at omp-par-scope.c:39
39          printf ("single_scope: thread_num=%d, s1=%d, i1=%d, s2=%d,
i2=%d\n",
(gdb) p s1
$1 = -3901428.39008634844799
(gdb) p s2
$2 = 102
(gdb) p s3
$3 = -3319055.88148504441733
(gdb) p i1
$4 = (int &) @0x7fffffffd5ec: 11
(gdb) p i2
$5 = 112
(gdb) p i3
No symbol "i3" in current context.
(gdb) 

Expected results:

Expected results can be found by compiling with gcc and then debugging with
gdb. (Though, at the moment, the value associated with i3 can only be found on
the master thread.  I am working on making it work for all threads.)

[kev at rawhide-1 tmp]$ gcc --version
gcc (GCC) 10.0.1 20200130 (Red Hat 10.0.1-0.7)
[...]
[kev at rawhide-1 tmp]$ gcc -g -fopenmp -o omp-par-scope omp-par-scope.c
[kev at rawhide-1 tmp]$ gdb -q omp-par-scope
Reading symbols from omp-par-scope...
(gdb) b 39
Breakpoint 1 at 0x40134e: file omp-par-scope.c, line 39.
(gdb) run
Starting program: /tmp/omp-par-scope 
Missing separate debuginfo for /lib64/libgomp.so.1
Try: dnf --enablerepo='*debug*' install
/usr/lib/debug/.build-id/ec/ae5692491ca61813e43a9988409c236a789a05.debug
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff7d6f700 (LWP 600426)]

Thread 1 "omp-par-scope" hit Breakpoint 1, single_scope._omp_fn.0 ()
    at omp-par-scope.c:39
39          printf ("single_scope: thread_num=%d, s1=%d, i1=%d, s2=%d,
i2=%d\n",
(gdb) p s1
$1 = -41
(gdb) p s2
$2 = 102
(gdb) p s3
$3 = -43
(gdb) p i1
$4 = 11
(gdb) p i2
$5 = 112
(gdb) p i3
$6 = 13
(gdb) q
A debugging session is active.

        Inferior 1 [process 600422] will be killed.

Quit anyway? (y or n) y

Additional information:

Looking at the DWARF produced by both gcc and clang is instructive.  gcc puts
the outlined function representing the parallel region in a nested subprogram.
clang puts the outlined function at the same level as the function containing
the parallel region; therefore variables within the containing function are not
visible.

Relevant GCC DWARF:

 <1><300>: Abbrev Number: 8 (DW_TAG_subprogram)
    <301>   DW_AT_external    : 1
    <301>   DW_AT_name        : (indirect string, offset: 0xc4): single_scope
    <305>   DW_AT_decl_file   : 1
    <306>   DW_AT_decl_line   : 26
    <307>   DW_AT_decl_column : 1
    <308>   DW_AT_prototyped  : 1
    <308>   DW_AT_low_pc      : 0x401196
    <310>   DW_AT_high_pc     : 0x7d
    <318>   DW_AT_frame_base  : 1 byte block: 9c        (DW_OP_call_frame_cfa)
    <31a>   DW_AT_GNU_all_tail_call_sites: 1
    <31a>   DW_AT_sibling     : <0x3f7>
 <2><31e>: Abbrev Number: 9 (DW_TAG_subprogram)
    <31f>   DW_AT_name        : (indirect string, offset: 0x48):
single_scope._omp_fn.0
    <323>   DW_AT_prototyped  : 1
    <323>   DW_AT_artificial  : 1
    <323>   DW_AT_low_pc      : 0x401314
    <32b>   DW_AT_high_pc     : 0x6a
    <333>   DW_AT_frame_base  : 1 byte block: 9c        (DW_OP_call_frame_cfa)
    <335>   DW_AT_GNU_all_tail_call_sites: 1
    <335>   DW_AT_sibling     : <0x38d>

[...]

 <2><38d>: Abbrev Number: 11 (DW_TAG_variable)
    <38e>   DW_AT_name        : s1
    <391>   DW_AT_decl_file   : 1
    <392>   DW_AT_decl_line   : 28
    <393>   DW_AT_decl_column : 14
    <394>   DW_AT_type        : <0x5e>
    <398>   DW_AT_location    : 9 byte block: 3 60 40 40 0 0 0 0 0     
(DW_OP_addr: 404060)
 <2><3a2>: Abbrev Number: 11 (DW_TAG_variable)
    <3a3>   DW_AT_name        : s2
    <3a6>   DW_AT_decl_file   : 1
    <3a7>   DW_AT_decl_line   : 28
    <3a8>   DW_AT_decl_column : 24
    <3a9>   DW_AT_type        : <0x5e>
    <3ad>   DW_AT_location    : 9 byte block: 3 68 40 40 0 0 0 0 0     
(DW_OP_addr: 404068)
 <2><3b7>: Abbrev Number: 11 (DW_TAG_variable)
    <3b8>   DW_AT_name        : s3
    <3bb>   DW_AT_decl_file   : 1
    <3bc>   DW_AT_decl_line   : 28
    <3bd>   DW_AT_decl_column : 34
    <3be>   DW_AT_type        : <0x5e>
    <3c2>   DW_AT_location    : 9 byte block: 3 64 40 40 0 0 0 0 0     
(DW_OP_addr: 404064)
 <2><3cc>: Abbrev Number: 11 (DW_TAG_variable)
    <3cd>   DW_AT_name        : i1
    <3d0>   DW_AT_decl_file   : 1
    <3d1>   DW_AT_decl_line   : 29
    <3d2>   DW_AT_decl_column : 7
    <3d3>   DW_AT_type        : <0x5e>
    <3d7>   DW_AT_location    : 2 byte block: 91 6c     (DW_OP_fbreg: -20)
 <2><3da>: Abbrev Number: 11 (DW_TAG_variable)
    <3db>   DW_AT_name        : i2
    <3de>   DW_AT_decl_file   : 1
    <3df>   DW_AT_decl_line   : 29
    <3e0>   DW_AT_decl_column : 16
    <3e1>   DW_AT_type        : <0x5e>
    <3e5>   DW_AT_location    : 2 byte block: 91 68     (DW_OP_fbreg: -24)
 <2><3e8>: Abbrev Number: 11 (DW_TAG_variable)
    <3e9>   DW_AT_name        : i3
    <3ec>   DW_AT_decl_file   : 1
    <3ed>   DW_AT_decl_line   : 29
    <3ee>   DW_AT_decl_column : 25
    <3ef>   DW_AT_type        : <0x5e>
    <3f3>   DW_AT_location    : 2 byte block: 91 64     (DW_OP_fbreg: -28)

CLANG DWARF:

 <1><2a>: Abbrev Number: 2 (DW_TAG_subprogram)
    <2b>   DW_AT_low_pc      : 0x4011c0
    <33>   DW_AT_high_pc     : 0xe1
    <37>   DW_AT_frame_base  : 1 byte block: 56         (DW_OP_reg6 (rbp))
    <39>   DW_AT_name        : (indirect string, offset: 0x50): single_scope
    <3d>   DW_AT_decl_file   : 1
    <3e>   DW_AT_decl_line   : 26
    <3f>   DW_AT_prototyped  : 1
    <3f>   DW_AT_external    : 1
 <2><3f>: Abbrev Number: 3 (DW_TAG_variable)
    <40>   DW_AT_name        : (indirect string, offset: 0x47): s1
    <44>   DW_AT_type        : <0xa9>
    <48>   DW_AT_decl_file   : 1
    <49>   DW_AT_decl_line   : 28
    <4a>   DW_AT_location    : 9 byte block: 3 70 40 40 0 0 0 0 0      
(DW_OP_addr: 404070)
 <2><54>: Abbrev Number: 3 (DW_TAG_variable)
    <55>   DW_AT_name        : (indirect string, offset: 0x4a): s2
    <59>   DW_AT_type        : <0xa9>
    <5d>   DW_AT_decl_file   : 1
    <5e>   DW_AT_decl_line   : 28
    <5f>   DW_AT_location    : 9 byte block: 3 74 40 40 0 0 0 0 0      
(DW_OP_addr: 404074)
 <2><69>: Abbrev Number: 3 (DW_TAG_variable)
    <6a>   DW_AT_name        : (indirect string, offset: 0x4d): s3
    <6e>   DW_AT_type        : <0xa9>
    <72>   DW_AT_decl_file   : 1
    <73>   DW_AT_decl_line   : 28
    <74>   DW_AT_location    : 9 byte block: 3 78 40 40 0 0 0 0 0      
(DW_OP_addr: 404078)
 <2><7e>: Abbrev Number: 4 (DW_TAG_variable)
    <7f>   DW_AT_location    : 2 byte block: 91 7c      (DW_OP_fbreg: -4)
    <82>   DW_AT_name        : (indirect string, offset: 0x124): i1
    <86>   DW_AT_decl_file   : 1
    <87>   DW_AT_decl_line   : 29
    <88>   DW_AT_type        : <0xa9>
 <2><8c>: Abbrev Number: 4 (DW_TAG_variable)
    <8d>   DW_AT_location    : 2 byte block: 91 78      (DW_OP_fbreg: -8)
    <90>   DW_AT_name        : (indirect string, offset: 0x127): i2
    <94>   DW_AT_decl_file   : 1
    <95>   DW_AT_decl_line   : 29
    <96>   DW_AT_type        : <0xa9>
 <2><9a>: Abbrev Number: 4 (DW_TAG_variable)
    <9b>   DW_AT_location    : 2 byte block: 91 74      (DW_OP_fbreg: -12)
    <9e>   DW_AT_name        : (indirect string, offset: 0x12a): i3
    <a2>   DW_AT_decl_file   : 1
    <a3>   DW_AT_decl_line   : 29
    <a4>   DW_AT_type        : <0xa9>
 <2><a8>: Abbrev Number: 0
 <1><a9>: Abbrev Number: 5 (DW_TAG_base_type)
    <aa>   DW_AT_name        : (indirect string, offset: 0x177): int
    <ae>   DW_AT_encoding    : 5        (signed)
    <af>   DW_AT_byte_size   : 4
 <1><b0>: Abbrev Number: 6 (DW_TAG_subprogram)
    <b1>   DW_AT_low_pc      : 0x4012b0
    <b9>   DW_AT_high_pc     : 0xd6
    <bd>   DW_AT_frame_base  : 1 byte block: 56         (DW_OP_reg6 (rbp))
    <bf>   DW_AT_name        : (indirect string, offset: 0x5d):
.omp_outlined._debug__
    <c3>   DW_AT_decl_file   : 1
    <c4>   DW_AT_decl_line   : 32
    <c5>   DW_AT_prototyped  : 1

The thing to observe here is that for clang, the subprogram for
.omp_outlined._debug__ is at level 1 as is the subprogram for single_scope
(which contains the parallel region.)

In the DWARF from GCC, single_scope is a nesting level 1.
single_scope._omp_fn.0 is nested within single_scope at level 2. Note too that
the variables s1, s2, s3, i1, i2, and i3 are also at nesting level 2.  (Some of
these also appear within single_scope._omp_fn.0, but I've removed those in the
interest of brevity.)

Anyway, at one time, GCC produced DWARF that's similar to what CLANG currently
produces. It was fairly easy to make GCC handle the single_scope case.  It was
trickier to make it produce correct DWARF output for the multi_scope function.

Some work will be needed on LLDB as well.  At the moment, LLDB is unable to
find all of the in-scope variables even when run against output from GCC.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200213/ee68b39d/attachment-0001.html>


More information about the llvm-bugs mailing list