Bug 459379 - gfortran DWARF declares a pointer type incorrectly
gfortran DWARF declares a pointer type incorrectly
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: gcc (Show other bugs)
5.2
All Linux
medium Severity medium
: rc
: ---
Assigned To: Jakub Jelinek
Petr Muller
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2008-08-18 02:20 EDT by Issue Tracker
Modified: 2016-09-19 22:04 EDT (History)
5 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-08-21 18:23:23 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
reproducer (831 bytes, text/plain)
2008-08-18 02:23 EDT, Jatin Nansi
no flags Details
reproducer code compiled with ifort 10.1.017 (597.24 KB, application/octet-stream)
2008-08-21 21:55 EDT, Ben Woodard
no flags Details

  None (edit)
Description Issue Tracker 2008-08-18 02:20:55 EDT
Escalated to Bugzilla from IssueTracker
Comment 1 Issue Tracker 2008-08-18 02:20:57 EDT
In gfortran DWARF, a pointer is incorrectly declared as an array (DW_TAG_array_type). The correct type would be pointer
(DW_TAG_pointer_type).

Red Hat Enterprise Linux Server release 5.2 (Tikanga)
2.6.18-92.el5
gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)


 > gfortran -g -O0 -o a_g.out tx_f90_contained_sub.f90

This fails both with gdb, and TotalView

Set breakpoint at line #30. Hit Go. Dive to 'b_sub'

rhel52-x8664:/home/seppo/Bugs/Bug_11351 > gdb ./a_g.out
GNU gdb Red Hat Linux (6.5-37.el5rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/libthread_db.so.1".

(gdb) break 30
Breakpoint 1 at 0x400b0e: file tx_f90_contained_sub.f90, line 30.
(gdb) run
Starting program: /nfs/netapp0/user/home/seppo/Bugs/Bug_11351/a_g.out

Breakpoint 1, sub_test_ (a_sub=(), c_sub=0x601278, c_size=@0x400e48)
     at tx_f90_contained_sub.f90:30
30        call contained_sub
Current language:  auto; currently fortran
(gdb) print b_sub
$1 = ()
(gdb)


 > readelf -w ./a_g.out

..
      DW_AT_location    : 2 byte block: 91 68    (DW_OP_fbreg: -24)
  <2><15e>: Abbrev Number: 12 (DW_TAG_variable)
      DW_AT_name        : b_sub
      DW_AT_decl_file   : 1
      DW_AT_decl_line   : 27
      DW_AT_type        : <266>
      DW_AT_location    : 3 byte block: 91 80 7e         (DW_OP_fbreg: -256)
  <2><16f>: Abbrev Number: 13 (DW_TAG_subprogram)
      DW_AT_sibling     : <1bd>
  ...
      DW_AT_type        : <250>
  <1><266>: Abbrev Number: 21 (DW_TAG_array_type)
      DW_AT_sibling     : <2aa>
      DW_AT_name        : array2_real4
      DW_AT_ordering    : 1      (column major)
      DW_AT_data_location: 2 byte block: 97 6 
(DW_OP_push_object_address; DW_OP_deref)
      DW_AT_associated  : 4 byte block: 97 6 30 2e 
(DW_OP_push_object_address; DW_OP_deref; DW
_OP_lit0; DW_OP_ne)
      DW_AT_type        : <e2>
  <2><285>: Abbrev Number: 22 (DW_TAG_subrange_type)
      DW_AT_lower_bound : 4 byte block: 97 23 20 6 
(DW_OP_push_object_address; DW_OP_plus_ucon
s
..

=> pointer b_sub is incorrectly declared as an array
(DW_TAG_array_type), instead, it should be of type pointer
(DW_TAG_pointer_type).

This bug was first reported to Etnus as a bug in TotalView. In researching it, it was discovered that this was a problem with gfortran and bounced back to LLNL.
This event sent from IssueTracker by jnansi  [Support Engineering Group]
 issue 199077
Comment 2 Issue Tracker 2008-08-18 02:20:58 EDT
Date problem reported: 8/12/08

Problem: gfortran DWARF declares a pointer type incorrectly.

Originally this issue was sent to Etnus as a possible issue with their
Totalview debugger, but, Etnus punted back to us saying it was a gfortran
problem.  The problem can be reproduce in gdb as well as TotalView.

Steps to reproduce:

1) Compile the attached .f90 program using "gfortran -g -O0 -o test.out
wrong-dwarf-type.f90"

2) run gdb using the steps below, then have a look at the readelf info.

