fix to allow halt in an exception handler to work
authorpenk
Tue, 27 Jan 2004 15:59:21 +0100
changeset 5455 05d522683185
parent 5454 6ca2820713d6
child 5456 91c198c1c3e9
fix to allow halt in an exception handler to work even if the handler was invoked via the debuggers abort button.
DebugView.st
--- a/DebugView.st	Mon Jan 26 17:38:36 2004 +0100
+++ b/DebugView.st	Tue Jan 27 15:59:21 2004 +0100
@@ -113,18 +113,20 @@
 enter
     "enter a debugger"
 
+    <context: #return>
+
     self enter:thisContext sender withMessage:'debugger entered'.
-
 !
 
 enter:aContext withMessage:aString 
     "enter a debugger"
 
+    <context: #return>
+
     ^ self
         enter:aContext 
         withMessage:aString 
         mayProceed:true
-
 !
 
 enter:aContext withMessage:aString mayProceed:mayProceed
@@ -138,32 +140,32 @@
     |active|
 
     StepInterruptPending := nil.
-    thisContext isRecursive ifTrue:[
-        |foundNoByteCodeContext c|
-    
-        "/ care for the special case, were the Debugger was autoloaded.
-        "/ in this case, thisContext IS recursive, but thats no error
-        "/ condition.
-        foundNoByteCodeContext := false.
-        c := thisContext findNextContextWithSelector:#enter:withMessage:mayProceed: or:#noByteCode or:nil.
-        [foundNoByteCodeContext not
-         and:[c notNil 
-         and:[c selector ~~ #enter:withMessage:mayProceed:]]] whileTrue:[
-            c selector == #noByteCode ifTrue:[
-                foundNoByteCodeContext := true
-            ].
-            c := c findNextContextWithSelector:#enter:withMessage:mayProceed: or:#noByteCode or:nil.
-        ].
-
-        foundNoByteCodeContext ifFalse:[
-            ('DebugView [warning]: reentered') errorPrintCR.
-
-            ^ MiniDebugger 
-                enter:aContext
-                withMessage:'DebugView [error]: recursive error (in debugger)'
-                mayProceed:mayProceed.
-        ]
-    ].
+"/    thisContext isRecursive ifTrue:[
+"/        |foundNoByteCodeContext c|
+"/    
+"/        "/ care for the special case, were the Debugger was autoloaded.
+"/        "/ in this case, thisContext IS recursive, but thats no error
+"/        "/ condition.
+"/        foundNoByteCodeContext := false.
+"/        c := thisContext findNextContextWithSelector:#enter:withMessage:mayProceed: or:#noByteCode or:nil.
+"/        [foundNoByteCodeContext not
+"/         and:[c notNil 
+"/         and:[c selector ~~ #enter:withMessage:mayProceed:]]] whileTrue:[
+"/            c selector == #noByteCode ifTrue:[
+"/                foundNoByteCodeContext := true
+"/            ].
+"/            c := c findNextContextWithSelector:#enter:withMessage:mayProceed: or:#noByteCode or:nil.
+"/        ].
+"/
+"/        foundNoByteCodeContext ifFalse:[
+"/            ('DebugView [warning]: reentered') errorPrintCR.
+"/
+"/            ^ MiniDebugger 
+"/                enter:aContext
+"/                withMessage:'DebugView [error]: recursive error (in debugger)'
+"/                mayProceed:mayProceed.
+"/        ]
+"/    ].
     ControlInterrupt handle:[:ex |
         'DebugView [info]: breakpoint in debugger setup ignored [enter.]' infoPrintCR.
         ('DebugView [info]: breakpoint on:' , ex suspendedContext printString) infoPrintCR.
@@ -202,6 +204,8 @@
 enterUnconditional:aContext withMessage:aString mayProceed:mayProceed
     "enter a debugger - do not check for recursive invocation"
 
+    <context: #return>
+
     |aDebugger proc|
 
     StepInterruptPending := nil.
@@ -1312,6 +1316,14 @@
 exit_abort
     |con|
 
+    "/ cannot simply raise an abort here, because if there is an abortHandler somewhere,
+    "/ that one would run on top of this context.
+    "/ Therefore, any controlInterrupt(i.e. halt) or reentering of the debugger from that handler
+    "/ would be interpreted as a recursive invocation (in #enter:select).
+    "/ To avoid this, we unwind all contexts and simulate the raise as if it was
+    "/ done in the #enter:select method.    
+    "/ You are not expected to understand this.
+
     "
      have to catch errors occuring in unwind-blocks
     "
@@ -1323,6 +1335,7 @@
 
         ex proceed
     ] do:[
+        "/ find the enter:select context.
         con := thisContext sender.
         [   
             (con selector == #enter:select:)
@@ -1330,8 +1343,18 @@
         ]
         whileFalse:[ con := con sender ].
 
-        con unwindThenDo:[AbortOperationRequest raise].
-"/        AbortOperationRequest raise.
+        "/ must skip over its caller (because this one has a ControlInterrupt handler too)
+        con sender receiver == self class ifTrue:[
+            con := con sender.
+            con sender receiver == self class ifTrue:[
+                con := con sender.
+                con isBlockContext ifTrue:[
+                    con := con methodHome.
+                ]
+            ].
+        ].
+
+        con unwindThenDo:[ AbortOperationRequest raise ].
     ].
     'DebugView [warning]: abort failed' errorPrintCR
 
@@ -4815,6 +4838,12 @@
     "Modified: 20.10.1996 / 18:11:24 / cg"
 ! !
 
+!DebugView methodsFor:'private queries'!
+
+isAborting
+    ^ exitAction == #abort
+! !
+
 !DebugView methodsFor:'private-cache handling'!
 
 cacheMyself
@@ -5808,7 +5837,7 @@
 !DebugView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libtool/DebugView.st,v 1.358 2004-01-26 16:38:36 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libtool/DebugView.st,v 1.359 2004-01-27 14:59:21 penk Exp $'
 ! !
 
 DebugView initialize!