summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/print.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/print.go')
-rw-r--r--libgo/go/runtime/print.go64
1 files changed, 58 insertions, 6 deletions
diff --git a/libgo/go/runtime/print.go b/libgo/go/runtime/print.go
index f789f89083..4db726a755 100644
--- a/libgo/go/runtime/print.go
+++ b/libgo/go/runtime/print.go
@@ -4,7 +4,32 @@
package runtime
-import "unsafe"
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// For gccgo, use go:linkname to rename compiler-called functions to
+// themselves, so that the compiler will export them.
+//
+//go:linkname printbool runtime.printbool
+//go:linkname printfloat runtime.printfloat
+//go:linkname printint runtime.printint
+//go:linkname printhex runtime.printhex
+//go:linkname printuint runtime.printuint
+//go:linkname printcomplex runtime.printcomplex
+//go:linkname printstring runtime.printstring
+//go:linkname printpointer runtime.printpointer
+//go:linkname printiface runtime.printiface
+//go:linkname printeface runtime.printeface
+//go:linkname printslice runtime.printslice
+//go:linkname printnl runtime.printnl
+//go:linkname printsp runtime.printsp
+//go:linkname printlock runtime.printlock
+//go:linkname printunlock runtime.printunlock
+// Temporary for C code to call:
+//go:linkname gwrite runtime.gwrite
+//go:linkname printhex runtime.printhex
// The compiler knows that a print of a value of this type
// should use printhex instead of printuint (decimal).
@@ -19,6 +44,36 @@ func bytes(s string) (ret []byte) {
return
}
+var (
+ // printBacklog is a circular buffer of messages written with the builtin
+ // print* functions, for use in postmortem analysis of core dumps.
+ printBacklog [512]byte
+ printBacklogIndex int
+)
+
+// recordForPanic maintains a circular buffer of messages written by the
+// runtime leading up to a process crash, allowing the messages to be
+// extracted from a core dump.
+//
+// The text written during a process crash (following "panic" or "fatal
+// error") is not saved, since the goroutine stacks will generally be readable
+// from the runtime datastructures in the core file.
+func recordForPanic(b []byte) {
+ printlock()
+
+ if atomic.Load(&panicking) == 0 {
+ // Not actively crashing: maintain circular buffer of print output.
+ for i := 0; i < len(b); {
+ n := copy(printBacklog[printBacklogIndex:], b[i:])
+ i += n
+ printBacklogIndex += n
+ printBacklogIndex %= len(printBacklog)
+ }
+ }
+
+ printunlock()
+}
+
var debuglock mutex
// The compiler emits calls to printlock and printunlock around
@@ -53,6 +108,7 @@ func gwrite(b []byte) {
if len(b) == 0 {
return
}
+ recordForPanic(b)
gp := getg()
if gp == nil || gp.writebuf == nil {
writeErr(b)
@@ -199,17 +255,13 @@ func printpointer(p unsafe.Pointer) {
}
func printstring(s string) {
- if uintptr(len(s)) > maxstring {
- gwrite(bytes("[string too long]"))
- return
- }
gwrite(bytes(s))
}
func printslice(s []byte) {
sp := (*slice)(unsafe.Pointer(&s))
print("[", len(s), "/", cap(s), "]")
- printpointer(unsafe.Pointer(sp.array))
+ printpointer(sp.array)
}
func printeface(e eface) {