Restore check for OpenMP for construct.
[official-gcc.git] / libgo / runtime / panic.c
blob8fe321f6af2de675268a7ee3b246dd82db406d4e
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 if (d->__free)
32 runtime_free(d);
36 void
37 runtime_startpanic(void)
39 M *m;
41 m = runtime_m();
42 if(runtime_mheap.cachealloc.size == 0) { // very early
43 runtime_printf("runtime: panic before malloc heap initialized\n");
44 m->mallocing = 1; // tell rest of panic not to try to malloc
45 } else if(m->mcache == nil) // can happen if called from signal handler or throw
46 m->mcache = runtime_allocmcache();
47 if(m->dying) {
48 runtime_printf("panic during panic\n");
49 runtime_exit(3);
51 m->dying = 1;
52 if(runtime_g() != nil)
53 runtime_g()->writebuf = nil;
54 runtime_xadd(&runtime_panicking, 1);
55 runtime_lock(&paniclk);
56 if(runtime_debug.schedtrace > 0 || runtime_debug.scheddetail > 0)
57 runtime_schedtrace(true);
58 runtime_freezetheworld();
61 void
62 runtime_dopanic(int32 unused __attribute__ ((unused)))
64 G *g;
65 static bool didothers;
66 bool crash;
67 int32 t;
69 g = runtime_g();
70 if(g->sig != 0)
71 runtime_printf("[signal %x code=%p addr=%p]\n",
72 g->sig, (void*)g->sigcode0, (void*)g->sigcode1);
74 if((t = runtime_gotraceback(&crash)) > 0){
75 if(g != runtime_m()->g0) {
76 runtime_printf("\n");
77 runtime_goroutineheader(g);
78 runtime_traceback();
79 runtime_printcreatedby(g);
80 } else if(t >= 2 || runtime_m()->throwing > 0) {
81 runtime_printf("\nruntime stack:\n");
82 runtime_traceback();
84 if(!didothers) {
85 didothers = true;
86 runtime_tracebackothers(g);
89 runtime_unlock(&paniclk);
90 if(runtime_xadd(&runtime_panicking, -1) != 0) {
91 // Some other m is panicking too.
92 // Let it print what it needs to print.
93 // Wait forever without chewing up cpu.
94 // It will exit when it's done.
95 static Lock deadlock;
96 runtime_lock(&deadlock);
97 runtime_lock(&deadlock);
100 if(crash)
101 runtime_crash();
103 runtime_exit(2);
106 void
107 runtime_throw(const char *s)
109 M *mp;
111 mp = runtime_m();
112 if(mp->throwing == 0)
113 mp->throwing = 1;
114 runtime_startpanic();
115 runtime_printf("fatal error: %s\n", s);
116 runtime_dopanic(0);
117 *(int32*)0 = 0; // not reached
118 runtime_exit(1); // even more not reached
121 void
122 runtime_panicstring(const char *s)
124 Eface err;
126 if(runtime_m()->mallocing) {
127 runtime_printf("panic: %s\n", s);
128 runtime_throw("panic during malloc");
130 if(runtime_m()->gcing) {
131 runtime_printf("panic: %s\n", s);
132 runtime_throw("panic during gc");
134 runtime_newErrorCString(s, &err);
135 runtime_panic(err);
138 void runtime_Goexit (void) __asm__ (GOSYM_PREFIX "runtime.Goexit");
140 void
141 runtime_Goexit(void)
143 rundefer();
144 runtime_goexit();