aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/pprof/trace_stack_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-07-22 13:09:26 +0200
committerRuss Cox <rsc@golang.org>2015-07-22 15:47:16 +0000
commitae1ea2aa94b366107f4f92a591d102fd32ad86ae (patch)
tree762c1f7f9399e385088feff953f271f44809ca30 /src/runtime/pprof/trace_stack_test.go
parent1a99ba55df902a2657d1ccfc52a60024c22dba98 (diff)
downloadgo-ae1ea2aa94b366107f4f92a591d102fd32ad86ae.tar.xz
runtime/trace: add new package
Move tracing functions from runtime/pprof to the new runtime/trace package. Fixes #9710 Change-Id: I718bcb2ae3e5959d9f72cab5e6708289e5c8ebd5 Reviewed-on: https://go-review.googlesource.com/12511 Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/pprof/trace_stack_test.go')
-rw-r--r--src/runtime/pprof/trace_stack_test.go285
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("---")
- }
- }
-}