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.

Reply via email to