zsh-workers
 help / color / mirror / code / Atom feed
* SIGFPE crash
@ 2011-05-07 21:56 Jon Mayo
  2011-05-07 22:17 ` Mikael Magnusson
  0 siblings, 1 reply; 12+ messages in thread
From: Jon Mayo @ 2011-05-07 21:56 UTC (permalink / raw)
  To: zsh workers

echo $[-9223372036854775808/-1]

this causes zsh to exit immediately with an FPE. Does anyone have a
patch to fix this?

- Jon


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 21:56 SIGFPE crash Jon Mayo
@ 2011-05-07 22:17 ` Mikael Magnusson
  2011-05-07 22:19   ` Jon Mayo
  0 siblings, 1 reply; 12+ messages in thread
From: Mikael Magnusson @ 2011-05-07 22:17 UTC (permalink / raw)
  To: Jon Mayo; +Cc: zsh workers

On 7 May 2011 23:56, Jon Mayo <jon.mayo@gmail.com> wrote:
> echo $[-9223372036854775808/-1]
>
> this causes zsh to exit immediately with an FPE. Does anyone have a
> patch to fix this?

diff --git a/Src/math.c b/Src/math.c
index 35b362d..3c08052 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -1053,8 +1053,12 @@ op(int what)
                    return;
                if (c.type == MN_FLOAT)
                    c.u.d = a.u.d / b.u.d;
-               else
-                   c.u.l = a.u.l / b.u.l;
+               else {
+                    if (a.u.l == LONG_MIN && b.u.l == -1)
+                        c.u.l = 0;
+                    else
+                       c.u.l = a.u.l / b.u.l;
+                }
                break;
            case MOD:
            case MODEQ:


Do we want to print a warning and/or use another value than 0 in this case?

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:17 ` Mikael Magnusson
@ 2011-05-07 22:19   ` Jon Mayo
  2011-05-07 22:27     ` Mikael Magnusson
  2011-05-09 10:35     ` Vincent Lefevre
  0 siblings, 2 replies; 12+ messages in thread
From: Jon Mayo @ 2011-05-07 22:19 UTC (permalink / raw)
  To: zsh workers

On Sat, May 7, 2011 at 3:17 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
> On 7 May 2011 23:56, Jon Mayo <jon.mayo@gmail.com> wrote:
>> echo $[-9223372036854775808/-1]
>>
>> this causes zsh to exit immediately with an FPE. Does anyone have a
>> patch to fix this?
>
> diff --git a/Src/math.c b/Src/math.c
> index 35b362d..3c08052 100644
> --- a/Src/math.c
> +++ b/Src/math.c
> @@ -1053,8 +1053,12 @@ op(int what)
>                    return;
>                if (c.type == MN_FLOAT)
>                    c.u.d = a.u.d / b.u.d;
> -               else
> -                   c.u.l = a.u.l / b.u.l;
> +               else {
> +                    if (a.u.l == LONG_MIN && b.u.l == -1)

should be LLONG_MIN

> +                        c.u.l = 0;

LLONG_MAX would be the closest answer, but 1 off. I would switch it
from integer to double type in this case, but that might be difficult.

> +                    else
> +                       c.u.l = a.u.l / b.u.l;
> +                }
>                break;
>            case MOD:
>            case MODEQ:
>
>
> Do we want to print a warning and/or use another value than 0 in this case?
>
> --
> Mikael Magnusson
>

-- Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:19   ` Jon Mayo
@ 2011-05-07 22:27     ` Mikael Magnusson
  2011-05-07 23:48       ` Phil Pennock
                         ` (3 more replies)
  2011-05-09 10:35     ` Vincent Lefevre
  1 sibling, 4 replies; 12+ messages in thread
From: Mikael Magnusson @ 2011-05-07 22:27 UTC (permalink / raw)
  To: Jon Mayo; +Cc: zsh workers

