@@ -573,6 +573,11 @@ type reproRunnerResult struct {
573573 repro * repro.Result
574574}
575575
576+ // Run executes the reproducer 3 times with slightly different options.
577+ // The objective is to verify whether the bug triggered by the reproducer affects the base kernel.
578+ // To avoid reporting false positives, the function does not require the kernel to crash with exactly
579+ // the same crash title as in the original crash report. Any single crash is accepted.
580+ // The result is sent back over the rr.done channel.
576581func (rr * reproRunner ) Run (ctx context.Context , r * repro.Result ) {
577582 pool := rr .kernel .pool
578583 cnt := int (rr .running .Add (1 ))
@@ -583,17 +588,19 @@ func (rr *reproRunner) Run(ctx context.Context, r *repro.Result) {
583588 }()
584589
585590 ret := reproRunnerResult {origReport : r .Report , repro : r }
586-
587- var result * instance. RunResult
588- var err error
589- for i := 0 ; i < 3 ; i ++ {
591+ for doneRuns := 0 ; doneRuns < 3 ; {
592+ if ctx . Err () != nil {
593+ return
594+ }
590595 opts := r .Opts
591596 opts .Repeat = true
592- if i == 0 || i == 1 {
597+ if doneRuns < 2 {
593598 // Two times out of 3, test with Threaded=true.
594- // The third time we leave it as is in case it was important.
599+ // The third time we leave it as it was in the reproducer (in case it was important) .
595600 opts .Threaded = true
596601 }
602+ var err error
603+ var result * instance.RunResult
597604 runErr := pool .Run (ctx , func (ctx context.Context , inst * vm.Instance , updInfo dispatcher.UpdateInfo ) {
598605 var ret * instance.ExecProgInstance
599606 ret , err = instance .SetupExecProg (inst , rr .kernel .cfg , rr .kernel .reporter , nil )
@@ -606,20 +613,24 @@ func (rr *reproRunner) Run(ctx context.Context, r *repro.Result) {
606613 Opts : opts ,
607614 })
608615 })
616+ logPrefix := fmt .Sprintf ("attempt #%d to run %q on base" , doneRuns , ret .origReport .Title )
609617 if errors .Is (runErr , context .Canceled ) {
610- break
618+ // Just exit without sending anything over the channel.
619+ log .Logf (1 , "%s: aborting due to context cancelation" , logPrefix )
620+ return
621+ } else if runErr != nil || err != nil {
622+ log .Logf (1 , "%s: skipping due to errors: %v / %v" , logPrefix , runErr , err )
623+ continue
611624 }
612- crashed := result != nil && result . Report != nil
613- log . Logf ( 1 , "attempt #%d to run %q on base: crashed=%v" , i , ret . origReport . Title , crashed )
614- if crashed {
625+ doneRuns ++
626+ if result != nil && result . Report != nil {
627+ log . Logf ( 1 , "%s: crashed with %s" , logPrefix , result . Report . Title )
615628 ret .crashReport = result .Report
616629 break
630+ } else {
631+ log .Logf (1 , "%s: did not crash" , logPrefix )
617632 }
618633 }
619- if err != nil {
620- log .Errorf ("failed to run repro: %v" , err )
621- return
622- }
623634 select {
624635 case rr .done <- ret :
625636 case <- ctx .Done ():
0 commit comments