github.com/lzhfromustc/gofuzz@v0.0.0-20211116160056-151b3108bbd1/runtime/semasleep_test.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build !plan9,!windows,!js
     6  
     7  package runtime_test
     8  
     9  import (
    10  	"os/exec"
    11  	"syscall"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  // Issue #27250. Spurious wakeups to pthread_cond_timedwait_relative_np
    17  // shouldn't cause semasleep to retry with the same timeout which would
    18  // cause indefinite spinning.
    19  func TestSpuriousWakeupsNeverHangSemasleep(t *testing.T) {
    20  	if *flagQuick {
    21  		t.Skip("-quick")
    22  	}
    23  
    24  	exe, err := buildTestProg(t, "testprog")
    25  	if err != nil {
    26  		t.Fatal(err)
    27  	}
    28  
    29  	start := time.Now()
    30  	cmd := exec.Command(exe, "After1")
    31  	if err := cmd.Start(); err != nil {
    32  		t.Fatalf("Failed to start command: %v", err)
    33  	}
    34  	doneCh := make(chan error, 1)
    35  	go func() {
    36  		doneCh <- cmd.Wait()
    37  	}()
    38  
    39  	// With the repro running, we can continuously send to it
    40  	// a non-terminal signal such as SIGIO, to spuriously
    41  	// wakeup pthread_cond_timedwait_relative_np.
    42  	unfixedTimer := time.NewTimer(2 * time.Second)
    43  	for {
    44  		select {
    45  		case <-time.After(200 * time.Millisecond):
    46  			// Send the pesky signal that toggles spinning
    47  			// indefinitely if #27520 is not fixed.
    48  			cmd.Process.Signal(syscall.SIGIO)
    49  
    50  		case <-unfixedTimer.C:
    51  			t.Error("Program failed to return on time and has to be killed, issue #27520 still exists")
    52  			cmd.Process.Signal(syscall.SIGKILL)
    53  			return
    54  
    55  		case err := <-doneCh:
    56  			if err != nil {
    57  				t.Fatalf("The program returned but unfortunately with an error: %v", err)
    58  			}
    59  			if time.Since(start) < 100*time.Millisecond {
    60  				t.Fatalf("The program stopped too quickly.")
    61  			}
    62  			return
    63  		}
    64  	}
    65  }