catch link(Pid) when trapping exits

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

catch link(Pid) when trapping exits

Francesco Mazzoli-2
In a process trapping exists,

catch link(Pid)

of a non existing pid returns true. If we are not trapping exists, the
return value is {'EXIT', {noproc, .....}}

Looking into this "feature", my guess is that executing exit(Pid,
Reason) when trapping exists returns true. I would however expect the
same behavior in both cases, however....

11> catch exit(hello).
{'EXIT',hello}
12> catch exit(self(), hello).
true
13> flush().
Shell got {'EXIT',<0.44.0>,hello}
ok

Is this a bug or a feature?

Francesco
--
http://www.erlang-consulting.com



Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Raimo Niskanen-3
francesco (Francesco Cesarini Erlang Training & Consulting) writes:

> In a process trapping exists,
>
> catch link(Pid)
>
> of a non existing pid returns true. If we are not trapping exists, the
> return value is {'EXIT', {noproc, .....}}
>

>From erl -man erlang:

    link(Pid) -> true

          Types
               Pid = pid() | port()

          Creates a link between the calling process and  another
          process  (or  port)  Pid,  if  there is not such a link
          already. If a process attempts  to  create  a  link  to
          itself, nothing is done. Returns true.

          Does not fail, but sends an  exit  signal  with  reason
          noproc  to  the  calling process if Pid does not exist.
          This means that, unless the calling process is trapping
          exits (see process_flag/2), it will exit if it tries to
          link to a non-existing process.

It is all there, really. Only it was written before exceptions
were invented as a concept in Erlang, uses the term
"exit signal" in a confusing way and lies about "does not fail".
Ok, it is maybe dead wrong, but the intention was right.
So, what happens is:

link(Pid) -> true           if Pid exists or the caller has
                            process_flag(trap_exit, true).
             error(noproc)  otherwise

The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
for error(noproc).            

Weird behaviour, in my opinion..

> Looking into this "feature", my guess is that executing exit(Pid,
> Reason) when trapping exists returns true. I would however expect the
> same behavior in both cases, however....
>
> 11> catch exit(hello).
> {'EXIT',hello}
> 12> catch exit(self(), hello).
> true
> 13> flush().
> Shell got {'EXIT',<0.44.0>,hello}
> ok
>
> Is this a bug or a feature?
>

This is a feature.

exit/1 causes an exception of class 'exit' in the calling process,
       which when enclosed in a catch evaluates to
       {'EXIT',Reason} - no stacktrace since it is of class 'exit'.

exit/2 sends an exit signal to the target process. And if
       the target process (self()) traps exits, it becomes
       a regular message.

> Francesco
> --
> http://www.erlang-consulting.com
>

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Francesco Mazzoli-2
> It is all there, really. Only it was written before exceptions
> were invented as a concept in Erlang, uses the term
> "exit signal" in a confusing way and lies about "does not fail".
> Ok, it is maybe dead wrong, but the intention was right.
> So, what happens is:
>
> link(Pid) -> true           if Pid exists or the caller has
>                             process_flag(trap_exit, true).
>              error(noproc)  otherwise
>
> The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
> for error(noproc).            
>
> Weird behaviour, in my opinion..

Exactly my point. Would it not be better to return error(noproc) even if
trapping exits instead of exit(Pid, Reason)?

Francesco
--
http://www.erlang-consulting.com



Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Raimo Niskanen-3
In reply to this post by Raimo Niskanen-3
Raimo Niskanen <raimo> writes:

Alright, that was only almost right:

link(Pid) -> error(noproc) if Pid is local and does not exist and
                           caller has process_flag(trap_exit, false)
             true          otherwise

And if the Pid dies, or even was remote and did not exist
(those cases can not be discriminated), the caller will get
an exit signal that can be converted to a regular message
with process_flag(trap_exit, true).

Let us see how long this explanation holds together...

