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.
10 // Code related to defer, panic and recover.
12 uint32 runtime_panicking
;
15 // Allocate a Defer, usually using per-P pool.
16 // Each defer must be released with freedefer.
27 p
->deferpool
= d
->__next
;
30 d
= runtime_malloc(sizeof(Defer
));
35 // Free the given defer.
36 // The defer cannot be used after this call.
38 runtime_freedefer(Defer
*d
)
45 d
->__next
= p
->deferpool
;
47 // No need to wipe out pointers in argp/pc/fn/args,
48 // because we empty the pool before GC.
51 // Run all deferred functions for the current goroutine.
59 while((d
= g
->defer
) != nil
) {
72 runtime_startpanic(void)
77 if(runtime_mheap
.cachealloc
.size
== 0) { // very early
78 runtime_printf("runtime: panic before malloc heap initialized\n");
79 m
->mallocing
= 1; // tell rest of panic not to try to malloc
80 } else if(m
->mcache
== nil
) // can happen if called from signal handler or throw
81 m
->mcache
= runtime_allocmcache();
85 if(runtime_g() != nil
)
86 runtime_g()->writebuf
= nil
;
87 runtime_xadd(&runtime_panicking
, 1);
88 runtime_lock(&paniclk
);
89 if(runtime_debug
.schedtrace
> 0 || runtime_debug
.scheddetail
> 0)
90 runtime_schedtrace(true);
91 runtime_freezetheworld();
94 // Something failed while panicing, probably the print of the
95 // argument to panic(). Just print a stack trace and exit.
97 runtime_printf("panic during panic\n");
101 // This is a genuine bug in the runtime, we couldn't even
102 // print the stack trace successfully.
104 runtime_printf("stack trace unavailable\n");
107 // Can't even print! Just exit.
113 runtime_dopanic(int32 unused
__attribute__ ((unused
)))
116 static bool didothers
;
122 runtime_printf("[signal %x code=%p addr=%p]\n",
123 g
->sig
, (void*)g
->sigcode0
, (void*)g
->sigcode1
);
125 if((t
= runtime_gotraceback(&crash
)) > 0){
126 if(g
!= runtime_m()->g0
) {
127 runtime_printf("\n");
128 runtime_goroutineheader(g
);
130 runtime_printcreatedby(g
);
131 } else if(t
>= 2 || runtime_m()->throwing
> 0) {
132 runtime_printf("\nruntime stack:\n");
137 runtime_tracebackothers(g
);
140 runtime_unlock(&paniclk
);
141 if(runtime_xadd(&runtime_panicking
, -1) != 0) {
142 // Some other m is panicking too.
143 // Let it print what it needs to print.
144 // Wait forever without chewing up cpu.
145 // It will exit when it's done.
146 static Lock deadlock
;
147 runtime_lock(&deadlock
);
148 runtime_lock(&deadlock
);
158 runtime_throw(const char *s
)
163 if(mp
->throwing
== 0)
165 runtime_startpanic();
166 runtime_printf("fatal error: %s\n", s
);
168 *(int32
*)0 = 0; // not reached
169 runtime_exit(1); // even more not reached
173 runtime_panicstring(const char *s
)
177 if(runtime_m()->mallocing
) {
178 runtime_printf("panic: %s\n", s
);
179 runtime_throw("panic during malloc");
181 if(runtime_m()->gcing
) {
182 runtime_printf("panic: %s\n", s
);
183 runtime_throw("panic during gc");
185 runtime_newErrorCString(s
, &err
);
189 void runtime_Goexit (void) __asm__ (GOSYM_PREFIX
"runtime.Goexit");