void runtime_tracebackothers(G *me) { G *g; for(g = runtime_allg; g != nil; g = g->alllink) { if(g == me || g->status == Gdead) continue; runtime_printf("\n"); runtime_goroutineheader(g); // runtime_traceback(g->sched.pc, g->sched.sp, 0, g); } }
void runtime_dopanic(int32 unused __attribute__ ((unused))) { G *g; static bool didothers; bool crash; int32 t; g = runtime_g(); if(g->sig != 0) runtime_printf("[signal %x code=%p addr=%p]\n", g->sig, (void*)g->sigcode0, (void*)g->sigcode1); if((t = runtime_gotraceback(&crash)) > 0){ if(g != runtime_m()->g0) { runtime_printf("\n"); runtime_goroutineheader(g); runtime_traceback(); runtime_printcreatedby(g); } else if(t >= 2 || runtime_m()->throwing > 0) { runtime_printf("\nruntime stack:\n"); runtime_traceback(); } 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); } if(crash) runtime_crash(); runtime_exit(2); }
void runtime_tracebackothers(G * volatile me) { G * volatile g; Traceback traceback; traceback.gp = me; for(g = runtime_allg; g != nil; g = g->alllink) { if(g == me || g->status == Gdead) continue; runtime_printf("\n"); runtime_goroutineheader(g); // Our only mechanism for doing a stack trace is // _Unwind_Backtrace. And that only works for the // current thread, not for other random goroutines. // So we need to switch context to the goroutine, get // the backtrace, and then switch back. // This means that if g is running or in a syscall, we // can't reliably print a stack trace. FIXME. if(g->status == Gsyscall || g->status == Grunning) { runtime_printf("no stack trace available\n"); runtime_goroutinetrailer(g); continue; } g->traceback = &traceback; #ifdef USING_SPLIT_STACK __splitstack_getcontext(&me->stack_context[0]); #endif getcontext(&me->context); if(g->traceback != nil) { runtime_gogo(g); } runtime_printtrace(traceback.pcbuf, traceback.c); runtime_goroutinetrailer(g); } }