...
Source file src/runtime/print.go
1
2
3
4
5 package runtime
6
7 import (
8 "runtime/internal/atomic"
9 "runtime/internal/sys"
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 func printhex(v uint64) {
220 const dig = "0123456789abcdef"
221 var buf [100]byte
222 i := len(buf)
223 for i--; i > 0; i-- {
224 buf[i] = dig[v%16]
225 if v < 16 {
226 break
227 }
228 v /= 16
229 }
230 i--
231 buf[i] = 'x'
232 i--
233 buf[i] = '0'
234 gwrite(buf[i:])
235 }
236
237 func printpointer(p unsafe.Pointer) {
238 printhex(uint64(uintptr(p)))
239 }
240
241 func printstring(s string) {
242 gwrite(bytes(s))
243 }
244
245 func printslice(s []byte) {
246 sp := (*slice)(unsafe.Pointer(&s))
247 print("[", len(s), "/", cap(s), "]")
248 printpointer(sp.array)
249 }
250
251 func printeface(e eface) {
252 print("(", e._type, ",", e.data, ")")
253 }
254
255 func printiface(i iface) {
256 print("(", i.tab, ",", i.data, ")")
257 }
258
259
260
261
262
263
264 func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
265 p1 := func(x uintptr) {
266 var buf [2 * sys.PtrSize]byte
267 for i := len(buf) - 1; i >= 0; i-- {
268 if x&0xF < 10 {
269 buf[i] = byte(x&0xF) + '0'
270 } else {
271 buf[i] = byte(x&0xF) - 10 + 'a'
272 }
273 x >>= 4
274 }
275 gwrite(buf[:])
276 }
277
278 printlock()
279 var markbuf [1]byte
280 markbuf[0] = ' '
281 for i := uintptr(0); p+i < end; i += sys.PtrSize {
282 if i%16 == 0 {
283 if i != 0 {
284 println()
285 }
286 p1(p + i)
287 print(": ")
288 }
289
290 if mark != nil {
291 markbuf[0] = mark(p + i)
292 if markbuf[0] == 0 {
293 markbuf[0] = ' '
294 }
295 }
296 gwrite(markbuf[:])
297 val := *(*uintptr)(unsafe.Pointer(p + i))
298 p1(val)
299 print(" ")
300
301
302 fn := findfunc(val)
303 if fn.valid() {
304 print("<", funcname(fn), "+", val-fn.entry, "> ")
305 }
306 }
307 println()
308 printunlock()
309 }
310
View as plain text