7357 firstContext := aContext. |
7357 firstContext := aContext. |
7358 verboseBacktrace := self verboseBacktraceHolder value. |
7358 verboseBacktrace := self verboseBacktraceHolder value. |
7359 |
7359 |
7360 m := contextView middleButtonMenu. |
7360 m := contextView middleButtonMenu. |
7361 m notNil ifTrue:[ |
7361 m notNil ifTrue:[ |
7362 m disable:#showMore. |
7362 m disable:#showMore. |
7363 ]. |
7363 ]. |
7364 canShowMore := false. |
7364 canShowMore := false. |
7365 |
7365 |
7366 aContext isNil ifTrue:[ |
7366 aContext isNil ifTrue:[ |
7367 text := Array with:'** no context **'. |
7367 text := Array with:'** no context **'. |
7368 contextArray := nil. |
7368 contextArray := nil. |
7369 ] ifFalse:[ |
7369 ] ifFalse:[ |
7370 text := OrderedCollection new:nChainShown. |
7370 text := OrderedCollection new:nChainShown. |
7371 contextArray := OrderedCollection new:nChainShown. |
7371 contextArray := OrderedCollection new:nChainShown. |
7372 |
7372 |
7373 con := aContext. |
7373 con := aContext. |
7374 calledContext := nil. |
7374 calledContext := nil. |
7375 |
7375 |
7376 '======================================' print. con printCR. |
7376 DebuggingContextWalk == true ifTrue:[ |
7377 alreadyInApplicationCode := |
7377 '======================================' print. con printCR. |
7378 con receiver isLazyValue not "/ careful to not force futures/lazy values |
7378 ]. |
7379 and:[con receiver isKindOf:ApplicationModel]. |
7379 alreadyInApplicationCode := |
7380 |
7380 con receiver isLazyValue not "/ careful to not force futures/lazy values |
7381 verboseBacktrace ~~ true ifTrue:[ |
7381 and:[con receiver isKindOf:ApplicationModel]. |
7382 "/ with dense backtrace, hide the ProcessorScheduler |
7382 |
7383 "/ contexts at the top; look for a Process>>suspend* |
7383 verboseBacktrace ~~ true ifTrue:[ |
7384 "/ context within the first 10 contexts |
7384 "/ with dense backtrace, hide the ProcessorScheduler |
7385 |
7385 "/ contexts at the top; look for a Process>>suspend* |
7386 suspendContext := nil. |
7386 "/ context within the first 10 contexts |
7387 c := con. |
7387 |
7388 1 to:10 do:[:i | |
7388 suspendContext := nil. |
7389 |selector| |
7389 c := con. |
7390 |
7390 1 to:10 do:[:i | |
7391 c notNil ifTrue:[ |
7391 |selector| |
7392 selector := c selector. |
7392 |
7393 selector notNil ifTrue:[ |
7393 c notNil ifTrue:[ |
7394 (selector isSymbol and:[(selector startsWith:'suspend') and:[c receiver isMemberOf:Process]]) ifTrue:[ |
7394 selector := c selector. |
7395 suspendContext := c. |
7395 selector notNil ifTrue:[ |
7396 calledBySuspendContext := cc. |
7396 (selector isSymbol and:[(selector startsWith:'suspend') and:[c receiver isMemberOf:Process]]) ifTrue:[ |
7397 ]. |
7397 suspendContext := c. |
7398 ]. |
7398 calledBySuspendContext := cc. |
7399 cc := c. |
7399 ]. |
7400 c := c sender. |
7400 ]. |
7401 ] |
7401 cc := c. |
7402 ]. |
7402 c := c sender. |
7403 suspendContext notNil ifTrue:[ |
7403 ] |
7404 con := suspendContext. |
7404 ]. |
7405 calledContext := calledBySuspendContext. |
7405 suspendContext notNil ifTrue:[ |
7406 suspendContext := nil |
7406 con := suspendContext. |
7407 ]. |
7407 calledContext := calledBySuspendContext. |
7408 ]. |
7408 suspendContext := nil |
7409 "/ Transcript show:'1 '; showCR:con. |
7409 ]. |
7410 con notNil ifTrue:[ |
7410 ]. |
7411 "/ hide the halt implementation |
7411 "/ Transcript show:'1 '; showCR:con. |
7412 sel := con selector. |
7412 con notNil ifTrue:[ |
7413 (self haltSelectors includes:sel) ifTrue:[ |
7413 "/ hide the halt implementation |
7414 (method := con method) notNil ifTrue:[ |
7414 sel := con selector. |
7415 method mclass == Object ifTrue:[ |
7415 (self haltSelectors includes:sel) ifTrue:[ |
7416 (sel isSymbol and:[ sel startsWith:'breakPoint:']) ifTrue:[ |
7416 (method := con method) notNil ifTrue:[ |
7417 isStoppedAtBreakPointWithParameter := true. |
7417 method mclass == Object ifTrue:[ |
7418 breakPointParameter := con argAt:1. |
7418 (sel isSymbol and:[ sel startsWith:'breakPoint:']) ifTrue:[ |
7419 ]. |
7419 isStoppedAtBreakPointWithParameter := true. |
7420 isStoppedAtHaltOrBreakPoint := true. |
7420 breakPointParameter := con argAt:1. |
7421 verboseBacktrace ~~ true ifTrue:[ |
7421 ]. |
7422 calledContext := con. |
7422 isStoppedAtHaltOrBreakPoint := true. |
7423 con := con sender. |
7423 verboseBacktrace ~~ true ifTrue:[ |
7424 ] |
7424 calledContext := con. |
7425 ] ifFalse:[ |
7425 con := con sender. |
7426 method mclass == Breakpoint ifTrue:[ |
7426 ] |
7427 isStoppedAtHaltOrBreakPoint := true. |
7427 ] ifFalse:[ |
7428 isStoppedAtStatementBreakpoint := true. |
7428 method mclass == Breakpoint ifTrue:[ |
7429 verboseBacktrace ~~ true ifTrue:[ |
7429 isStoppedAtHaltOrBreakPoint := true. |
7430 calledContext := con. |
7430 isStoppedAtStatementBreakpoint := true. |
7431 con := con sender. |
7431 verboseBacktrace ~~ true ifTrue:[ |
7432 ]. |
7432 calledContext := con. |
7433 "/ Transcript show:'2 '; showCR:con. |
7433 con := con sender. |
7434 ]. |
7434 ]. |
7435 ]. |
7435 "/ Transcript show:'2 '; showCR:con. |
7436 ]. |
7436 ]. |
7437 ]. |
7437 ]. |
7438 ]. |
7438 ]. |
7439 |
7439 ]. |
7440 (verboseBacktrace not or:[ hideSupportCode]) ifTrue:[ |
7440 ]. |
7441 [ |
7441 |
7442 con notNil |
7442 (verboseBacktrace not or:[ hideSupportCode]) ifTrue:[ |
7443 and:[ con isBlockContext not |
7443 [ |
7444 and:[ con method notNil |
7444 con notNil |
7445 and:[ (con method shouldBeSkippedInDebuggersWalkBack) |
7445 and:[ con isBlockContext not |
7446 and:[ (self haltSelectors includes: con selector) not]]]] |
7446 and:[ con method notNil |
7447 ] whileTrue:[ |
7447 and:[ (con method shouldBeSkippedInDebuggersWalkBack) |
7448 "/ Transcript show:'xx '; showCR:con. |
7448 and:[ (self haltSelectors includes: con selector) not]]]] |
7449 calledContext := con. |
7449 ] whileTrue:[ |
7450 con := con sender |
7450 "/ Transcript show:'xx '; showCR:con. |
7451 ]. |
7451 calledContext := con. |
7452 ]. |
7452 con := con sender |
7453 |
7453 ]. |
7454 " |
7454 ]. |
7455 get them all, by walking along the caller chain. |
7455 |
7456 depending on the settings, skip some intermediate contexts |
7456 " |
7457 (such as collection enumeration implementations), which are usually not |
7457 get them all, by walking along the caller chain. |
7458 of interest when debugging an application. |
7458 depending on the settings, skip some intermediate contexts |
7459 On the fly, gather some additional information |
7459 (such as collection enumeration implementations), which are usually not |
7460 such as: are we at a halt/breakpoint, are we in a modal dialog opened, |
7460 of interest when debugging an application. |
7461 are we coming from an application model's action etc. |
7461 On the fly, gather some additional information |
7462 " |
7462 such as: are we at a halt/breakpoint, are we in a modal dialog opened, |
7463 count := 0. |
7463 are we coming from an application model's action etc. |
7464 [con notNil and:[count <= nChainShown]] whileTrue:[ |
7464 " |
7465 "/ remember any halt/breakpoint or openModal on the fly |
7465 count := 0. |
7466 '---' print. con printCR. |
7466 [con notNil and:[count <= nChainShown]] whileTrue:[ |
7467 sel := con selector. |
7467 "/ remember any halt/breakpoint or openModal on the fly |
7468 (self haltSelectors includes:sel) ifTrue:[ |
7468 DebuggingContextWalk == true ifTrue:[ '---' print. con printCR ]. |
7469 (method := con method) notNil ifTrue:[ |
7469 |
7470 method mclass == Object ifTrue:[ |
7470 sel := con selector. |
7471 (sel isSymbol and:[sel startsWith:'breakPoint:']) ifTrue:[ |
7471 (self haltSelectors includes:sel) ifTrue:[ |
7472 isStoppedAtBreakPointWithParameter := true. |
7472 (method := con method) notNil ifTrue:[ |
7473 breakPointParameter := con argAt:1. |
7473 method mclass == Object ifTrue:[ |
7474 ]. |
7474 (sel isSymbol and:[sel startsWith:'breakPoint:']) ifTrue:[ |
7475 isStoppedAtHaltOrBreakPoint := true. |
7475 isStoppedAtBreakPointWithParameter := true. |
7476 ] ifFalse:[ |
7476 breakPointParameter := con argAt:1. |
7477 method mclass == Breakpoint ifTrue:[ |
7477 ]. |
7478 isStoppedAtHaltOrBreakPoint := true. |
7478 isStoppedAtHaltOrBreakPoint := true. |
7479 ]. |
7479 ] ifFalse:[ |
7480 ] |
7480 method mclass == Breakpoint ifTrue:[ |
7481 ] |
7481 isStoppedAtHaltOrBreakPoint := true. |
7482 ] ifFalse:[ |
7482 ]. |
7483 ((sel == #openModal) or:[sel == #openModal:]) ifTrue:[ |
7483 ] |
7484 isStoppedInModalDialog := true. |
7484 ] |
7485 ] ifFalse:[ |
7485 ] ifFalse:[ |
7486 alreadyInApplicationCode ifFalse:[ |
7486 ((sel == #openModal) or:[sel == #openModal:]) ifTrue:[ |
7487 (con receiver isLazyValue not "/ careful to not force futures/lazy values |
7487 isStoppedInModalDialog := true. |
7488 and:[con receiver isKindOf:ApplicationModel]) ifTrue:[ |
7488 ] ifFalse:[ |
7489 isStoppedInApplicationAction := true. |
7489 alreadyInApplicationCode ifFalse:[ |
7490 ] |
7490 (con receiver isLazyValue not "/ careful to not force futures/lazy values |
7491 ] |
7491 and:[con receiver isKindOf:ApplicationModel]) ifTrue:[ |
7492 ] |
7492 isStoppedInApplicationAction := true. |
7493 ]. |
7493 ] |
7494 |
7494 ] |
7495 [ |
7495 ] |
7496 |show1| |
7496 ]. |
7497 |
7497 |
7498 show1 := self showingContext1:con calling:calledContext. |
7498 [ |
7499 DebuggingDebugger3 == true ifTrue:[ |
7499 |show1| |
7500 'showingContext1: (' print. con print. ') --> ' print. show1 printCR. |
7500 |
7501 ]. |
7501 show1 := self showingContext1:con calling:calledContext. |
7502 show1 |
7502 DebuggingDebugger3 == true ifTrue:[ |
7503 ] whileFalse:[ |
7503 'showingContext1: (' print. con print. ') --> ' print. show1 printCR. |
7504 calledContext := con. |
7504 ]. |
7505 con := con sender. |
7505 show1 |
7506 ]. |
7506 ] whileFalse:[ |
7507 |
7507 calledContext := con. |
7508 show2 := self showingContext2:con nesting:count. |
7508 con := con sender. |
7509 DebuggingDebugger3 == true ifTrue:[ |
7509 ]. |
7510 'showingContext2: (' print. con print. ') --> ' print. show2 printCR. |
7510 |
7511 ]. |
7511 show2 := self showingContext2:con nesting:count. |
7512 |
7512 DebuggingDebugger3 == true ifTrue:[ |
7513 show2 ifTrue:[ |
7513 'showingContext2: (' print. con print. ') --> ' print. show2 printCR. |
7514 contextArray add:con. |
7514 ]. |
7515 |
7515 |
7516 (MoreDebuggingDetail == true) ifTrue:[ |
7516 show2 ifTrue:[ |
7517 nm := (((ObjectMemory addressOf:con) printStringRadix:16) , ' ' , con printString). |
7517 contextArray add:con. |
7518 ] ifFalse:[ |
7518 |
7519 nm := self contextListEntryFor:con. |
7519 (MoreDebuggingDetail == true) ifTrue:[ |
7520 ]. |
7520 nm := (((ObjectMemory addressOf:con) printStringRadix:16) , ' ' , con printString). |
7521 text add:nm. |
7521 ] ifFalse:[ |
7522 count := count + 1. |
7522 nm := self contextListEntryFor:con. |
7523 ]. |
7523 ]. |
7524 |
7524 text add:nm. |
7525 "/ with hidden support code, skip over internals of exceptions |
7525 count := count + 1. |
7526 hideSupportCode == true ifTrue:[ |
7526 ]. |
7527 "/ Transcript showCR:'x'. |
7527 |
7528 (con isBlockContext |
7528 "/ with hidden support code, skip over internals of exceptions |
7529 and:[ (h := con home) notNil |
7529 hideSupportCode == true ifTrue:[ |
7530 and:[ (self is:h inCallingChainOf:con) ]]) ifTrue:[ |
7530 "/ Transcript showCR:'x'. |
7531 |blocksReceiver| |
7531 (con isBlockContext |
7532 blocksReceiver := con receiver. |
7532 and:[ (h := con home) notNil |
7533 c := con sender. |
7533 and:[ (self is:h inCallingChainOf:con) ]]) ifTrue:[ |
7534 [ |
7534 |blocksReceiver| |
7535 c notNil |
7535 blocksReceiver := con receiver. |
7536 and:[ |
7536 c := con sender. |
7537 sndr := c sender. |
7537 [ |
7538 (sndr ~= h) |
7538 c notNil |
7539 and:[ |
7539 and:[ |
7540 blocksReceiver isCollection "/ skip collection implementations |
7540 sndr := c sender. |
7541 or:[ ( #( #'handle:do:' "/ skip exception implementations |
7541 (sndr ~= h) |
7542 #'handleDo:' |
7542 and:[ |
7543 #'answer:do:' |
7543 blocksReceiver isCollection "/ skip collection implementations |
7544 #'ensure:' ) includes: c selector ) |
7544 or:[ ( #( #'handle:do:' "/ skip exception implementations |
7545 or:[ #'perform:*' "/ skip perform implementations |
7545 #'handleDo:' |
7546 match: c selector ]] |
7546 #'answer:do:' |
7547 ] |
7547 #'ensure:' ) includes: c selector ) |
7548 ] |
7548 or:[ #'perform:*' "/ skip perform implementations |
7549 ] whileTrue:[ |
7549 match: c selector ]] |
7550 c := sndr |
7550 ] |
7551 ]. |
7551 ] |
7552 c notNil ifTrue:[ |
7552 ] whileTrue:[ |
7553 con := c "sender". |
7553 c := sndr |
7554 ]. |
7554 ]. |
7555 ]. |
7555 c notNil ifTrue:[ |
7556 ]. |
7556 con := c "sender". |
7557 |
7557 ]. |
7558 "/ |
7558 ]. |
7559 "/ kludge: if it's a wrapped method, then hide the wrap-call |
7559 ]. |
7560 "/ |
7560 |
7561 method := con method. |
7561 "/ |
7562 method notNil ifTrue:[ |
7562 "/ kludge: if it's a wrapped method, then hide the wrap-call |
7563 called := con. |
7563 "/ |
7564 caller := con sender. |
7564 method := con method. |
7565 (caller notNil and:[caller receiver == method]) ifTrue:[ |
7565 method notNil ifTrue:[ |
7566 called2 := caller. |
7566 called := con. |
7567 caller2 := caller sender. |
7567 caller := con sender. |
7568 caller2 notNil ifTrue:[ |
7568 (caller notNil and:[caller receiver == method]) ifTrue:[ |
7569 (caller2 method isWrapped |
7569 called2 := caller. |
7570 and:[ caller2 method originalMethod == method ]) ifTrue:[ |
7570 caller2 := caller sender. |
7571 calledContext := called2. |
7571 caller2 notNil ifTrue:[ |
7572 con := caller2 |
7572 (caller2 method isWrapped |
7573 ]. |
7573 and:[ caller2 method originalMethod == method ]) ifTrue:[ |
7574 ]. |
7574 calledContext := called2. |
7575 |
7575 con := caller2 |
7576 ]. |
7576 ]. |
7577 caller := caller2 := nil |
7577 ]. |
7578 ]. |
7578 |
7579 |
7579 ]. |
7580 "/ with dense backtrace, skip the doIt method's context |
7580 caller := caller2 := nil |
7581 "/ (its dummy anyway) and fake that context's name |
7581 ]. |
7582 |
7582 |
7583 verboseBacktrace ~~ true ifTrue:[ |
7583 "/ with dense backtrace, skip the doIt method's context |
7584 (con isBlockContext |
7584 "/ (its dummy anyway) and fake that context's name |
7585 and:[(h := con home) == con sender |
7585 |
7586 and:[h notNil |
7586 verboseBacktrace ~~ true ifTrue:[ |
7587 and:[(self setOfHiddenCallingSelectors includes:h selector) |
7587 (con isBlockContext |
7588 and:[h method who isNil]]]]) ifTrue:[ |
7588 and:[(h := con home) == con sender |
7589 calledContext := con. |
7589 and:[h notNil |
7590 con := con sender. |
7590 and:[(self setOfHiddenCallingSelectors includes:h selector) |
7591 text removeLast. |
7591 and:[h method who isNil]]]]) ifTrue:[ |
7592 |
7592 calledContext := con. |
7593 text add:(self contextListEntryFor:con methodHome). |
7593 con := con sender. |
7594 ]. |
7594 text removeLast. |
7595 h := nil. "/ never keep refs to contexts unless you really need them ... |
7595 |
7596 ]. |
7596 text add:(self contextListEntryFor:con methodHome). |
7597 |
7597 ]. |
7598 "/ with dense backtrace, don't show contexts below the doIt |
7598 h := nil. "/ never keep refs to contexts unless you really need them ... |
7599 ( verboseBacktrace ~~ true |
7599 ]. |
7600 and:[ (self setOfHiddenCallingSelectors includes:con selector) ]) ifTrue:[ |
7600 |
7601 con := nil. |
7601 "/ with dense backtrace, don't show contexts below the doIt |
7602 ] ifFalse:[ |
7602 ( verboseBacktrace ~~ true |
7603 calledContext := con. |
7603 and:[ (self setOfHiddenCallingSelectors includes:con selector) ]) ifTrue:[ |
7604 con := con sender |
7604 con := nil. |
7605 ]. |
7605 ] ifFalse:[ |
7606 ]. |
7606 calledContext := con. |
7607 |
7607 con := con sender |
7608 " |
7608 ]. |
7609 did we reach the end ? |
7609 ]. |
7610 " |
7610 |
7611 (con isNil or:[con sender isNil]) ifTrue:[ |
7611 " |
7612 |
7612 did we reach the end ? |
7613 "/ the very last one is the startup context |
7613 " |
7614 "/ (in main) - it has nil as receiver and nil as selector |
7614 (con isNil or:[con sender isNil]) ifTrue:[ |
7615 |
7615 |
7616 (contextArray notEmpty |
7616 "/ the very last one is the startup context |
7617 and:[contextArray last selector isNil]) ifTrue:[ |
7617 "/ (in main) - it has nil as receiver and nil as selector |
7618 contextArray removeLast. |
7618 |
7619 text removeLast |
7619 (contextArray notEmpty |
7620 ]. |
7620 and:[contextArray last selector isNil]) ifTrue:[ |
7621 |
7621 contextArray removeLast. |
7622 verboseBacktrace ~~ true ifTrue:[ |
7622 text removeLast |
7623 "/ in dense mode, remove process startup contexts (if any) |
7623 ]. |
7624 |
7624 |
7625 (contextArray size > 0 |
7625 verboseBacktrace ~~ true ifTrue:[ |
7626 and:[(con := contextArray last) methodClass == Process]) ifTrue:[ |
7626 "/ in dense mode, remove process startup contexts (if any) |
7627 con selector == #start ifTrue:[ |
7627 |
7628 contextArray removeLast. |
7628 (contextArray size > 0 |
7629 text removeLast. |
7629 and:[(con := contextArray last) methodClass == Process]) ifTrue:[ |
7630 |
7630 con selector == #start ifTrue:[ |
7631 [contextArray size > 0 |
7631 contextArray removeLast. |
7632 and:[contextArray last methodHome == con]] whileTrue:[ |
7632 text removeLast. |
7633 contextArray removeLast. |
7633 |
7634 text removeLast. |
7634 [contextArray size > 0 |
7635 ] |
7635 and:[contextArray last methodHome == con]] whileTrue:[ |
7636 ] |
7636 contextArray removeLast. |
7637 ] |
7637 text removeLast. |
7638 ] |
7638 ] |
7639 ] ifFalse:[ |
7639 ] |
7640 m notNil ifTrue:[ |
7640 ] |
7641 m enable:#showMore. |
7641 ] |
7642 ]. |
7642 ] ifFalse:[ |
7643 canShowMore := true. |
7643 m notNil ifTrue:[ |
7644 text add:(resources string:'*** more walkback follows - click here to see them ***') |
7644 m enable:#showMore. |
7645 ]. |
7645 ]. |
|
7646 canShowMore := true. |
|
7647 text add:(resources string:'*** more walkback follows - click here to see them ***') |
|
7648 ]. |
7646 ]. |
7649 ]. |
7647 |
7650 |
7648 contextView setList:text. |
7651 contextView setList:text. |
7649 |
7652 |
7650 releaseInspectors ifTrue:[ |
7653 releaseInspectors ifTrue:[ |
7651 receiverInspector release. |
7654 receiverInspector release. |
7652 contextInspector release. |
7655 contextInspector release. |
7653 ]. |
7656 ]. |
7654 |
7657 |
7655 m notNil ifTrue:[ |
7658 m notNil ifTrue:[ |
7656 m disableAll:#(addBreakpoint removeBreakpoint browseImplementors browseSenders browseReceiversClass). |
7659 m disableAll:#(addBreakpoint removeBreakpoint browseImplementors browseSenders browseReceiversClass). |
7657 ]. |
7660 ]. |
7658 self updateMenuItems. |
7661 self updateMenuItems. |
7659 ^ true |
7662 ^ true |
7660 |
7663 |
7661 "Created: / 14-12-1995 / 19:10:31 / cg" |
7664 "Created: / 14-12-1995 / 19:10:31 / cg" |