On 8 May 2011 00:19, Jon Mayo <jon.mayo@gmail.com> wrote:
> On Sat, May 7, 2011 at 3:17 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
>> On 7 May 2011 23:56, Jon Mayo <jon.mayo@gmail.com> wrote:
>>> echo $[-9223372036854775808/-1]
>>>
>>> this causes zsh to exit immediately with an FPE. Does anyone have a
>>> patch to fix this?
>>
>> diff --git a/Src/math.c b/Src/math.c
>> index 35b362d..3c08052 100644
>> --- a/Src/math.c
>> +++ b/Src/math.c
>> @@ -1053,8 +1053,12 @@ op(int what)
>>                    return;
>>                if (c.type == MN_FLOAT)
>>                    c.u.d = a.u.d / b.u.d;
>> -               else
>> -                   c.u.l = a.u.l / b.u.l;
>> +               else {
>> +                    if (a.u.l == LONG_MIN && b.u.l == -1)
>
> should be LLONG_MIN
>
>> +                        c.u.l = 0;
>
> LLONG_MAX would be the closest answer, but 1 off. I would switch it
> from integer to double type in this case, but that might be difficult.

It should probably be neither, zsh does some weird stuff to find a
suitably long type for .l, which may or may not be a long long.

>> +                    else
>> +                       c.u.l = a.u.l / b.u.l;
>> +                }
>>                break;
>>            case MOD:
>>            case MODEQ:
>>
>>
>> Do we want to print a warning and/or use another value than 0 in this case?

This is assuming we want to do this at all, I am told that only
division will generate an exception on x86, but presumably other
arches behave differently, and bash behaves the same way too
(exception + die). Does some sort of standard have anything to say on
the matter? I'm guessing someone has thought of it before and clearly
nobody ever did anything about it.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:27     ` Mikael Magnusson
@ 2011-05-07 23:48       ` Phil Pennock
  2011-05-08  0:05       ` Jon Mayo
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Phil Pennock @ 2011-05-07 23:48 UTC (permalink / raw)
  To: zsh-workers

On 2011-05-08 at 00:27 +0200, Mikael Magnusson wrote:
[ mod/modeq ]
> This is assuming we want to do this at all, I am told that only
> division will generate an exception on x86, but presumably other
> arches behave differently, and bash behaves the same way too
> (exception + die). Does some sort of standard have anything to say on
> the matter? I'm guessing someone has thought of it before and clearly
> nobody ever did anything about it.

At least in the INT_MIN case for integers, modulo arithmetic generates
this exception.

I checked, Exim has the same issue, http://bugs.exim.org/1112 filed,
referencing this thread.  From that:

% exim -be
> ${eval:-2147483648%-1}
zsh: floating point exception  exim -be

*sigh*

-Phil


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:27     ` Mikael Magnusson
  2011-05-07 23:48       ` Phil Pennock
@ 2011-05-08  0:05       ` Jon Mayo
  2011-05-08  0:10         ` Mikael Magnusson
  2011-05-08  2:46         ` Bart Schaefer
  2011-05-08 17:33       ` Peter Stephenson
  2011-05-09 10:21       ` Vincent Lefevre
  3 siblings, 2 replies; 12+ messages in thread
From: Jon Mayo @ 2011-05-08  0:05 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: zsh workers