[root@dhcp243-202 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.2 (Tikanga)
[root@dhcp243-202 ~]# gfortran -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada
--enable-java-awt=gtk --disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)
[root@dhcp243-202 ~]# gfortran -g -O0 -o test.out wrong-dwarf-type.f90
[root@dhcp243-202 ~]# gdb -q ./test.out
Using host libthread_db library "/lib64/libthread_db.so.1".
(gdb) break 30
Breakpoint 1 at 0x400b0e: file wrong-dwarf-type.f90, line 30.
(gdb) run
Starting program: /root/test.out

Breakpoint 1, sub_test_ (a_sub=(), c_sub=0x601278, c_size=@0x400e48) at
wrong-dwarf-type.f90:30
30         call contained_sub
Current language:  auto; currently fortran
(gdb) print b_sub
$1 = ()
(gdb)

[root@dhcp243-202]# readelf -w ./test.out
...
 <2><145>: Abbrev Number: 12 (DW_TAG_variable)
     DW_AT_name        : b_sub
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 27
     DW_AT_type        : <24d>
     DW_AT_location    : 3 byte block: 91 80 7e         (DW_OP_fbreg:
-256)
 <2><156>: Abbrev Number: 13 (DW_TAG_subprogram)
     DW_AT_sibling     : <1a4>
...
<1><24d>: Abbrev Number: 21 (DW_TAG_array_type)
     DW_AT_sibling     : <291>
     DW_AT_name        : array2_real4
     DW_AT_ordering    : 1      (column major)
     DW_AT_data_location: 2 byte block: 97 6   
(DW_OP_push_object_address; DW_OP_deref)
     DW_AT_associated  : 4 byte block: 97 6 30 2e      
(DW_OP_push_object_address; DW_OP_deref; DW_OP_lit0; DW_OP_ne)
     DW_AT_type        : <c9>
 <2><26c>: Abbrev Number: 22 (DW_TAG_subrange_type)
     DW_AT_lower_bound : 4 byte block: 97 23 20 6      
