Bug 58913 - Segmentation fault on real128 array
Summary: Segmentation fault on real128 array
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-10-29 17:46 UTC by Rodrigo Rodrigues
Modified: 2013-11-25 02:13 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rodrigo Rodrigues 2013-10-29 17:46:02 UTC
I cannot "write" a variable which contains an array of real(kind=real128). Scalars seem to work right.
I got this behavior when running this simple program:

01  program main
02    use iso_fortran_env
03    real(real128), dimension(2) :: a
04    a = (/0., 1./)
05    write(*,*) a
06  end program

>gfortran main.txt -o main    #successfully compiles!
>main                         #runtime error!

Program received signal SIGSEGV: Segmentation Fault - invalid memory reference.

Backtrace for this error:
#0 ffffffff

Same error is obtained if I:
I)   change real(real128) to real(16) in line 03
II)  change line 04 to a = (/0._real128, 1._real128)
III) change line 04 to a = real((/0., 1./), kind=real128)
IV)  declare a variable "b", assign b = a and try to write "b"
V)   try to write the value of a pointer pointing to a
VI)  make variable "a" PARAMETER, SAVE, TARGET or ALLOCATABLE

More weird is that the program successfully run if I:
a)   change line 05 to write(*,*) a(1)
b)   change line 05 to write(*,*) (/0., 1./)
b)   change line 05 to write(*,*) 2*a or any other expression whose result IS NOT a direct reference to "a" or any other variable with real128 array.
c)   put a write statement with a value or scalar variable of kind=real128 anywhere in the program's body, no matter if before, after or even inside the write statement of line 05
d)   change real(real128) to any other real kind in line 03
e)   make "a" scalar

Any ideas?
Comment 1 kargl 2013-10-29 19:36:43 UTC
What operating system?  Where did you get gfortran?

Your program works for 4.7.4, 4.8.2, and trunk on
x86_64 FreeBSD
Comment 2 kargl 2013-10-29 19:40:27 UTC
(In reply to kargl from comment #1)
> What operating system?  Where did you get gfortran?
> 
> Your program works for 4.7.4, 4.8.2, and trunk on
> x86_64 FreeBSD

I take it back.  Your program does not work as you
may have intended on my system. real128 from 
iso_fortran_env is set to 10 not the desired 16.

However, changing real128 to 16 works.
Comment 3 Rodrigo Rodrigues 2013-10-29 19:47:36 UTC
Windows 7 x86
I got gfortran from mingw.

Actually, real128 returns 16 in my machine. It is totally equivalent to 16 here.
Comment 4 Steve Kargl 2013-10-29 19:54:06 UTC
On Tue, Oct 29, 2013 at 07:47:36PM +0000, rrodrigues at poli dot ufrj.br wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58913
> 
> --- Comment #3 from Rodrigo Rodrigues <rrodrigues at poli dot ufrj.br> ---
> Windows 7 x86
> I got gfortran from mingw.
> 

Can you add -g to the command line and get a backtrace
with gdb?

Can you post the file created with the -fdump-tree-original
option?
Comment 5 Rodrigo Rodrigues 2013-10-29 20:02:08 UTC
There is no compile error. Adding -g for running doesn't show any new information, just the same:

Program received signal SIGSEGV: Segmentation Fault - invalid memory reference.

Backtrace for this error:
#0 ffffffff


The dump file have:

MAIN__ ()
{
  real(kind=16) a[2];

  {
    static real(kind=16) A.0[2] = {0.0, 1.0e+0};

    (void) (MEM[(c_char * {ref-all})&a] = MEM[(c_char * {ref-all})&A.0]);
    {
      struct __st_parameter_dt dt_parm.1;

      dt_parm.1.common.filename = &"main.f90"[1]{lb: 1 sz: 1};
      dt_parm.1.common.line = 5;
      dt_parm.1.common.flags = 128;
      dt_parm.1.common.unit = 6;
      _gfortran_st_write (&dt_parm.1);
      {
        struct array1_real(kind=16) parm.2;

        parm.2.dtype = 1049;
        parm.2.dim[0].lbound = 1;
        parm.2.dim[0].ubound = 2;
        parm.2.dim[0].stride = 1;
        parm.2.data = (void *) &a[0];
        parm.2.offset = -1;
        _gfortran_transfer_array_write (&dt_parm.1, &parm.2, 16, 0);
      }
      _gfortran_st_write_done (&dt_parm.1);
    }
  }
}


main (integer(kind=4) argc, character(kind=1) * * argv)
{
  static integer(kind=4) options.3[7] = {68, 1023, 0, 0, 1, 1, 0};

  _gfortran_set_args (argc, argv);
  _gfortran_set_options (7, &options.3[0]);
  MAIN__ ();
  return 0;
}
Comment 6 Steve Kargl 2013-10-29 20:21:49 UTC
On Tue, Oct 29, 2013 at 08:02:08PM +0000, rrodrigues at poli dot ufrj.br wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58913
> 
> --- Comment #5 from Rodrigo Rodrigues <rrodrigues at poli dot ufrj.br> ---
> There is no compile error. Adding -g for running doesn't show any new
> information, just the same:
> 
> Program received signal SIGSEGV: Segmentation Fault
> - invalid memory reference.
> 
> Backtrace for this error:
> #0 ffffffff

You need to run the file within gdb to get a backtrace.
I don't use MingW so I'm not sure how to do this.  On
FreeBSD, one would do

% gfortran -o z a.f90
% gdb ./z
gdb> run
(segfault occurs)
gdb> bt
(trace of function calls)

> The dump file have:

A quick glance shows that the dump looks like what I have here.

> MAIN__ ()
> {

(snip)

>         _gfortran_transfer_array_write (&dt_parm.1, &parm.2, 16, 0);

What I hope gdb shows is that segfault occurs in this function.
This would then mean we have an OS specific issue.
Comment 7 Rodrigo Rodrigues 2013-10-29 20:39:15 UTC
Here goes the backtrack:

#0  0x00000000 in ?? ()
#1  0x0042d483 in output_float_FMT_G_16 (comp_d=<optimized out>, 
    zero_flag=<optimized out>, sign_bit=<optimized out>, 
    size=<optimized out>, buffer=<optimized out>, m=<optimized out>, 
    f=0x22fb6c, dtp=<optimized out>)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1112
#2  write_float (dtp=dtp@entry=0x22fcf8, f=f@entry=0x22fbbc, 
    source=source@entry=0x22fe70 "", len=len@entry=16, comp_d=comp_d@entry=1)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1259
