<html><head>
<style id="css_styles">blockquote.cite { margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc }
blockquote.cite2 {margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc; margin-top: 3px; padding-top: 0px; }
a img { border: 0px; }
li[style='text-align: center;'], li[style='text-align: center; '], li[style='text-align: right;'], li[style='text-align: right; '] { list-style-position: inside;}
body { font-family: 'Segoe UI'; font-size: 12pt; }
.quote { margin-left: 1em; margin-right: 1em; border-left: 5px #ebebeb solid; padding-left: 0.3em; }
blockquote.cite { margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc }
blockquote.cite2 {margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc; margin-top: 3px; padding-top: 0px; }
a img { border: 0px; }
li[style='text-align: center;'], li[style='text-align: center; '], li[style='text-align: right;'], li[style='text-align: right; '] { list-style-position: inside;}
body { font-family: 'Segoe UI'; font-size: 12pt; }
.quote { margin-left: 1em; margin-right: 1em; border-left: 5px #ebebeb solid; padding-left: 0.3em; }
</style>
</head>
<body><div>Hi Juan,
all,</div><div><br /></div><div>Question: Was there a particular reason for this definition:
</div><div>```
</div><div>suspendedContext
</div><div> "Answer the context the receiver has suspended.
</div><div> I am Ready to Run or Suspended. Answer the context I was running when last preempted.
</div><div><br /></div><div> Otherwise, (Running or Terminated) answer nil."
</div><div><br /></div><div> ^self isTerminated ifFalse: [ suspendedContext ]
</div><div>```
</div><div>instead of using the simple original:
</div><div>```
</div><div>suspendedContext
</div><div> "Answer the context the receiver has suspended."
</div><div><br /></div><div> ^suspendedContext
</div><div>```
</div><div><br /></div><div>The reason I'm asking is it messes up with debugging some edge case scenarios I've been working on:
</div><div><br /></div><div>With Eliot we've fixed VM crashes when running e.g.
</div><div><br /></div><div> [[^ 1] on: BlockCannotReturn do: [:ex | ex resume] ] fork
</div><div><br /></div><div>However, even after fixing the crashes the debugging of this scenario remained broken. I've identified the root cause in an incorrect simulation of returns in #return:from:. The fix is enclosed, but the debugging in Cuis still fails in some cases - e.g. if you debug the following example and just keep stepping over until a nonsensical error appears.
</div><div><br /></div><div> [[self halt. ^ 1] on: BlockCannotReturn do: [:ex | ex resume] ] fork
</div><div><br /></div><div>And here I've tracked the root cause to your version of #suspendedContext. It answers nil for a terminated process but a process may be terminated yet a sender's context chain still hanging there; by nilling the suspended context you lose that information and the debugging fails.
</div><div><br /></div><div>I've included the "original" simple version of #suspendedContext in the enclosed changeset but feel free to make any changes, of course.
</div><div><br /></div><div>Now debugging of the example works fine for any of stepping over, through or into.
</div><div><br /></div><div>Explanation of the #return:from: bug:
</div><div>Previously the method allowed returning to a dead or nil context, and, in addition, didn't nil the context that can't be returned to. These are two independent bugs. The VM doesn't allow such returns and does nil the context.
</div><div><br /></div><div>Fixing #return:from:, however, changes (i.e. fixes) the (incorrect) semantics of some other simulation methods: #stepToCallee won't return to a dead or nil sender now and the same goes for #step. There are cases where this incorrect bahavior has been (mis)used, e.g. in #runUntilErrorOrReturnFrom:
</div><div><br /></div><div>In order to fix this the easiest possible way I've created a version of #stepToCallee fulfilling this incorrect expectation - see #stepToCalleeOrNil. Ideally, I think, the use of #stepToCalleeOrNil in #runUntilErrorOrReturnFrom should be replaced with a "standard" (as opposed to a "simulation") code, e.g. using #releaseTo:, as the next step later.
</div><div><br /></div><div>Explanation of the VM crash fix:
</div><div>The fix simply nills the context that can't be returned to. This can be done either in #cannotReturn: just by setting pc to nil before returning but Eliot suggested a more conceptual solution: in #cannotReturn:to:. This way we can save the failing context, and the pc where the return failed, inside the BCR exception for further use when debugging.
</div><div><br /></div><div>One more note: the direct debugger invocation in #cannotReturn: had to be replaced with raising an error in order to be able to test this situation properly - see the enclosed test.
</div><div><br /></div><div>It is possible there are some more cases taking advantage of making an illegal return to a dead or nil context during simulation, especially some debugger tests may be (mis)designed (because simplified) using this "feature" ;)
</div><div><br /></div><div>I hope I haven't missed something important; please let me know what you think.
</div><div><br /></div><div>Best regards,
</div><div>Jaromir</div><div><br /></div><div id="signature_old" style="clear:both"><div id="x57b63d33bbce4a9085be84e73df734d9"><div>
--</div><div><font face="Segoe UI Light">Jaromir Matas</font></div><div><font size="2" style="font-size: 10pt;" face="Segoe UI Light"><a href="mailto:mail@jaromir.net">mail@jaromir.net</a></font></div><div><br /></div></div></div><div><br /></div></body></html>