mirror of
https://github.com/golang/go
synced 2024-11-12 09:50:21 -07:00
runtime: initialize traceback variables earlier
Our traceback code needs to know the PC of several special functions, including goexit, mcall, etc. Make sure that these PCs are initialized before any traceback occurs. Fixes #8766 LGTM=rsc R=golang-codereviews, rsc, khr, bradfitz CC=golang-codereviews https://golang.org/cl/145570043
This commit is contained in:
parent
f13cec9f57
commit
70b2da98ca
@ -131,6 +131,7 @@ runtime·schedinit(void)
|
||||
|
||||
runtime·sched.maxmcount = 10000;
|
||||
|
||||
runtime·tracebackinit();
|
||||
runtime·symtabinit();
|
||||
runtime·stackinit();
|
||||
runtime·mallocinit();
|
||||
|
@ -841,6 +841,7 @@ void runtime·mpreinit(M*);
|
||||
void runtime·minit(void);
|
||||
void runtime·unminit(void);
|
||||
void runtime·signalstack(byte*, int32);
|
||||
void runtime·tracebackinit(void);
|
||||
void runtime·symtabinit(void);
|
||||
Func* runtime·findfunc(uintptr);
|
||||
int32 runtime·funcline(Func*, uintptr, String*);
|
||||
|
@ -31,20 +31,36 @@ import "unsafe"
|
||||
const usesLR = GOARCH != "amd64" && GOARCH != "amd64p32" && GOARCH != "386"
|
||||
|
||||
var (
|
||||
deferprocPC = funcPC(deferproc)
|
||||
goexitPC = funcPC(goexit)
|
||||
jmpdeferPC = funcPC(jmpdefer)
|
||||
mcallPC = funcPC(mcall)
|
||||
morestackPC = funcPC(morestack)
|
||||
mstartPC = funcPC(mstart)
|
||||
newprocPC = funcPC(newproc)
|
||||
newstackPC = funcPC(newstack)
|
||||
rt0_goPC = funcPC(rt0_go)
|
||||
sigpanicPC = funcPC(sigpanic)
|
||||
// initialized in tracebackinit
|
||||
deferprocPC uintptr
|
||||
goexitPC uintptr
|
||||
jmpdeferPC uintptr
|
||||
mcallPC uintptr
|
||||
morestackPC uintptr
|
||||
mstartPC uintptr
|
||||
newprocPC uintptr
|
||||
rt0_goPC uintptr
|
||||
sigpanicPC uintptr
|
||||
|
||||
externalthreadhandlerp uintptr // initialized elsewhere
|
||||
)
|
||||
|
||||
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.
|
||||
deferprocPC = funcPC(deferproc)
|
||||
goexitPC = funcPC(goexit)
|
||||
jmpdeferPC = funcPC(jmpdefer)
|
||||
mcallPC = funcPC(mcall)
|
||||
morestackPC = funcPC(morestack)
|
||||
mstartPC = funcPC(mstart)
|
||||
newprocPC = funcPC(newproc)
|
||||
rt0_goPC = funcPC(rt0_go)
|
||||
sigpanicPC = funcPC(sigpanic)
|
||||
}
|
||||
|
||||
// Traceback over the deferred function calls.
|
||||
// Report them like calls that have been invoked but not started executing yet.
|
||||
func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer) {
|
||||
@ -81,6 +97,9 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns
|
||||
// collector (callback != nil). A little clunky to merge these, but avoids
|
||||
// duplicating the code and all its subtlety.
|
||||
func gentraceback(pc0 uintptr, sp0 uintptr, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max int, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer, printall bool) int {
|
||||
if goexitPC == 0 {
|
||||
gothrow("gentraceback before goexitPC initialization")
|
||||
}
|
||||
g := getg()
|
||||
gotraceback := gotraceback(nil)
|
||||
if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp.
|
||||
|
Loading…
Reference in New Issue
Block a user