#FEATURE by exept
class: MessageTracer class
added: #trapMethod:inProcess:withChildProcesses:
--- a/MessageTracer.st Sun Sep 08 16:43:18 2019 +0200
+++ b/MessageTracer.st Sun Sep 15 11:13:23 2019 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1994 by Claus Gittinger
All Rights Reserved
@@ -790,6 +792,39 @@
"Modified: 22.10.1996 / 17:40:06 / cg"
!
+trapMethod:aMethod inProcess:aProcess withChildProcesses:withChildProcessesBoolean
+ "arrange for the debugger to be entered when aMethod is about to be executed,
+ but only, if executed by aProcess or one of aProcess's offspring.
+ This allows for breakpoints to be set on system-critical code.
+ The trap will only fire for selected processes (making browsers etc. still usable).
+ Use unwrapMethod or untrapClass to remove this trap.
+ Be careful, to not place a trap on code needed in the debugger (i.e. on scrollBars etc.);
+ if there is a need to trap those, use the low-level wrap-methods, and put a check into the
+ entry/leave blocks."
+
+ |pid|
+
+ pid := aProcess id. "/ fetch here, so the child detection works even when aProcess has died
+ ^ self wrapMethod:aMethod
+ onEntry:[:con |
+ |active shouldBreak|
+
+ active := Processor activeProcess.
+ withChildProcessesBoolean ifTrue:[
+ shouldBreak := (active processGroupId = pid) or:[ active creatorId = pid]
+ ] ifFalse:[
+ shouldBreak := active processGroupId = pid.
+ ].
+ shouldBreak ifTrue:[
+ BreakpointSignal raiseRequestWith:nil errorString:nil in:con
+ ]
+ ]
+ onExit:LeaveBreakBlock.
+
+ "Created: 14.10.1996 / 15:38:46 / cg"
+ "Modified: 22.10.1996 / 17:40:06 / cg"
+!
+
trapMethod:aMethod onReturnIf:conditionBlock
"arrange for the debugger to be entered when aMethod returns
and conditionBlock evaluates to true.