From 1bc5aee63eb72b341f506ad058502cd0361f0d10 Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Tue, 25 Mar 2014 22:37:19 -0700 Subject: Initial checkin of GCC 4.9.0 from trunk (r208799). Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba --- gcc-4.9/libgo/runtime/panic.c | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 gcc-4.9/libgo/runtime/panic.c (limited to 'gcc-4.9/libgo/runtime/panic.c') 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(); +} -- cgit v1.2.3