blob: 88a84d1120a4a66e6dfb4d647cb02fd551b007f5 [file] [log] [blame]
Kai Backman79435562009-05-26 11:18:42 -07001// Copyright 2009 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
Kai Backman52891952009-06-10 11:53:07 -07005#include "runtime.h"
6#include "defs.h"
7#include "signals.h"
8#include "os.h"
9
Russ Cox6c196012010-04-05 12:51:09 -070010void
Russ Cox68b42552010-11-04 14:00:19 -040011runtime·dumpregs(Sigcontext *r)
Russ Cox6c196012010-04-05 12:51:09 -070012{
Russ Cox68b42552010-11-04 14:00:19 -040013 runtime·printf("trap %x\n", r->trap_no);
14 runtime·printf("error %x\n", r->error_code);
15 runtime·printf("oldmask %x\n", r->oldmask);
16 runtime·printf("r0 %x\n", r->arm_r0);
17 runtime·printf("r1 %x\n", r->arm_r1);
18 runtime·printf("r2 %x\n", r->arm_r2);
19 runtime·printf("r3 %x\n", r->arm_r3);
20 runtime·printf("r4 %x\n", r->arm_r4);
21 runtime·printf("r5 %x\n", r->arm_r5);
22 runtime·printf("r6 %x\n", r->arm_r6);
23 runtime·printf("r7 %x\n", r->arm_r7);
24 runtime·printf("r8 %x\n", r->arm_r8);
25 runtime·printf("r9 %x\n", r->arm_r9);
26 runtime·printf("r10 %x\n", r->arm_r10);
27 runtime·printf("fp %x\n", r->arm_fp);
28 runtime·printf("ip %x\n", r->arm_ip);
29 runtime·printf("sp %x\n", r->arm_sp);
30 runtime·printf("lr %x\n", r->arm_lr);
31 runtime·printf("pc %x\n", r->arm_pc);
32 runtime·printf("cpsr %x\n", r->arm_cpsr);
33 runtime·printf("fault %x\n", r->fault_address);
Russ Cox6c196012010-04-05 12:51:09 -070034}
Kai Backman52891952009-06-10 11:53:07 -070035
36/*
37 * This assembler routine takes the args from registers, puts them on the stack,
38 * and calls sighandler().
39 */
Russ Cox68b42552010-11-04 14:00:19 -040040extern void runtime·sigtramp(void);
41extern void runtime·sigignore(void); // just returns
42extern void runtime·sigreturn(void); // calls runtime·sigreturn
Kai Backman52891952009-06-10 11:53:07 -070043
David Symondsb5866492009-12-15 18:21:29 -080044String
Russ Cox68b42552010-11-04 14:00:19 -040045runtime·signame(int32 sig)
David Symondsb5866492009-12-15 18:21:29 -080046{
47 if(sig < 0 || sig >= NSIG)
Russ Cox68b42552010-11-04 14:00:19 -040048 return runtime·emptystring;
49 return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
David Symondsb5866492009-12-15 18:21:29 -080050}
51
Russ Cox6c196012010-04-05 12:51:09 -070052void
Russ Cox690291a2011-02-23 14:47:42 -050053runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
Russ Cox6c196012010-04-05 12:51:09 -070054{
55 Ucontext *uc;
Russ Cox5963dba2010-04-08 18:15:30 -070056 Sigcontext *r;
Russ Cox5963dba2010-04-08 18:15:30 -070057
58 uc = context;
59 r = &uc->uc_mcontext;
60
Russ Coxc19b3732011-03-23 11:43:37 -040061 if(sig == SIGPROF) {
62 runtime·sigprof((uint8*)r->arm_pc, (uint8*)r->arm_sp, (uint8*)r->arm_lr, gp);
63 return;
64 }
65
Russ Cox690291a2011-02-23 14:47:42 -050066 if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
Russ Cox5963dba2010-04-08 18:15:30 -070067 // Make it look like a call to the signal func.
68 // Have to pass arguments out of band since
69 // augmenting the stack frame would break
70 // the unwinding code.
71 gp->sig = sig;
72 gp->sigcode0 = info->si_code;
73 gp->sigcode1 = r->fault_address;
Russ Cox12307002011-01-18 14:15:11 -050074 gp->sigpc = r->arm_pc;
Russ Cox5963dba2010-04-08 18:15:30 -070075
76 // If this is a leaf function, we do smash LR,
77 // but we're not going back there anyway.
Russ Coxc3e54f02010-04-13 22:31:47 -070078 // Don't bother smashing if r->arm_pc is 0,
79 // which is probably a call to a nil func: the
80 // old link register is more useful in the stack trace.
81 if(r->arm_pc != 0)
82 r->arm_lr = r->arm_pc;
Russ Cox68b42552010-11-04 14:00:19 -040083 r->arm_pc = (uintptr)runtime·sigpanic;
Russ Cox5963dba2010-04-08 18:15:30 -070084 return;
85 }
Kai Backman52891952009-06-10 11:53:07 -070086
Russ Cox68b42552010-11-04 14:00:19 -040087 if(runtime·sigtab[sig].flags & SigQueue) {
88 if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
Russ Cox6c196012010-04-05 12:51:09 -070089 return;
Russ Cox68b42552010-11-04 14:00:19 -040090 runtime·exit(2); // SIGINT, SIGTERM, etc
Russ Cox6c196012010-04-05 12:51:09 -070091 }
Kai Backman52891952009-06-10 11:53:07 -070092
Russ Cox68b42552010-11-04 14:00:19 -040093 if(runtime·panicking) // traceback already printed
94 runtime·exit(2);
95 runtime·panicking = 1;
Kai Backman52891952009-06-10 11:53:07 -070096
Russ Cox6c196012010-04-05 12:51:09 -070097 if(sig < 0 || sig >= NSIG)
Russ Cox68b42552010-11-04 14:00:19 -040098 runtime·printf("Signal %d\n", sig);
Russ Cox6c196012010-04-05 12:51:09 -070099 else
Russ Cox68b42552010-11-04 14:00:19 -0400100 runtime·printf("%s\n", runtime·sigtab[sig].name);
Kai Backman52891952009-06-10 11:53:07 -0700101
Russ Cox68b42552010-11-04 14:00:19 -0400102 runtime·printf("PC=%x\n", r->arm_pc);
103 runtime·printf("\n");
Kai Backman52891952009-06-10 11:53:07 -0700104
Russ Cox68b42552010-11-04 14:00:19 -0400105 if(runtime·gotraceback()){
Russ Cox690291a2011-02-23 14:47:42 -0500106 runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, gp);
107 runtime·tracebackothers(gp);
Russ Cox68b42552010-11-04 14:00:19 -0400108 runtime·printf("\n");
109 runtime·dumpregs(r);
Russ Cox6c196012010-04-05 12:51:09 -0700110 }
111
112// breakpoint();
Russ Cox68b42552010-11-04 14:00:19 -0400113 runtime·exit(2);
Russ Cox6c196012010-04-05 12:51:09 -0700114}
Kai Backman52891952009-06-10 11:53:07 -0700115
116void
Russ Cox68b42552010-11-04 14:00:19 -0400117runtime·signalstack(byte *p, int32 n)
Kai Backman52891952009-06-10 11:53:07 -0700118{
Russ Cox6c196012010-04-05 12:51:09 -0700119 Sigaltstack st;
Kai Backman52891952009-06-10 11:53:07 -0700120
Russ Cox6c196012010-04-05 12:51:09 -0700121 st.ss_sp = p;
122 st.ss_size = n;
123 st.ss_flags = 0;
Russ Cox68b42552010-11-04 14:00:19 -0400124 runtime·sigaltstack(&st, nil);
Kai Backman52891952009-06-10 11:53:07 -0700125}
126
Russ Coxc19b3732011-03-23 11:43:37 -0400127static void
128sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
129{
130 Sigaction sa;
131
132 runtime·memclr((byte*)&sa, sizeof sa);
133 sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
134 if(restart)
135 sa.sa_flags |= SA_RESTART;
136 sa.sa_mask = ~0ULL;
137 sa.sa_restorer = (void*)runtime·sigreturn;
Russ Cox6b335712011-03-27 23:39:42 -0400138 if(fn == runtime·sighandler)
139 fn = (void*)runtime·sigtramp;
Russ Cox1f223462011-03-25 12:30:49 -0400140 sa.sa_handler = fn;
Russ Coxc19b3732011-03-23 11:43:37 -0400141 runtime·rt_sigaction(i, &sa, nil, 8);
142}
143
Kai Backman52891952009-06-10 11:53:07 -0700144void
Russ Cox68b42552010-11-04 14:00:19 -0400145runtime·initsig(int32 queue)
Kai Backman52891952009-06-10 11:53:07 -0700146{
Russ Coxc19b3732011-03-23 11:43:37 -0400147 int32 i;
148 void *fn;
Kai Backman52891952009-06-10 11:53:07 -0700149
Russ Cox68b42552010-11-04 14:00:19 -0400150 runtime·siginit();
Russ Cox6c196012010-04-05 12:51:09 -0700151
Russ Cox6c196012010-04-05 12:51:09 -0700152 for(i = 0; i<NSIG; i++) {
Russ Cox68b42552010-11-04 14:00:19 -0400153 if(runtime·sigtab[i].flags) {
154 if((runtime·sigtab[i].flags & SigQueue) != queue)
Ian Lance Taylor807605d2010-06-28 17:14:17 -0700155 continue;
Russ Cox68b42552010-11-04 14:00:19 -0400156 if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
Russ Coxc19b3732011-03-23 11:43:37 -0400157 fn = runtime·sighandler;
Russ Cox6c196012010-04-05 12:51:09 -0700158 else
Russ Coxc19b3732011-03-23 11:43:37 -0400159 fn = runtime·sigignore;
160 sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
Russ Cox6c196012010-04-05 12:51:09 -0700161 }
162 }
Kai Backman52891952009-06-10 11:53:07 -0700163}
Russ Coxc19b3732011-03-23 11:43:37 -0400164
165void
166runtime·resetcpuprofiler(int32 hz)
167{
Russ Coxc19b3732011-03-23 11:43:37 -0400168 Itimerval it;
169
170 runtime·memclr((byte*)&it, sizeof it);
171 if(hz == 0) {
172 runtime·setitimer(ITIMER_PROF, &it, nil);
173 sigaction(SIGPROF, SIG_IGN, true);
174 } else {
175 sigaction(SIGPROF, runtime·sighandler, true);
176 it.it_interval.tv_sec = 0;
177 it.it_interval.tv_usec = 1000000 / hz;
178 it.it_value = it.it_interval;
179 runtime·setitimer(ITIMER_PROF, &it, nil);
180 }
181 m->profilehz = hz;
182}
Russ Cox8698bb62011-04-25 16:58:00 -0400183
184void
185os·sigpipe(void)
186{
187 sigaction(SIGPIPE, SIG_DFL, false);
188 runtime·raisesigpipe();
189}