Bugs in Erlang code

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Bugs in Erlang code

Kostis Sagonas-3
[ Apologies for the plug for Dialyzer, but I am currently quite excited. ]

  Intro: As part of Dialyzer, we have been developing a type
         analysis for Erlang that is significantly different
         that the one the current version of Dialyzer is using.
         It is not totally usable yet, but it is very powerful.
         Stay tuned for its release!


I am really amazed at some of the bugs we have been able to find
in supposedly well-tested Erlang code using the new type analysis.

Many of them, we've reported directly to the OTP team and they are
already fixed.  Some others we've finding every day as the analysis
gets stronger and stronger.  For example, today I've come across
the following code (in kernel/src/rpc.erl).

=======================================================================
yield(Key) when pid(Key) ->
    {value, R} = do_yield(Key, infinite),
    R.

nb_yield(Key, infinite) when pid(Key) ->
    do_yield(Key, infinite);
nb_yield(Key, Timeout) when pid(Key), integer(Timeout), Timeout >= 0 ->
    do_yield(Key, Timeout).

nb_yield(Key) when pid(Key) ->
    do_yield(Key, 0).

do_yield(Key, Timeout) ->
    receive
        {Key,{promise_reply,R}} ->
            {value,R}
        after Timeout ->
            timeout
    end.
=========================================================================

There are actually two (and arguably three) errors in the above code!

Dialyzer found them.

QUIZ for the seasoned Erlang programmers: Who can spot them?

Cheers,
Kostis



Reply | Threaded
Open this post in threaded view
|

Bugs in Erlang code

Alexey Shchepin-3
Hello, Kostis!

On Thu, 17 Mar 2005 01:14:39 +0100 (MET), you said:

 KS> I am really amazed at some of the bugs we have been able to find in
 KS> supposedly well-tested Erlang code using the new type analysis.

 KS> Many of them, we've reported directly to the OTP team and they are already
 KS> fixed.  Some others we've finding every day as the analysis gets stronger
 KS> and stronger.  For example, today I've come across the following code (in
 KS> kernel/src/rpc.erl).

 KS> =======================================================================
 KS> yield(Key) when pid(Key) ->
 KS>     {value, R} = do_yield(Key, infinite),
 KS>     R.

do_yield can return 'timeout', so there can be 'badmatch' error, and second
argument should be 'infinity'.

 KS>
 KS> nb_yield(Key, infinite) when pid(Key) ->
 KS>     do_yield(Key, infinite);

Again 'infinity'.

 KS> nb_yield(Key, Timeout) when pid(Key), integer(Timeout), Timeout >= 0 ->
 KS>     do_yield(Key, Timeout).
 KS>
 KS> nb_yield(Key) when pid(Key) ->
 KS>     do_yield(Key, 0).
 KS>
 KS> do_yield(Key, Timeout) ->
 KS>     receive
 KS>         {Key,{promise_reply,R}} ->
 KS>             {value,R}
 KS>         after Timeout ->
 KS>             timeout
 KS>     end.
 KS> =========================================================================

The rest looks ok for me.

 KS> There are actually two (and arguably three) errors in the above code!

 KS> Dialyzer found them.

 KS> QUIZ for the seasoned Erlang programmers: Who can spot them?



Reply | Threaded
Open this post in threaded view
|

Bugs in Erlang code

Luke Gorrie-3
In reply to this post by Kostis Sagonas-3
Kostis Sagonas <kostis> writes:

> QUIZ for the seasoned Erlang programmers: Who can spot them?

Interesting that bugs becomes obvious once you know they're there. I
don't even think it's knowing the bugs exist that makes them obvious,
it's just carefully reading the code - which one happens to rarely do
except when there's known to be an obscure bug.

I've got a stone-age dializer here:

  http://fresh.homeunix.net/~luke/misc/emacs/pbook.pdf
  http://fresh.homeunix.net/~luke/misc/emacs/pbook.el

It takes time to use but it's time well spent when I can afford to.




Reply | Threaded
Open this post in threaded view
|

Bugs in Erlang code

Raimo Niskanen-3
In reply to this post by Alexey Shchepin-3
If the second argument to do_yield is corrected to 'infinity' it will
not return 'timeout', I would say that is not a bug, just mere ugly.

So the bug is that 'infinity' is misspelled as 'infinite' in two places.

alexey (Alexey Shchepin) writes:

