diff options
Diffstat (limited to 'libgo/go/runtime/traceback_gccgo.go')
-rw-r--r-- | libgo/go/runtime/traceback_gccgo.go | 49 |
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 } |