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