On Sat, May 7, 2011 at 3:27 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
> On 8 May 2011 00:19, Jon Mayo <jon.mayo@gmail.com> wrote:
>> On Sat, May 7, 2011 at 3:17 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
>>> On 7 May 2011 23:56, Jon Mayo <jon.mayo@gmail.com> wrote:
>>>> echo $[-9223372036854775808/-1]
>>>>
>>>> this causes zsh to exit immediately with an FPE. Does anyone have a
>>>> patch to fix this?
>>>
>>> diff --git a/Src/math.c b/Src/math.c
>>> index 35b362d..3c08052 100644
>>> --- a/Src/math.c
>>> +++ b/Src/math.c
>>> @@ -1053,8 +1053,12 @@ op(int what)
>>>                    return;
>>>                if (c.type == MN_FLOAT)
>>>                    c.u.d = a.u.d / b.u.d;
>>> -               else
>>> -                   c.u.l = a.u.l / b.u.l;
>>> +               else {
>>> +                    if (a.u.l == LONG_MIN && b.u.l == -1)
>>
>> should be LLONG_MIN
>>
>>> +                        c.u.l = 0;
>>
>> LLONG_MAX would be the closest answer, but 1 off. I would switch it
>> from integer to double type in this case, but that might be difficult.
>
> It should probably be neither, zsh does some weird stuff to find a
> suitably long type for .l, which may or may not be a long long.
>
>>> +                    else
>>> +                       c.u.l = a.u.l / b.u.l;
>>> +                }
>>>                break;
>>>            case MOD:
>>>            case MODEQ:
>>>
>>>
>>> Do we want to print a warning and/or use another value than 0 in this case?
>
> This is assuming we want to do this at all, I am told that only
> division will generate an exception on x86, but presumably other
> arches behave differently, and bash behaves the same way too
> (exception + die). Does some sort of standard have anything to say on
> the matter? I'm guessing someone has thought of it before and clearly
> nobody ever did anything about it.
>

perhaps scripts that care can just use a trap? and all my worrying was
for nothing?
mostly I ran into the issue while I dropped out of vi to do some
calculations, and ended up having zsh crash and had to recover my
editing session. minor annoyance really.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-08  0:05       ` Jon Mayo
@ 2011-05-08  0:10         ` Mikael Magnusson
  2011-05-08  2:46         ` Bart Schaefer
  1 sibling, 0 replies; 12+ messages in thread
From: Mikael Magnusson @ 2011-05-08  0:10 UTC (permalink / raw)
  To: Jon Mayo; +Cc: zsh workers

On 8 May 2011 02:05, Jon Mayo <jon.mayo@gmail.com> wrote:
> On Sat, May 7, 2011 at 3:27 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
>> This is assuming we want to do this at all, I am told that only
>> division will generate an exception on x86, but presumably other
>> arches behave differently, and bash behaves the same way too
>> (exception + die). Does some sort of standard have anything to say on
>> the matter? I'm guessing someone has thought of it before and clearly
>> nobody ever did anything about it.
>>
>
> perhaps scripts that care can just use a trap? and all my worrying was
> for nothing?
> mostly I ran into the issue while I dropped out of vi to do some
> calculations, and ended up having zsh crash and had to recover my
> editing session. minor annoyance really.

Using a trap doesn't seem to work, it just causes an infinite loop
running the instruction over and over again.
fwiw, bash behaves the same way, both with regards to crashing and
looping on the trap.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-08  0:05       ` Jon Mayo
  2011-05-08  0:10         ` Mikael Magnusson
@ 2011-05-08  2:46         ` Bart Schaefer
  2011-05-08  7:03           ` Jon Mayo
  1 sibling, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2011-05-08  2:46 UTC (permalink / raw)
  To: Jon Mayo, zsh workers

On May 7,  2:56pm, Jon Mayo wrote:
}
} echo $[-9223372036854775808/-1]
} 
} this causes zsh to exit immediately with an FPE. Does anyone have a
} patch to fix this?

Interesting.

schaefer<505> echo $[-9223372036854775808/-1]  
-9223372036854775808
schaefer<506> echo $[-9223372036854775809/-1]
zsh: number truncated after 18 digits: 9223372036854775809/-1
922337203685477580

No FPE in either case.

On May 7,  5:05pm, Jon Mayo wrote:
}
} perhaps scripts that care can just use a trap? and all my worrying was
} for nothing?

I'm having a hard time testing this because I can't get a mathematically
induced FPE, but recall that (quoting the doc):

   * The return status from function traps is special, whereas a return
     from a list trap causes the surrounding context to return with the
     given status.

So if you use

    trap 'return 1' FPE

you might avoid the infinite retry of the operation that Mikael reported.

-- 


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-08  2:46         ` Bart Schaefer
@ 2011-05-08  7:03           ` Jon Mayo
  0 siblings, 0 replies; 12+ messages in thread
From: Jon Mayo @ 2011-05-08  7:03 UTC (permalink / raw)
  To: Bart Schaefer, zsh workers

On Sat, May 7, 2011 at 7:46 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On May 7,  2:56pm, Jon Mayo wrote:
> }
> } echo $[-9223372036854775808/-1]
> }
> } this causes zsh to exit immediately with an FPE. Does anyone have a
> } patch to fix this?
>
> Interesting.
>
> schaefer<505> echo $[-9223372036854775808/-1]
> -9223372036854775808
> schaefer<506> echo $[-9223372036854775809/-1]
> zsh: number truncated after 18 digits: 9223372036854775809/-1
> 922337203685477580
>
> No FPE in either case.
>
> On May 7,  5:05pm, Jon Mayo wrote:
> }
> } perhaps scripts that care can just use a trap? and all my worrying was
> } for nothing?
>
> I'm having a hard time testing this because I can't get a mathematically
> induced FPE, but recall that (quoting the doc):
>
>   * The return status from function traps is special, whereas a return
>     from a list trap causes the surrounding context to return with the
>     given status.
>
> So if you use
>
>    trap 'return 1' FPE
>
> you might avoid the infinite retry of the operation that Mikael reported.
>
> --
>

nope, it spins with 100% cpu even on that one.

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2790 jon       20   0 40740 3292 1896 R  100  0.0   0:17.17 zsh

- Jon


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:27     ` Mikael Magnusson
  2011-05-07 23:48       ` Phil Pennock
  2011-05-08  0:05       ` Jon Mayo
