Source file src/internal/trace/testdata/testprog/wait-on-pipe.go

     1  // Copyright 2023 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  // Tests a goroutine sitting blocked in a syscall for
     6  // an entire generation. This is a regression test for
     7  // #65196.
     8  
     9  //go:build ignore
    10  
    11  package main
    12  
    13  import (
    14  	"log"
    15  	"os"
    16  	"runtime/trace"
    17  	"syscall"
    18  	"time"
    19  )
    20  
    21  func main() {
    22  	// Create a pipe to block on.
    23  	var p [2]int
    24  	if err := syscall.Pipe(p[:]); err != nil {
    25  		log.Fatalf("failed to create pipe: %v", err)
    26  	}
    27  	rfd, wfd := p[0], p[1]
    28  
    29  	// Create a goroutine that blocks on the pipe.
    30  	done := make(chan struct{})
    31  	go func() {
    32  		var data [1]byte
    33  		_, err := syscall.Read(rfd, data[:])
    34  		if err != nil {
    35  			log.Fatalf("failed to read from pipe: %v", err)
    36  		}
    37  		done <- struct{}{}
    38  	}()
    39  
    40  	// Give the goroutine ample chance to block on the pipe.
    41  	time.Sleep(10 * time.Millisecond)
    42  
    43  	// Start tracing.
    44  	if err := trace.Start(os.Stdout); err != nil {
    45  		log.Fatalf("failed to start tracing: %v", err)
    46  	}
    47  
    48  	// This isn't enough to have a full generation pass by default,
    49  	// but it is generally enough in stress mode.
    50  	time.Sleep(100 * time.Millisecond)
    51  
    52  	// Write to the pipe to unblock it.
    53  	if _, err := syscall.Write(wfd, []byte{10}); err != nil {
    54  		log.Fatalf("failed to write to pipe: %v", err)
    55  	}
    56  
    57  	// Wait for the goroutine to unblock and start running.
    58  	// This is helpful to catch incorrect information written
    59  	// down for the syscall-blocked goroutine, since it'll start
    60  	// executing, and that execution information will be
    61  	// inconsistent.
    62  	<-done
    63  
    64  	// Stop tracing.
    65  	trace.Stop()
    66  }
    67  

View as plain text