github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/runtime/testdata/testprog/traceback_ancestors.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 package main 6 7 import ( 8 "fmt" 9 "runtime" 10 ) 11 12 func init() { 13 register("TracebackAncestors", TracebackAncestors) 14 } 15 16 const numGoroutines = 3 17 const numFrames = 2 18 19 func TracebackAncestors() { 20 w := make(chan struct{}) 21 recurseThenCallGo(w, numGoroutines, numFrames) 22 <-w 23 printStack() 24 close(w) 25 } 26 27 func printStack() { 28 buf := make([]byte, 1024) 29 for { 30 n := runtime.Stack(buf, true) 31 if n < len(buf) { 32 fmt.Print(string(buf[:n])) 33 return 34 } 35 buf = make([]byte, 2*len(buf)) 36 } 37 } 38 39 func recurseThenCallGo(w chan struct{}, frames int, goroutines int) { 40 if frames == 0 { 41 // Signal to TracebackAncestors that we are done recursing and starting goroutines. 42 w <- struct{}{} 43 <-w 44 return 45 } 46 if goroutines == 0 { 47 // Start the next goroutine now that there are no more recursions left 48 // for this current goroutine. 49 go recurseThenCallGo(w, frames-1, numFrames) 50 return 51 } 52 recurseThenCallGo(w, frames, goroutines-1) 53 }