19 bigStep skipLineNr steppedContextAddress canAbort |
19 bigStep skipLineNr steppedContextAddress canAbort |
20 abortButton terminateButton continueButton |
20 abortButton terminateButton continueButton |
21 stepButton sendButton returnButton restartButton |
21 stepButton sendButton returnButton restartButton |
22 exclusive inspecting nChainShown |
22 exclusive inspecting nChainShown |
23 inspectedProcess updateProcess |
23 inspectedProcess updateProcess |
24 monitorToggle' |
24 monitorToggle stepping steppedContextLineno actualContext inWrap' |
25 classVariableNames:'CachedDebugger CachedExclusive MoreDebuggingDetail' |
25 classVariableNames:'CachedDebugger CachedExclusive OpenDebuggers MoreDebuggingDetail' |
26 poolDictionaries:'' |
26 poolDictionaries:'' |
27 category:'Interface-Debugger' |
27 category:'Interface-Debugger' |
28 ! |
28 ! |
29 |
29 |
30 DebugView comment:' |
30 DebugView comment:' |
31 COPYRIGHT (c) 1989 by Claus Gittinger |
31 COPYRIGHT (c) 1989 by Claus Gittinger |
32 All Rights Reserved |
32 All Rights Reserved |
33 |
33 |
34 $Header: /cvs/stx/stx/libtool/DebugView.st,v 1.20 1994-11-28 21:11:09 claus Exp $ |
34 $Header: /cvs/stx/stx/libtool/DebugView.st,v 1.21 1995-02-06 00:59:38 claus Exp $ |
35 '! |
35 '! |
36 |
36 |
37 !DebugView class methodsFor:'documentation'! |
37 !DebugView class methodsFor:'documentation'! |
38 |
38 |
39 copyright |
39 copyright |
90 |
90 |
91 new |
91 new |
92 "return a new DebugView - return a cached debugger if it already |
92 "return a new DebugView - return a cached debugger if it already |
93 exists" |
93 exists" |
94 |
94 |
95 |debugger active| |
95 |debugger| |
96 |
96 |
97 "need a blocking debugger if no processes or |
97 " |
|
98 need a blocking debugger if no processes or |
98 or if its a timing/interrupt process |
99 or if its a timing/interrupt process |
99 (because otherwise we would not get any events here ..." |
100 (because otherwise we would not get any events here ... |
100 |
101 " |
101 active := Processor activeProcess. |
102 Processor activeProcessIsSystemProcess ifTrue:[ |
102 |
|
103 (ProcessorScheduler isPureEventDriven |
|
104 or:[(active priority >= Processor userInterruptPriority) |
|
105 or:[active id == 0 |
|
106 or:[active nameOrId endsWith:'dispatcher']]]) ifTrue:[ |
|
107 CachedExclusive isNil ifTrue:[ |
103 CachedExclusive isNil ifTrue:[ |
108 debugger := self newExclusive |
104 debugger := self newExclusive |
109 ] ifFalse:[ |
105 ] ifFalse:[ |
110 debugger := CachedExclusive. |
106 debugger := CachedExclusive. |
111 CachedExclusive := nil. |
107 CachedExclusive := nil. |
126 newExclusive |
122 newExclusive |
127 "return a debugger for exclusive display access" |
123 "return a debugger for exclusive display access" |
128 |
124 |
129 |debugger| |
125 |debugger| |
130 |
126 |
131 debugger := super on:ModalDisplay. |
127 debugger := super new. |
132 debugger label:'Debugger'. |
128 debugger label:'Debugger'. |
133 debugger icon:(Form fromFile:'Debugger.xbm' resolution:100). |
129 debugger icon:(Form fromFile:'Debugger.xbm' resolution:100). |
134 debugger exclusive:true. |
130 debugger exclusive:true. |
135 ^ debugger |
131 ^ debugger |
136 ! |
132 ! |
137 |
133 |
138 newDebugger |
134 newDebugger |
139 "force creation of a new debugger" |
135 "force creation of a new debugger" |
140 |
136 |
141 CachedDebugger := nil. |
137 CachedDebugger := nil. |
142 CachedExclusive := nil |
138 CachedExclusive := nil. |
143 |
139 OpenDebuggers := nil. |
144 "DebugView newDebugger" |
140 |
|
141 " |
|
142 DebugView newDebugger |
|
143 " |
145 ! |
144 ! |
146 |
145 |
147 enterWithMessage:aString |
146 enterWithMessage:aString |
148 "the standard way of entering the debugger - sent from Objects |
147 "the standard way of entering the debugger - sent from Objects |
149 error- and halt messages" |
148 error- and halt messages" |
173 enter:aContext withMessage:aString |
172 enter:aContext withMessage:aString |
174 "enter a debugger; if this is a recursive invocation, enter |
173 "enter a debugger; if this is a recursive invocation, enter |
175 a MiniDebugger instead. |
174 a MiniDebugger instead. |
176 This is the standard way of entering the debugger; |
175 This is the standard way of entering the debugger; |
177 sent from error- and halt messages." |
176 sent from error- and halt messages." |
|
177 |
|
178 StepInterruptPending := nil. |
|
179 |
|
180 " |
|
181 well, it could be a stepping or sending debugger up there; |
|
182 in this case, return to it. This happens, when a stepping process |
|
183 runs into an error (for example, a halt). In this case, we want the |
|
184 stepping debugger to come up again instead of a new one. |
|
185 " |
|
186 OpenDebuggers notNil ifTrue:[ |
|
187 OpenDebuggers do:[:aDebugger | |
|
188 aDebugger notNil ifTrue:[ |
|
189 (aDebugger inspectedProcess == Processor activeProcess) ifTrue:[ |
|
190 "/ 'entering stepping debugger again' printNL. |
|
191 aDebugger unstep. |
|
192 aDebugger label:aString , ' (' , Processor activeProcess nameOrId , ')'. |
|
193 ^ aDebugger enter:aContext. |
|
194 ] |
|
195 ] |
|
196 ] |
|
197 ]. |
178 |
198 |
179 thisContext isRecursive ifTrue:[ |
199 thisContext isRecursive ifTrue:[ |
180 ^ MiniDebugger enterWithMessage:'recursive error'. |
200 ^ MiniDebugger enterWithMessage:'recursive error'. |
181 ]. |
201 ]. |
182 ^ self enterUnconditional:aContext withMessage:aString |
202 ^ self enterUnconditional:aContext withMessage:aString |
409 super realize. |
423 super realize. |
410 exclusive ifTrue:[ |
424 exclusive ifTrue:[ |
411 windowGroup := nil |
425 windowGroup := nil |
412 ]. |
426 ]. |
413 |
427 |
414 inspectedProcess notNil ifTrue:[ |
428 inspecting ifTrue:[ |
415 " |
429 inspectedProcess notNil ifTrue:[ |
416 set prio somewhat higher (by 2, to allow walkBack-update process |
430 " |
417 to run between mine and the debugged processes prio) |
431 set prio somewhat higher (by 2, to allow walkBack-update process |
418 " |
432 to run between mine and the debugged processes prio) |
419 Processor activeProcess |
433 " |
420 priority:(inspectedProcess priority + 2 min:16). |
434 Processor activeProcess |
|
435 priority:(inspectedProcess priority + 2 min:16). |
|
436 ] |
421 ] |
437 ] |
422 ! ! |
438 ! ! |
423 |
439 |
424 !DebugView methodsFor:'interrupt handling'! |
440 !DebugView methodsFor:'interrupt handling'! |
425 |
441 |
426 stepInterrupt |
442 stepInterrupt |
427 |where here s isWrap method lastWrappedConAddr wrappedMethod| |
443 |where here s isWrap method lastWrappedConAddr wrappedMethod inBlock left ignore| |
428 |
444 |
429 Processor activeProcess ~~ inspectedProcess ifTrue:[ |
445 Processor activeProcess ~~ inspectedProcess ifTrue:[ |
430 'stray step interrupt' errorPrintNL. |
446 'stray step interrupt' errorPrintNL. |
431 ^ self |
447 ^ self |
432 ]. |
448 ]. |
433 |
449 |
434 " |
450 " |
435 kludge: check if we are in a wrapper methods hidden setup-sequence |
451 kludge to hide breakpoint wrappers in the context list: |
|
452 check if we are in a wrapper methods hidden setup-sequence |
|
453 if so, ignore the interrupt and continue single sending |
436 " |
454 " |
437 here := thisContext. "stepInterrupt" |
455 here := thisContext. "stepInterrupt" |
438 here := here sender. "the interrupted context" |
456 here := here sender. "the interrupted context" |
439 |
457 |
|
458 "/ '*******' printNL. |
440 "/ 'here in ' print. |
459 "/ 'here in ' print. |
441 "/ ((ObjectMemory addressOf:here) printStringRadix:16)print. '' printNL. |
460 "/ ((ObjectMemory addressOf:here) printStringRadix:16)print. '' printNL. |
442 |
461 |
443 where := here. |
462 where := here. |
444 isWrap := false. |
463 isWrap := false. |
445 wrappedMethod := nil. |
464 left := false. |
446 5 timesRepeat:[ |
465 |
|
466 inWrap ifTrue:[ |
|
467 wrappedMethod := nil. |
|
468 3 timesRepeat:[ |
447 "/ where selector printNL. |
469 "/ where selector printNL. |
448 where notNil ifTrue:[ |
470 (where notNil and:[where isBlockContext not]) ifTrue:[ |
449 method := where method. |
471 method := where method. |
450 (method notNil and:[method isWrapped]) ifTrue:[ |
472 (method notNil and:[method isWrapped]) ifTrue:[ |
451 " |
473 " |
452 in a wrapper method |
474 in a wrapper method |
453 " |
475 " |
454 wrappedMethod ~~ method ifTrue:[ |
476 wrappedMethod ~~ method ifTrue:[ |
455 wrappedMethod := method. |
477 wrappedMethod := method. |
456 lastWrappedConAddr := ObjectMemory addressOf:where. |
478 lastWrappedConAddr := ObjectMemory addressOf:where. |
457 where sender receiver == method originalMethod ifFalse:[ |
479 where sender receiver == method originalMethod ifFalse:[ |
458 isWrap := true. |
480 isWrap := true. |
|
481 ] |
|
482 ] ifFalse:[ |
|
483 (ObjectMemory addressOf:where) == steppedContextAddress ifTrue:[ |
|
484 "/ 'change stepCon from: ' print. |
|
485 "/ (steppedContextAddress printStringRadix:16)print. |
|
486 "/ ' to: ' print. |
|
487 "/ (lastWrappedConAddr printStringRadix:16)printNL. |
|
488 |
|
489 inWrap := false. |
|
490 steppedContextAddress := lastWrappedConAddr |
|
491 ] |
459 ] |
492 ] |
460 ] ifFalse:[ |
493 ]. |
461 (ObjectMemory addressOf:where) == steppedContextAddress ifTrue:[ |
494 where := where sender |
462 "/ 'change stepCon from: ' print. |
495 ] |
463 "/ (steppedContextAddress printStringRadix:16)print. |
496 ]. |
464 "/ ' to: ' print. |
|
465 "/ (lastWrappedConAddr printStringRadix:16)printNL. |
|
466 |
|
467 steppedContextAddress := lastWrappedConAddr |
|
468 ] |
|
469 ] |
|
470 ]. |
|
471 where := where sender |
|
472 ] |
|
473 ]. |
497 ]. |
474 |
498 |
475 isWrap ifTrue:[ |
499 isWrap ifTrue:[ |
476 "/ 'ignore wrap' printNL. |
500 "/ 'ignore wrap' printNL. |
|
501 "/ ' ' printNL. |
477 " |
502 " |
478 ignore, while in wrappers hidden setup |
503 ignore, while in wrappers hidden setup |
479 " |
504 " |
480 where := nil. here := nil. |
505 where := nil. here := nil. |
481 ObjectMemory flushInlineCaches. |
506 ObjectMemory flushInlineCaches. |
483 InterruptPending := true. |
508 InterruptPending := true. |
484 InStepInterrupt := nil. |
509 InStepInterrupt := nil. |
485 ^ nil |
510 ^ nil |
486 ]. |
511 ]. |
487 |
512 |
|
513 inBlock := false. |
|
514 |
488 " |
515 " |
489 is this for a send or a step ? |
516 is this for a send or a step ? |
490 " |
517 " |
491 bigStep ifTrue:[ |
518 bigStep ifTrue:[ |
492 " |
519 " |
493 a step - ignore all contexts below the interresting one |
520 a step - ignore all contexts below the interresting one |
494 " |
521 " |
495 where := here. "the interrupted context" |
522 where := here. "the interrupted context" |
|
523 |
|
524 where home notNil ifTrue:[ |
|
525 (ObjectMemory addressOf:where home) == steppedContextAddress ifTrue:[ |
|
526 "/ '*block*' printNL. |
|
527 inBlock := true |
|
528 ] |
|
529 ]. |
|
530 |
496 (ObjectMemory addressOf:where) == steppedContextAddress ifFalse:[ |
531 (ObjectMemory addressOf:where) == steppedContextAddress ifFalse:[ |
497 where := where sender. |
532 where := where sender. |
498 "/ 'look for ' print. |
533 |
|
534 where home notNil ifTrue:[ |
|
535 (ObjectMemory addressOf:where home) == steppedContextAddress ifTrue:[ |
|
536 "/ '*block*' printNL. |
|
537 inBlock := true. |
|
538 ] |
|
539 ]. |
|
540 |
|
541 "/ 'looking for ' print. |
499 "/ (steppedContextAddress printStringRadix:16)print. '' printNL. |
542 "/ (steppedContextAddress printStringRadix:16)print. '' printNL. |
|
543 |
500 (ObjectMemory addressOf:where) == steppedContextAddress ifFalse:[ |
544 (ObjectMemory addressOf:where) == steppedContextAddress ifFalse:[ |
501 " |
545 " |
502 check if we are in a context below steppedContext |
546 check if we are in a context below steppedContext |
503 (i.e. if steppedContext can be reached from |
547 (i.e. if steppedContext can be reached from |
504 interrupted context. Not using context-ref but its |
548 interrupted context. Not using context-ref but its |
505 address to avoid creation of many useless contexts.) |
549 address to avoid creation of many useless contexts.) |
506 " |
550 " |
507 [where notNil] whileTrue:[ |
551 inBlock ifFalse:[ |
|
552 [where notNil] whileTrue:[ |
508 "/ ((ObjectMemory addressOf:where) printStringRadix:16)print. ' ' print. |
553 "/ ((ObjectMemory addressOf:where) printStringRadix:16)print. ' ' print. |
509 "/ where selector printNL. |
554 "/ where selector printNL. |
510 (ObjectMemory addressOf:where) == steppedContextAddress ifTrue:[ |
555 (ObjectMemory addressOf:where) == steppedContextAddress ifTrue:[ |
511 "/ 'found it - below' printNL. |
556 "/ 'found it - below; ignore' printNL. |
512 " |
557 " |
513 found the interresting context somwehere up in the |
558 found the interresting context somwehere up in the |
514 chain. We seem to be still below the interresting one ... |
559 chain. We seem to be still below the interresting one ... |
515 " |
560 " |
516 tracing == true ifTrue:[ |
561 tracing == true ifTrue:[ |
517 here printString printNewline |
562 here printString printNewline |
|
563 ]. |
|
564 where := nil. here := nil. |
|
565 " |
|
566 yes, a context below |
|
567 - continue and schedule another stepInterrupt. |
|
568 Must flush caches since optimized methods not always |
|
569 look for pending interrupts |
|
570 " |
|
571 ObjectMemory flushInlineCaches. |
|
572 StepInterruptPending := true. |
|
573 InterruptPending := true. |
|
574 InStepInterrupt := nil. |
|
575 ^ nil |
518 ]. |
576 ]. |
519 where := nil. here := nil. |
577 where := where sender |
520 " |
|
521 yes, a context below |
|
522 - continue and schedule another stepInterrupt. |
|
523 Must flush caches since optimized methods not always |
|
524 look for pending interrupts |
|
525 " |
|
526 ObjectMemory flushInlineCaches. |
|
527 StepInterruptPending := true. |
|
528 InterruptPending := true. |
|
529 InStepInterrupt := nil. |
|
530 ^ nil |
|
531 ]. |
578 ]. |
532 where := where sender |
579 s := 'left stepped method'. |
|
580 left := true. |
533 ]. |
581 ]. |
534 s := 'left stepped method' |
|
535 ] ifTrue:[ |
582 ] ifTrue:[ |
536 "/ 'found it right in sender' printNL. |
583 "/ 'found it right in sender' printNL. |
537 s := 'after step' |
584 s := 'after step' |
538 ]. |
585 ]. |
539 ] ifTrue:[ |
586 ] ifTrue:[ |
540 "/ 'found it right away' printNL. |
587 "/ 'found it right away' printNL. |
541 s := 'after step' |
588 s := 'after step' |
542 ]. |
589 ]. |
543 tracing := false. |
|
544 bigStep := false. |
|
545 ] ifFalse:[ |
590 ] ifFalse:[ |
546 |
591 "/ ' send' printNL. |
547 " |
592 " |
548 a send |
593 a send |
549 " |
594 " |
550 steppedContextAddress := nil. |
595 steppedContextAddress := nil. |
551 s := 'after send' |
596 s := 'after send' |
552 ]. |
597 ]. |
553 |
598 |
|
599 inBlock ifTrue:[ |
|
600 "/ 'inBlock' printNL. |
|
601 s := 'in block'. |
|
602 ]. |
|
603 |
|
604 "/ where notNil ifTrue:[ |
|
605 "/ '(' print. steppedContextLineno print. ') ' print. |
|
606 "/ where print. |
|
607 "/ '[' print. where lineNumber print. ']' printNL. |
|
608 "/ ]. |
|
609 |
|
610 ignore := false. |
|
611 (bigStep |
|
612 and:[where notNil |
|
613 and:[where lineNumber == steppedContextLineno]]) ifTrue:[ |
|
614 "/ 'same line - ignored' printNL. |
|
615 ignore := true |
|
616 ]. |
|
617 |
|
618 (left not |
|
619 and:[skipLineNr notNil |
|
620 and:[where lineNumber ~~ skipLineNr]]) ifTrue:[ |
|
621 "/ 'skip (' print. skipLineNr print. ' unreached - ignored' printNL. |
|
622 ignore := true |
|
623 ]. |
|
624 |
|
625 ignore ifTrue:[ |
|
626 "/' ' printNL. |
|
627 where := nil. here := nil. |
|
628 " |
|
629 yes, a context below |
|
630 - continue and schedule another stepInterrupt. |
|
631 Must flush caches since optimized methods not always |
|
632 look for pending interrupts |
|
633 " |
|
634 ObjectMemory flushInlineCaches. |
|
635 StepInterruptPending := true. |
|
636 InterruptPending := true. |
|
637 InStepInterrupt := nil. |
|
638 ^ nil |
|
639 ]. |
|
640 |
|
641 "/ ' ' printNL. |
|
642 |
554 name := Processor activeProcess nameOrId. |
643 name := Processor activeProcess nameOrId. |
555 self label:(s , ' (process: ' , name , ')'). |
644 self label:(s , ' (process: ' , name , ')'). |
|
645 |
|
646 tracing := false. |
|
647 bigStep := false. |
556 |
648 |
557 "release refs to context" |
649 "release refs to context" |
558 where := nil. here := nil. |
650 where := nil. here := nil. |
559 self enter:thisContext sender |
651 self enter:thisContext sender |
560 ! ! |
652 ! ! |
658 selection := self interrestingContextFrom:aContext. |
760 selection := self interrestingContextFrom:aContext. |
659 ] ifFalse:[ |
761 ] ifFalse:[ |
660 " |
762 " |
661 if we came here by a big-step, show the method where we are |
763 if we came here by a big-step, show the method where we are |
662 " |
764 " |
663 steppedContextAddress notNil ifTrue:[ |
765 (ObjectMemory addressOf:aContext) == steppedContextAddress ifTrue:[ |
664 (ObjectMemory addressOf:aContext) == steppedContextAddress ifTrue:[ |
766 selection := 1 |
665 selection := 1 |
767 ] ifFalse:[ |
666 ] ifFalse:[ |
768 (ObjectMemory addressOf:aContext sender) == steppedContextAddress ifTrue:[ |
667 (ObjectMemory addressOf:aContext sender) == steppedContextAddress ifTrue:[ |
769 selection := 2 |
668 selection := 2 |
|
669 ] |
|
670 ] |
770 ] |
671 ] |
771 ] |
672 ] |
772 ] |
673 ]. |
773 ]. |
674 |
774 |
675 selection notNil ifTrue:[ |
775 selection notNil ifTrue:[ |
676 self showSelection:selection. |
776 self showSelection:selection. |
677 contextView selection:selection |
777 contextView selection:selection. |
|
778 selection > 1 ifTrue:[ |
|
779 contextView scrollToLine:(selection - 1) |
|
780 ] |
678 ]. |
781 ]. |
679 |
782 |
680 m := contextView middleButtonMenu. |
783 m := contextView middleButtonMenu. |
681 m notNil ifTrue:[ |
784 m notNil ifTrue:[ |
682 canAbort := inspecting or:[Object abortSignal isHandled]. |
785 canAbort := inspecting or:[Object abortSignal isHandled]. |
721 This is required, since the debugger is reused, |
824 This is required, since the debugger is reused, |
722 to avoid keeping references to the debuggees objects |
825 to avoid keeping references to the debuggees objects |
723 forever. |
826 forever. |
724 " |
827 " |
725 contextArray := nil. |
828 contextArray := nil. |
726 codeView contents:nil. |
|
727 codeView acceptAction:nil. |
829 codeView acceptAction:nil. |
728 contextView contents:nil. |
830 contextView contents:nil. |
729 receiverInspector release. |
831 receiverInspector release. |
730 contextInspector release. |
832 contextInspector release. |
731 |
833 |
732 (exitAction == #step) ifFalse:[ |
834 (exitAction == #step) ifFalse:[ |
733 self unrealize. |
835 self unrealize. |
734 device synchronizeOutput. |
836 device synchronizeOutput. |
735 (exitAction == #abort) ifTrue:[ |
837 (exitAction == #abort) ifTrue:[ |
736 selectedContext := nil. |
838 selectedContext := actualContext := nil. |
737 busy := false. |
839 self cacheMyself. |
738 exclusive ifTrue:[CachedExclusive := self] ifFalse:[CachedDebugger := self]. |
|
739 " |
840 " |
740 have to catch errors occuring in unwind-blocks |
841 have to catch errors occuring in unwind-blocks |
741 " |
842 " |
742 Object errorSignal handle:[:ex | |
843 Object errorSignal handle:[:ex | |
743 'ignored error while unwinding: ' errorPrint. |
844 'ignored error while unwinding: ' errorPrint. |
748 ]. |
849 ]. |
749 'abort failed' errorPrintNL |
850 'abort failed' errorPrintNL |
750 ]. |
851 ]. |
751 (exitAction == #return) ifTrue:[ |
852 (exitAction == #return) ifTrue:[ |
752 selectedContext notNil ifTrue:[ |
853 selectedContext notNil ifTrue:[ |
|
854 " |
|
855 if there is a selection in the codeView, |
|
856 evaluate it and use the result as return value |
|
857 " |
|
858 codeView hasSelection ifTrue:[ |
|
859 s := codeView selection asString. |
|
860 Object errorSignal handle:[:ex | |
|
861 'DEBUGGER: error - returning nil' printNL. |
|
862 retval := nil. |
|
863 ex return |
|
864 ] do:[ |
|
865 retval := codeView doItAction value:s. |
|
866 ]. |
|
867 ]. |
|
868 |
753 con := selectedContext. |
869 con := selectedContext. |
754 selectedContext := nil. |
870 selectedContext := actualContext := nil. |
755 busy := false. |
871 self cacheMyself. |
756 exclusive ifTrue:[CachedExclusive := self] ifFalse:[CachedDebugger := self]. |
|
757 " |
872 " |
758 have to catch errors occuring in unwind-blocks |
873 have to catch errors occuring in unwind-blocks |
759 " |
874 " |
760 Object errorSignal handle:[:ex | |
875 Object errorSignal handle:[:ex | |
761 'ignored error while unwinding: ' errorPrint. |
876 'ignored error while unwinding: ' errorPrint. |
762 ex errorString errorPrintNL. |
877 ex errorString errorPrintNL. |
763 ex proceed |
878 ex proceed |
764 ] do:[ |
879 ] do:[ |
765 con unwind. |
880 con unwind:retval. |
766 ]. |
881 ]. |
767 'cannot return selected context' errorPrintNL |
882 'cannot return from selected context' errorPrintNL |
768 ] |
883 ] |
769 ] ifFalse:[ |
884 ] ifFalse:[ |
770 (exitAction == #restart) ifTrue:[ |
885 (exitAction == #restart) ifTrue:[ |
771 selectedContext notNil ifTrue:[ |
886 selectedContext notNil ifTrue:[ |
772 con := selectedContext. |
887 con := selectedContext. |
773 selectedContext := nil. |
888 selectedContext := actualContext := nil. |
774 busy := false. |
889 self cacheMyself. |
775 exclusive ifTrue:[CachedExclusive := self] ifFalse:[CachedDebugger := self]. |
|
776 " |
890 " |
777 have to catch errors occuring in unwind-blocks |
891 have to catch errors occuring in unwind-blocks |
778 " |
892 " |
779 Object errorSignal handle:[:ex | |
893 Object errorSignal handle:[:ex | |
780 'ignored error while unwinding: ' errorPrint. |
894 'ignored error while unwinding: ' errorPrint. |
808 ] |
921 ] |
809 ] |
922 ] |
810 ] |
923 ] |
811 ]. |
924 ]. |
812 |
925 |
813 selectedContext := nil. |
926 selectedContext := actualContext := nil. |
814 |
927 |
815 grabber notNil ifTrue:[ |
928 grabber notNil ifTrue:[ |
816 device grabPointerInView:grabber. |
929 device grabPointerInView:grabber. |
817 grabber := nil. |
930 grabber := nil. |
818 ]. |
931 ]. |
819 |
932 |
820 (exitAction == #step) ifTrue:[ |
933 (exitAction == #step) ifTrue:[ |
821 "scedule another stepInterrupt |
934 "scedule another stepInterrupt |
822 - must flush caches since optimized methods not always |
935 - must flush caches since optimized methods not always |
823 look for pending interrupts" |
936 look for pending interrupts" |
|
937 OpenDebuggers isNil ifTrue:[ |
|
938 OpenDebuggers := WeakArray with:self |
|
939 ] ifFalse:[ |
|
940 (OpenDebuggers includes:self) ifFalse:[ |
|
941 idx := OpenDebuggers identityIndexOf:nil. |
|
942 idx ~~ 0 ifTrue:[ |
|
943 OpenDebuggers at:idx put:self |
|
944 ] ifFalse:[ |
|
945 OpenDebuggers := OpenDebuggers copyWith:self |
|
946 ] |
|
947 ] |
|
948 ]. |
|
949 self label:'single stepping - please wait ...'. |
|
950 stepping := true. |
824 ObjectMemory flushInlineCaches. |
951 ObjectMemory flushInlineCaches. |
825 |
952 |
826 ObjectMemory stepInterruptHandler:self. |
953 ObjectMemory stepInterruptHandler:self. |
827 StepInterruptPending := true. |
954 StepInterruptPending := true. |
828 InterruptPending := true. |
955 InterruptPending := true. |
829 InStepInterrupt := nil |
956 InStepInterrupt := nil |
830 ] ifFalse:[ |
957 ] ifFalse:[ |
831 busy := false. |
958 OpenDebuggers notNil ifTrue:[ |
832 exclusive ifTrue:[CachedExclusive := self] ifFalse:[CachedDebugger := self] |
959 idx := OpenDebuggers identityIndexOf:self. |
|
960 idx ~~ 0 ifTrue:[ |
|
961 OpenDebuggers at:idx put:nil |
|
962 ] |
|
963 ]. |
|
964 self cacheMyself. |
833 ] |
965 ] |
834 ! |
966 ! |
835 |
967 |
836 openOn:aProcess |
968 openOn:aProcess |
837 "enter the debugger on a process - |
969 "enter the debugger on a process - |
999 self processAction:[inspectedProcess interruptWith:aBlock.] |
1164 self processAction:[inspectedProcess interruptWith:aBlock.] |
1000 ! |
1165 ! |
1001 |
1166 |
1002 exclusive:aBoolean |
1167 exclusive:aBoolean |
1003 exclusive := aBoolean |
1168 exclusive := aBoolean |
|
1169 ! |
|
1170 |
|
1171 unstep |
|
1172 stepping := false. |
|
1173 bigStep := false. |
|
1174 steppedContextAddress := nil. |
|
1175 exitAction := nil |
1004 ! |
1176 ! |
1005 |
1177 |
1006 interrestingContextFrom:aContext |
1178 interrestingContextFrom:aContext |
1007 "return an interresting contexts offset, or nil. |
1179 "return an interresting contexts offset, or nil. |
1008 This is the context initially shown in the walkback. |
1180 This is the context initially shown in the walkback. |
1009 We move up the calling chain, skipping all intermediate Signal |
1181 We move up the calling chain, skipping all intermediate Signal |
1010 and Exception contexts, to present the context in which the error |
1182 and Exception contexts, to present the context in which the error |
1011 actually occured. |
1183 actually occured. |
1012 Just for your convenience :-)" |
1184 Just for your convenience :-)" |
1013 |
1185 |
1014 |c found offset sel prev| |
1186 |c found offset sel prev ex| |
1015 |
1187 |
1016 "somewhere, at the bottom, there must be a raise ..." |
1188 "somewhere, at the bottom, there must be a raise ..." |
1017 |
1189 |
1018 c := aContext. |
1190 c := aContext. |
1019 1 to:5 do:[:i | |
1191 1 to:5 do:[:i | |
1020 c isNil ifTrue:[^ 1 "^ nil"]. |
1192 c isNil ifTrue:[^ 1 "^ nil"]. |
1021 sel := c selector. |
1193 sel := c selector. |
1022 (sel == #raise) ifTrue:[ |
1194 (sel == #raise) ifTrue:[ |
|
1195 (c receiver isKindOf:Exception) ifTrue:[ |
|
1196 ex := c receiver |
|
1197 ]. |
1023 offset := i. |
1198 offset := i. |
1024 found := c |
1199 found := c |
1025 ]. |
1200 ]. |
1026 c := c sender. |
1201 c := c sender. |
|
1202 ]. |
|
1203 |
|
1204 " |
|
1205 if this is a noHandler exception, skip forward |
|
1206 to the erronous context |
|
1207 " |
|
1208 ex notNil ifTrue:[ |
|
1209 ex signal == Signal noHandlerSignal ifTrue:[ |
|
1210 c := ex suspendedContext |
|
1211 ] |
1027 ]. |
1212 ]. |
1028 |
1213 |
1029 (c := found) isNil ifTrue:[^ 1]. |
1214 (c := found) isNil ifTrue:[^ 1]. |
1030 |
1215 |
1031 " |
1216 " |
1223 ] ifFalse:[ |
1408 ] ifFalse:[ |
1224 sel := homeContext selector. |
1409 sel := homeContext selector. |
1225 sel notNil ifTrue:[ |
1410 sel notNil ifTrue:[ |
1226 canAccept := true. |
1411 canAccept := true. |
1227 |
1412 |
1228 "/ implementorClass := homeContext searchClass whichClassImplements:sel. |
|
1229 implementorClass := homeContext methodClass. |
1413 implementorClass := homeContext methodClass. |
1230 implementorClass isNil ifTrue:[ |
1414 implementorClass isNil ifTrue:[ |
1231 " |
1415 " |
1232 special: look if this context was create by |
1416 special: look if this context was created by |
1233 valueWithReceiver kind of method invocation; |
1417 valueWithReceiver kind of method invocation; |
1234 if so, grab the method from the sender and show it |
1418 if so, grab the method from the sender and show it |
1235 " |
1419 " |
1236 "/ con sender selector printNL. |
|
1237 (con sender notNil |
1420 (con sender notNil |
1238 and:[(con sender selector == #valueWithReceiver:arguments:selector:search:) |
1421 and:[(con sender selector startsWith:'valueWithReceiver:') |
1239 and:[con sender receiver isKindOf:Method]]) ifTrue:[ |
1422 and:[con sender receiver isKindOf:Method]]) ifTrue:[ |
1240 method := con sender receiver. |
1423 method := con sender receiver. |
1241 code := method source. |
1424 code := method source. |
1242 canAccept := false. |
1425 canAccept := false. |
1243 ] ifFalse:[ |
1426 ] ifFalse:[ |
1244 self showError:'** no method - no source **' |
1427 con method notNil ifTrue:[ |
|
1428 method := con method. |
|
1429 code := method source. |
|
1430 canAccept := false. |
|
1431 ] ifFalse:[ |
|
1432 self showError:'** no method - no source **' |
|
1433 ] |
1245 ] |
1434 ] |
1246 ] ifFalse:[ |
1435 ] ifFalse:[ |
1247 method := implementorClass compiledMethodAt:sel. |
1436 method := implementorClass compiledMethodAt:sel. |
1248 code := method source. |
1437 code := method source. |
1249 code isNil ifTrue:[ |
1438 code isNil ifTrue:[ |
1491 exitAction := #step. |
1680 exitAction := #step. |
1492 ProcessorScheduler isPureEventDriven ifFalse:[ |
1681 ProcessorScheduler isPureEventDriven ifFalse:[ |
1493 "exit private event-loop" |
1682 "exit private event-loop" |
1494 catchBlock notNil ifTrue:[catchBlock value]. |
1683 catchBlock notNil ifTrue:[catchBlock value]. |
1495 'DEBUGGER: oops, send failed' errorPrintNL. |
1684 'DEBUGGER: oops, send failed' errorPrintNL. |
1496 "/ self warn:'send failed'. |
|
1497 sendButton turnOff. |
1685 sendButton turnOff. |
1498 "/ sendButton disable. |
|
1499 ]. |
1686 ]. |
1500 ] |
1687 ] |
1501 ! |
1688 ! |
1502 |
1689 |
1503 doStep:lineNr |
1690 doStep:lineNr |
1504 "step from menu" |
1691 "step until we pass lineNr (if nonNil) or to next line (if nil)" |
|
1692 |
|
1693 |con method| |
1505 |
1694 |
1506 inspecting ifTrue:[^ self]. |
1695 inspecting ifTrue:[^ self]. |
1507 |
1696 |
1508 canContinue ifTrue:[ |
1697 canContinue ifTrue:[ |
1509 selectedContext notNil ifTrue:[ |
1698 selectedContext notNil ifTrue:[ |
1510 steppedContextAddress := ObjectMemory addressOf:selectedContext |
1699 con := selectedContext. |
|
1700 steppedContextLineno := actualContext lineNumber. |
1511 ] ifFalse:[ |
1701 ] ifFalse:[ |
1512 steppedContextAddress := ObjectMemory addressOf:(contextArray at:2) |
1702 con := contextArray at:2. |
1513 ]. |
1703 steppedContextLineno := con lineNumber. |
|
1704 ]. |
|
1705 |
|
1706 steppedContextAddress := ObjectMemory addressOf:con. |
|
1707 " |
|
1708 if we step in a wrapped method, |
|
1709 prepare to skip the prolog ... |
|
1710 " |
|
1711 "/ ' step con:' print. steppedContextAddress printHex. ' ' printNL. |
|
1712 inWrap := false. |
|
1713 method := con method. |
|
1714 (method notNil and:[method isWrapped]) ifTrue:[ |
|
1715 inWrap := true |
|
1716 ]. |
|
1717 |
|
1718 con := nil. |
1514 bigStep := true. |
1719 bigStep := true. |
1515 skipLineNr := lineNr. |
1720 skipLineNr := lineNr. |
1516 haveControl := false. |
1721 haveControl := false. |
1517 exitAction := #step. |
1722 exitAction := #step. |
1518 ProcessorScheduler isPureEventDriven ifFalse:[ |
1723 ProcessorScheduler isPureEventDriven ifFalse:[ |
1519 "exit private event-loop" |
1724 "exit private event-loop" |
1520 catchBlock notNil ifTrue:[catchBlock value]. |
1725 catchBlock notNil ifTrue:[catchBlock value]. |
1521 'DEBUGGER: oops, step failed' errorPrintNL. |
1726 'DEBUGGER: oops, step failed' errorPrintNL. |
1522 "/ self warn:'step failed'. |
|
1523 stepButton turnOff. |
1727 stepButton turnOff. |
1524 "/ stepButton disable. |
|
1525 ]. |
1728 ]. |
1526 ] |
1729 ] |
1527 ! |
1730 ! |
1528 |
1731 |
1529 doStep |
1732 doStep |
1675 exitAction := #restart. |
1874 exitAction := #restart. |
1676 ProcessorScheduler isPureEventDriven ifFalse:[ |
1875 ProcessorScheduler isPureEventDriven ifFalse:[ |
1677 "exit private event-loop" |
1876 "exit private event-loop" |
1678 catchBlock notNil ifTrue:[catchBlock value]. |
1877 catchBlock notNil ifTrue:[catchBlock value]. |
1679 'DEBUGGER: oops, restart failed' errorPrintNL. |
1878 'DEBUGGER: oops, restart failed' errorPrintNL. |
1680 "/ self warn:'restart failed'. |
|
1681 restartButton turnOff. |
1879 restartButton turnOff. |
1682 "/ restartButton disable |
|
1683 ]. |
1880 ]. |
1684 ! |
1881 ! |
1685 |
1882 |
1686 doTrace |
1883 doTrace |
1687 "tracing - not really implemented ..." |
1884 "tracing - not really implemented ..." |
1688 |
1885 |
1689 |v b| |
1886 |v b| |
1690 |
1887 |
1691 self warn:'this function is not yet implemented'. |
1888 self warn:'this function is not yet implemented'. |
1692 |
1889 |
1693 false ifTrue:[ |
1890 "/ traceView isNil ifTrue:[ |
1694 traceView isNil ifTrue:[ |
1891 "/ v := StandardSystemView on:Display. |
1695 v := StandardSystemView on:Display. |
1892 "/ v label:'Debugger-Trace'. |
1696 v label:'Debugger-Trace'. |
1893 "/ v icon:icon. |
1697 v icon:icon. |
1894 "/ |
1698 |
1895 "/ b := Button label:'untrace' in:v. |
1699 b := Button label:'untrace' in:v. |
1896 "/ b origin:(0 @ 0) extent:(1.0 @ (b height)). |
1700 b origin:(0 @ 0) extent:(1.0 @ (b height)). |
1897 "/ b action:[ |
1701 b action:[ |
1898 "/ StepInterruptPending := false. |
1702 StepInterruptPending := false. |
1899 "/ tracing := false. |
1703 tracing := false. |
1900 "/ v unrealize. |
1704 v unrealize. |
1901 "/ traceView := nil |
1705 traceView := nil |
1902 "/ ]. |
1706 ]. |
1903 "/ traceView := ScrollableView for:TextCollector in:v. |
1707 traceView := ScrollableView for:TextCollector in:v. |
1904 "/ traceView origin:(0 @ (b height)) |
1708 traceView origin:(0 @ (b height)) |
1905 "/ extent:[v width @ (v height - b height)] |
1709 extent:[v width @ (v height - b height)] |
1906 "/ ]. |
1710 ]. |
1907 "/ v realize. |
1711 v realize. |
1908 "/ |
1712 ]. |
1909 "/ tracing := true. |
1713 tracing := true. |
|
1714 ! |
1910 ! |
1715 |
1911 |
1716 doNoTrace |
1912 doNoTrace |
1717 traceView notNil ifTrue:[ |
1913 traceView notNil ifTrue:[ |
1718 traceView topView destroy. |
1914 traceView topView destroy. |