1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // The compiler knows that a print of a value of this type
13 // should use printhex instead of printuint (decimal).
16 func bytes(s string) (ret []byte) {
17 rp := (*slice)(unsafe.Pointer(&ret))
18 sp := stringStructOf(&s)
26 // printBacklog is a circular buffer of messages written with the builtin
27 // print* functions, for use in postmortem analysis of core dumps.
28 printBacklog [512]byte
32 // recordForPanic maintains a circular buffer of messages written by the
33 // runtime leading up to a process crash, allowing the messages to be
34 // extracted from a core dump.
36 // The text written during a process crash (following "panic" or "fatal
37 // error") is not saved, since the goroutine stacks will generally be readable
38 // from the runtime data structures in the core file.
39 func recordForPanic(b []byte) {
42 if panicking.Load() == 0 {
43 // Not actively crashing: maintain circular buffer of print output.
44 for i := 0; i < len(b); {
45 n := copy(printBacklog[printBacklogIndex:], b[i:])
47 printBacklogIndex += n
48 printBacklogIndex %= len(printBacklog)
57 // The compiler emits calls to printlock and printunlock around
58 // the multiple calls that implement a single Go print or println
59 // statement. Some of the print helpers (printslice, for example)
60 // call print recursively. There is also the problem of a crash
61 // happening during the print routines and needing to acquire
62 // the print lock to print information about the crash.
63 // For both these reasons, let a thread acquire the printlock 'recursively'.
67 mp.locks++ // do not reschedule between printlock++ and lock(&debuglock).
69 if mp.printlock == 1 {
72 mp.locks-- // now we know debuglock is held and holding up mp.locks for us.
78 if mp.printlock == 0 {
83 // write to goroutine-local buffer if diverting output,
84 // or else standard error.
85 func gwrite(b []byte) {
91 // Don't use the writebuf if gp.m is dying. We want anything
92 // written through gwrite to appear in the terminal rather
93 // than be written to in some buffer, if we're in a panicking state.
94 // Note that we can't just clear writebuf in the gp.m.dying case
95 // because a panic isn't allowed to have any write barriers.
96 if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
101 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
102 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
113 func printbool(v bool) {
121 func printfloat(v float64) {
126 case v+v == v && v > 0:
129 case v+v == v && v < 0:
134 const n = 7 // digits printed
160 for i := 0; i < n; i++ {
170 // format +d.dddd+edd
171 for i := 0; i < n; i++ {
173 buf[i+2] = byte(s + '0')
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'
193 func printcomplex(c complex128) {
194 print("(", real(c), imag(c), "i)")
197 func printuint(v uint64) {
200 for i--; i > 0; i-- {
201 buf[i] = byte(v%10 + '0')
210 func printint(v int64) {
218 var minhexdigits = 0 // protected by printlock
220 func printhex(v uint64) {
221 const dig = "0123456789abcdef"
224 for i--; i > 0; i-- {
226 if v < 16 && len(buf)-i >= minhexdigits {
238 func printpointer(p unsafe.Pointer) {
239 printhex(uint64(uintptr(p)))
241 func printuintptr(p uintptr) {
245 func printstring(s string) {
249 func printslice(s []byte) {
250 sp := (*slice)(unsafe.Pointer(&s))
251 print("[", len(s), "/", cap(s), "]")
252 printpointer(sp.array)
255 func printeface(e eface) {
256 print("(", e._type, ",", e.data, ")")
259 func printiface(i iface) {
260 print("(", i.tab, ",", i.data, ")")
263 // hexdumpWords prints a word-oriented hex dump of [p, end).
265 // If mark != nil, it will be called with each printed word's address
266 // and should return a character mark to appear just before that
267 // word's value. It can return 0 to indicate no mark.
268 func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
272 minhexdigits = int(unsafe.Sizeof(uintptr(0)) * 2)
273 for i := uintptr(0); p+i < end; i += goarch.PtrSize {
278 print(hex(p+i), ": ")
282 markbuf[0] = mark(p + i)
288 val := *(*uintptr)(unsafe.Pointer(p + i))
292 // Can we symbolize val?
295 print("<", funcname(fn), "+", hex(val-fn.entry()), "> ")