2013-09-12 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / runtime / panic.c
blob7d79256cf41204759c9c182c142af476e8bf5937
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 #include "runtime.h"
6 #include "malloc.h"
7 #include "go-defer.h"
8 #include "go-panic.h"
10 // Code related to defer, panic and recover.
12 uint32 runtime_panicking;
13 static Lock paniclk;
15 // Run all deferred functions for the current goroutine.
16 static void
17 rundefer(void)
19 G *g;
20 Defer *d;
22 g = runtime_g();
23 while((d = g->defer) != nil) {
24 void (*pfn)(void*);
26 g->defer = d->__next;
27 pfn = d->__pfn;
28 d->__pfn = nil;
29 if (pfn != nil)
30 (*pfn)(d->__arg);
31 runtime_free(d);
35 void
36 runtime_startpanic(void)
38 M *m;
40 m = runtime_m();
41 if(runtime_mheap == 0 || runtime_mheap->cachealloc.size == 0) { // very early
42 runtime_printf("runtime: panic before malloc heap initialized\n");
43 m->mallocing = 1; // tell rest of panic not to try to malloc
44 } else if(m->mcache == nil) // can happen if called from signal handler or throw
45 m->mcache = runtime_allocmcache();
46 if(m->dying) {
47 runtime_printf("panic during panic\n");
48 runtime_exit(3);
50 m->dying = 1;
51 runtime_xadd(&runtime_panicking, 1);
52 runtime_lock(&paniclk);
55 void
56 runtime_dopanic(int32 unused __attribute__ ((unused)))
58 G *g;
59 static bool didothers;
60 bool crash;
62 g = runtime_g();
63 if(g->sig != 0)
64 runtime_printf("[signal %x code=%p addr=%p]\n",
65 g->sig, (void*)g->sigcode0, (void*)g->sigcode1);
67 if(runtime_gotraceback(&crash)){
68 if(g != runtime_m()->g0) {
69 runtime_printf("\n");
70 runtime_goroutineheader(g);
71 runtime_traceback();
72 runtime_goroutinetrailer(g);
74 if(!didothers) {
75 didothers = true;
76 runtime_tracebackothers(g);
79 runtime_unlock(&paniclk);
80 if(runtime_xadd(&runtime_panicking, -1) != 0) {
81 // Some other m is panicking too.
82 // Let it print what it needs to print.
83 // Wait forever without chewing up cpu.
84 // It will exit when it's done.
85 static Lock deadlock;
86 runtime_lock(&deadlock);
87 runtime_lock(&deadlock);
90 if(crash)
91 runtime_crash();
93 runtime_exit(2);
96 void
97 runtime_throw(const char *s)
99 M *mp;
101 mp = runtime_m();
102 if(mp->throwing == 0)
103 mp->throwing = 1;
104 runtime_startpanic();
105 runtime_printf("fatal error: %s\n", s);
106 runtime_dopanic(0);
107 *(int32*)0 = 0; // not reached
108 runtime_exit(1); // even more not reached
111 void
112 runtime_panicstring(const char *s)
114 Eface err;
116 if(runtime_m()->gcing) {
117 runtime_printf("panic: %s\n", s);
118 runtime_throw("panic during gc");
120 runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
121 runtime_panic(err);
124 void runtime_Goexit (void) __asm__ (GOSYM_PREFIX "runtime.Goexit");
126 void
127 runtime_Goexit(void)
129 rundefer();
130 runtime_goexit();