diff options
Diffstat (limited to 'src/runtime/pprof/trace_stack_test.go')
| -rw-r--r-- | src/runtime/pprof/trace_stack_test.go | 285 |
1 files changed, 0 insertions, 285 deletions
diff --git a/src/runtime/pprof/trace_stack_test.go b/src/runtime/pprof/trace_stack_test.go deleted file mode 100644 index 984879dc92..0000000000 --- a/src/runtime/pprof/trace_stack_test.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pprof_test - -import ( - "bytes" - "internal/trace" - "net" - "os" - "runtime" - . "runtime/pprof" - "sync" - "testing" - "time" -) - -// TestTraceSymbolize tests symbolization and that events has proper stacks. -// In particular that we strip bottom uninteresting frames like goexit, -// top uninteresting frames (runtime guts). -func TestTraceSymbolize(t *testing.T) { - skipTraceTestsIfNeeded(t) - if runtime.GOOS == "nacl" { - t.Skip("skipping: nacl tests fail with 'failed to symbolize trace: failed to start addr2line'") - } - buf := new(bytes.Buffer) - if err := StartTrace(buf); err != nil { - t.Fatalf("failed to start tracing: %v", err) - } - - // Now we will do a bunch of things for which we verify stacks later. - // It is impossible to ensure that a goroutine has actually blocked - // on a channel, in a select or otherwise. So we kick off goroutines - // that need to block first in the hope that while we are executing - // the rest of the test, they will block. - go func() { - select {} - }() - go func() { - var c chan int - c <- 0 - }() - go func() { - var c chan int - <-c - }() - done1 := make(chan bool) - go func() { - <-done1 - }() - done2 := make(chan bool) - go func() { - done2 <- true - }() - c1 := make(chan int) - c2 := make(chan int) - go func() { - select { - case <-c1: - case <-c2: - } - }() - var mu sync.Mutex - mu.Lock() - go func() { - mu.Lock() - mu.Unlock() - }() - var wg sync.WaitGroup - wg.Add(1) - go func() { - wg.Wait() - }() - cv := sync.NewCond(&sync.Mutex{}) - go func() { - cv.L.Lock() - cv.Wait() - cv.L.Unlock() - }() - ln, err := net.Listen("tcp", "localhost:0") - if err != nil { - t.Fatalf("failed to listen: %v", err) - } - go func() { - c, err := ln.Accept() - if err != nil { - t.Fatalf("failed to accept: %v", err) - } - c.Close() - }() - rp, wp, err := os.Pipe() - if err != nil { - t.Fatalf("failed to create a pipe: %v", err) - } - defer rp.Close() - defer wp.Close() - pipeReadDone := make(chan bool) - go func() { - var data [1]byte - rp.Read(data[:]) - pipeReadDone <- true - }() - - time.Sleep(time.Millisecond) - runtime.GC() - runtime.Gosched() - time.Sleep(time.Millisecond) // the last chance for the goroutines above to block - done1 <- true - <-done2 - select { - case c1 <- 0: - case c2 <- 0: - } - mu.Unlock() - wg.Done() - cv.Signal() - c, err := net.Dial("tcp", ln.Addr().String()) - if err != nil { - t.Fatalf("failed to dial: %v", err) - } - c.Close() - var data [1]byte - wp.Write(data[:]) - <-pipeReadDone - - StopTrace() - events, _, err := parseTrace(buf) - if err != nil { - t.Fatalf("failed to parse trace: %v", err) - } - err = trace.Symbolize(events, os.Args[0]) - if err != nil { - t.Fatalf("failed to symbolize trace: %v", err) - } - - // Now check that the stacks are correct. - type frame struct { - Fn string - Line int - } - type eventDesc struct { - Type byte - Stk []frame - } - want := []eventDesc{ - eventDesc{trace.EvGCStart, []frame{ - frame{"runtime.GC", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 106}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoSched, []frame{ - frame{"runtime/pprof_test.TestTraceSymbolize", 107}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoCreate, []frame{ - frame{"runtime/pprof_test.TestTraceSymbolize", 39}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoStop, []frame{ - frame{"runtime.block", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func1", 38}, - }}, - eventDesc{trace.EvGoStop, []frame{ - frame{"runtime.chansend1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func2", 42}, - }}, - eventDesc{trace.EvGoStop, []frame{ - frame{"runtime.chanrecv1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func3", 46}, - }}, - eventDesc{trace.EvGoBlockRecv, []frame{ - frame{"runtime.chanrecv1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func4", 50}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"runtime.chansend1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 109}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoBlockSend, []frame{ - frame{"runtime.chansend1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func5", 54}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"runtime.chanrecv1", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 110}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoBlockSelect, []frame{ - frame{"runtime.selectgo", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func6", 59}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"runtime.selectgo", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 111}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoBlockSync, []frame{ - frame{"sync.(*Mutex).Lock", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func7", 67}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"sync.(*Mutex).Unlock", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 115}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoBlockSync, []frame{ - frame{"sync.(*WaitGroup).Wait", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func8", 73}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"sync.(*WaitGroup).Add", 0}, - frame{"sync.(*WaitGroup).Done", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 116}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoBlockCond, []frame{ - frame{"sync.(*Cond).Wait", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func9", 78}, - }}, - eventDesc{trace.EvGoUnblock, []frame{ - frame{"sync.(*Cond).Signal", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 117}, - frame{"testing.tRunner", 0}, - }}, - eventDesc{trace.EvGoSleep, []frame{ - frame{"time.Sleep", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize", 108}, - frame{"testing.tRunner", 0}, - }}, - } - // Stacks for the following events are OS-dependent due to OS-specific code in net package. - if runtime.GOOS != "windows" && runtime.GOOS != "plan9" { - want = append(want, []eventDesc{ - eventDesc{trace.EvGoBlockNet, []frame{ - frame{"net.(*netFD).accept", 0}, - frame{"net.(*TCPListener).AcceptTCP", 0}, - frame{"net.(*TCPListener).Accept", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func10", 86}, - }}, - eventDesc{trace.EvGoSysCall, []frame{ - frame{"syscall.read", 0}, - frame{"syscall.Read", 0}, - frame{"os.(*File).read", 0}, - frame{"os.(*File).Read", 0}, - frame{"runtime/pprof_test.TestTraceSymbolize.func11", 101}, - }}, - }...) - } - matched := make([]bool, len(want)) - for _, ev := range events { - wantLoop: - for i, w := range want { - if matched[i] || w.Type != ev.Type || len(w.Stk) != len(ev.Stk) { - continue - } - - for fi, f := range ev.Stk { - wf := w.Stk[fi] - if wf.Fn != f.Fn || wf.Line != 0 && wf.Line != f.Line { - continue wantLoop - } - } - matched[i] = true - } - } - for i, m := range matched { - if m { - continue - } - w := want[i] - t.Errorf("did not match event %v at %v:%v", trace.EventDescriptions[w.Type].Name, w.Stk[0].Fn, w.Stk[0].Line) - t.Errorf("seen the following events of this type:") - for _, ev := range events { - if ev.Type != w.Type { - continue - } - for _, f := range ev.Stk { - t.Logf(" %v:%v", f.Fn, f.Line) - } - t.Logf("---") - } - } -} |
