[ENH] Enhanced Debugging Experience (first shot)

Hans-Martin Mosner hmm at heeg.de
Fri Jul 20 13:03:22 UTC 2001


Doug Way wrote:
> One other nice thing to fix at some point would be the PC highlighting for NonBoolean receiver errors. For example, if you Do this in a workspace:
> 
> nil ifTrue: [x _ 'asdfas' asSortedCollection].
> 
> The NonBoolean receiver debugger comes up, but the #asSortedCollection method is currently highlighted, when it seems that #ifTrue: should be highlighted instead.

I've looked into it, but the matter is a little complicated.
The pc of the context causing the #mustBeBoolean exception is positioned just after the jump-if-false bytecode. Therefore, the line in the notification 'proceed for truth' magically works, because the #mustBeBoolean context returns to this place.
However, to distinguish this situation from a normal message send, the debugger would have to look at more than the selected context, which would make things more complicated and possibly unstable.

There's another tricky matter here which makes the #mustBeBoolean handling inherently dangerous:
Since the #mustBeBoolean method returns true, the context's stack has one additional value.
In those cases where ifTrue:ifFalse: is being used as a statement this does not hurt much except possibly in borderline situations where the context has a small frame size, and that size just suffixes. In such a situation the additional value would cause later pushes to write after the context, possibly into the header of the next object. Horrors!
In cases where the value of ifTrue:ifFalse: is being used as the operand in an expression, things might also look strange. For example, execute "3 + (nil ifTrue: [2] ifFalse: [3])" and proceed from the #mustBeBoolean notifier.
Instead of the expected value 5 you get another notifier telling you that true does not understand #+.

In my opinion, the handling of non-boolean conditions in the VM should be handled such that the PC is left in front of the jump instruction. Then the returned value would be consumed by the jump, and everything would be fine. You could then even proceed with a value of false if that seems more appropriate.

Of course, all of this is probably rather irrelevant, because the first thing you would do when you stumble across such a case is to fix the underlying bug which causes the receiver of ifTrue:ifFalse: to be a non-boolean in the first place...

Cheers,
Hans-Martin




More information about the Squeak-dev mailing list