//go:linkname setTraceback runtime/debug.SetTraceback funcsetTraceback(levelstring){vartuint32switchlevel{case"none":t=0case"single","":t=1<<tracebackShiftcase"all":t=1<<tracebackShift|tracebackAllcase"system":t=2<<tracebackShift|tracebackAllcase"crash":t=2<<tracebackShift|tracebackAll|tracebackCrashdefault:t=tracebackAllifn,ok:=atoi(level);ok&&n==int(uint32(n)){t|=uint32(n)<<tracebackShift}}// when C owns the process, simply exit'ing the process on fatal errors // and panics is surprising. Be louder and abort instead. if islibrary || isarchive { t|=tracebackCrash}t|=traceback_envatomic.Store(&traceback_cache,t)}
// Keep a cached value to make gotraceback fast,// since we call it on every call to gentraceback. // The cached value is a uint32 in which the low bits // are the "crash" and "all" settings and the remaining // bits are the traceback value (0 off, 1 on, 2 include system).const ( tracebackCrash=1<<iotatracebackAlltracebackShift=iota)vartraceback_cacheuint32=2<<tracebackShiftvartraceback_envuint32// gotraceback returns the current traceback settings.// // If level is 0, suppress all tracebacks. // If level is 1, show tracebacks, but exclude runtime frames. // If level is 2, show tracebacks including runtime frames. // If all is set, print all goroutine stacks. Otherwise, print just the current goroutine. // If crash is set, crash (core dump, etc) after tracebacking.// //go:nosplit funcgotraceback()(levelint32,all,crashbool){gp:=getg()t:=atomic.Load(&traceback_cache)crash=t&tracebackCrash!=0all=gp.m.throwing>=throwTypeUser||t&tracebackAll!=0ifgp.m.traceback!=0{level=int32(gp.m.traceback)}elseifgp.m.throwing>=throwTypeRuntime{// Always include runtime frames in runtime throws unless // otherwise overridden by m.traceback. level = 2 }else{level=int32(t>>tracebackShift)}return}
// gp is the crashing g running on this M, but may be a user G, while getg() is // always g0. funcdopanic_m(gp*g,pc,spuintptr)bool{ifgp.sig!=0{signame:=signame(gp.sig)ifsigname!=""{print("[signal ",signame)}else{print("[signal ",hex(gp.sig))}print(" code=",hex(gp.sigcode0)," addr=",hex(gp.sigcode1)," pc=",hex(gp.sigpc),"]\n")}level,all,docrash:=gotraceback()iflevel>0{ifgp!=gp.m.curg{all=true}ifgp!=gp.m.g0{print("\n")goroutineheader(gp)traceback(pc,sp,0,gp)}elseiflevel>=2||gp.m.throwing>=throwTypeRuntime{print("\nruntime stack:\n")traceback(pc,sp,0,gp)}if!didothers&&all{didothers=truetracebackothers(gp)}}unlock(&paniclk)ifpanicking.Add(-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. lock(&deadlock) lock(&deadlock)}printDebugLog()returndocrash}