void runtime·dopanic(int32 unused) { static bool didothers; if(g->sig != 0) runtime·printf("[signal %x code=%p addr=%p pc=%p]\n", g->sig, g->sigcode0, g->sigcode1, g->sigpc); if(runtime·gotraceback()){ if(g != m->g0) { runtime·printf("\n"); runtime·goroutineheader(g); runtime·traceback(runtime·getcallerpc(&unused), runtime·getcallersp(&unused), 0, g); } if(!didothers) { didothers = true; runtime·tracebackothers(g); } } runtime·unlock(&paniclk); if(runtime·xadd(&runtime·panicking, -1) != 0) { // Some other m is panicking too. // Let it print what it needs to print. // Wait forever without chewing up cpu. // It will exit when it's done. static Lock deadlock; runtime·lock(&deadlock); runtime·lock(&deadlock); } runtime·exit(2); }
// func caller(n int) (pc uintptr, file string, line int, ok bool) int32 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) { byte *pc, *sp; sp = runtime·getcallersp(&skip); pc = runtime·getcallerpc(&skip); return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m); }
int32 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) { uintptr pc, sp; sp = runtime·getcallersp(&skip); pc = (uintptr)runtime·getcallerpc(&skip); return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m, nil, nil, false); }
runtime·stdcall(void *fn, int32 count, ...) { m->libcall.fn = fn; m->libcall.n = count; m->libcall.args = (uintptr*)&count + 1; if(m->profilehz != 0) { // leave pc/sp for cpu profiler m->libcallg = g; m->libcallpc = (uintptr)runtime·getcallerpc(&fn); // sp must be the last, because once async cpu profiler finds // all three values to be non-zero, it will use them m->libcallsp = (uintptr)runtime·getcallersp(&fn); } runtime·asmcgocall(runtime·asmstdcall, &m->libcall); m->libcallsp = 0; return (void*)m->libcall.r1; }