Bug 95104 - [9/10 Regression] Segfault on a legal WAIT statement
Summary: [9/10 Regression] Segfault on a legal WAIT statement
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 9.3.0
: P4 normal
Target Milestone: 9.4
Assignee: anlauf
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-05-13 12:42 UTC by Bill Long
Modified: 2020-10-19 05:36 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-05-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bill Long 2020-05-13 12:42:08 UTC
> cat test.f90
      program test
              wait (10, iostat=ios)
              print *, ios
              close (10)
      end program test


> gfortran test.f90
> ./a.out

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

Backtrace for this error:
#0  0x7f3f0334159f in ???
#1  0x4007f6 in ???
#2  0x4008c7 in ???
#3  0x7f3f0332c349 in ???
#4  0x4006f9 in ???
	at ../sysdeps/x86_64/start.S:120
#5  0xffffffffffffffff in ???
Segmentation fault (core dumped)
longb@jupiter:/cray/css/users/longb/spr/jira/22703> gfortran --version
GNU Fortran (GCC) 9.3.0 20200312 (Cray Inc.)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Comment 1 Bill Long 2020-05-13 12:43:49 UTC
The program appears to be legal and should execute and print 0.  

The last paragraph of 12.7.2 WAIT statement (current Fortran standard) is

 
Execution of a WAIT statement specifying a unit that does not exist, has no file connected to it, or is not open for asynchronous input/output is permitted, provided that the WAIT statement has no ID= specifier; such a WAIT statement does not cause an error or end-of-file condition to occur.
Comment 2 kargls 2020-05-13 16:14:07 UTC
0x284321d9 in _gfortran_st_wait_async (wtp=0xffbfe488)
    at ../../../gcc/libgfortran/io/transfer.c:4495