(DW_OP_push_object_address; DW_OP_plus_uconst: 32
....

According to Etnus, pointer b_sub is incorrectly declared as an array
(DW_TAG_array_type), instead, it should be of type pointer
(DW_TAG_pointer_type).

What is needed from SEG / Engineering:  This is one of several gfortran
issues that Etnus has identified with our products.  Can we please get
some gfortran guru eyes on these so we can get them fixed?

Thanks.






This event sent from IssueTracker by jnansi  [Support Engineering Group]
 issue 199077
Comment 3 Jatin Nansi 2008-08-18 02:23:31 EDT
Created attachment 314463 [details]
reproducer
Comment 4 Jakub Jelinek 2008-08-21 18:23:23 EDT
Representing of b_sub as DW_TAG_array_type with DW_AT_associated attribute is
correct, see Dwarf3 standard, D.2.1.
Comment 5 Ben Woodard 2008-08-21 21:53:13 EDT
Jakub, can you explain that in a bit more detail so that I can explain it to the customer correctly. I've read through section D.2.1 of the DWARF3 spec and I have the FORTRAN 95 handbook right here next to me but I'm far from being able to say that I know FORTRAN or DWARF3.

To me it seems as though 'a' is a 2D array with a two elements in each direction. This is passed as a parameter to sub_test.

The array is called "a_sub" within the scope of sub_test and the parameter is given the "target" attribute so that it can be referenced with a pointer. 

b_sub appears to me to be declared to be a pointer to a 2D array. Then b_sub is assigned the pointer a_sub. A simplified version in C parlance it looks to me like:

void sub_test(float **a);

float a[2][2];

int main(){
  a[0][0]=1.0,
  a[0][1]=2.0,
  a[1][0]=3.0,
  a[1][1]=4.0;

  sub_test(a);
}

void sub_test(float **a_sub){
   float **b_sub;
   b_sub=a_sub;
}

So I don't really see exactly where in D.2.1 it says that b_sub can be an array, as opposed to being a pointer to an array.

Futhermore, at the very least we have an incompatibility between gfortran and gdb.

[ben@quince tmp]$ gdb a.out 
GNU gdb Red Hat Linux (6.5-37.el5_2.2rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/libthread_db.so.1".

(gdb) b 30
Breakpoint 1 at 0x400b0e: file wrong-dwarf-type.f90, line 30.
(gdb) r
Starting program: /tmp/a.out 

Breakpoint 1, sub_test_ (a_sub=(), c_sub=0x601278, c_size=@0x400e48)
    at wrong-dwarf-type.f90:30
30         call contained_sub
Current language:  auto; currently fortran
(gdb) p b_sub
$1 = ()
(gdb) ptype b_sub
type = real*4 (0:-1,0:-1)
(gdb) whatis b_sub
type = real*4 (0:-1,0:-1)
(gdb) p b_sub(1,1)
$1 = 1.5352626e-41
(gdb) 

the value printed for b_sub(1,1) is quite obviously wrong because it was previously assigned the value of 1.

On the other hand when you look at the same source code compiled with ifort 10.1.017 gdb seems to interpret the data better:

atlas1@ben:ifort-10.1.017 -g -o a.out-ifort-10.1.017 wrong-dwarf-type.f90 
atlas1@ben:gdb a.out-ifort-10.1.017 
GNU gdb Red Hat Linux (6.5-25.el5_1.1rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/libthread_db.so.1".

(gdb) b 30
Breakpoint 1 at 0x402cd6: file wrong-dwarf-type.f90, line 30.
(gdb) r
Starting program: /g/g0/ben/a.out-ifort-10.1.017 

Breakpoint 1, sub_test (a_sub=(), a_sub=(), c_sub=(), c_sub=(), c_size=2, 
    c_size=2) at wrong-dwarf-type.f90:30
30         call contained_sub
Current language:  auto; currently fortran
(gdb) p b_sub
$1 = (PTR TO -> ( real*4 (0:-1,0:-1))) 0x68c44c
(gdb) p b_sub(1,1)
$2 = 2

This looks to me like gdb is interpreting the type of b_sub more in line with my expectations and the value printed appears to be a sensible real rather than 1.5352626e-41. As for why it prints 2 rather than 1. I'm not sure yet. That may be another problem with GDB or ifort. I verified with TotalView that the array looks "right" in its variable view. My guess is that it has something to do with  interpreting the origin of the array as in starting with 0 or 1. When I get to the bottom of that, if need be I'll file a bug against GDB regarding that.
Comment 6 Ben Woodard 2008-08-21 21:55:49 EDT
Created attachment 314767 [details]
reproducer code compiled with ifort 10.1.017
Comment 7 Issue Tracker 2008-08-21 22:06:56 EDT
The behavior of GDB is consistent with the portland group's fortran
compiler as well. This leads me to suspect that the incorrect value
printed for b_sub(1,1) is more likely a bug in gdb than a problem with
ifort or the way that the DWARF information for b_sub is constructed.

atlas1@ben:gdb a.out-pgf90-7.2.2 
GNU gdb Red Hat Linux (6.5-25.el5_1.1rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host
libthread_db library "/lib64/libthread_db.so.1".

(gdb) b 30
Breakpoint 1 at 0x4020c8: file wrong-dwarf-type.f90, line 30.
(gdb) r
Starting program: /g/g0/ben/a.out-pgf90-7.2.2 
[Thread debugging using libthread_db enabled]
[New Thread 46912508778208 (LWP 16636)]
[Switching to Thread 46912508778208 (LWP 16636)]

Breakpoint 1, sub_test_ (a_sub=(), c_sub=(), c_size=2)
    at wrong-dwarf-type.f90:30
30         call contained_sub
Current language:  auto; currently fortran
(gdb) p b_sub
$1 = (PTR TO -> ( real*4 (0:-1,0:-1))) 0x63b850
(gdb) p b_sub(1,1)
$2 = 2
(gdb) 



This event sent from IssueTracker by woodard 
 issue 199077
Comment 8 Jakub Jelinek 2008-08-22 03:25:36 EDT
D.2.1 (figure 51) contains a Fortran sample code example, which shows that an array pointer is represented as DW_TAG_array_type with DW_AT_associated flag (and elsewhere the standard says that Fortran pointers are represented by the DW_AT_associated attribute in the various DW_TAG_*_type DIEs).
You know, Fortran pointers are just variables with POINTER attribute, and even the implementation for Fortran array pointers is very unsimilar to C/C++ pointers - they are implemented as Array descriptors exactly like say assumed shape arrays.
So they really can't be represented as DW_TAG_pointer_type, which tells the debugger that there is a C style pointer somewhere that needs to be dereferenced to get at the pointer target's type.  Here is no such pointer anywhere.

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