Source file
src/runtime/print.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/goarch"
9 "unsafe"
10 )
11
12
13
14 type hex uint64
15
16 func bytes(s string) (ret []byte) {
17 rp := (*slice)(unsafe.Pointer(&ret))
18 sp := stringStructOf(&s)
19 rp.array = sp.str
20 rp.len = sp.len
21 rp.cap = sp.len
22 return
23 }
24
25 var (
26
27
28 printBacklog [512]byte
29 printBacklogIndex int
30 )
31
32
33
34
35
36
37
38
39 func recordForPanic(b []byte) {
40 printlock()
41
42 if panicking.Load() == 0 {
43
44 for i := 0; i < len(b); {
45 n := copy(printBacklog[printBacklogIndex:], b[i:])
46 i += n
47 printBacklogIndex += n
48 printBacklogIndex %= len(printBacklog)
49 }
50 }
51
52 printunlock()
53 }
54
55 var debuglock mutex
56
57
58
59
60
61
62
63
64
65 func printlock() {
66 mp := getg().m
67 mp.locks++
68 mp.printlock++
69 if mp.printlock == 1 {
70 lock(&debuglock)
71 }
72 mp.locks--
73 }
74
75 func printunlock() {
76 mp := getg().m
77 mp.printlock--
78 if mp.printlock == 0 {
79 unlock(&debuglock)
80 }
81 }
82
83
84
85 func gwrite(b []byte) {
86 if len(b) == 0 {
87 return
88 }
89 recordForPanic(b)
90 gp := getg()
91
92
93
94
95
96 if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
97 writeErr(b)
98 return
99 }
100
101 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
102 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
103 }
104
105 func printsp() {
106 printstring(" ")
107 }
108
109 func printnl() {
110 printstring("\n")
111 }
112
113 func printbool(v bool) {
114 if v {
115 printstring("true")
116 } else {
117 printstring("false")
118 }
119 }
120
121 func printfloat(v float64) {
122 switch {
123 case v != v:
124 printstring("NaN")
125 return
126 case v+v == v && v > 0:
127 printstring("+Inf")
128 return
129 case v+v == v && v < 0:
130 printstring("-Inf")
131 return
132 }
133
134 const n = 7
135 var buf [n + 7]byte
136 buf[0] = '+'
137 e := 0
138 if v == 0 {
139 if 1/v < 0 {
140 buf[0] = '-'
141 }
142 } else {
143 if v < 0 {
144 v = -v
145 buf[0] = '-'
146 }
147
148
149 for v >= 10 {
150 e++
151 v /= 10
152 }
153 for v < 1 {
154 e--
155 v *= 10
156 }
157
158
159 h := 5.0
160 for i := 0; i < n; i++ {
161 h /= 10
162 }
163 v += h
164 if v >= 10 {
165 e++
166 v /= 10
167 }
168 }
169
170
171 for i := 0; i < n; i++ {
172 s := int(v)
173 buf[i+2] = byte(s + '0')
174 v -= float64(s)
175 v *= 10
176 }
177 buf[1] = buf[2]
178 buf[2] = '.'
179
180 buf[n+2] = 'e'
181 buf[n+3] = '+'
182 if e < 0 {
183 e = -e
184 buf[n+3] = '-'
185 }
186
187 buf[n+4] = byte(e/100) + '0'
188 buf[n+5] = byte(e/10)%10 + '0'
189 buf[n+6] = byte(e%10) + '0'
190 gwrite(buf[:])
191 }
192
193 func printcomplex(c complex128) {
194 print("(", real(c), imag(c), "i)")
195 }
196
197 func printuint(v uint64) {
198 var buf [100]byte
199 i := len(buf)
200 for i--; i > 0; i-- {
201 buf[i] = byte(v%10 + '0')
202 if v < 10 {
203 break
204 }
205 v /= 10
206 }
207 gwrite(buf[i:])
208 }
209
210 func printint(v int64) {
211 if v < 0 {
212 printstring("-")
213 v = -v
214 }
215 printuint(uint64(v))
216 }
217
218 var minhexdigits = 0
219
220 func printhex(v uint64) {
221 const dig = "0123456789abcdef"
222 var buf [100]byte
223 i := len(buf)
224 for i--; i > 0; i-- {
225 buf[i] = dig[v%16]
226 if v < 16 && len(buf)-i >= minhexdigits {
227 break
228 }
229 v /= 16
230 }
231 i--
232 buf[i] = 'x'
233 i--
234 buf[i] = '0'
235 gwrite(buf[i:])
236 }
237
238 func printpointer(p unsafe.Pointer) {
239 printhex(uint64(uintptr(p)))
240 }
241 func printuintptr(p uintptr) {
242 printhex(uint64(p))
243 }
244
245 func printstring(s string) {
246 gwrite(bytes(s))
247 }
248
249 func printslice(s []byte) {
250 sp := (*slice)(unsafe.Pointer(&s))
251 print("[", len(s), "/", cap(s), "]")
252 printpointer(sp.array)
253 }
254
255 func printeface(e eface) {
256 print("(", e._type, ",", e.data, ")")
257 }
258
259 func printiface(i iface) {
260 print("(", i.tab, ",", i.data, ")")
261 }
262
263
264
265
266
267
268 func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
269 printlock()
270 var markbuf [1]byte
271 markbuf[0] = ' '
272 minhexdigits = int(unsafe.Sizeof(uintptr(0)) * 2)
273 for i := uintptr(0); p+i < end; i += goarch.PtrSize {
274 if i%16 == 0 {
275 if i != 0 {
276 println()
277 }
278 print(hex(p+i), ": ")
279 }
280
281 if mark != nil {
282 markbuf[0] = mark(p + i)
283 if markbuf[0] == 0 {
284 markbuf[0] = ' '
285 }
286 }
287 gwrite(markbuf[:])
288 val := *(*uintptr)(unsafe.Pointer(p + i))
289 print(hex(val))
290 print(" ")
291
292
293 fn := findfunc(val)
294 if fn.valid() {
295 print("<", funcname(fn), "+", hex(val-fn.entry()), "> ")
296 }
297 }
298 minhexdigits = 0
299 println()
300 printunlock()
301 }
302
View as plain text