]> Cypherpunks.ru repositories - gostls13.git/blob - src/internal/trace/v2/testdata/testprog/stacks.go
runtime: add execution tracer v2 behind GOEXPERIMENT=exectracer2
[gostls13.git] / src / internal / trace / v2 / testdata / testprog / stacks.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 stack symbolization.
6
7 //go:build ignore
8
9 package main
10
11 import (
12         "log"
13         "net"
14         "os"
15         "runtime"
16         "runtime/trace"
17         "sync"
18         "time"
19 )
20
21 func main() {
22         if err := trace.Start(os.Stdout); err != nil {
23                 log.Fatalf("failed to start tracing: %v", err)
24         }
25         defer trace.Stop() // in case of early return
26
27         // Now we will do a bunch of things for which we verify stacks later.
28         // It is impossible to ensure that a goroutine has actually blocked
29         // on a channel, in a select or otherwise. So we kick off goroutines
30         // that need to block first in the hope that while we are executing
31         // the rest of the test, they will block.
32         go func() { // func1
33                 select {}
34         }()
35         go func() { // func2
36                 var c chan int
37                 c <- 0
38         }()
39         go func() { // func3
40                 var c chan int
41                 <-c
42         }()
43         done1 := make(chan bool)
44         go func() { // func4
45                 <-done1
46         }()
47         done2 := make(chan bool)
48         go func() { // func5
49                 done2 <- true
50         }()
51         c1 := make(chan int)
52         c2 := make(chan int)
53         go func() { // func6
54                 select {
55                 case <-c1:
56                 case <-c2:
57                 }
58         }()
59         var mu sync.Mutex
60         mu.Lock()
61         go func() { // func7
62                 mu.Lock()
63                 mu.Unlock()
64         }()
65         var wg sync.WaitGroup
66         wg.Add(1)
67         go func() { // func8
68                 wg.Wait()
69         }()
70         cv := sync.NewCond(&sync.Mutex{})
71         go func() { // func9
72                 cv.L.Lock()
73                 cv.Wait()
74                 cv.L.Unlock()
75         }()
76         ln, err := net.Listen("tcp", "127.0.0.1:0")
77         if err != nil {
78                 log.Fatalf("failed to listen: %v", err)
79         }
80         go func() { // func10
81                 c, err := ln.Accept()
82                 if err != nil {
83                         log.Printf("failed to accept: %v", err)
84                         return
85                 }
86                 c.Close()
87         }()
88         rp, wp, err := os.Pipe()
89         if err != nil {
90                 log.Fatalf("failed to create a pipe: %v", err)
91         }
92         defer rp.Close()
93         defer wp.Close()
94         pipeReadDone := make(chan bool)
95         go func() { // func11
96                 var data [1]byte
97                 rp.Read(data[:])
98                 pipeReadDone <- true
99         }()
100
101         time.Sleep(100 * time.Millisecond)
102         runtime.GC()
103         runtime.Gosched()
104         time.Sleep(100 * time.Millisecond) // the last chance for the goroutines above to block
105         done1 <- true
106         <-done2
107         select {
108         case c1 <- 0:
109         case c2 <- 0:
110         }
111         mu.Unlock()
112         wg.Done()
113         cv.Signal()
114         c, err := net.Dial("tcp", ln.Addr().String())
115         if err != nil {
116                 log.Fatalf("failed to dial: %v", err)
117         }
118         c.Close()
119         var data [1]byte
120         wp.Write(data[:])
121         <-pipeReadDone
122
123         oldGoMaxProcs := runtime.GOMAXPROCS(0)
124         runtime.GOMAXPROCS(oldGoMaxProcs + 1)
125
126         trace.Stop()
127
128         runtime.GOMAXPROCS(oldGoMaxProcs)
129 }