[committed] Ensure that gfortran.dg/achar_2.f90 can fail

Message ID f6cd89a1-e8f8-05fd-397f-72881161e083@mentor.com
State New
Headers show
Series
  • [committed] Ensure that gfortran.dg/achar_2.f90 can fail
Related show

Commit Message

Tobias Burnus Oct. 31, 2019, 4:12 p.m.
At some point, 'call abort()' was changed to 'stop'; this works fine as 
long as exit status is != 0. At least on my Linux system, this works 
until 255. (Which matches POSIX, which requires 8 bits.) For "stop 256", 
I get an exit status == 0.

I am not sure whether other systems break earlier, but I assume most 
support 0 to 255. Currently, gcc/testsuite/*fortran* has those maximal 
'stop' counts:

127
127
144
174
192
240
1516 ! <-- this was patched.

In libgomp, the current record are 222 and 242. Hence, when adding 
extensive test cases, one needs to watch out!

Cheers,

Tobias

Comments

Steve Kargl Oct. 31, 2019, 4:42 p.m. | #1
On Thu, Oct 31, 2019 at 05:12:39PM +0100, Tobias Burnus wrote:
> At some point, 'call abort()' was changed to 'stop'; this works fine as 

> long as exit status is != 0. At least on my Linux system, this works 

> until 255. (Which matches POSIX, which requires 8 bits.) For "stop 256", 

> I get an exit status == 0.

>

> I am not sure whether other systems break earlier, but I assume most 

> support 0 to 255. Currently, gcc/testsuite/*fortran* has those maximal 

> 'stop' counts:


FreeBSD's manpage for exit(3) (and _Exit()) states

     Both functions make the low-order eight bits of the status
     argument available to a parent process which has called a
     wait(2)-family function.

I suspect the other BSDs also follow posix.  I wonder if gfortran
should either apply a mask to the stop code or simply map nonzero
values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT.  Perhaps,

Index: runtime/stop.c
===================================================================
--- runtime/stop.c      (revision 277638)
+++ runtime/stop.c      (working copy)
@@ -123,7 +123,7 @@ stop_numeric (int code, bool quiet)
       report_exception ();
       st_printf ("STOP %d\n", code);
     }
-  exit (code);
+  exit (EXIT_FAILURE);
 }


-- 
Steve
Jakub Jelinek Oct. 31, 2019, 4:46 p.m. | #2
On Thu, Oct 31, 2019 at 09:42:07AM -0700, Steve Kargl wrote:
> On Thu, Oct 31, 2019 at 05:12:39PM +0100, Tobias Burnus wrote:

> > At some point, 'call abort()' was changed to 'stop'; this works fine as 

> > long as exit status is != 0. At least on my Linux system, this works 

> > until 255. (Which matches POSIX, which requires 8 bits.) For "stop 256", 

> > I get an exit status == 0.

> >

> > I am not sure whether other systems break earlier, but I assume most 

> > support 0 to 255. Currently, gcc/testsuite/*fortran* has those maximal 

> > 'stop' counts:

> 

> FreeBSD's manpage for exit(3) (and _Exit()) states

> 

>      Both functions make the low-order eight bits of the status

>      argument available to a parent process which has called a

>      wait(2)-family function.

> 

> I suspect the other BSDs also follow posix.  I wonder if gfortran

> should either apply a mask to the stop code or simply map nonzero

> values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT.  Perhaps,


I think being able to supply the exact code to shell is useful,
perhaps we should just use
  exit (code > 255 ? 255 : code);
or similar?

	Jakub
Tobias Burnus Oct. 31, 2019, 4:51 p.m. | #3
On 10/31/19 5:42 PM, Steve Kargl wrote:
> I suspect the other BSDs also follow posix. I wonder if gfortran 

> should either apply a mask to the stop code or simply map nonzero 

> values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT. Perhaps,

>

> -  exit (code);

> +  exit (EXIT_FAILURE);



Or "exit (code > 255 ? EXIT_FAILURE : code);". I think EXIT_FAILURE is 1 
on most systems. I recall that windows interpreted exit(3) as abort, 
which can also be surprising. (But is fine for our testsuite purpose.)

SIGABRT sounds wrong for STOP as:

"Execution of a STOP statement initiates normal termination of 
execution.  Execution of an ERROR STOP statement initiates error 
termination of execution."

Otherwise, the standard states: "When an image is terminated by a STOP 
or ERROR STOP statement, its stop code, if any, is made available in a 
processor-dependent manner. If the stop-code is an integer, it is 
recommended that the value be used as the process exit status, if the 
processor supports that concept. If the stop-code in a STOP statement is 
of type character or does not appear, or if an end-program-stmt is 
executed, it is recommended that the value zero be supplied as the 
process exit status, if the processor supports that concept. If the 
stop-code in an ERROR STOP statement is of type character or does not 
appear, it is recommended that a processor-dependent nonzero value be 
supplied as the process exit status, if the processor supports that 
concept."

Cheers,

Tobias
Steve Kargl Oct. 31, 2019, 4:55 p.m. | #4
On Thu, Oct 31, 2019 at 05:46:38PM +0100, Jakub Jelinek wrote:
> On Thu, Oct 31, 2019 at 09:42:07AM -0700, Steve Kargl wrote:

> > On Thu, Oct 31, 2019 at 05:12:39PM +0100, Tobias Burnus wrote:

> > > At some point, 'call abort()' was changed to 'stop'; this works fine as 

> > > long as exit status is != 0. At least on my Linux system, this works 

> > > until 255. (Which matches POSIX, which requires 8 bits.) For "stop 256", 

> > > I get an exit status == 0.

> > >

> > > I am not sure whether other systems break earlier, but I assume most 

> > > support 0 to 255. Currently, gcc/testsuite/*fortran* has those maximal 

> > > 'stop' counts:

> > 

> > FreeBSD's manpage for exit(3) (and _Exit()) states

> > 

> >      Both functions make the low-order eight bits of the status

> >      argument available to a parent process which has called a

> >      wait(2)-family function.

> > 

> > I suspect the other BSDs also follow posix.  I wonder if gfortran

> > should either apply a mask to the stop code or simply map nonzero

> > values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT.  Perhaps,

> 

> I think being able to supply the exact code to shell is useful,

> perhaps we should just use

>   exit (code > 255 ? 255 : code);

> or similar?

> 


I'm fine with this option.  I'll work up a patch
later with the above, and add some documentation
to the gfortran manual.

-- 
Steve
Steve Kargl Oct. 31, 2019, 5:03 p.m. | #5
On Thu, Oct 31, 2019 at 05:51:38PM +0100, Tobias Burnus wrote:
> On 10/31/19 5:42 PM, Steve Kargl wrote:

> > I suspect the other BSDs also follow posix. I wonder if gfortran 

> > should either apply a mask to the stop code or simply map nonzero 

> > values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT. Perhaps,

> >

> > -  exit (code);

> > +  exit (EXIT_FAILURE);

> 

> 

> Or "exit (code > 255 ? EXIT_FAILURE : code);". I think EXIT_FAILURE is 1 

> on most systems. I recall that windows interpreted exit(3) as abort, 

> which can also be surprising. (But is fine for our testsuite purpose.)


As I replied to Jakub, I'm fine with the ternary expression.

I did a brief scan of signal.h, and there is a SIGSTOP.
Depending on whether a user installed a signal handler,
SIGSTOP might lead to a zombie process so I did not
mention it as a possibility.

-- 
Steve
Janne Blomqvist Oct. 31, 2019, 7:30 p.m. | #6
On Thu, Oct 31, 2019 at 7:03 PM Steve Kargl
<sgk@troutmask.apl.washington.edu> wrote:
>

> On Thu, Oct 31, 2019 at 05:51:38PM +0100, Tobias Burnus wrote:

> > On 10/31/19 5:42 PM, Steve Kargl wrote:

> > > I suspect the other BSDs also follow posix. I wonder if gfortran

> > > should either apply a mask to the stop code or simply map nonzero

> > > values to one of EXIT_FAILURE, SIGQUIT, or SIGABRT. Perhaps,

> > >

> > > -  exit (code);

> > > +  exit (EXIT_FAILURE);

> >

> >

> > Or "exit (code > 255 ? EXIT_FAILURE : code);". I think EXIT_FAILURE is 1

> > on most systems. I recall that windows interpreted exit(3) as abort,

> > which can also be surprising. (But is fine for our testsuite purpose.)

>

> As I replied to Jakub, I'm fine with the ternary expression.

>

> I did a brief scan of signal.h, and there is a SIGSTOP.

> Depending on whether a user installed a signal handler,

> SIGSTOP might lead to a zombie process so I did not

> mention it as a possibility.


I'd personally prefer the current behavior. I.e. just let the
underlying OS/libc handle it as it sees fit. No need to invent our own
semantics here. Tobias quoted the relevant part of the standard, which
the current implementation fulfills just fine.

-- 
Janne Blomqvist
Steve Kargl Oct. 31, 2019, 8:04 p.m. | #7
On Thu, Oct 31, 2019 at 09:30:26PM +0200, Janne Blomqvist wrote:
> 

> I'd personally prefer the current behavior. I.e. just let the

> underlying OS/libc handle it as it sees fit. No need to invent our own

> semantics here. Tobias quoted the relevant part of the standard, which

> the current implementation fulfills just fine.

> 


I'm fine with that.  I suppose someone should
document how gfortran communicates an exit 
status to an invoking shell handle; especially
when the stop codes exceeds 255.

-- 
Steve
Janne Blomqvist Nov. 1, 2019, 10:15 a.m. | #8
On Thu, Oct 31, 2019 at 10:04 PM Steve Kargl
<sgk@troutmask.apl.washington.edu> wrote:
>

> On Thu, Oct 31, 2019 at 09:30:26PM +0200, Janne Blomqvist wrote:

> >

> > I'd personally prefer the current behavior. I.e. just let the

> > underlying OS/libc handle it as it sees fit. No need to invent our own

> > semantics here. Tobias quoted the relevant part of the standard, which

> > the current implementation fulfills just fine.

> >

>

> I'm fine with that.  I suppose someone should

> document how gfortran communicates an exit

> status to an invoking shell handle; especially

> when the stop codes exceeds 255.


In principle yes, but how to do it without bogging down into minutiae
of how different targets allow retrieving the process exit status?

For POSIX, we can say that the 8 lowest order bits are used.  Except
if using the POSIX 2008 waitid() function which allows the parent
process to retrieve the full 32 bits. And Windows apparently use
32-bit unsigned integers. And then all the weird targets that a
handful of people around the world for some reason care about, etc.

More info at wikipedia: https://en.wikipedia.org/wiki/Exit_status

Perhaps some note that positive integers in the range [0,255] are
somewhat portable?

-- 
Janne Blomqvist

Patch

Index: gcc/testsuite/gfortran.dg/achar_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/achar_2.f90	(revision 277672)
+++ gcc/testsuite/gfortran.dg/achar_2.f90	(revision 277678)
@@ -2023,4 +2023,9 @@ 
   c = "ÿ"
   if (achar(i) /= "ÿ") STOP 1514
   if (iachar(c) /= iachar("ÿ")) STOP 1515
+  print *, 'DONE'
 end program main
+
+! DejaGNU only checks the exit code but 'STOP 256' has exit code 0. Hence,
+! check output for:
+! { dg-output "DONE" }