Ah, excellent. Good catch. I learned something about defer. The ordering of the close was my problem, however. The way I *actually* handle closing the trace is:
func (t *FileTracer) Stop() error { if t == nil { return nil } trace.Stop() return t.f.Close() } On Friday, August 4, 2017 at 12:42:31 AM UTC-6, Dave Cheney wrote: > > > > On Friday, 4 August 2017 15:46:39 UTC+10, Evan Leis wrote: >> >> I ran into this same problem, and found this post! >> It looks like you're making the same simple mistake I was: >> >> # erroneous: >> defer f.Close() >> defer trace.Stop() >> > > Defers run in LIFO order. This sample will call trace.Stop, then > f.Close(). > >> >> You must stop the trace *before* closing the output file. >> >> # corrected: >> defer func() { >> trace.Stop() >> panic(f.Close()) # Be sure to handle file-closing errors. They're >> important!! >> } >> > > This sample will panic the program every time > > >> >> On Tuesday, October 11, 2016 at 8:21:17 AM UTC-6, xavier zebier wrote: >>> >>> Hello, >>> I m trying to use the go tool trace. My code is >>> >>> >>> package main >>> >>> import ( >>> "flag" >>> "fmt" >>> "math" >>> "net/http" >>> "os" >>> "runtime" >>> "runtime/trace" >>> "time" >>> ) >>> >>> func indexHandler(w http.ResponseWriter, r *http.Request) { >>> primesInRangeParallel(10, 64) >>> fmt.Fprintf(w, "hello world, I'm running on %s with an %s CPU ", >>> runtime.GOOS, runtime.GOARCH) >>> >>> } >>> >>> func main() { >>> flag.Parse() >>> f, errs := os.Create(time.Now().Format("2006-01-02T150405.out")) >>> if errs != nil { >>> panic(errs) >>> } >>> >>> if err := trace.Start(f); err != nil { >>> panic(err) >>> } >>> >>> defer f.Close() >>> defer trace.Stop() >>> http.HandleFunc("/", indexHandler) >>> >>> http.ListenAndServe(":8080", nil) >>> } >>> >>> // We will use this struct to communicate results via a channel >>> type PrimeResult struct { >>> number int64 // A number >>> prime bool // Is prime or not >>> } >>> >>> /** >>> * A function to return a prime calculation over a channel. This way >>> * we don't need to have 2 versions of isPrime function, one for >>> * sequential calculations and another for paralel >>> */ >>> >>> func isPrimeAsync(number int64, channel chan PrimeResult) { >>> >>> result := new(PrimeResult) >>> result.number = number >>> result.prime = isPrime(number) >>> channel <- *result >>> } >>> >>> /** >>> * Accepts a range of integers [min, max] and a channel and it executes >>> * in PARALEL the processes that check if a number is prime or not. >>> * >>> * This function does nothing with the result. In another point, somebody >>> * will have to read the channel and process the results >>> */ >>> func firePrimeCalculations(min int64, max int64, channel chan >>> PrimeResult) { >>> var i int64 >>> for i = min; i <= max; i++ { >>> go isPrimeAsync(i, channel) >>> } >>> } >>> >>> /** >>> * Accepts a range of integers [min, max] and >>> * returns an array with all the prime numbers in this range. >>> * >>> * Execution is done in paralel. First it fires all the >>> * processes that check for a prime number. These processes >>> * will write the result in a channel. >>> * >>> * We will receive the results over this channel creating the >>> * list of prime numbers and returning it >>> * >>> */ >>> >>> func primesInRangeParallel(min int64, max int64) []int64 { >>> var primeNumbers []int64 >>> var res PrimeResult >>> var prev int64 >>> >>> channel := make(chan PrimeResult) >>> defer close(channel) >>> >>> go firePrimeCalculations(min, max, channel) >>> >>> prev = 0 >>> for i := min; i <= max; i++ { >>> res = <-channel >>> if res.prime { >>> primeNumbers = append(primeNumbers, res.number) >>> >>> done := 100 * (i - min) / (max - min) >>> if prev != done { >>> fmt.Printf("%d %% done.\n", done) >>> prev = done >>> } >>> } >>> } >>> return primeNumbers >>> } >>> func isPrime(candidate int64) bool { >>> var i, limit int64 >>> >>> if candidate == 2 { >>> return true >>> } >>> >>> if math.Mod(float64(candidate), 2) == 0 { >>> return false >>> } >>> >>> limit = int64(math.Ceil(math.Sqrt(float64(candidate)))) >>> for i = 3; i <= limit; i += 2 { //Only odd numbers >>> if math.Mod(float64(candidate), float64(i)) == 0 { >>> return false >>> } >>> } >>> return true >>> } >>> >>> The prime number calculation is basically there to get some calculation. >>> >>> My go env command gives : >>> >>> C:\repo\gonew\src\github.com\tixu\trace>go env >>> set GOARCH=amd64 >>> set GOBIN= >>> set GOEXE=.exe >>> set GOHOSTARCH=amd64 >>> set GOHOSTOS=windows >>> set GOOS=windows >>> set GOPATH=c:\repo\gonew >>> set GORACE= >>> set GOROOT=C:\Go >>> set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64 >>> set CC=gcc >>> set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 >>> set CXX=g++ >>> set CGO_ENABLED=1 >>> >>> >>> >>> And I get the following error : >>> >>> C:\repo\gonew\src\github.com\tixu\trace>go tool trace Trace >>> 2016-10-11T153554.out >>> 2016/10/11 15:36:45 Parsing trace... >>> failed to parse trace: no EvFrequency event >>> >>> Can you help me .? >>> >>> Thanks in advance, >>> >>> Xavier >>> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.