void Panic(int type) { dopanic_type dopanic(type); const InputDeviceList & inlist = InputDeviceClass::GetDeviceList(); std::for_each(inlist.begin(),inlist.end(),dopanic); const BoxListType & boxlist = BoxClass::GetBoxList(); std::for_each(boxlist.begin(),boxlist.end(),dopanic); const OutputDeviceList & outlist = OutputDeviceClass::GetDeviceList(); std::for_each(outlist.begin(),outlist.end(),dopanic); }
// The implementation of the predeclared function panic. void runtime·panic(Eface e) { Defer *d; Panic *p; void *pc, *argp; p = runtime·mal(sizeof *p); p->arg = e; p->link = g->panic; p->stackbase = g->stackbase; g->panic = p; for(;;) { d = g->defer; if(d == nil) break; // take defer off list in case of recursive panic g->defer = d->link; g->ispanic = true; // rock for newstack, where reflect.newstackcall ends up argp = d->argp; pc = d->pc; runtime·newstackcall(d->fn, (byte*)d->args, d->siz); freedefer(d); if(p->recovered) { g->panic = p->link; if(g->panic == nil) // must be done with signal g->sig = 0; runtime·free(p); // Pass information about recovering frame to recovery. g->sigcode0 = (uintptr)argp; g->sigcode1 = (uintptr)pc; runtime·mcall(recovery); runtime·throw("recovery failed"); // mcall should not return } } // ran out of deferred calls - old-school panic now runtime·startpanic(); printpanics(g->panic); runtime·dopanic(0); }
// The implementation of the predeclared function panic. void runtime·panic(Eface e) { Defer *d; Panic *p; p = runtime·mal(sizeof *p); p->arg = e; p->link = g->panic; p->stackbase = g->stackbase; g->panic = p; for(;;) { d = g->defer; if(d == nil) break; // take defer off list in case of recursive panic g->defer = d->link; g->ispanic = true; // rock for newstack, where reflect.call ends up reflect·call(d->fn, d->args, d->siz); if(p->recovered) { g->panic = p->link; if(g->panic == nil) // must be done with signal g->sig = 0; runtime·free(p); // put recovering defer back on list // for scheduler to find. d->link = g->defer; g->defer = d; runtime·mcall(recovery); runtime·throw("recovery failed"); // mcall should not return } if(!d->nofree) runtime·free(d); } // ran out of deferred calls - old-school panic now runtime·startpanic(); printpanics(g->panic); runtime·dopanic(0); }
void runtime·startpanic(void) { if(runtime·mheap.cachealloc.size == 0) { // very early runtime·printf("runtime: panic before malloc heap initialized\n"); m->mallocing = 1; // tell rest of panic not to try to malloc } else if(m->mcache == nil) // can happen if called from signal handler or throw m->mcache = runtime·allocmcache(); switch(m->dying) { case 0: m->dying = 1; if(g != nil) g->writebuf = nil; runtime·xadd(&runtime·panicking, 1); runtime·lock(&paniclk); if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0) runtime·schedtrace(true); runtime·freezetheworld(); return; case 1: // Something failed while panicing, probably the print of the // argument to panic(). Just print a stack trace and exit. m->dying = 2; runtime·printf("panic during panic\n"); runtime·dopanic(0); runtime·exit(3); case 2: // This is a genuine bug in the runtime, we couldn't even // print the stack trace successfully. m->dying = 3; runtime·printf("stack trace unavailable\n"); runtime·exit(4); default: // Can't even print! Just exit. runtime·exit(5); } }