1
2
3
4
5
6
7 package base
8
9 import (
10 "fmt"
11 "log"
12 "os"
13 "reflect"
14 "strconv"
15 "strings"
16 )
17
18
19 var Debug DebugFlags
20
21
22
23
24
25
26
27 type DebugFlags struct {
28 Append int `help:"print information about append compilation"`
29 Checkptr int `help:"instrument unsafe pointer conversions"`
30 Closure int `help:"print information about closure compilation"`
31 DclStack int `help:"run internal dclstack check"`
32 Defer int `help:"print information about defer compilation"`
33 DisableNil int `help:"disable nil checks"`
34 DumpPtrs int `help:"show Node pointers values in dump output"`
35 DwarfInl int `help:"print information about DWARF inlined function creation"`
36 Export int `help:"print export data"`
37 GCProg int `help:"print dump of GC programs"`
38 InlFuncsWithClosures int `help:"allow functions with closures to be inlined"`
39 Libfuzzer int `help:"enable coverage instrumentation for libfuzzer"`
40 LocationLists int `help:"print information about DWARF location list creation"`
41 Nil int `help:"print information about nil checks"`
42 NoOpenDefer int `help:"disable open-coded defers"`
43 PCTab string `help:"print named pc-value table"`
44 Panic int `help:"show all compiler panics"`
45 Slice int `help:"print information about slice compilation"`
46 SoftFloat int `help:"force compiler to emit soft-float code"`
47 TypeAssert int `help:"print information about type assertion inlining"`
48 TypecheckInl int `help:"eager typechecking of inline function bodies"`
49 WB int `help:"print information about write barriers"`
50 ABIWrap int `help:"print information about ABI wrapper generation"`
51
52 any bool
53 }
54
55
56 func (d *DebugFlags) Any() bool { return d.any }
57
58 type debugField struct {
59 name string
60 help string
61 val interface{}
62 }
63
64 var debugTab []debugField
65
66 func init() {
67 v := reflect.ValueOf(&Debug).Elem()
68 t := v.Type()
69 for i := 0; i < t.NumField(); i++ {
70 f := t.Field(i)
71 if f.Name == "any" {
72 continue
73 }
74 name := strings.ToLower(f.Name)
75 help := f.Tag.Get("help")
76 if help == "" {
77 panic(fmt.Sprintf("base.Debug.%s is missing help text", f.Name))
78 }
79 ptr := v.Field(i).Addr().Interface()
80 switch ptr.(type) {
81 default:
82 panic(fmt.Sprintf("base.Debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
83 case *int, *string:
84
85 }
86 debugTab = append(debugTab, debugField{name, help, ptr})
87 }
88 }
89
90
91
92
93 var DebugSSA func(phase, flag string, val int, valString string) string
94
95
96 func parseDebug(debugstr string) {
97
98 if debugstr == "" {
99 return
100 }
101 Debug.any = true
102 Split:
103 for _, name := range strings.Split(debugstr, ",") {
104 if name == "" {
105 continue
106 }
107
108 if name == "help" {
109 fmt.Print(debugHelpHeader)
110 maxLen := len("ssa/help")
111 for _, t := range debugTab {
112 if len(t.name) > maxLen {
113 maxLen = len(t.name)
114 }
115 }
116 for _, t := range debugTab {
117 fmt.Printf("\t%-*s\t%s\n", maxLen, t.name, t.help)
118 }
119
120 fmt.Printf("\t%-*s\t%s\n", maxLen, "ssa/help", "print help about SSA debugging")
121 fmt.Print(debugHelpFooter)
122 os.Exit(0)
123 }
124 val, valstring, haveInt := 1, "", true
125 if i := strings.IndexAny(name, "=:"); i >= 0 {
126 var err error
127 name, valstring = name[:i], name[i+1:]
128 val, err = strconv.Atoi(valstring)
129 if err != nil {
130 val, haveInt = 1, false
131 }
132 }
133 for _, t := range debugTab {
134 if t.name != name {
135 continue
136 }
137 switch vp := t.val.(type) {
138 case nil:
139
140 case *string:
141 *vp = valstring
142 case *int:
143 if !haveInt {
144 log.Fatalf("invalid debug value %v", name)
145 }
146 *vp = val
147 default:
148 panic("bad debugtab type")
149 }
150 continue Split
151 }
152
153 if DebugSSA != nil && strings.HasPrefix(name, "ssa/") {
154
155
156
157 phase := name[4:]
158 flag := "debug"
159 if i := strings.Index(phase, "/"); i >= 0 {
160 flag = phase[i+1:]
161 phase = phase[:i]
162 }
163 err := DebugSSA(phase, flag, val, valstring)
164 if err != "" {
165 log.Fatalf(err)
166 }
167 continue Split
168 }
169 log.Fatalf("unknown debug key -d %s\n", name)
170 }
171 }
172
173 const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]
174
175 <key> is one of:
176
177 `
178
179 const debugHelpFooter = `
180 <value> is key-specific.
181
182 Key "checkptr" supports values:
183 "0": instrumentation disabled
184 "1": conversions involving unsafe.Pointer are instrumented
185 "2": conversions to unsafe.Pointer force heap allocation
186
187 Key "pctab" supports values:
188 "pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata"
189 `
190
View as plain text