| | |
| | |
| | |
| |
|
| | |
| |
|
| | package main |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | import "C" |
| |
|
| | import ( |
| | "bytes" |
| | "fmt" |
| | "internal/profile" |
| | "os" |
| | "runtime/pprof" |
| | "time" |
| | ) |
| |
|
| | func init() { |
| | register("CgoCallbackPprof", CgoCallbackPprof) |
| | } |
| |
|
| | func CgoCallbackPprof() { |
| | C.start_callback_pprof_thread() |
| |
|
| | var buf bytes.Buffer |
| | if err := pprof.StartCPUProfile(&buf); err != nil { |
| | fmt.Printf("Error starting CPU profile: %v\n", err) |
| | os.Exit(1) |
| | } |
| | time.Sleep(1 * time.Second) |
| | pprof.StopCPUProfile() |
| |
|
| | p, err := profile.Parse(&buf) |
| | if err != nil { |
| | fmt.Printf("Error parsing profile: %v\n", err) |
| | os.Exit(1) |
| | } |
| |
|
| | foundCallee := false |
| | for _, s := range p.Sample { |
| | funcs := flattenFrames(s) |
| | if len(funcs) == 0 { |
| | continue |
| | } |
| |
|
| | leaf := funcs[0] |
| | if leaf.Name != "main.go_callback1_callee" { |
| | continue |
| | } |
| | foundCallee = true |
| |
|
| | if len(funcs) < 2 { |
| | fmt.Printf("Profile: %s\n", p) |
| | frames := make([]string, len(funcs)) |
| | for i := range funcs { |
| | frames[i] = funcs[i].Name |
| | } |
| | fmt.Printf("FAIL: main.go_callback1_callee sample missing caller in frames %v\n", frames) |
| | os.Exit(1) |
| | } |
| |
|
| | if funcs[1].Name != "main.go_callback1" { |
| | |
| | fmt.Printf("Profile: %s\n", p) |
| | frames := make([]string, len(funcs)) |
| | for i := range funcs { |
| | frames[i] = funcs[i].Name |
| | } |
| | fmt.Printf("FAIL: main.go_callback1_callee sample caller got %s want main.go_callback1 in frames %v\n", funcs[1].Name, frames) |
| | os.Exit(1) |
| | } |
| | } |
| |
|
| | if !foundCallee { |
| | fmt.Printf("Missing main.go_callback1_callee sample in profile %s\n", p) |
| | os.Exit(1) |
| | } |
| |
|
| | fmt.Printf("OK\n") |
| | } |
| |
|
| | |
| | func flattenFrames(s *profile.Sample) []*profile.Function { |
| | ret := make([]*profile.Function, 0, len(s.Location)) |
| | for _, loc := range s.Location { |
| | for _, line := range loc.Line { |
| | ret = append(ret, line.Function) |
| | } |
| | } |
| | return ret |
| | } |
| |
|
| | |
| | func go_callback1() { |
| | |
| | |
| | go_callback1_callee() |
| | } |
| |
|
| | func go_callback1_callee() { |
| | C.c_callback() |
| |
|
| | |
| | for { |
| | } |
| | } |
| |
|
| | |
| | func go_callback2() { |
| | } |
| |
|