... |
... |
@@ -595,77 +595,67 @@ interpretBCO (Capability* cap) |
595
|
595
|
debugBelch("\n\n");
|
596
|
596
|
);
|
597
|
597
|
|
598
|
|
- // On entering interpretBCO, check if the step-out flag is set for this
|
599
|
|
- // thread. If yes, push a step-out frame between the first frame and second
|
600
|
|
- // frame.
|
601
|
|
- //
|
602
|
|
- // This frame will be responsible for enabling the first breakpoint that
|
603
|
|
- // comes after it is evaluated (i.e. for breaking right after evaluation of
|
604
|
|
- // this bco returns).
|
605
|
|
- //
|
606
|
|
- // See Note [Debugger: Step-out] for details
|
607
|
|
- // TODOOOOOOOOOOOOOOOO UPDATES
|
|
598
|
+ /* If the "step-out" flag is set for this thread, find the *continuation*
|
|
599
|
+ * BCO on the stack and activate its breakpoint specifically. Be careful to
|
|
600
|
+ * use SafeSp macros to handle stack underflows.
|
|
601
|
+ *
|
|
602
|
+ * See Note [Debugger: Step-out]
|
|
603
|
+ */
|
608
|
604
|
if (cap->r.rCurrentTSO->flags & TSO_STOP_AFTER_RETURN) {
|
609
|
605
|
|
610
|
|
- StgPtr frame;
|
611
|
606
|
StgBCO* bco;
|
612
|
607
|
StgWord16* bco_instrs;
|
613
|
|
- frame = Sp;
|
614
|
|
-
|
615
|
|
- frame += stack_frame_sizeW((StgClosure *)frame); // ignore first BCO because this is the one we are stopped at. We only want to stop at the next one up the stack.
|
616
|
|
-
|
617
|
|
- // Insert the stg_stop_after_ret_frame after the first frame that is NOT a
|
618
|
|
- // case continuation BCO.
|
619
|
|
- //
|
620
|
|
- // Do /not/ insert a step-out frame between case continuation
|
621
|
|
- // frames and their parent BCO frame. Case continuation BCOs may have
|
622
|
|
- // non-local stack references. See Note [Case continuation BCOs].
|
623
|
|
-
|
624
|
|
- // UPDATE COMMENTS: NOW FIND STOP FRAME AND ACTIVATE IT
|
625
|
|
- while (get_itbl((StgClosure*)frame)->type != RET_BCO)
|
626
|
|
- { // TODO: HANDLE IF STACK BOTTOM
|
627
|
|
- frame += stack_frame_sizeW((StgClosure *)frame);
|
628
|
|
- printf("Wasn't right, keep going\n");
|
629
|
|
- }
|
630
|
|
-
|
631
|
|
- printf("Found frame\n");
|
|
608
|
+ StgHalfWord type;
|
632
|
609
|
|
633
|
|
- // TODO: Handle stack bottom edge case!? if frame == STACK BOTTOM...
|
634
|
|
- // stack underflow *and* overflow...
|
|
610
|
+ /* Store the entry Sp; traverse the stack modifying Sp (using Sp macros);
|
|
611
|
+ * restore Sp afterwards. */
|
|
612
|
+ StgPtr restoreStackPointer = Sp;
|
635
|
613
|
|
636
|
|
- // Then write it.
|
637
|
|
- // ((StgStopAfterRetFrame*)frame)->enabled = 1;
|
|
614
|
+ /* The first BCO on the stack is the one we are already stopped at.
|
|
615
|
+ * Skip it. */
|
|
616
|
+ Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp));
|
638
|
617
|
|
639
|
|
- // TODO: Write profiling info if needed
|
|
618
|
+ /* Traverse upwards until continuation BCO, or the end */
|
|
619
|
+ while ((type = get_itbl((StgClosure*)Sp)->type) != RET_BCO
|
|
620
|
+ && type != STOP_FRAME) {
|
|
621
|
+ Sp = SafeSpWP(stack_frame_sizeW((StgClosure *)Sp));
|
|
622
|
+ }
|
640
|
623
|
|
641
|
|
- bco = (StgBCO*)(frame[1]); // BCO is first argument of RET_BCO frame
|
642
|
|
- ASSERT(get_itbl((StgClosure*)bco)->type == BCO);
|
643
|
|
- bco_instrs = (StgWord16*)(bco->instrs->payload);
|
|
624
|
+ ASSERT(type == RET_BCO || type == STOP_FRAME);
|
|
625
|
+ if (type == RET_BCO) {
|
644
|
626
|
|
645
|
|
- if ((bco_instrs[0] /* BRK_FUN ALWAYS FIRST INSTR */ & 0xFF) == bci_BRK_FUN) {
|
646
|
|
- printf("Found BRK FUN\n");
|
647
|
|
- printf("Enabling breakpoint of BCO: %p\n", bco);
|
|
627
|
+ bco = (StgBCO*)(SpW(1)); // BCO is first arg of a RET_BCO
|
|
628
|
+ ASSERT(get_itbl((StgClosure*)bco)->type == BCO);
|
|
629
|
+ bco_instrs = (StgWord16*)(bco->instrs->payload);
|
648
|
630
|
|
649
|
|
- int brk_array, tick_index;
|
650
|
|
- StgArrBytes *breakPoints;
|
651
|
|
- StgPtr* ptrs;
|
|
631
|
+ /* A breakpoint instruction (BRK_FUN or BRK_ALTS) is always the first
|
|
632
|
+ * instruction in a BCO */
|
|
633
|
+ if ((bco_instrs[0] & 0xFF) == bci_BRK_FUN) {
|
|
634
|
+ int brk_array, tick_index;
|
|
635
|
+ StgArrBytes *breakPoints;
|
|
636
|
+ StgPtr* ptrs;
|
652
|
637
|
|
653
|
|
- ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
|
654
|
|
- brk_array = bco_instrs[1];
|
655
|
|
- tick_index = bco_instrs[6];
|
|
638
|
+ ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
|
|
639
|
+ brk_array = bco_instrs[1];
|
|
640
|
+ tick_index = bco_instrs[6];
|
656
|
641
|
|
657
|
|
- breakPoints = (StgArrBytes *) BCO_PTR(brk_array);
|
658
|
|
- // ACTIVATE
|
659
|
|
- ((StgInt*)breakPoints->payload)[tick_index] = 0;
|
|
642
|
+ breakPoints = (StgArrBytes *) BCO_PTR(brk_array);
|
|
643
|
+ // ACTIVATE the breakpoint by tick index
|
|
644
|
+ ((StgInt*)breakPoints->payload)[tick_index] = 0;
|
|
645
|
+ }
|
|
646
|
+ else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) {
|
|
647
|
+ // ACTIVATE BRK_ALTS by setting its only argument to ON
|
|
648
|
+ bco_instrs[1] = 1;
|
|
649
|
+ }
|
660
|
650
|
}
|
661
|
|
- else if ((bco_instrs[0] & 0xFF) == bci_BRK_INTERNAL) {
|
662
|
|
- printf("Found BRK INTERNAL\n");
|
663
|
|
- printf("Enabling breakpoint of BCO: %p\n", bco);
|
664
|
|
- bco_instrs[1] = 1; // ACTIVATE
|
|
651
|
+ else /* type == STOP_FRAME */ {
|
|
652
|
+ /* No continuation frame to further stop at: Nothing to do */
|
665
|
653
|
}
|
666
|
654
|
|
667
|
|
- // Frame was pushed, mark as done to not do it again
|
|
655
|
+ // Mark as done to not do it again
|
668
|
656
|
cap->r.rCurrentTSO->flags &= ~TSO_STOP_AFTER_RETURN;
|
|
657
|
+
|
|
658
|
+ Sp = restoreStackPointer;
|
669
|
659
|
}
|
670
|
660
|
|
671
|
661
|
// ------------------------------------------------------------------------
|