1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "bufio"
19 "cmd/internal/objabi"
20 "cmd/internal/pgo"
21 "cmd/internal/telemetry/counter"
22 "flag"
23 "fmt"
24 "log"
25 "os"
26 )
27
28 func usage() {
29 fmt.Fprintf(os.Stderr, "usage: go tool preprofile [-v] [-o output] -i input\n\n")
30 flag.PrintDefaults()
31 os.Exit(2)
32 }
33
34 var (
35 output = flag.String("o", "", "output file path")
36 input = flag.String("i", "", "input pprof file path")
37 )
38
39 func preprocess(profileFile string, outputFile string) error {
40 f, err := os.Open(profileFile)
41 if err != nil {
42 return fmt.Errorf("error opening profile: %w", err)
43 }
44 defer f.Close()
45
46 r := bufio.NewReader(f)
47 d, err := pgo.FromPProf(r)
48 if err != nil {
49 return fmt.Errorf("error parsing profile: %w", err)
50 }
51
52 var out *os.File
53 if outputFile == "" {
54 out = os.Stdout
55 } else {
56 out, err = os.Create(outputFile)
57 if err != nil {
58 return fmt.Errorf("error creating output file: %w", err)
59 }
60 defer out.Close()
61 }
62
63 w := bufio.NewWriter(out)
64 if _, err := d.WriteTo(w); err != nil {
65 return fmt.Errorf("error writing output file: %w", err)
66 }
67
68 return nil
69 }
70
71 func main() {
72 objabi.AddVersionFlag()
73
74 log.SetFlags(0)
75 log.SetPrefix("preprofile: ")
76 counter.Open()
77
78 flag.Usage = usage
79 flag.Parse()
80 counter.Inc("preprofile/invocations")
81 counter.CountFlags("preprofile/flag:", *flag.CommandLine)
82 if *input == "" {
83 log.Print("Input pprof path required (-i)")
84 usage()
85 }
86
87 if err := preprocess(*input, *output); err != nil {
88 log.Fatal(err)
89 }
90 }
91
View as plain text