#3  0x0041f78f in __gfortrani_write_real (dtp=dtp@entry=0x22fcf8, 
    source=source@entry=0x22fe70 "", length=length@entry=16)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/write.c:1470
#4  0x00419dd4 in list_formatted_write_scalar (size=16, kind=16, p=0x22fe70, 
    type=BT_REAL, dtp=0x22fcf8)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/write.c:1571
#5  __gfortrani_list_formatted_write (dtp=0x22fcf8, type=BT_REAL, p=0x22fe70, 
    kind=16, size=16, nelems=2)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/write.c:1599
#6  0x0041704b in __gfortran_transfer_array (dtp=0x22fcf8, desc=0x22fe58, 
    kind=16, charlen=<optimized out>)
    at ../../../gcc-4.8.0-mingw/libgfortran/io/transfer.c:2170
#7  0x0040173d in MAIN__ ()
#8  0x00401786 in main ()
Comment 8 Steve Kargl 2013-10-29 20:55:07 UTC
On Tue, Oct 29, 2013 at 08:39:15PM +0000, rrodrigues at poli dot ufrj.br wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58913
> 
> --- Comment #7 from Rodrigo Rodrigues <rrodrigues at poli dot ufrj.br> ---
> Here goes the backtrack:
> 
> #0  0x00000000 in ?? ()
> #1  0x0042d483 in output_float_FMT_G_16 (comp_d=<optimized out>, 
>     zero_flag=<optimized out>, sign_bit=<optimized out>, 
>     size=<optimized out>, buffer=<optimized out>, m=<optimized out>, 
>     f=0x22fb6c, dtp=<optimized out>)
>     at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1112
> #2  write_float (dtp=dtp@entry=0x22fcf8, f=f@entry=0x22fbbc, 
>     source=source@entry=0x22fe70 "", len=len@entry=16, comp_d=comp_d@entry=1)
>     at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1259

Unfortnately, your trace suggests to me that this is MingW 
specific.  I can't help beyond this point.  Prehaps, ping 
the MingW developers?
Comment 9 Rodrigo Rodrigues 2013-10-30 03:41:38 UTC
(In reply to Steve Kargl from comment #8)
> Unfortnately, your trace suggests to me that this is MingW 
> specific.  I can't help beyond this point.  Prehaps, ping 
> the MingW developers?

Yeah, I have to agree.

I've tested tonight on two linux machines: a x86 ubuntu with gfortran 4.8.1 and real128=16 and a x64 xubuntu with gfortran 4.7.3 and real128=10. Both worked and run properly.

I also tested on a win8 x86 machine, with gfortran 4.8.0 abd real128=16 and it worked too. I don't remember where did I get gfortran for that machine, I don't know if it was from MingW also... but I don't think so.

Well, I'll try to contact MingW developers. Thank you Steve.
Comment 10 Rodrigo Rodrigues 2013-11-12 11:45:57 UTC
(In reply to Steve Kargl from comment #8)
> On Tue, Oct 29, 2013 at 08:39:15PM +0000, rrodrigues at poli dot ufrj.br
> wrote:
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58913
> > 
> > --- Comment #7 from Rodrigo Rodrigues <rrodrigues at poli dot ufrj.br> ---
> > Here goes the backtrack:
> > 
> > #0  0x00000000 in ?? ()
> > #1  0x0042d483 in output_float_FMT_G_16 (comp_d=<optimized out>, 
> >     zero_flag=<optimized out>, sign_bit=<optimized out>, 
> >     size=<optimized out>, buffer=<optimized out>, m=<optimized out>, 
> >     f=0x22fb6c, dtp=<optimized out>)
> >     at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1112
> > #2  write_float (dtp=dtp@entry=0x22fcf8, f=f@entry=0x22fbbc, 
> >     source=source@entry=0x22fe70 "", len=len@entry=16, comp_d=comp_d@entry=1)
> >     at ../../../gcc-4.8.0-mingw/libgfortran/io/write_float.def:1259
> 
> Unfortnately, your trace suggests to me that this is MingW 
> specific.  I can't help beyond this point.  Prehaps, ping 
> the MingW developers?

Well, as I got gfortran binaries from http://www.equation.com/
I've contacted the Equation Team and they confirmed that that is a platform specific bug. They addressed this bug and recommended to not use real128 float numbers.

So I think that this bug report can be closed here. Thank you for the attention.
Comment 11 kargl 2013-11-25 00:57:52 UTC
Remove myself from cc list.
Comment 12 Rodrigo Rodrigues 2013-11-25 02:13:31 UTC
Ok, marking as invalid and closing...