diff options
| author | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-09-08 00:08:51 -0400 |
| commit | c007ce824d9a4fccb148f9204e04c23ed2984b71 (patch) | |
| tree | 7dcac257114ef5c446be5b7b68c27dea230b7c09 /src/pkg/runtime/panic.c | |
| parent | 220a6de47eced55956eb8af8d643d4f5b67fd634 (diff) | |
| download | go-c007ce824d9a4fccb148f9204e04c23ed2984b71.tar.xz | |
build: move package sources from src/pkg to src
Preparation was in CL 134570043.
This CL contains only the effect of 'hg mv src/pkg/* src'.
For more about the move, see golang.org/s/go14nopkg.
Diffstat (limited to 'src/pkg/runtime/panic.c')
| -rw-r--r-- | src/pkg/runtime/panic.c | 219 |
1 files changed, 0 insertions, 219 deletions
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c deleted file mode 100644 index e38ce740bc..0000000000 --- a/src/pkg/runtime/panic.c +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "runtime.h" -#include "arch_GOARCH.h" -#include "stack.h" -#include "malloc.h" -#include "textflag.h" - -// Code related to defer, panic and recover. - -// TODO: remove once code is moved to Go -extern Defer* runtime·newdefer(int32 siz); -extern runtime·freedefer(Defer *d); - -uint32 runtime·panicking; -static Mutex paniclk; - -void -runtime·deferproc_m(void) { - int32 siz; - FuncVal *fn; - uintptr argp; - uintptr callerpc; - Defer *d; - - siz = g->m->scalararg[0]; - fn = g->m->ptrarg[0]; - argp = g->m->scalararg[1]; - callerpc = g->m->scalararg[2]; - g->m->ptrarg[0] = nil; - - d = runtime·newdefer(siz); - d->fn = fn; - d->pc = callerpc; - d->argp = argp; - runtime·memmove(d->args, (void*)argp, siz); -} - -// Unwind the stack after a deferred function calls recover -// after a panic. Then arrange to continue running as though -// the caller of the deferred function returned normally. -void -runtime·recovery_m(G *gp) -{ - void *argp; - uintptr pc; - - // Info about defer passed in G struct. - argp = (void*)gp->sigcode0; - pc = (uintptr)gp->sigcode1; - - // Unwind to the stack frame with d's arguments in it. - runtime·unwindstack(gp, argp); - - // Make the deferproc for this d return again, - // this time returning 1. The calling function will - // jump to the standard return epilogue. - // The -2*sizeof(uintptr) makes up for the - // two extra words that are on the stack at - // each call to deferproc. - // (The pc we're returning to does pop pop - // before it tests the return value.) - // On the arm there are 2 saved LRs mixed in too. - if(thechar == '5') - gp->sched.sp = (uintptr)argp - 4*sizeof(uintptr); - else - gp->sched.sp = (uintptr)argp - 2*sizeof(uintptr); - gp->sched.pc = pc; - gp->sched.lr = 0; - gp->sched.ret = 1; - runtime·gogo(&gp->sched); -} - -// Free stack frames until we hit the last one -// or until we find the one that contains the sp. -void -runtime·unwindstack(G *gp, byte *sp) -{ - Stktop *top; - byte *stk; - - // Must be called from a different goroutine, usually m->g0. - if(g == gp) - runtime·throw("unwindstack on self"); - - while((top = (Stktop*)gp->stackbase) != 0 && top->stackbase != 0) { - stk = (byte*)gp->stackguard - StackGuard; - if(stk <= sp && sp < (byte*)gp->stackbase) - break; - gp->stackbase = top->stackbase; - gp->stackguard = top->stackguard; - gp->stackguard0 = gp->stackguard; - runtime·stackfree(gp, stk, top); - } - - if(sp != nil && (sp < (byte*)gp->stackguard - StackGuard || (byte*)gp->stackbase < sp)) { - runtime·printf("recover: %p not in [%p, %p]\n", sp, gp->stackguard - StackGuard, gp->stackbase); - runtime·throw("bad unwindstack"); - } -} - -void -runtime·startpanic_m(void) -{ - if(runtime·mheap.cachealloc.size == 0) { // very early - runtime·printf("runtime: panic before malloc heap initialized\n"); - g->m->mallocing = 1; // tell rest of panic not to try to malloc - } else if(g->m->mcache == nil) // can happen if called from signal handler or throw - g->m->mcache = runtime·allocmcache(); - switch(g->m->dying) { - case 0: - g->m->dying = 1; - if(g != nil) { - g->writebuf.array = nil; - g->writebuf.len = 0; - g->writebuf.cap = 0; - } - 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. - g->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. - g->m->dying = 3; - runtime·printf("stack trace unavailable\n"); - runtime·exit(4); - default: - // Can't even print! Just exit. - runtime·exit(5); - } -} - -void -runtime·dopanic_m(void) -{ - G *gp; - uintptr sp, pc; - static bool didothers; - bool crash; - int32 t; - - gp = g->m->ptrarg[0]; - g->m->ptrarg[0] = nil; - pc = g->m->scalararg[0]; - sp = g->m->scalararg[1]; - if(gp->sig != 0) - runtime·printf("[signal %x code=%p addr=%p pc=%p]\n", - gp->sig, gp->sigcode0, gp->sigcode1, gp->sigpc); - - if((t = runtime·gotraceback(&crash)) > 0){ - if(gp != gp->m->g0) { - runtime·printf("\n"); - runtime·goroutineheader(gp); - runtime·traceback(pc, sp, 0, gp); - } else if(t >= 2 || g->m->throwing > 0) { - runtime·printf("\nruntime stack:\n"); - runtime·traceback(pc, sp, 0, gp); - } - if(!didothers) { - didothers = true; - runtime·tracebackothers(gp); - } - } - 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 Mutex deadlock; - runtime·lock(&deadlock); - runtime·lock(&deadlock); - } - - if(crash) - runtime·crash(); - - runtime·exit(2); -} - -bool -runtime·canpanic(G *gp) -{ - M *m; - uint32 status; - - // Note that g is m->gsignal, different from gp. - // Note also that g->m can change at preemption, so m can go stale - // if this function ever makes a function call. - m = g->m; - - // Is it okay for gp to panic instead of crashing the program? - // Yes, as long as it is running Go code, not runtime code, - // and not stuck in a system call. - if(gp == nil || gp != m->curg) - return false; - if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0) - return false; - status = runtime·readgstatus(gp); - if((status&~Gscan) != Grunning || gp->syscallsp != 0) - return false; -#ifdef GOOS_windows - if(m->libcallsp != 0) - return false; -#endif - return true; -} |