4495      if (ASYNC_IO && u->au)
(gdb) p u
$1 = (gfc_unit *) 0x0
Comment 3 Bill Long 2020-05-13 16:18:26 UTC
A comment from the original user:  gfortran 8.3.0 appears to do the right thing. So perhaps a regression somewhere in the 9.x line?
Comment 4 kargls 2020-05-13 16:24:49 UTC
(In reply to Bill Long from comment #3)
> A comment from the original user:  gfortran 8.3.0 appears to do the right
> thing. So perhaps a regression somewhere in the 9.x line?

A note of the gfortran  wiki says full asynchronous support became
available in 9.1.  SO, likely a bug introduced in 9.  This fixes 
the segfault as it is never correct to dereference a NULL pointer.

Index: libgfortran/io/transfer.c
===================================================================
--- libgfortran/io/transfer.c	(revision 280157)
+++ libgfortran/io/transfer.c	(working copy)
@@ -4492,7 +4492,7 @@ void
 st_wait_async (st_parameter_wait *wtp)
 {
   gfc_unit *u = find_unit (wtp->common.unit);
-  if (ASYNC_IO && u->au)
+  if (ASYNC_IO && u && u->au)
     {
       if (wtp->common.flags & IOPARM_WAIT_HAS_ID)
 	async_wait_id (&(wtp->common), u->au, *wtp->id);


With this patch, your program prints '0'.  Don't know if this
is the only thing that needs fixing.  Thanks for the bug report.
Comment 5 anlauf 2020-05-26 20:06:25 UTC
So a 9/10/11 regression.
Comment 6 anlauf 2020-05-26 20:30:36 UTC
Steve, do you want me to commit it for you, including backports?

Testcase:

! { dg-do run }
! PR libfortran/95104 - Segfault on a legal WAIT statement

program test
  wait (10, iostat=ios)
  if (ios /= 0) stop 1
  close (10)
end program test
Comment 7 Steve Kargl 2020-05-26 21:10:23 UTC
On Tue, May 26, 2020 at 08:30:36PM +0000, anlauf at gcc dot gnu.org wrote:
> 
> --- Comment #6 from anlauf at gcc dot gnu.org ---
> Steve, do you want me to commit it for you, including backports?
> 

I no longer commit, because I do not use git and have
no day-job reason to learn it.  As trunk advances from
the last available svn revision, I'll simply stop
submitting patches.
Comment 8 GCC Commits 2020-05-26 21:30:16 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:56f03cd12be26828788a27f6f3c250041a958e45

commit r11-646-g56f03cd12be26828788a27f6f3c250041a958e45
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Tue May 26 23:29:52 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    Referencing a unit in a WAIT statement that has not been opened before
    resulted in a NULL pointer dereference.  Check for this condition.
    
    2020-05-26  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/transfer.c (st_wait_async): Do not dereference NULL pointer.
    
    gcc/testsuite/
            PR libfortran/95104
            * gfortran.dg/pr95104.f90: New test.
    
    Co-Authored-By: Steven G. Kargl  <kargl@gcc.gnu.org>
Comment 9 anlauf 2020-05-26 21:34:48 UTC
Fixed on master for gcc-11.

Backports pending.
Comment 10 GCC Commits 2020-05-27 19:05:54 UTC
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:50cd4503e59f29e379d0515c48e67d0658ee4562

commit r10-8193-g50cd4503e59f29e379d0515c48e67d0658ee4562
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Tue May 26 23:29:52 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    Referencing a unit in a WAIT statement that has not been opened before
    resulted in a NULL pointer dereference.  Check for this condition.
    
    2020-05-26  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/transfer.c (st_wait_async): Do not dereference NULL pointer.
    
    gcc/testsuite/
            PR libfortran/95104
            * gfortran.dg/pr95104.f90: New test.
    
    Co-Authored-By: Steven G. Kargl  <kargl@gcc.gnu.org>
    (cherry picked from commit 56f03cd12be26828788a27f6f3c250041a958e45)
Comment 11 GCC Commits 2020-05-27 19:08:32 UTC
The releases/gcc-9 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:6f64bc18a664e1d003120cfa8508cb5fe06fa7ad

commit r9-8629-g6f64bc18a664e1d003120cfa8508cb5fe06fa7ad
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Tue May 26 23:29:52 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    Referencing a unit in a WAIT statement that has not been opened before
    resulted in a NULL pointer dereference.  Check for this condition.
    
    2020-05-26  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/transfer.c (st_wait_async): Do not dereference NULL pointer.
    
    gcc/testsuite/
            PR libfortran/95104
            * gfortran.dg/pr95104.f90: New test.
    
    Co-Authored-By: Steven G. Kargl  <kargl@gcc.gnu.org>
    (cherry picked from commit 56f03cd12be26828788a27f6f3c250041a958e45)
Comment 12 anlauf 2020-05-27 19:18:19 UTC
Fixed on master for gcc-11, and backported to 10- and 9-branches.

Thanks for the report!
Comment 13 Rainer Orth 2020-05-28 08:34:19 UTC
The new testcase FAILs on (at least): Solaris (both sparc and x86):

+FAIL: gfortran.dg/pr95104.f90   -O0  execution test
+FAIL: gfortran.dg/pr95104.f90   -O1  execution test
+FAIL: gfortran.dg/pr95104.f90   -O2  execution test
+FAIL: gfortran.dg/pr95104.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
+FAIL: gfortran.dg/pr95104.f90   -O3 -g  execution test
+FAIL: gfortran.dg/pr95104.f90   -Os  execution test

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

Backtrace for this error:

After recompiling libgfortran with -g3 -O0, I see

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0xfec554a8 in pthread_mutex_unlock () from /lib/libc.so.1
(gdb) where
#0  0xfec554a8 in pthread_mutex_unlock () from /lib/libc.so.1
#1  0xff1287bc in __gthread_mutex_unlock (__mutex=0xc8)
    at ../libgcc/gthr-default.h:779
#2  0xff12a178 in _gfortrani_unlock_unit (u=0x0)
    at /vol/gcc/src/hg/master/local/libgfortran/io/unit.c:771
#3  0xff127ffc in _gfortran_st_wait_async (wtp=0xffbfe750)
    at /vol/gcc/src/hg/master/local/libgfortran/io/transfer.c:4511
#4  0x00010eac in test ()
    at /vol/gcc/src/hg/master/local/gcc/testsuite/gfortran.dg/pr95104.f90:5
#5  0x00010f40 in main (argc=1, argv=0xffbfe992)
    at /vol/gcc/src/hg/master/local/gcc/testsuite/gfortran.dg/pr95104.f90:8
#6  0x00010c74 in _start ()

#3  0xff127ffc in _gfortran_st_wait_async (wtp=0xffbfe750)
    at /vol/gcc/src/hg/master/local/libgfortran/io/transfer.c:4511
4511	  unlock_unit (u);
(gdb) p u
$2 = (gfc_unit *) 0x0

Either the unlock_unit needs to be guarded by if (u) or moved into the 
if (ASYNC_IO && u ...) check.
Comment 14 GCC Commits 2020-05-28 19:53:59 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:6ce3d791dfcba469e709935aba5743640f7d4959

commit r11-704-g6ce3d791dfcba469e709935aba5743640f7d4959
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Thu May 28 21:53:17 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    The initial commit for this PR uncovered a latent issue with unit locking
    in the Fortran run-time library.  Add check for valid unit.
    
    2020-05-28  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/unit.c (unlock_unit): Guard by check for NULL pointer.
Comment 15 GCC Commits 2020-05-28 20:04:41 UTC
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:e1396ee72e68cc8fba99ce986f2910cd39e335b8

commit r10-8202-ge1396ee72e68cc8fba99ce986f2910cd39e335b8
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Thu May 28 21:53:17 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    The initial commit for this PR uncovered a latent issue with unit locking
    in the Fortran run-time library.  Add check for valid unit.
    
    2020-05-28  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/unit.c (unlock_unit): Guard by check for NULL pointer.
    
    (cherry picked from commit 6ce3d791dfcba469e709935aba5743640f7d4959)
Comment 16 GCC Commits 2020-05-28 20:14:15 UTC
The releases/gcc-9 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:0d607ecbf125551513e182a181ca9c6e25dc7609

commit r9-8633-g0d607ecbf125551513e182a181ca9c6e25dc7609
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Thu May 28 21:53:17 2020 +0200

    PR fortran/95104 - Segfault on a legal WAIT statement
    
    The initial commit for this PR uncovered a latent issue with unit locking
    in the Fortran run-time library.  Add check for valid unit.
    
    2020-05-28  Harald Anlauf  <anlauf@gmx.de>
    
    libgfortran/
            PR libfortran/95104
            * io/unit.c (unlock_unit): Guard by check for NULL pointer.
    
    (cherry picked from commit 6ce3d791dfcba469e709935aba5743640f7d4959)
Comment 17 anlauf 2020-05-28 20:16:02 UTC
Should be fixed now.

Thanks, Rainer, for precisely pointing at the latent issue.
Comment 18 Bill Long 2020-10-18 20:47:17 UTC
Original submitted asking about the GCC version that has / will have the fix.
Comment 19 Thomas Koenig 2020-10-19 05:36:07 UTC
Fixed for 10.2. 9.4 and 11.1 will have the fix in.