> Hello, Kostis!
>
> On Thu, 17 Mar 2005 01:14:39 +0100 (MET), you said:
>
>  KS> I am really amazed at some of the bugs we have been able to find in
>  KS> supposedly well-tested Erlang code using the new type analysis.
>
>  KS> Many of them, we've reported directly to the OTP team and they are already
>  KS> fixed.  Some others we've finding every day as the analysis gets stronger
>  KS> and stronger.  For example, today I've come across the following code (in
>  KS> kernel/src/rpc.erl).
>
>  KS> =======================================================================
>  KS> yield(Key) when pid(Key) ->
>  KS>     {value, R} = do_yield(Key, infinite),
>  KS>     R.
>
> do_yield can return 'timeout', so there can be 'badmatch' error, and second
> argument should be 'infinity'.
>
>  KS>
>  KS> nb_yield(Key, infinite) when pid(Key) ->
>  KS>     do_yield(Key, infinite);
>
> Again 'infinity'.
>
>  KS> nb_yield(Key, Timeout) when pid(Key), integer(Timeout), Timeout >= 0 ->
>  KS>     do_yield(Key, Timeout).
>  KS>
>  KS> nb_yield(Key) when pid(Key) ->
>  KS>     do_yield(Key, 0).
>  KS>
>  KS> do_yield(Key, Timeout) ->
>  KS>     receive
>  KS>         {Key,{promise_reply,R}} ->
>  KS>             {value,R}
>  KS>         after Timeout ->
>  KS>             timeout
>  KS>     end.
>  KS> =========================================================================
>
> The rest looks ok for me.
>
>  KS> There are actually two (and arguably three) errors in the above code!
>
>  KS> Dialyzer found them.
>
>  KS> QUIZ for the seasoned Erlang programmers: Who can spot them?
>

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


Reply | Threaded
Open this post in threaded view
|

Bugs in Erlang code

Björn Gustavsson-3
In reply to this post by Kostis Sagonas-3
Thanks!

I have written the missing test cases for async_call/4 and friends,
and corrected the two bugs ("infinity" instead of "infinite").

Matching against {value,R} in yield/1 is not a bug, since
do_yield(Key, Atom) cannot return anything else than {value,R}
(or crash if Atom is not infinity).

/Bjorn

P.S. Here is the updated code (which will be included in R10B-4).

yield(Key) when is_pid(Key) ->
    {value,R} = do_yield(Key, infinity),
    R.

nb_yield(Key, infinity=Inf) when is_pid(Key) ->
    do_yield(Key, Inf);
nb_yield(Key, Timeout) when is_pid(Key), is_integer(Timeout), Timeout >= 0 ->
    do_yield(Key, Timeout).

nb_yield(Key) when is_pid(Key) ->
    do_yield(Key, 0).

do_yield(Key, Timeout) ->
    receive
        {Key,{promise_reply,R}} ->
            {value,R}
        after Timeout ->
            timeout
    end.



Kostis Sagonas <kostis> writes:

> [ Apologies for the plug for Dialyzer, but I am currently quite excited. ]
>
>   Intro: As part of Dialyzer, we have been developing a type
> analysis for Erlang that is significantly different
> that the one the current version of Dialyzer is using.
> It is not totally usable yet, but it is very powerful.
> Stay tuned for its release!
>
>
> I am really amazed at some of the bugs we have been able to find
> in supposedly well-tested Erlang code using the new type analysis.
>
> Many of them, we've reported directly to the OTP team and they are
> already fixed.  Some others we've finding every day as the analysis
> gets stronger and stronger.  For example, today I've come across
> the following code (in kernel/src/rpc.erl).
>
> =======================================================================
> yield(Key) when pid(Key) ->
>     {value, R} = do_yield(Key, infinite),
>     R.
>
> nb_yield(Key, infinite) when pid(Key) ->
>     do_yield(Key, infinite);
> nb_yield(Key, Timeout) when pid(Key), integer(Timeout), Timeout >= 0 ->
>     do_yield(Key, Timeout).
>
> nb_yield(Key) when pid(Key) ->
>     do_yield(Key, 0).
>
> do_yield(Key, Timeout) ->
>     receive
>         {Key,{promise_reply,R}} ->
>             {value,R}
>         after Timeout ->
>             timeout
>     end.
> =========================================================================
>
> There are actually two (and arguably three) errors in the above code!
>
> Dialyzer found them.
>
> QUIZ for the seasoned Erlang programmers: Who can spot them?
>
> Cheers,
> Kostis
>

--
Bj?rn Gustavsson, Erlang/OTP, Ericsson AB