> francesco (Francesco Cesarini Erlang Training & Consulting) writes:
>
> > In a process trapping exists,
> >
> > catch link(Pid)
> >
> > of a non existing pid returns true. If we are not trapping exists, the
> > return value is {'EXIT', {noproc, .....}}
> >
>
> From erl -man erlang:
>
>     link(Pid) -> true
>
>           Types
>                Pid = pid() | port()
>
>           Creates a link between the calling process and  another
>           process  (or  port)  Pid,  if  there is not such a link
>           already. If a process attempts  to  create  a  link  to
>           itself, nothing is done. Returns true.
>
>           Does not fail, but sends an  exit  signal  with  reason
>           noproc  to  the  calling process if Pid does not exist.
>           This means that, unless the calling process is trapping
>           exits (see process_flag/2), it will exit if it tries to
>           link to a non-existing process.
>
> It is all there, really. Only it was written before exceptions
> were invented as a concept in Erlang, uses the term
> "exit signal" in a confusing way and lies about "does not fail".
> Ok, it is maybe dead wrong, but the intention was right.
> So, what happens is:
>
> link(Pid) -> true           if Pid exists or the caller has
>                             process_flag(trap_exit, true).
>              error(noproc)  otherwise
>
> The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
> for error(noproc).            
>
> Weird behaviour, in my opinion..
>
> > Looking into this "feature", my guess is that executing exit(Pid,
> > Reason) when trapping exists returns true. I would however expect the
> > same behavior in both cases, however....
> >
> > 11> catch exit(hello).
> > {'EXIT',hello}
> > 12> catch exit(self(), hello).
> > true
> > 13> flush().
> > Shell got {'EXIT',<0.44.0>,hello}
> > ok
> >
> > Is this a bug or a feature?
> >
>
> This is a feature.
>
> exit/1 causes an exception of class 'exit' in the calling process,
>        which when enclosed in a catch evaluates to
>        {'EXIT',Reason} - no stacktrace since it is of class 'exit'.
>
> exit/2 sends an exit signal to the target process. And if
>        the target process (self()) traps exits, it becomes
>        a regular message.
>
> > Francesco
> > --
> > http://www.erlang-consulting.com
> >
>
> --
>
> / Raimo Niskanen, Erlang/OTP, Ericsson AB

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Raimo Niskanen-3
In reply to this post by Francesco Mazzoli-2
francesco (Francesco Cesarini Erlang Training & Consulting) writes:

Yes it would.

Even better would be to never do error(noproc) but always
let a failing link send the exit signal even if the process
does not exist at the time of the call to link(Pid).

As always - it can not be changed now due to the
Backwards Compatibility Ghost.

> > It is all there, really. Only it was written before exceptions
> > were invented as a concept in Erlang, uses the term
> > "exit signal" in a confusing way and lies about "does not fail".
> > Ok, it is maybe dead wrong, but the intention was right.
> > So, what happens is:
> > link(Pid) -> true           if Pid exists or the caller has
> >                             process_flag(trap_exit, true).
> >              error(noproc)  otherwise
> > The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
> > for error(noproc).             Weird behaviour, in my opinion..
>
> Exactly my point. Would it not be better to return error(noproc) even
> if trapping exits instead of exit(Pid, Reason)?
>
> Francesco
> --
> http://www.erlang-consulting.com
>

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Robert Virding-5
In reply to this post by Francesco Mazzoli-2
No, no, no it should definitely NOT return error(noproc).

The reason is that the whole process communication mechanism, including
links, was originally designed to be asynchronous on the sending side.
Sending a message is asychronous, ou don't wait in the send to find out
if it arrived. Link/1 works the same way. The call does not wait until
the link is set up but just sends the request and continues. If the
process does not exist the caller is notified by a noproc exit signal
from the non-existent process (yes I know but from who else could it
receive it?).

The important point is that in bothe cases the call is asynchronous.
This also means, mostly importantly, that both calls function the same
way irrespective of whether the other process is local or remote. This
was also an original goal.

If this has significantly changed since then then someone has missed the
original intentions.

Robert


Francesco Cesarini (Erlang Training & Consulting) wrote:

>> It is all there, really. Only it was written before exceptions
>> were invented as a concept in Erlang, uses the term
>> "exit signal" in a confusing way and lies about "does not fail".
>> Ok, it is maybe dead wrong, but the intention was right.
>> So, what happens is:
>>
>> link(Pid) -> true           if Pid exists or the caller has
>>                             process_flag(trap_exit, true).
>>              error(noproc)  otherwise
>>
>> The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
>> for error(noproc).            
>> Weird behaviour, in my opinion..
>
>
> Exactly my point. Would it not be better to return error(noproc) even
> if trapping exits instead of exit(Pid, Reason)?
>
> Francesco
> --
> http://www.erlang-consulting.com
>
>


Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Raimo Niskanen-3
robert.virding (Robert Virding) writes:

I have dug into the archives...

This was introduced fairly recently, in R9B, in conjunction
with the rewrite for more than 255 remote nodes.

We will look into this and decide what to do.

