s390.c: Rename cfun_set_fpr_bit to cfun_set_fpr_save and cfun_fpr_bit_p to cfun_fpr_s...
[gcc.git] / libgo / runtime / panic.c
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.
4
5 #include "runtime.h"
6 #include "go-defer.h"
7 #include "go-panic.h"
8
9 // Code related to defer, panic and recover.
10
11 uint32 runtime_panicking;
12 static Lock paniclk;
13
14 // Run all deferred functions for the current goroutine.
15 static void
16 rundefer(void)
17 {
18 G *g;
19 Defer *d;
20
21 g = runtime_g();
22 while((d = g->defer) != nil) {
23 void (*pfn)(void*);
24
25 g->defer = d->__next;
26 pfn = d->__pfn;
27 d->__pfn = nil;
28 if (pfn != nil)
29 (*pfn)(d->__arg);
30 runtime_free(d);
31 }
32 }
33
34 void
35 runtime_startpanic(void)
36 {
37 M *m;
38
39 m = runtime_m();
40 if(m->dying) {
41 runtime_printf("panic during panic\n");
42 runtime_exit(3);
43 }
44 m->dying = 1;
45 runtime_xadd(&runtime_panicking, 1);
46 runtime_lock(&paniclk);
47 }
48
49 void
50 runtime_dopanic(int32 unused __attribute__ ((unused)))
51 {
52 G *g;
53 static bool didothers;
54
55 g = runtime_g();
56 if(g->sig != 0)
57 runtime_printf("[signal %x code=%p addr=%p]\n",
58 g->sig, (void*)g->sigcode0, (void*)g->sigcode1);
59
60 if(runtime_gotraceback()){
61 if(g != runtime_m()->g0) {
62 runtime_printf("\n");
63 runtime_goroutineheader(g);
64 runtime_traceback();
65 runtime_goroutinetrailer(g);
66 }
67 if(!didothers) {
68 didothers = true;
69 runtime_tracebackothers(g);
70 }
71 }
72 runtime_unlock(&paniclk);
73 if(runtime_xadd(&runtime_panicking, -1) != 0) {
74 // Some other m is panicking too.
75 // Let it print what it needs to print.
76 // Wait forever without chewing up cpu.
77 // It will exit when it's done.
78 static Lock deadlock;
79 runtime_lock(&deadlock);
80 runtime_lock(&deadlock);
81 }
82
83 runtime_exit(2);
84 }
85
86 void
87 runtime_throw(const char *s)
88 {
89 M *mp;
90
91 mp = runtime_m();
92 if(mp->throwing == 0)
93 mp->throwing = 1;
94 runtime_startpanic();
95 runtime_printf("fatal error: %s\n", s);
96 runtime_dopanic(0);
97 *(int32*)0 = 0; // not reached
98 runtime_exit(1); // even more not reached
99 }
100
101 void
102 runtime_panicstring(const char *s)
103 {
104 Eface err;
105
106 if(runtime_m()->gcing) {
107 runtime_printf("panic: %s\n", s);
108 runtime_throw("panic during gc");
109 }
110 runtime_newErrorString(runtime_gostringnocopy((const byte*)s), &err);
111 runtime_panic(err);
112 }
113
114 void runtime_Goexit (void) __asm__ (GOSYM_PREFIX "runtime.Goexit");
115
116 void
117 runtime_Goexit(void)
118 {
119 rundefer();
120 runtime_goexit();
121 }