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); } }
static void gtraceback(G* gp) { G* ret; runtime_traceback(nil); runtime_goroutinetrailer(gp); ret = gp->dotraceback; gp->dotraceback = nil; runtime_gogo(ret); }