> No, no, no it should definitely NOT return error(noproc).
>
> The reason is that the whole process communication mechanism,
> including links, was originally designed to be asynchronous on the
> sending side. Sending a message is asychronous, ou don't wait in the
> send to find out if it arrived. Link/1 works the same way. The call
> does not wait until the link is set up but just sends the request and
> continues. If the process does not exist the caller is notified by a
> noproc exit signal from the non-existent process (yes I know but from
> who else could it receive it?).
>
> The important point is that in bothe cases the call is
> asynchronous. This also means, mostly importantly, that both calls
> function the same way irrespective of whether the other process is
> local or remote. This was also an original goal.
>
> If this has significantly changed since then then someone has missed
> the original intentions.
>
> Robert
>
>
> Francesco Cesarini (Erlang Training & Consulting) wrote:
>
> >> It is all there, really. Only it was written before exceptions
> >> were invented as a concept in Erlang, uses the term
> >> "exit signal" in a confusing way and lies about "does not fail".
> >> Ok, it is maybe dead wrong, but the intention was right.
> >> So, what happens is:
> >>
> >> link(Pid) -> true           if Pid exists or the caller has
> >>                             process_flag(trap_exit, true).
> >>              error(noproc)  otherwise
> >>
> >> The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
> >> for error(noproc).            Weird behaviour, in my opinion..
> >
> >
> > Exactly my point. Would it not be better to return error(noproc)
> > even if trapping exits instead of exit(Pid, Reason)?
> >
> > Francesco
> > --
> > http://www.erlang-consulting.com
> >
> >

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Rickard Green-4
No, this behavior was there before R9B, e.g. R5B01:

/usr/local/otp/releases/otp_beam_sunos5_r5b01_patched/bin/erl
Erlang (BEAM) emulator version 4.8.2.8

Eshell V4.8.2.8  (abort with ^G)
1> catch link(pid(0,1234,0)).
{'EXIT',{noproc,{shell,evaluator,[link,[<0.1234.0>]]}}}
2> process_flag(trap_exit,true).
false
3> catch link(pid(0,1234,0)).
true
4> flush().
Shell got {'EXIT',<0.1234.0>,noproc}
ok
5>

It was introduced before OTP. I had a quick look at the R1 code and it
was present there too.

Regards,
Rickard Green, Erlang/OTP

Raimo Niskanen wrote:

> robert.virding (Robert Virding) writes:
>
> I have dug into the archives...
>
> This was introduced fairly recently, in R9B, in conjunction
> with the rewrite for more than 255 remote nodes.
>
> We will look into this and decide what to do.
>
>
>>No, no, no it should definitely NOT return error(noproc).
>>
>>The reason is that the whole process communication mechanism,
>>including links, was originally designed to be asynchronous on the
>>sending side. Sending a message is asychronous, ou don't wait in the
>>send to find out if it arrived. Link/1 works the same way. The call
>>does not wait until the link is set up but just sends the request and
>>continues. If the process does not exist the caller is notified by a
>>noproc exit signal from the non-existent process (yes I know but from
>>who else could it receive it?).
>>
>>The important point is that in bothe cases the call is
>>asynchronous. This also means, mostly importantly, that both calls
>>function the same way irrespective of whether the other process is
>>local or remote. This was also an original goal.
>>
>>If this has significantly changed since then then someone has missed
>>the original intentions.
>>
>>Robert
>>
>>
>>Francesco Cesarini (Erlang Training & Consulting) wrote:
>>
>>
>>>>It is all there, really. Only it was written before exceptions
>>>>were invented as a concept in Erlang, uses the term
>>>>"exit signal" in a confusing way and lies about "does not fail".
>>>>Ok, it is maybe dead wrong, but the intention was right.
>>>>So, what happens is:
>>>>
>>>>link(Pid) -> true           if Pid exists or the caller has
>>>>                            process_flag(trap_exit, true).
>>>>             error(noproc)  otherwise
>>>>
>>>>The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
>>>>for error(noproc).            Weird behaviour, in my opinion..
>>>
>>>
>>>Exactly my point. Would it not be better to return error(noproc)
>>>even if trapping exits instead of exit(Pid, Reason)?
>>>
>>>Francesco
>>>--
>>>http://www.erlang-consulting.com
>>>
>>>
>
>



Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Robert Virding-5
In reply to this post by Raimo Niskanen-3
You have made a modification which goes against fundamental principle
(asynchronous message passing and transparency of local remote
processes) of the process communication mechanism. We, Joe, Mike and I,
probably never wrote down the priinciples but they were there. Although
sometimes we aourselves weren't completely consistent either (registered
processes).

Robert

Raimo Niskanen wrote:

