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