This repository contains an experimental C allocation profiler for Go.
WARNING: This is very much a work in progress. It still needs plenty of work to be production-ready. Use at your own peril!
It's been lightly tested on Linux (Ubuntu 20.04) and macos (Big Sur).
On macos, you don't need to do anything special.
On Linux, you'll need a linker that supports the --wrap argument (such as the GNU
linker, or mold) which is required to provide replacements for the allocation
functions since dlsym uses calloc.
For Go versions prior to Go 1.15, you will also need to explicitly allow this argument for use by CGo by setting the following environment variable:
export CGO_LDFLAGS_ALLOW="-Wl,--wrap=.*"
Import this package and use the cmemprof.Profiler interface to start and stop
profiling:
package main
import (
"os"
"github.com/nsrip-dd/cmemprof"
)
func main() {
var profiler cmemprof.Profile
profiler.Start(512*1024)
defer func() {
f, _ := os.Create("cmem.pprof")
defer f.Close()
p, err := profiler.Stop()
if err != nil {
return
}
p.Write(f)
}
// your code here
}You will also need to import a cgo symbolizer such as
github.com/ianlancetaylor/cgosymbolizer somewhere in your program to see the C
portion of call stacks in the profiles.
- It's not optimized so there is noticeable overhead when the profiler is enabled.
- This library has a few workarounds to avoid crashes due to unusual interactions between the Go runtime, cgo-generated code, and intercepting malloc. These workarounds depend on unstable implementation details. As such, this code may break your program for future Go releases. Use with caution.