Repository: go
Issue: doc: runtime/pprof: block profiler documentation needs some love
Labels: Documentation,help wanted,NeedsFix

Reading https://golang.org/pkg/runtime/pprof/ does not make clear how to use the blocking profiler in an application.

The blog post at http://blog.golang.org/profiling-go-programs (2011) finishes with:

> The goroutine blocking profile will be explained in a future post. Stay tuned.

But I cannot find any follow up.

In a post [to the mailing list](https://groups.google.com/d/topic/golang-nuts/QqZedWrqgOc/discussion) someone said that Brad mentioned it [briefly in a talk](https://github.com/bradfitz/talk-yapc-asia-2015/blob/master/talk.md), but he only mentions `go test -blockprofile`, and I'm not running tests.

I have used several search engines to look for materials but they all point at runtime/pprof and other not-useful-to-me blog posts. Getting creative, I just thought I would dive in and try to use it:

``` go
    f, err := os.Create("block.pprof")
    if err != nil {
        log.Fatal(err)
    }
    p := pprof.Lookup("block")
    defer func() {
        err := p.WriteTo(f, 0)
        if err != nil {
            log.Fatalf("Error writing block profile: %v", err)
        }
    }()
```

Which results in a file with contents which don't look useful:

```
--- contention:
cycles/second=2494323129
```

Finally, I [searched github for "pprof lookup block"](https://github.com/search?l=go&q=pprof+lookup+block&type=Code&utf8=%E2%9C%93). This appears to show some examples of its use and reveals the function [`runtime.SetBlockProfile`](https://golang.org/pkg/runtime/#SetBlockProfileRate). However, this function is also quite confusingly documented.

> `func SetBlockProfileRate(rate int)`
> 
> SetBlockProfileRate controls the fraction of goroutine blocking events that are reported in the blocking profile. The profiler aims to sample an average of one blocking event per rate nanoseconds spent blocked.
> 
> To include every blocking event in the profile, pass rate = 1. To turn off profiling entirely, pass rate <= 0.

Is `rate` really a fraction, between 0 and 1? If so, since it is an `int`, it would seem my options are to either pass it 0 or 1, but the suggestion that it is a fraction seems contradictory. Is it necessary to call this function to start the profiler?

To conclude, the documentation at `runtime/pprof` really needs to make it clear how to use the block profiler. Some facts which are still not clear to me, even after reading code found elsewhere:
- What kind of questions can be answered with a block profile?
  - Will it help me identify contention on a channel write?
  - Will it tell me where in my program is contending?
- How do I use the block profiler in my application?
- Is there something one must do to start the block profiler?
- How often can one write a block profile? Once at the end of a running program?
- Why is there not a `StartBlockProfiler` function?
- How does one interpret the results of a block profile?

P.S. I did eventually find [Debugging performance issues in Go programs](https://software.intel.com/en-us/blogs/2014/05/10/debugging-performance-issues-in-go-programs), which answers some of these questions. But unfortunately it was not easy to find for some reason.