aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libgo/runtime/panic.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
committerBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
commit1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch)
treec607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/libgo/runtime/panic.c
parent283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff)
downloadtoolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/libgo/runtime/panic.c')
-rw-r--r--gcc-4.9/libgo/runtime/panic.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/gcc-4.9/libgo/runtime/panic.c b/gcc-4.9/libgo/runtime/panic.c
new file mode 100644
index 000000000..8fe321f6a
--- /dev/null
+++ b/gcc-4.9/libgo/runtime/panic.c
@@ -0,0 +1,145 @@
+// 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 "malloc.h"
+#include "go-defer.h"
+#include "go-panic.h"
+
+// Code related to defer, panic and recover.
+
+uint32 runtime_panicking;
+static Lock paniclk;
+
+// Run all deferred functions for the current goroutine.
+static void
+rundefer(void)
+{
+ G *g;
+ Defer *d;
+
+ g = runtime_g();
+ while((d = g->defer) != nil) {
+ void (*pfn)(void*);
+
+ g->defer = d->__next;
+ pfn = d->__pfn;
+ d->__pfn = nil;
+ if (pfn != nil)
+ (*pfn)(d->__arg);
+ if (d->__free)
+ runtime_free(d);
+ }
+}
+
+void
+runtime_startpanic(void)
+{
+ M *m;
+
+ m = runtime_m();
+ 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();
+ if(m->dying) {
+ runtime_printf("panic during panic\n");
+ runtime_exit(3);
+ }
+ m->dying = 1;
+ if(runtime_g() != nil)
+ runtime_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();
+}
+
+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_throw(const char *s)
+{
+ M *mp;
+
+ mp = runtime_m();
+ if(mp->throwing == 0)
+ mp->throwing = 1;
+ runtime_startpanic();
+ runtime_printf("fatal error: %s\n", s);
+ runtime_dopanic(0);
+ *(int32*)0 = 0; // not reached
+ runtime_exit(1); // even more not reached
+}
+
+void
+runtime_panicstring(const char *s)
+{
+ Eface err;
+
+ if(runtime_m()->mallocing) {
+ runtime_printf("panic: %s\n", s);
+ runtime_throw("panic during malloc");
+ }
+ if(runtime_m()->gcing) {
+ runtime_printf("panic: %s\n", s);
+ runtime_throw("panic during gc");
+ }
+ runtime_newErrorCString(s, &err);
+ runtime_panic(err);
+}
+
+void runtime_Goexit (void) __asm__ (GOSYM_PREFIX "runtime.Goexit");
+
+void
+runtime_Goexit(void)
+{
+ rundefer();
+ runtime_goexit();
+}