...
Source file
src/runtime/print.go
Documentation: runtime
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 if gp == nil || gp.writebuf == nil {
93 writeErr(b)
94 return
95 }
96
97 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
98 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
99 }
100
101 func printsp() {
102 printstring(" ")
103 }
104
105 func printnl() {
106 printstring("\n")
107 }
108
109 func printbool(v bool) {
110 if v {
111 printstring("true")
112 } else {
113 printstring("false")
114 }
115 }
116
117 func printfloat(v float64) {
118 switch {
119 case v != v:
120 printstring("NaN")
121 return
122 case v+v == v && v > 0:
123 printstring("+Inf")
124 return
125 case v+v == v && v < 0:
126 printstring("-Inf")
127 return
128 }
129
130 const n = 7
131 var buf [n + 7]byte
132 buf[0] = '+'
133 e := 0
134 if v == 0 {
135 if 1/v < 0 {
136 buf[0] = '-'
137 }
138 } else {
139 if v < 0 {
140 v = -v
141 buf[0] = '-'
142 }
143
144
145 for v >= 10 {
146 e++
147 v /= 10
148 }
149 for v < 1 {
150 e--
151 v *= 10
152 }
153
154
155 h := 5.0
156 for i := 0; i < n; i++ {
157 h /= 10
158 }
159 v += h
160 if v >= 10 {
161 e++
162 v /= 10
163 }
164 }
165
166
167 for i := 0; i < n; i++ {
168 s := int(v)
169 buf[i+2] = byte(s + '0')
170 v -= float64(s)
171 v *= 10
172 }
173 buf[1] = buf[2]
174 buf[2] = '.'
175
176 buf[n+2] = 'e'
177 buf[n+3] = '+'
178 if e < 0 {
179 e = -e
180 buf[n+3] = '-'
181 }
182
183 buf[n+4] = byte(e/100) + '0'
184 buf[n+5] = byte(e/10)%10 + '0'
185 buf[n+6] = byte(e%10) + '0'
186 gwrite(buf[:])
187 }
188
189 func printcomplex(c complex128) {
190 print("(", real(c), imag(c), "i)")
191 }
192
193 func printuint(v uint64) {
194 var buf [100]byte
195 i := len(buf)
196 for i--; i > 0; i-- {
197 buf[i] = byte(v%10 + '0')
198 if v < 10 {
199 break
200 }
201 v /= 10
202 }
203 gwrite(buf[i:])
204 }
205
206 func printint(v int64) {
207 if v < 0 {
208 printstring("-")
209 v = -v
210 }
211 printuint(uint64(v))
212 }
213
214 func printhex(v uint64) {
215 const dig = "0123456789abcdef"
216 var buf [100]byte
217 i := len(buf)
218 for i--; i > 0; i-- {
219 buf[i] = dig[v%16]
220 if v < 16 {
221 break
222 }
223 v /= 16
224 }
225 i--
226 buf[i] = 'x'
227 i--
228 buf[i] = '0'
229 gwrite(buf[i:])
230 }
231
232 func printpointer(p unsafe.Pointer) {
233 printhex(uint64(uintptr(p)))
234 }
235
236 func printstring(s string) {
237 gwrite(bytes(s))
238 }
239
240 func printslice(s []byte) {
241 sp := (*slice)(unsafe.Pointer(&s))
242 print("[", len(s), "/", cap(s), "]")
243 printpointer(sp.array)
244 }
245
246 func printeface(e eface) {
247 print("(", e._type, ",", e.data, ")")
248 }
249
250 func printiface(i iface) {
251 print("(", i.tab, ",", i.data, ")")
252 }
253
254
255
256
257
258
259 func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
260 p1 := func(x uintptr) {
261 var buf [2 * sys.PtrSize]byte
262 for i := len(buf) - 1; i >= 0; i-- {
263 if x&0xF < 10 {
264 buf[i] = byte(x&0xF) + '0'
265 } else {
266 buf[i] = byte(x&0xF) - 10 + 'a'
267 }
268 x >>= 4
269 }
270 gwrite(buf[:])
271 }
272
273 printlock()
274 var markbuf [1]byte
275 markbuf[0] = ' '
276 for i := uintptr(0); p+i < end; i += sys.PtrSize {
277 if i%16 == 0 {
278 if i != 0 {
279 println()
280 }
281 p1(p + i)
282 print(": ")
283 }
284
285 if mark != nil {
286 markbuf[0] = mark(p + i)
287 if markbuf[0] == 0 {
288 markbuf[0] = ' '
289 }
290 }
291 gwrite(markbuf[:])
292 val := *(*uintptr)(unsafe.Pointer(p + i))
293 p1(val)
294 print(" ")
295
296
297 fn := findfunc(val)
298 if fn.valid() {
299 print("<", funcname(fn), "+", val-fn.entry, "> ")
300 }
301 }
302 println()
303 printunlock()
304 }
305
View as plain text