>robert.virding (Robert Virding) writes:
>
>I have dug into the archives...
>
>This was introduced fairly recently, in R9B, in conjunction
>with the rewrite for more than 255 remote nodes.
>
>We will look into this and decide what to do.
>
>  
>
>>No, no, no it should definitely NOT return error(noproc).
>>
>>The reason is that the whole process communication mechanism,
>>including links, was originally designed to be asynchronous on the
>>sending side. Sending a message is asychronous, ou don't wait in the
>>send to find out if it arrived. Link/1 works the same way. The call
>>does not wait until the link is set up but just sends the request and
>>continues. If the process does not exist the caller is notified by a
>>noproc exit signal from the non-existent process (yes I know but from
>>who else could it receive it?).
>>
>>The important point is that in bothe cases the call is
>>asynchronous. This also means, mostly importantly, that both calls
>>function the same way irrespective of whether the other process is
>>local or remote. This was also an original goal.
>>
>>If this has significantly changed since then then someone has missed
>>the original intentions.
>>
>>Robert
>>
>>
>>Francesco Cesarini (Erlang Training & Consulting) wrote:
>>
>>    
>>
>>>>It is all there, really. Only it was written before exceptions
>>>>were invented as a concept in Erlang, uses the term
>>>>"exit signal" in a confusing way and lies about "does not fail".
>>>>Ok, it is maybe dead wrong, but the intention was right.
>>>>So, what happens is:
>>>>
>>>>link(Pid) -> true           if Pid exists or the caller has
>>>>                            process_flag(trap_exit, true).
>>>>             error(noproc)  otherwise
>>>>
>>>>The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
>>>>for error(noproc).            Weird behaviour, in my opinion..
>>>>        
>>>>
>>>Exactly my point. Would it not be better to return error(noproc)
>>>even if trapping exits instead of exit(Pid, Reason)?
>>>
>>>Francesco
>>>--
>>>http://www.erlang-consulting.com
>>>
>>>
>>>      
>>>
>
>  
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20051030/8e04c05f/attachment.html>

Reply | Threaded
Open this post in threaded view
|

catch link(Pid) when trapping exits

Raimo Niskanen-3
In reply to this post by Rickard Green-4
Sorry, I read the source wrong. Should have tried instead.
It is an old behaviour.

rickard.s.green (Rickard Green) writes:

> No, this behavior was there before R9B, e.g. R5B01:
>
> /usr/local/otp/releases/otp_beam_sunos5_r5b01_patched/bin/erl
> Erlang (BEAM) emulator version 4.8.2.8
>
> Eshell V4.8.2.8  (abort with ^G)
> 1> catch link(pid(0,1234,0)).
> {'EXIT',{noproc,{shell,evaluator,[link,[<0.1234.0>]]}}}
> 2> process_flag(trap_exit,true).
> false
> 3> catch link(pid(0,1234,0)).
> true
> 4> flush().
> Shell got {'EXIT',<0.1234.0>,noproc}
> ok
> 5>
>
> It was introduced before OTP. I had a quick look at the R1 code and it
> was present there too.
>
> Regards,
> Rickard Green, Erlang/OTP
>
> Raimo Niskanen wrote:
> > robert.virding (Robert Virding) writes:
> > I have dug into the archives...
> > This was introduced fairly recently, in R9B, in conjunction
> > with the rewrite for more than 255 remote nodes.
> > We will look into this and decide what to do.
> >
> >>No, no, no it should definitely NOT return error(noproc).
> >>
> >>The reason is that the whole process communication mechanism,
> >>including links, was originally designed to be asynchronous on the
> >>sending side. Sending a message is asychronous, ou don't wait in the
> >>send to find out if it arrived. Link/1 works the same way. The call
> >>does not wait until the link is set up but just sends the request and
> >>continues. If the process does not exist the caller is notified by a
> >>noproc exit signal from the non-existent process (yes I know but from
> >>who else could it receive it?).
> >>
> >>The important point is that in bothe cases the call is
> >>asynchronous. This also means, mostly importantly, that both calls
> >>function the same way irrespective of whether the other process is
> >>local or remote. This was also an original goal.
> >>
> >>If this has significantly changed since then then someone has missed
> >>the original intentions.
> >>
> >>Robert
> >>
> >>
> >>Francesco Cesarini (Erlang Training & Consulting) wrote:
> >>
> >>
> >>>>It is all there, really. Only it was written before exceptions
> >>>>were invented as a concept in Erlang, uses the term
> >>>>"exit signal" in a confusing way and lies about "does not fail".
> >>>>Ok, it is maybe dead wrong, but the intention was right.
> >>>>So, what happens is:
> >>>>
> >>>>link(Pid) -> true           if Pid exists or the caller has
> >>>>                            process_flag(trap_exit, true).
> >>>>             error(noproc)  otherwise
> >>>>
> >>>>The enclosing catch evaluates to {'EXIT',{noproc,Stackdump}}
> >>>>for error(noproc).            Weird behaviour, in my opinion..
> >>>
> >>>
> >>>Exactly my point. Would it not be better to return error(noproc)
> >>>even if trapping exits instead of exit(Pid, Reason)?
> >>>
> >>>Francesco
> >>> --
> >>>http://www.erlang-consulting.com
> >>>
> >>>
> >
>

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB