@@ -71,18 +71,20 @@ func (t *thread) Evaluate(ctx Context, c gateway.Client, headRef gateway.Referen
7171 }
7272 defer t .reset ()
7373
74+ var next * step
7475 action := stepContinue
7576 if cfg .StopOnEntry {
76- action = stepNext
77+ // If we are stopping on entry, automatically advance to the
78+ // entrypoint.
79+ action , next = stepNext , t .entrypoint
7780 }
7881
7982 var (
8083 k string
8184 refs map [string ]gateway.Reference
82- next = t .entrypoint
8385 err error
8486 )
85- for next != nil {
87+ for {
8688 event := t .needsDebug (next , action , err )
8789 if event .Reason != "" {
8890 select {
@@ -98,7 +100,9 @@ func (t *thread) Evaluate(ctx Context, c gateway.Client, headRef gateway.Referen
98100 }
99101
100102 t .setBreakpoints (ctx )
101- k , next , refs , err = t .seekNext (ctx , next , action )
103+ if k , next , refs , err = t .seekNext (ctx , next , action ); next == nil {
104+ break
105+ }
102106 }
103107 return nil
104108}
@@ -487,19 +491,24 @@ func (t *thread) setBreakpoints(ctx Context) {
487491}
488492
489493func (t * thread ) seekNext (ctx Context , from * step , action stepType ) (string , * step , map [string ]gateway.Reference , error ) {
490- // If we're at the end, return no digest to signal that
491- // we should conclude debugging.
492- var target * step
494+ // Determine how we are going to limit the scan for the next step.
495+ var limit func (s * step ) * step
493496 switch action {
494497 case stepNext :
495- target = t .continueDigest (from , from .next )
498+ limit = func (s * step ) * step {
499+ return s .next
500+ }
496501 case stepIn :
497- target = from .in
502+ limit = func (s * step ) * step {
503+ return s .in
504+ }
498505 case stepOut :
499- target = t . continueDigest ( from , from . out )
500- case stepContinue :
501- target = t . continueDigest ( from , nil )
506+ limit = func ( s * step ) * step {
507+ return s . out
508+ }
502509 }
510+
511+ target := t .continueDigest (from , limit )
503512 return t .seek (ctx , target )
504513}
505514
@@ -525,8 +534,10 @@ func (t *thread) seek(ctx Context, target *step) (k string, result *step, mounts
525534 return k , result , refs , nil
526535}
527536
528- func (t * thread ) continueDigest (from , until * step ) * step {
529- if len (t .bps ) == 0 && until == nil {
537+ func (t * thread ) continueDigest (from * step , limit func (* step ) * step ) * step {
538+ // First chance to exit early. If there's no function for limiting
539+ // the until step and no breakpoints then just go directly to the end step.
540+ if len (t .bps ) == 0 && limit == nil {
530541 return nil
531542 }
532543
@@ -539,6 +550,27 @@ func (t *thread) continueDigest(from, until *step) *step {
539550 return ok
540551 }
541552
553+ // Special case. When we aren't coming from any step we consider
554+ // whether the entrypoint itself is a breakpoint. If it is, we stop
555+ // there. Otherwise, we treat the entrypoint as the from location.
556+ if from == nil {
557+ if isBreakpoint (t .entrypoint .dgst ) {
558+ return t .entrypoint
559+ }
560+ from = t .entrypoint
561+ }
562+
563+ var until * step
564+ if limit != nil {
565+ until = limit (from )
566+ }
567+
568+ // Second chance to exit early. If we've fully resolved from and the
569+ // limit function doesn't return an end step, just go directly to the end.
570+ if len (t .bps ) == 0 && until == nil {
571+ return nil
572+ }
573+
542574 next := func (s * step ) * step {
543575 cur := s .in
544576 for cur != nil && cur != until {
0 commit comments