コード例 #1
0
ファイル: panic.c プロジェクト: eggfly/go-linux-arm
// 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);
}
コード例 #2
0
ファイル: cgocall.c プロジェクト: cloudaice/golang
void
runtime·cgocallbackg1(void)
{
	CallbackArgs *cb;
	Defer d;

	if(m->needextram) {
		m->needextram = 0;
		runtime·newextram();
	}

	// Add entry to defer stack in case of panic.
	d.fn = &unwindmf;
	d.siz = 0;
	d.link = g->defer;
	d.argp = (void*)-1;  // unused because unwindm never recovers
	d.special = true;
	d.free = false;
	g->defer = &d;

	if(raceenabled && !m->racecall)
		runtime·raceacquire(&cgosync);

	// Invoke callback.
	cb = CBARGS;
	runtime·newstackcall(cb->fn, cb->arg, cb->argsize);

	if(raceenabled && !m->racecall)
		runtime·racereleasemerge(&cgosync);

	// Pop defer.
	// Do not unwind m->g0->sched.sp.
	// Our caller, cgocallback, will do that.
	if(g->defer != &d || d.fn != &unwindmf)
		runtime·throw("runtime: bad defer entry in cgocallback");
	g->defer = d.link;
}