aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/traceback_gccgo.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/traceback_gccgo.go')
-rw-r--r--libgo/go/runtime/traceback_gccgo.go49
1 files changed, 46 insertions, 3 deletions
diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go
index 611aba9..d060e09 100644
--- a/libgo/go/runtime/traceback_gccgo.go
+++ b/libgo/go/runtime/traceback_gccgo.go
@@ -9,7 +9,7 @@ package runtime
import (
"runtime/internal/sys"
- _ "unsafe" // for go:linkname
+ "unsafe"
)
// For gccgo, use go:linkname to rename compiler-called functions to
@@ -20,6 +20,34 @@ import (
//go:linkname goroutineheader runtime.goroutineheader
//go:linkname printcreatedby runtime.printcreatedby
+var (
+ // initialized in tracebackinit
+ runfinqPC uintptr
+ bgsweepPC uintptr
+ forcegchelperPC uintptr
+ timerprocPC uintptr
+ gcBgMarkWorkerPC uintptr
+)
+
+func tracebackinit() {
+ // Go variable initialization happens late during runtime startup.
+ // Instead of initializing the variables above in the declarations,
+ // schedinit calls this function so that the variables are
+ // initialized and available earlier in the startup sequence.
+ // This doesn't use funcPC to avoid memory allocation.
+ // FIXME: We should be able to use funcPC when escape analysis is on.
+ f1 := runfinq
+ runfinqPC = **(**uintptr)(unsafe.Pointer(&f1))
+ f2 := bgsweep
+ bgsweepPC = **(**uintptr)(unsafe.Pointer(&f2))
+ f3 := forcegchelper
+ forcegchelperPC = **(**uintptr)(unsafe.Pointer(&f3))
+ f4 := timerproc
+ timerprocPC = **(**uintptr)(unsafe.Pointer(&f4))
+ f5 := gcBgMarkWorker
+ gcBgMarkWorkerPC = **(**uintptr)(unsafe.Pointer(&f5))
+}
+
func printcreatedby(gp *g) {
// Show what created goroutine, except main goroutine (goid 1).
pc := gp.gopc
@@ -168,14 +196,26 @@ func goroutineheader(gp *g) {
// isSystemGoroutine reports whether the goroutine g must be omitted in
// stack dumps and deadlock detector.
func isSystemGoroutine(gp *g) bool {
- // FIXME.
- return false
+ // FIXME: This doesn't work reliably for gccgo because in many
+ // cases the startpc field will be set to a thunk rather than
+ // to one of these addresses.
+ pc := gp.startpc
+ return pc == runfinqPC && !fingRunning ||
+ pc == bgsweepPC ||
+ pc == forcegchelperPC ||
+ pc == timerprocPC ||
+ pc == gcBgMarkWorkerPC
}
func tracebackothers(me *g) {
var tb tracebackg
tb.gp = me
+ // The getTraceback function will modify me's stack context.
+ // Preserve it in case we have been called via systemstack.
+ context := me.context
+ stackcontext := me.stackcontext
+
level, _, _ := gotraceback()
// Show the current goroutine first, if we haven't already.
@@ -225,4 +265,7 @@ func tracebackothers(me *g) {
}
}
unlock(&allglock)
+
+ me.context = context
+ me.stackcontext = stackcontext
}