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.
8 "runtime/internal/atomic"
12 // For gccgo, use go:linkname to rename compiler-called functions to
13 // themselves, so that the compiler will export them.
15 //go:linkname printbool runtime.printbool
16 //go:linkname printfloat runtime.printfloat
17 //go:linkname printint runtime.printint
18 //go:linkname printhex runtime.printhex
19 //go:linkname printuint runtime.printuint
20 //go:linkname printcomplex runtime.printcomplex
21 //go:linkname printstring runtime.printstring
22 //go:linkname printpointer runtime.printpointer
23 //go:linkname printiface runtime.printiface
24 //go:linkname printeface runtime.printeface
25 //go:linkname printslice runtime.printslice
26 //go:linkname printnl runtime.printnl
27 //go:linkname printsp runtime.printsp
28 //go:linkname printlock runtime.printlock
29 //go:linkname printunlock runtime.printunlock
30 // Temporary for C code to call:
31 //go:linkname gwrite runtime.gwrite
32 //go:linkname printhex runtime.printhex
34 // The compiler knows that a print of a value of this type
35 // should use printhex instead of printuint (decimal).
38 func bytes(s
string) (ret
[]byte) {
39 rp
:= (*slice
)(unsafe
.Pointer(&ret
))
40 sp
:= stringStructOf(&s
)
48 // printBacklog is a circular buffer of messages written with the builtin
49 // print* functions, for use in postmortem analysis of core dumps.
50 printBacklog
[512]byte
54 // recordForPanic maintains a circular buffer of messages written by the
55 // runtime leading up to a process crash, allowing the messages to be
56 // extracted from a core dump.
58 // The text written during a process crash (following "panic" or "fatal
59 // error") is not saved, since the goroutine stacks will generally be readable
60 // from the runtime datastructures in the core file.
61 func recordForPanic(b
[]byte) {
64 if atomic
.Load(&panicking
) == 0 {
65 // Not actively crashing: maintain circular buffer of print output.
66 for i
:= 0; i
< len(b
); {
67 n
:= copy(printBacklog
[printBacklogIndex
:], b
[i
:])
69 printBacklogIndex
+= n
70 printBacklogIndex
%= len(printBacklog
)
79 // The compiler emits calls to printlock and printunlock around
80 // the multiple calls that implement a single Go print or println
81 // statement. Some of the print helpers (printsp, for example)
82 // call print recursively. There is also the problem of a crash
83 // happening during the print routines and needing to acquire
84 // the print lock to print information about the crash.
85 // For both these reasons, let a thread acquire the printlock 'recursively'.
89 mp
.locks
++ // do not reschedule between printlock++ and lock(&debuglock).
91 if mp
.printlock
== 1 {
94 mp
.locks
-- // now we know debuglock is held and holding up mp.locks for us.
100 if mp
.printlock
== 0 {
105 // write to goroutine-local buffer if diverting output,
106 // or else standard error.
107 func gwrite(b
[]byte) {
113 if gp
== nil || gp
.writebuf
== nil {
118 n
:= copy(gp
.writebuf
[len(gp
.writebuf
):cap(gp
.writebuf
)], b
)
119 gp
.writebuf
= gp
.writebuf
[:len(gp
.writebuf
)+n
]
130 func printbool(v
bool) {
138 func printfloat(v
float64) {
143 case v
+v
== v
&& v
> 0:
146 case v
+v
== v
&& v
< 0:
151 const n
= 7 // digits printed
177 for i
:= 0; i
< n
; i
++ {
187 // format +d.dddd+edd
188 for i
:= 0; i
< n
; i
++ {
190 buf
[i
+2] = byte(s
+ '0')
204 buf
[n
+4] = byte(e
/100) + '0'
205 buf
[n
+5] = byte(e
/10)%10
+ '0'
206 buf
[n
+6] = byte(e%10
) + '0'
210 func printcomplex(c complex128
) {
211 print("(", real(c
), imag(c
), "i)")
214 func printuint(v
uint64) {
217 for i
--; i
> 0; i
-- {
218 buf
[i
] = byte(v%10
+ '0')
227 func printint(v
int64) {
235 func printhex(v
uint64) {
236 const dig
= "0123456789abcdef"
239 for i
--; i
> 0; i
-- {
253 func printpointer(p unsafe
.Pointer
) {
254 printhex(uint64(uintptr(p
)))
257 func printstring(s
string) {
261 func printslice(s
[]byte) {
262 sp
:= (*slice
)(unsafe
.Pointer(&s
))
263 print("[", len(s
), "/", cap(s
), "]")
264 printpointer(sp
.array
)
267 func printeface(e eface
) {
268 print("(", e
._type
, ",", e
.data
, ")")
271 func printiface(i iface
) {
272 print("(", i
.tab
, ",", i
.data
, ")")