How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

marcel.taeumel
Hi, all.

Try this (on a Windows machine?):

v := [^ true].
v value.

A debugger appears with BlockCannotReturn. Try proceed. The VM will crash. My image is 4.6, but it also happens 4.5 with a #2776 CogVM. ...and also in Squeak 3.9 with an interpreter VM. However in 3.9, I can hit proceed at least once--the second click crashes the VM.

Why's that?

Best,
Marcel
Reply | Threaded
Open this post in threaded view
|

Re: How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

Eliot Miranda-2
Hi Marcel,

On Thu, Jun 25, 2015 at 5:45 AM, marcel.taeumel <[hidden email]> wrote:
Hi, all.

Try this (on a Windows machine?):

v := [^ true].
v value.

A debugger appears with BlockCannotReturn. Try proceed. The VM will crash.
My image is 4.6, but it also happens 4.5 with a #2776 CogVM. ...and also in
Squeak 3.9 with an interpreter VM. However in 3.9, I can hit proceed at
least once--the second click crashes the VM.

I've just tried this with VMMaker.oscog-eem.1370/r3386 VMs in an updated trunk Squeak 4.5 (non Spur) image and a Spur image and see nothing wrong.  Are you not missing something from the expression?  I can't see how the above would produce a cannot return; the mehtod returnds via the ^-return in the block.  But that's fine, and should be equivalent to [^true] value.


Why's that?

Best,
Marcel



--
View this message in context: http://forum.world.st/How-to-crash-CogVM-or-InterpreterVM-while-debugging-BlockCannotReturn-tp4834042.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.




--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

marcel.taeumel
You have to execute one statement after the other, not both in the same do-it. It is just an example for the BlockCannotReturn error.

I am bothering with the VM crash when proceeding such an error.

Best,
Marcel
Reply | Threaded
Open this post in threaded view
|

Re: How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

Eliot Miranda-2
In reply to this post by marcel.taeumel
Hi Marcel,

On Thu, Jun 25, 2015 at 5:45 AM, marcel.taeumel <[hidden email]> wrote:
Hi, all.

Try this (on a Windows machine?):

v := [^ true].
v value.

A debugger appears with BlockCannotReturn. Try proceed. The VM will crash.
My image is 4.6, but it also happens 4.5 with a #2776 CogVM. ...and also in
Squeak 3.9 with an interpreter VM. However in 3.9, I can hit proceed at
least once--the second click crashes the VM.

Why's that?

It's because the pc is left pointing at the bytecode following the return, not the return itself, so when one proceeds one starts to execute random code.  If you try the same thing in the TackInterpreter you can proceed without crashing the VM but executing the method produces (when I tried it) an MNU form sending the message selector 3 (the Integer 3) to nil.l  This is because the VM was executing the trailer bytes of the method.

Here's the bytecode for the method:

17 <8F 00 00 01> closureNumCopied: 0 numArgs: 0 bytes 21 to 21
21 <79> return: true
22 <81 C0> storeIntoLit: v
24 <7C> returnTop

When the cannot return is raised, the block activation's pc ends up being 22, /not/ 21.  So when one proceeds the VM executes the storeIntoLit:, which is bad because there isn't even anything on the stack to store.  So chaos ensues.

David, what's the pc in an Interpreter VM?

There are two solutions I can think of.  One is to leave the pc positioned at the return, and one is to have the proceed machinery check that the bytecode pc is valid and not proceed if it isn't.  I prefer the latter.  Adding support for the former requires more metadata to be generated in methods and hacks to the pc mapping machinery which usually deals with addresses immediately after something (e.g. a send is mapped at the return address for the send, the instruction following the call of the send).  It's pretty clear that the proceed attept is bogus here and the image could easily cause an error.  e.g.

self embeddedBlockClosures collect: [:ea| ea startpc -> ea endPC] an OrderedCollection(21->21)
self initialPC -> self endPC 17->24

And so it's easy to check whether a context's pc is in range before proceeding.
 

Best,
Marcel



--
View this message in context: http://forum.world.st/How-to-crash-CogVM-or-InterpreterVM-while-debugging-BlockCannotReturn-tp4834042.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.




--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

Eliot Miranda-2


On Fri, Jun 26, 2015 at 9:10 PM, Eliot Miranda <[hidden email]> wrote:
Hi Marcel,

On Thu, Jun 25, 2015 at 5:45 AM, marcel.taeumel <[hidden email]> wrote:
Hi, all.

Try this (on a Windows machine?):

v := [^ true].
v value.

A debugger appears with BlockCannotReturn. Try proceed. The VM will crash.
My image is 4.6, but it also happens 4.5 with a #2776 CogVM. ...and also in
Squeak 3.9 with an interpreter VM. However in 3.9, I can hit proceed at
least once--the second click crashes the VM.

Why's that?

It's because the pc is left pointing at the bytecode following the return, not the return itself, so when one proceeds one starts to execute random code.  If you try the same thing in the TackInterpreter you can proceed without crashing the VM but executing the method produces (when I tried it) an MNU form sending the message selector 3 (the Integer 3) to nil.l  This is because the VM was executing the trailer bytes of the method.

Here's the bytecode for the method:

17 <8F 00 00 01> closureNumCopied: 0 numArgs: 0 bytes 21 to 21
21 <79> return: true
22 <81 C0> storeIntoLit: v
24 <7C> returnTop