@ 2011-05-08 17:33       ` Peter Stephenson
  2011-05-09 10:21       ` Vincent Lefevre
  3 siblings, 0 replies; 12+ messages in thread
From: Peter Stephenson @ 2011-05-08 17:33 UTC (permalink / raw)
  To: zsh workers

On Sun, 8 May 2011 00:27:30 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> >> +                    if (a.u.l == LONG_MIN && b.u.l == -1)
> >
> > should be LLONG_MIN
> >
> 
> It should probably be neither, zsh does some weird stuff to find a
> suitably long type for .l, which may or may not be a long long.

It needs a test in configure.ac where we check the type, around line
967, to check if LLONG_MIN and LLONG_MAX exist and if so define
ZSH_INT_MIN and ZSH_INT_MAX to those, and a bit later (after
the 64 bit stuff) if we didn't define them yet, test for LONG_MIN and
LONG_MAX and use those, otherwise (which shouldn't really happen) just
use some hackery with sizeof and shifts as a fallback (and perhaps print
a warning that we'd like to know about it).

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:27     ` Mikael Magnusson
                         ` (2 preceding siblings ...)
  2011-05-08 17:33       ` Peter Stephenson
@ 2011-05-09 10:21       ` Vincent Lefevre
  3 siblings, 0 replies; 12+ messages in thread
From: Vincent Lefevre @ 2011-05-09 10:21 UTC (permalink / raw)
  To: zsh-workers

On 2011-05-08 00:27:30 +0200, Mikael Magnusson wrote:
> This is assuming we want to do this at all,

One should have a well-defined behavior.

> I am told that only division will generate an exception on x86, but
> presumably other arches behave differently,

Perhaps, but this also depends on the compiler. The operation
LONG_MIN/(-1) has an undefined behavior in two's complement
because the result is not representable. So, it should be avoided.

> and bash behaves the same way too (exception + die). Does some sort
> of standard have anything to say on the matter? I'm guessing someone
> has thought of it before and clearly nobody ever did anything about
> it.

It seems that POSIX just says:

  If the expression is invalid, the expansion fails and the shell
  shall write a message to standard error indicating the failure.

The behavior doesn't seem to be explicitly specified when there is
an overflow, and may be covered by an extension to provide a valid
result (e.g. using floating-point). Otherwise I suppose that the
behavior should not be worse than an invalid expression, e.g. a
crash shouldn't occur.

At least zsh should behave in a consistent way. For instance,
$((0/0)) returns an error, so that it should be the same case
with the minimum integer divided by -1.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: SIGFPE crash
  2011-05-07 22:19   ` Jon Mayo
  2011-05-07 22:27     ` Mikael Magnusson
@ 2011-05-09 10:35     ` Vincent Lefevre
  1 sibling, 0 replies; 12+ messages in thread
From: Vincent Lefevre @ 2011-05-09 10:35 UTC (permalink / raw)
  To: zsh-workers

On 2011-05-07 15:19:43 -0700, Jon Mayo wrote:
> On Sat, May 7, 2011 at 3:17 PM, Mikael Magnusson <mikachu@gmail.com> wrote:
> > On 7 May 2011 23:56, Jon Mayo <jon.mayo@gmail.com> wrote:
> >> echo $[-9223372036854775808/-1]
> >>
> >> this causes zsh to exit immediately with an FPE. Does anyone have a
> >> patch to fix this?
> >
> > diff --git a/Src/math.c b/Src/math.c
> > index 35b362d..3c08052 100644
> > --- a/Src/math.c
> > +++ b/Src/math.c
> > @@ -1053,8 +1053,12 @@ op(int what)
> >                    return;
> >                if (c.type == MN_FLOAT)
> >                    c.u.d = a.u.d / b.u.d;
> > -               else
> > -                   c.u.l = a.u.l / b.u.l;
> > +               else {
> > +                    if (a.u.l == LONG_MIN && b.u.l == -1)
> 
> should be LLONG_MIN
> 
> > +                        c.u.l = 0;
> 
> LLONG_MAX would be the closest answer, but 1 off.

I think this would be very bad. "closest answer" makes sense in
floating-point arithmetic, but on the integers, one can have a
different metric, and zsh doesn't know the choice of the user.

> I would switch it from integer to double type in this case, but that
> might be difficult.

This wouldn't be consistent with the other cases of error, such
as overflows:

$ echo $((-9223372036854775808-1))
9223372036854775807

(the switch to floating-point would have given a different result,
which would be negative) or divisions by 0:

$ echo $((0/0))
zsh: division by zero

with exit status 1, instead of NaN.

IMHO, the best behavior would be an error "division overflow" with
exit status 1.

Note: the modular arithmetic can make sense with addition, subtraction
and multiplication (though an error may be safer), but not with the
division, so that returning LLONG_MIN would not be a good idea, IMHO.
Also, I haven't looked at the zsh code, but if zsh obtains modular
arithmetic by a side effect of the behavior of the processor, then
this is wrong: overflow on signed integer types is undefined behavior
in C (with GCC, you need the -fwrapv option if you want to support
modular arithmetic on signed integer types, otherwise one doesn't know
what optimizations will do).

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-05-09 10:35 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-07 21:56 SIGFPE crash Jon Mayo
2011-05-07 22:17 ` Mikael Magnusson
2011-05-07 22:19   ` Jon Mayo
2011-05-07 22:27     ` Mikael Magnusson
2011-05-07 23:48       ` Phil Pennock
2011-05-08  0:05       ` Jon Mayo
2011-05-08  0:10         ` Mikael Magnusson
2011-05-08  2:46         ` Bart Schaefer
2011-05-08  7:03           ` Jon Mayo
2011-05-08 17:33       ` Peter Stephenson
2011-05-09 10:21       ` Vincent Lefevre
2011-05-09 10:35     ` Vincent Lefevre

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).