254 |
254 |
255 "Modified: / 22-10-2010 / 13:52:02 / cg" |
255 "Modified: / 22-10-2010 / 13:52:02 / cg" |
256 ! |
256 ! |
257 |
257 |
258 isHaltToBeIgnored |
258 isHaltToBeIgnored |
259 |c haltingMethod lineNrInHaltingMethod| |
259 |c sender haltingMethod lineNrInHaltingMethod| |
260 |
260 |
261 "/ should a halt be ignored ? |
261 "/ should a halt be ignored ? |
262 IgnoredHalts isNil ifTrue:[^ false]. |
262 IgnoredHalts isNil ifTrue:[^ false]. |
263 |
263 |
264 "/ look for a breakpoint-wrapper's context |
264 "/ look for a breakpoint-wrapper's context |
265 c := thisContext findNextContextWithSelector:#doRaise or:nil or:nil. |
265 c := thisContext findNextContextWithSelector:#doRaise or:nil or:nil. |
266 c notNil ifTrue:[ |
266 c notNil ifTrue:[ |
267 (c receiver isKindOf:NoHandlerError) ifTrue:[ |
267 (c receiver isKindOf:NoHandlerError) ifTrue:[ |
268 c := c sender findNextContextWithSelector:#doRaise or:nil or:nil. |
268 c := c sender findNextContextWithSelector:#doRaise or:nil or:nil. |
269 ]. |
269 ]. |
270 (c receiver isKindOf:BreakPointInterrupt) ifFalse:[ |
270 (c receiver isKindOf:BreakPointInterrupt) ifFalse:[ |
271 c := nil |
271 c := nil |
272 ] ifTrue:[ |
272 ] ifTrue:[ |
273 [ (c sender receiver isKindOf:BreakPointInterrupt) |
273 [ ((sender := c sender) receiver isKindOf:BreakPointInterrupt) |
274 or:[ c sender receiver == BreakPointInterrupt ]] whileTrue:[ |
274 or:[ sender receiver == BreakPointInterrupt ]] whileTrue:[ |
275 c := c sender |
275 c := sender |
276 ]. |
276 ]. |
277 [ c sender isBlockContext ] whileTrue:[ |
277 [ (sender := c sender) isBlockContext ] whileTrue:[ |
278 c := c sender |
278 c := sender |
279 ]. |
279 ]. |
280 ]. |
280 sender := nil. "/ avoid keeping a reference to this context |
|
281 ]. |
281 ]. |
282 ]. |
282 |
283 |
283 c isNil ifTrue:[ |
284 c isNil ifTrue:[ |
284 "/ look for halts or explicit breakpoints |
285 "/ look for halts or explicit breakpoints |
285 c := thisContext findNextContextWithSelector:#halt or:#halt: or:nil. |
286 c := thisContext findNextContextWithSelector:#halt or:#halt: or:nil. |
286 c isNil ifTrue:[ |
287 c isNil ifTrue:[ |
287 c := thisContext findNextContextWithSelector:#breakPoint: or:#breakPoint:info: or:nil. |
288 c := thisContext findNextContextWithSelector:#breakPoint: or:#breakPoint:info: or:nil. |
288 c isNil ifTrue:[ |
289 c isNil ifTrue:[ |
289 ^ false |
290 ^ false |
290 ]. |
291 ]. |
291 ]. |
292 ]. |
292 ]. |
293 ]. |
293 |
294 |
294 c := c sender. |
295 c := c sender. |
|
296 "/ a code-breakpoint ? |
|
297 (c receiver isKindOf:Breakpoint) ifTrue:[ |
|
298 c := c sender. |
|
299 ]. |
295 haltingMethod := c method. |
300 haltingMethod := c method. |
296 |
301 |
297 haltingMethod isWrapped ifTrue:[ |
302 haltingMethod isWrapped ifTrue:[ |
298 lineNrInHaltingMethod := 1. |
303 lineNrInHaltingMethod := 1. |
299 ] ifFalse:[ |
304 ] ifFalse:[ |
300 lineNrInHaltingMethod := c lineNumber. |
305 lineNrInHaltingMethod := c lineNumber. |
301 "/ Transcript showCR:c. |
306 "/ Transcript showCR:c. |
302 ]. |
307 ]. |
303 |
308 |
304 ^ self |
309 ^ self |
305 isHaltToBeIgnoredIn:haltingMethod |
310 isHaltToBeIgnoredIn:haltingMethod |
306 atLineNr:lineNrInHaltingMethod |
311 atLineNr:lineNrInHaltingMethod |
307 modifyEntryCount:true. |
312 modifyEntryCount:true. |
308 |
313 |
309 "Created: / 22-10-2010 / 12:09:53 / cg" |
314 "Created: / 22-10-2010 / 12:09:53 / cg" |
310 "Modified: / 22-10-2010 / 13:51:25 / cg" |
315 "Modified: / 27-01-2012 / 11:08:32 / cg" |
311 ! |
316 ! |
312 |
317 |
313 isHaltToBeIgnoredIn:haltingMethod atLineNr:lineNrInHaltingMethod |
318 isHaltToBeIgnoredIn:haltingMethod atLineNr:lineNrInHaltingMethod |
314 ^ self |
319 ^ self |
315 isHaltToBeIgnoredIn:haltingMethod |
320 isHaltToBeIgnoredIn:haltingMethod |
5542 |
5558 |
5543 |con text method caller caller2 called called2 m count c cc |
5559 |con text method caller caller2 called called2 m count c cc |
5544 suspendContext calledBySuspendContext nm h calledContext| |
5560 suspendContext calledBySuspendContext nm h calledContext| |
5545 |
5561 |
5546 (contextArray size > 0 and:[aContext == (contextArray at:1)]) ifTrue:[ |
5562 (contextArray size > 0 and:[aContext == (contextArray at:1)]) ifTrue:[ |
5547 "no change" |
5563 "no change" |
5548 ^ false |
5564 ^ false |
5549 ]. |
5565 ]. |
5550 |
5566 |
5551 isStoppedAtHaltOrBreakPoint := false. |
5567 isStoppedAtHaltOrBreakPoint := false. |
5552 firstContext := aContext. |
5568 firstContext := aContext. |
5553 |
5569 |
5554 m := contextView middleButtonMenu. |
5570 m := contextView middleButtonMenu. |
5555 m notNil ifTrue:[ |
5571 m notNil ifTrue:[ |
5556 m disable:#showMore. |
5572 m disable:#showMore. |
5557 ]. |
5573 ]. |
5558 canShowMore := false. |
5574 canShowMore := false. |
5559 |
5575 |
5560 aContext isNil ifTrue:[ |
5576 aContext isNil ifTrue:[ |
5561 text := Array with:'** no context **'. |
5577 text := Array with:'** no context **'. |
5562 contextArray := nil. |
5578 contextArray := nil. |
5563 ] ifFalse:[ |
5579 ] ifFalse:[ |
5564 text := OrderedCollection new:nChainShown. |
5580 text := OrderedCollection new:nChainShown. |
5565 contextArray := OrderedCollection new:nChainShown. |
5581 contextArray := OrderedCollection new:nChainShown. |
5566 con := aContext. |
5582 con := aContext. |
5567 calledContext := nil. |
5583 calledContext := nil. |
5568 |
5584 |
5569 verboseBacktrace ~~ true ifTrue:[ |
5585 verboseBacktrace ~~ true ifTrue:[ |
5570 "/ with dense backtrace, hide the ProcessorScheduler |
5586 "/ with dense backtrace, hide the ProcessorScheduler |
5571 "/ contexts at the top; look for a Process>>suspend* |
5587 "/ contexts at the top; look for a Process>>suspend* |
5572 "/ context within the first 10 contexts |
5588 "/ context within the first 10 contexts |
5573 |
5589 |
5574 suspendContext := nil. |
5590 suspendContext := nil. |
5575 c := con. |
5591 c := con. |
5576 1 to:10 do:[:i | |
5592 1 to:10 do:[:i | |
5577 |sel| |
5593 |sel| |
5578 |
5594 |
5579 c notNil ifTrue:[ |
5595 c notNil ifTrue:[ |
5580 (sel := c selector) notNil ifTrue:[ |
5596 (sel := c selector) notNil ifTrue:[ |
5581 ((sel isSymbol and:[sel startsWith:'suspend']) |
5597 ((sel isSymbol and:[sel startsWith:'suspend']) |
5582 and:[c receiver isMemberOf:Process]) ifTrue:[ |
5598 and:[c receiver isMemberOf:Process]) ifTrue:[ |
5583 suspendContext := c. |
5599 suspendContext := c. |
5584 calledBySuspendContext := cc. |
5600 calledBySuspendContext := cc. |
5585 ]. |
5601 ]. |
5586 ]. |
5602 ]. |
5587 cc := c. |
5603 cc := c. |
5588 c := c sender. |
5604 c := c sender. |
5589 ] |
5605 ] |
5590 ]. |
5606 ]. |
5591 suspendContext notNil ifTrue:[ |
5607 suspendContext notNil ifTrue:[ |
5592 con := suspendContext. |
5608 con := suspendContext. |
5593 calledContext := calledBySuspendContext. |
5609 calledContext := calledBySuspendContext. |
5594 suspendContext := nil |
5610 suspendContext := nil |
5595 ]. |
5611 ]. |
5596 ]. |
5612 ]. |
5597 |
5613 |
5598 con notNil ifTrue:[ |
5614 con notNil ifTrue:[ |
5599 "/ hide the halt implementation |
5615 "/ hide the halt implementation |
5600 (self haltSelectors includes:con selector) ifTrue:[ |
5616 (self haltSelectors includes:con selector) ifTrue:[ |
5601 (con method notNil and:[con method mclass == Object]) ifTrue:[ |
5617 (method := con method) notNil ifTrue:[ |
5602 isStoppedAtHaltOrBreakPoint := true. |
5618 method mclass == Object ifTrue:[ |
5603 verboseBacktrace ~~ true ifTrue:[ |
5619 isStoppedAtHaltOrBreakPoint := true. |
5604 calledContext := con. |
5620 verboseBacktrace ~~ true ifTrue:[ |
5605 con := con sender. |
5621 calledContext := con. |
5606 ] |
5622 con := con sender. |
5607 ]. |
5623 ] |
5608 ] |
5624 ] ifFalse:[ |
5609 ]. |
5625 method mclass == Breakpoint ifTrue:[ |
5610 " |
5626 isStoppedAtHaltOrBreakPoint := true. |
5611 get them all |
5627 verboseBacktrace ~~ true ifTrue:[ |
5612 " |
5628 calledContext := con. |
5613 count := 0. |
5629 con := con sender. |
5614 [con notNil and:[count <= nChainShown]] whileTrue:[ |
5630 ] |
5615 (self haltSelectors includes:con selector) ifTrue:[ |
5631 ]. |
5616 (con method notNil and:[con method mclass == Object]) ifTrue:[ |
5632 ]. |
5617 isStoppedAtHaltOrBreakPoint := true. |
5633 ]. |
5618 ] |
5634 ]. |
5619 ]. |
5635 ]. |
5620 |
5636 " |
5621 [ |
5637 get them all |
5622 DebuggingDebugger == true ifTrue:[ |
5638 " |
5623 'showingContext1: (' print. con print. |
5639 count := 0. |
5624 ') --> ' print. (self showingContext1:con calling:calledContext) printCR. |
5640 [con notNil and:[count <= nChainShown]] whileTrue:[ |
5625 ]. |
5641 (self haltSelectors includes:con selector) ifTrue:[ |
5626 self showingContext1:con calling:calledContext |
5642 (method := con method) notNil ifTrue:[ |
5627 ] whileFalse:[ |
5643 method mclass == Object ifTrue:[ |
5628 calledContext := con. |
5644 isStoppedAtHaltOrBreakPoint := true. |
5629 con := con sender. |
5645 ] ifFalse:[ |
5630 ]. |
5646 method mclass == Breakpoint ifTrue:[ |
5631 |
5647 isStoppedAtHaltOrBreakPoint := true. |
5632 DebuggingDebugger == true ifTrue:[ |
5648 ]. |
5633 'showingContext2: (' print. con print. |
5649 ] |
5634 ') --> ' print. (self showingContext2:con nesting:count) printCR. |
5650 ] |
5635 ]. |
5651 ]. |
5636 |
5652 |
5637 (self showingContext2:con nesting:count) ifTrue:[ |
5653 [ |
5638 "/ ignore it, if its in the same |
5654 DebuggingDebugger == true ifTrue:[ |
5639 "/ method as the previous context |
5655 'showingContext1: (' print. con print. |
|
5656 ') --> ' print. (self showingContext1:con calling:calledContext) printCR. |
|
5657 ]. |
|
5658 self showingContext1:con calling:calledContext |
|
5659 ] whileFalse:[ |
|
5660 calledContext := con. |
|
5661 con := con sender. |
|
5662 ]. |
|
5663 |
|
5664 DebuggingDebugger == true ifTrue:[ |
|
5665 'showingContext2: (' print. con print. |
|
5666 ') --> ' print. (self showingContext2:con nesting:count) printCR. |
|
5667 ]. |
|
5668 |
|
5669 (self showingContext2:con nesting:count) ifTrue:[ |
|
5670 "/ ignore it, if its in the same |
|
5671 "/ method as the previous context |
5640 "/ (verboseBacktrace ~~ true |
5672 "/ (verboseBacktrace ~~ true |
5641 "/ and:[count > 0 |
5673 "/ and:[count > 0 |
5642 "/ and:[contextArray last method == con method |
5674 "/ and:[contextArray last method == con method |
5643 "/ and:[(contextArray last isBlockContext not |
5675 "/ and:[(contextArray last isBlockContext not |
5644 "/ & con isBlockContext not) not ]]]) ifTrue:[ |
5676 "/ & con isBlockContext not) not ]]]) ifTrue:[ |
5645 "/ "/ skip it, if its in the same method |
5677 "/ "/ skip it, if its in the same method |
5646 "/ "/ as the called context. |
5678 "/ "/ as the called context. |
5647 "/ ] ifFalse:[ |
5679 "/ ] ifFalse:[ |
5648 contextArray add:con. |
5680 contextArray add:con. |
5649 |
5681 |
5650 (MoreDebuggingDetail == true) ifTrue:[ |
5682 (MoreDebuggingDetail == true) ifTrue:[ |
5651 nm := (((ObjectMemory addressOf:con) printStringRadix:16) , ' ' , con printString). |
5683 nm := (((ObjectMemory addressOf:con) printStringRadix:16) , ' ' , con printString). |
5652 ] ifFalse:[ |
5684 ] ifFalse:[ |
5653 Error |
5685 Error |
5654 handle:[:ex | nm := '???' ] |
5686 handle:[:ex | nm := '???' ] |
5655 do:[ |
5687 do:[ |
5656 nm := self contextListEntryFor:con. |
5688 nm := self contextListEntryFor:con. |
5657 ]. |
5689 ]. |
5658 ]. |
5690 ]. |
5659 text add:nm. |
5691 text add:nm. |
5660 count := count + 1. |
5692 count := count + 1. |
5661 "/ ]. |
5693 "/ ]. |
5662 ]. |
5694 ]. |
5663 |
5695 |
5664 "/ |
5696 "/ |
5665 "/ kludge: if its a wrapped method, then hide the wrap-call |
5697 "/ kludge: if its a wrapped method, then hide the wrap-call |
5666 "/ |
5698 "/ |
5667 method := con method. |
5699 method := con method. |
5668 (method notNil and:[method isWrapped]) ifTrue:[ |
5700 (method notNil and:[method isWrapped]) ifTrue:[ |
5669 called := con. |
5701 called := con. |
5670 caller := con sender. |
5702 caller := con sender. |
5671 (caller notNil and:[caller receiver == method originalMethod]) ifTrue:[ |
5703 (caller notNil and:[caller receiver == method originalMethod]) ifTrue:[ |
5672 called2 := caller. |
5704 called2 := caller. |
5673 caller2 := caller sender. |
5705 caller2 := caller sender. |
5674 (caller2 notNil and:[caller2 method == method]) ifTrue:[ |
5706 (caller2 notNil and:[caller2 method == method]) ifTrue:[ |
5675 calledContext := called2. |
5707 calledContext := called2. |
5676 con := caller2 |
5708 con := caller2 |
5677 ] |
5709 ] |
5678 ]. |
5710 ]. |
5679 caller := caller2 := nil |
5711 caller := caller2 := nil |
5680 ]. |
5712 ]. |
5681 |
5713 |
5682 "/ with dense backtrace, skip the doIt methods context |
5714 "/ with dense backtrace, skip the doIt methods context |
5683 "/ (its dummy anyway) and fake that contexts name |
5715 "/ (its dummy anyway) and fake that contexts name |
5684 |
5716 |
5685 verboseBacktrace ~~ true ifTrue:[ |
5717 verboseBacktrace ~~ true ifTrue:[ |
5686 (con isBlockContext |
5718 (con isBlockContext |
5687 and:[(h := con home) == con sender |
5719 and:[(h := con home) == con sender |
5688 and:[h notNil |
5720 and:[h notNil |
5689 and:[(self setOfHiddenCallingSelectors includes:h selector) |
5721 and:[(self setOfHiddenCallingSelectors includes:h selector) |
5690 and:[h method who isNil]]]]) ifTrue:[ |
5722 and:[h method who isNil]]]]) ifTrue:[ |
5691 calledContext := con. |
5723 calledContext := con. |
5692 con := con sender. |
5724 con := con sender. |
5693 text removeLast. |
5725 text removeLast. |
5694 |
5726 |
5695 text add:(self contextListEntryFor:con methodHome). |
5727 text add:(self contextListEntryFor:con methodHome). |
5696 ]. |
5728 ]. |
5697 h := nil. "/ never keep refs to contexts unless you really need them ... |
5729 h := nil. "/ never keep refs to contexts unless you really need them ... |
5698 ]. |
5730 ]. |
5699 |
5731 |
5700 "/ with dense backtrace, dont show below the doIt |
5732 "/ with dense backtrace, dont show below the doIt |
5701 ( verboseBacktrace ~~ true |
5733 ( verboseBacktrace ~~ true |
5702 and:[ (self setOfHiddenCallingSelectors includes:con selector) ]) ifTrue:[ |
5734 and:[ (self setOfHiddenCallingSelectors includes:con selector) ]) ifTrue:[ |
5703 con := nil. |
5735 con := nil. |
5704 ] ifFalse:[ |
5736 ] ifFalse:[ |
5705 calledContext := con. |
5737 calledContext := con. |
5706 con := con sender |
5738 con := con sender |
5707 ] |
5739 ] |
5708 ]. |
5740 ]. |
5709 |
5741 |
5710 " |
5742 " |
5711 did we reach the end ? |
5743 did we reach the end ? |
5712 " |
5744 " |
5713 (con isNil or:[con sender isNil]) ifTrue:[ |
5745 (con isNil or:[con sender isNil]) ifTrue:[ |
5714 |
5746 |
5715 "/ the very last one is the startup context |
5747 "/ the very last one is the startup context |
5716 "/ (in main) - it has nil as receiver and nil as selector |
5748 "/ (in main) - it has nil as receiver and nil as selector |
5717 |
5749 |
5718 (contextArray notEmpty |
5750 (contextArray notEmpty |
5719 and:[contextArray last selector isNil]) ifTrue:[ |
5751 and:[contextArray last selector isNil]) ifTrue:[ |
5720 contextArray removeLast. |
5752 contextArray removeLast. |
5721 text removeLast |
5753 text removeLast |
5722 ]. |
5754 ]. |
5723 |
5755 |
5724 verboseBacktrace ~~ true ifTrue:[ |
5756 verboseBacktrace ~~ true ifTrue:[ |
5725 "/ in dense mode, remove the process startup |
5757 "/ in dense mode, remove the process startup |
5726 "/ contexts (if any) |
5758 "/ contexts (if any) |
5727 |
5759 |
5728 (contextArray size > 0 |
5760 (contextArray size > 0 |
5729 and:[(con := contextArray last) methodClass == Process]) ifTrue:[ |
5761 and:[(con := contextArray last) methodClass == Process]) ifTrue:[ |
5730 con selector == #start ifTrue:[ |
5762 con selector == #start ifTrue:[ |
5731 contextArray removeLast. |
5763 contextArray removeLast. |
5732 text removeLast. |
5764 text removeLast. |
5733 |
5765 |
5734 [contextArray size > 0 |
5766 [contextArray size > 0 |
5735 and:[contextArray last methodHome == con]] whileTrue:[ |
5767 and:[contextArray last methodHome == con]] whileTrue:[ |
5736 contextArray removeLast. |
5768 contextArray removeLast. |
5737 text removeLast. |
5769 text removeLast. |
5738 ] |
5770 ] |
5739 ] |
5771 ] |
5740 ] |
5772 ] |
5741 ] |
5773 ] |
5742 ] ifFalse:[ |
5774 ] ifFalse:[ |
5743 m notNil ifTrue:[ |
5775 m notNil ifTrue:[ |
5744 m enable:#showMore. |
5776 m enable:#showMore. |
5745 ]. |
5777 ]. |
5746 canShowMore := true. |
5778 canShowMore := true. |
5747 text add:(resources string:'*** more walkback follows - click here to see them ***') |
5779 text add:(resources string:'*** more walkback follows - click here to see them ***') |
5748 ]. |
5780 ]. |
5749 ]. |
5781 ]. |
5750 |
5782 |
5751 contextView setList:text. |
5783 contextView setList:text. |
5752 |
5784 |
5753 releaseInspectors ifTrue:[ |
5785 releaseInspectors ifTrue:[ |
5754 receiverInspector release. |
5786 receiverInspector release. |
5755 contextInspector release. |
5787 contextInspector release. |
5756 ]. |
5788 ]. |
5757 |
5789 |
5758 m notNil ifTrue:[ |
5790 m notNil ifTrue:[ |
5759 m disableAll:#(addBreakpoint removeBreakpoint browseImplementors browseSenders browseReceiversClass). |
5791 m disableAll:#(addBreakpoint removeBreakpoint browseImplementors browseSenders browseReceiversClass). |
5760 ]. |
5792 ]. |
5761 self updateMenuItems. |
5793 self updateMenuItems. |
5762 ^ true |
5794 ^ true |
5763 |
5795 |
5764 "Created: / 14-12-1995 / 19:10:31 / cg" |
5796 "Created: / 14-12-1995 / 19:10:31 / cg" |
5765 "Modified: / 21-05-2007 / 13:31:02 / cg" |
5797 "Modified: / 27-01-2012 / 11:13:21 / cg" |
5766 ! |
5798 ! |
5767 |
5799 |
5768 setContextSkippingInterruptContexts:aContext |
5800 setContextSkippingInterruptContexts:aContext |
5769 "show calling chain from aContext in the walk-back listview. |
5801 "show calling chain from aContext in the walk-back listview. |
5770 Ignore any non-interesting interrupt-context." |
5802 Ignore any non-interesting interrupt-context." |