When the cannot return is raised, the block activation's pc ends up being 22, /not/ 21.  So when one proceeds the VM executes the storeIntoLit:, which is bad because there isn't even anything on the stack to store.  So chaos ensues.

David, what's the pc in an Interpreter VM?

There are two solutions I can think of.  One is to leave the pc positioned at the return, and one is to have the proceed machinery check that the bytecode pc is valid and not proceed if it isn't.  I prefer the latter.  Adding support for the former requires more metadata to be generated in methods and hacks to the pc mapping machinery which usually deals with addresses immediately after something (e.g. a send is mapped at the return address for the send, the instruction following the call of the send).

Actually I don't think I'm on track here.  In fact, the return bytecode has been dispatched and raised an error while it is executing.  So the pc being positioned after the return is correct.  In fact, I think the interpreter will have the pc positioned after the return also.  Hence the Cogit would be wrong to try and map the address following the non-local retrn to the return itself.  In fact, leaving the pc where it is now is correct.  One *could* change the VM spec and require the VM to back up the pc in this case.  But its a lot of effort to add to the VM (bytecodes are variable length; certain returns are compounds, push value, return top).  I think the right thing to do is have the image check for a valid pc before proceeding.  The VM has raised the error correctly.  Why burden it with dealing with a situation that shouldn't happen?  Patient: "Doctor, it hurts when I proceed after a cannot return!".  Doctor: "Don't do that.".

  It's pretty clear that the proceed attept is bogus here and the image could easily cause an error.  e.g.

self embeddedBlockClosures collect: [:ea| ea startpc -> ea endPC] an OrderedCollection(21->21)
self initialPC -> self endPC 17->24

And so it's easy to check whether a context's pc is in range before proceeding.
 

Best,
Marcel



--
View this message in context: http://forum.world.st/How-to-crash-CogVM-or-InterpreterVM-while-debugging-BlockCannotReturn-tp4834042.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.




--
best,
Eliot



--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: How to crash CogVM or InterpreterVM while debugging BlockCannotReturn

Karl Ramberg


On Sat, Jun 27, 2015 at 6:21 AM, Eliot Miranda <[hidden email]> wrote:


On Fri, Jun 26, 2015 at 9:10 PM, Eliot Miranda <[hidden email]> wrote:
Hi Marcel,

On Thu, Jun 25, 2015 at 5:45 AM, marcel.taeumel <[hidden email]> wrote:
Hi, all.

Try this (on a Windows machine?):

v := [^ true].
v value.

A debugger appears with BlockCannotReturn. Try proceed. The VM will crash.
My image is 4.6, but it also happens 4.5 with a #2776 CogVM. ...and also in
Squeak 3.9 with an interpreter VM. However in 3.9, I can hit proceed at
least once--the second click crashes the VM.

Why's that?

It's because the pc is left pointing at the bytecode following the return, not the return itself, so when one proceeds one starts to execute random code.  If you try the same thing in the TackInterpreter you can proceed without crashing the VM but executing the method produces (when I tried it) an MNU form sending the message selector 3 (the Integer 3) to nil.l  This is because the VM was executing the trailer bytes of the method.

Here's the bytecode for the method:

17 <8F 00 00 01> closureNumCopied: 0 numArgs: 0 bytes 21 to 21
21 <79> return: true
22 <81 C0> storeIntoLit: v
24 <7C> returnTop

When the cannot return is raised, the block activation's pc ends up being 22, /not/ 21.  So when one proceeds the VM executes the storeIntoLit:, which is bad because there isn't even anything on the stack to store.  So chaos ensues.

David, what's the pc in an Interpreter VM?

There are two solutions I can think of.  One is to leave the pc positioned at the return, and one is to have the proceed machinery check that the bytecode pc is valid and not proceed if it isn't.  I prefer the latter.  Adding support for the former requires more metadata to be generated in methods and hacks to the pc mapping machinery which usually deals with addresses immediately after something (e.g. a send is mapped at the return address for the send, the instruction following the call of the send).

Actually I don't think I'm on track here.  In fact, the return bytecode has been dispatched and raised an error while it is executing.  So the pc being positioned after the return is correct.  In fact, I think the interpreter will have the pc positioned after the return also.  Hence the Cogit would be wrong to try and map the address following the non-local retrn to the return itself.  In fact, leaving the pc where it is now is correct.  One *could* change the VM spec and require the VM to back up the pc in this case.  But its a lot of effort to add to the VM (bytecodes are variable length; certain returns are compounds, push value, return top).  I think the right thing to do is have the image check for a valid pc before proceeding.  The VM has raised the error correctly.  Why burden it with dealing with a situation that shouldn't happen?  Patient: "Doctor, it hurts when I proceed after a cannot return!".  Doctor: "Don't do that.".

+1
Seems like the most sane thing to do here.

Karl 

  It's pretty clear that the proceed attept is bogus here and the image could easily cause an error.  e.g.

self embeddedBlockClosures collect: [:ea| ea startpc -> ea endPC] an OrderedCollection(21->21)
self initialPC -> self endPC 17->24

And so it's easy to check whether a context's pc is in range before proceeding.
 

Best,
Marcel



--
View this message in context: http://forum.world.st/How-to-crash-CogVM-or-InterpreterVM-while-debugging-BlockCannotReturn-tp4834042.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.




--
best,
Eliot



--
best,
Eliot