LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "defs.h" | 6 #include "defs.h" |
7 #include "signals.h" | 7 #include "signals.h" |
8 #include "os.h" | 8 #include "os.h" |
9 | 9 |
10 void | 10 void |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) | 53 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) |
54 { | 54 { |
55 Ucontext *uc; | 55 Ucontext *uc; |
56 Mcontext *mc; | 56 Mcontext *mc; |
57 Sigcontext *r; | 57 Sigcontext *r; |
58 uintptr *sp; | 58 uintptr *sp; |
59 | 59 |
60 uc = context; | 60 uc = context; |
61 mc = &uc->uc_mcontext; | 61 mc = &uc->uc_mcontext; |
62 r = (Sigcontext*)mc; // same layout, more conveient names | 62 r = (Sigcontext*)mc; // same layout, more conveient names |
| 63 |
| 64 if(sig == SIGPROF) { |
| 65 runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp); |
| 66 return; |
| 67 } |
63 | 68 |
64 if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) { | 69 if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) { |
65 // Make it look like a call to the signal func. | 70 // Make it look like a call to the signal func. |
66 // Have to pass arguments out of band since | 71 // Have to pass arguments out of band since |
67 // augmenting the stack frame would break | 72 // augmenting the stack frame would break |
68 // the unwinding code. | 73 // the unwinding code. |
69 gp->sig = sig; | 74 gp->sig = sig; |
70 gp->sigcode0 = info->si_code; | 75 gp->sigcode0 = info->si_code; |
71 gp->sigcode1 = ((uintptr*)info)[2]; | 76 gp->sigcode1 = ((uintptr*)info)[2]; |
72 gp->sigpc = r->rip; | 77 gp->sigpc = r->rip; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 runtime·signalstack(byte *p, int32 n) | 122 runtime·signalstack(byte *p, int32 n) |
118 { | 123 { |
119 Sigaltstack st; | 124 Sigaltstack st; |
120 | 125 |
121 st.ss_sp = p; | 126 st.ss_sp = p; |
122 st.ss_size = n; | 127 st.ss_size = n; |
123 st.ss_flags = 0; | 128 st.ss_flags = 0; |
124 runtime·sigaltstack(&st, nil); | 129 runtime·sigaltstack(&st, nil); |
125 } | 130 } |
126 | 131 |
| 132 static void |
| 133 sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart) |
| 134 { |
| 135 Sigaction sa; |
| 136 |
| 137 runtime·memclr((byte*)&sa, sizeof sa); |
| 138 sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; |
| 139 if(restart) |
| 140 sa.sa_flags |= SA_RESTART; |
| 141 sa.sa_mask = ~0ULL; |
| 142 sa.sa_restorer = (void*)runtime·sigreturn; |
| 143 if(fn == runtime·sighandler) |
| 144 fn = (void*)runtime·sigtramp; |
| 145 sa.sa_handler = fn; |
| 146 runtime·rt_sigaction(i, &sa, nil, 8); |
| 147 } |
| 148 |
127 void | 149 void |
128 runtime·initsig(int32 queue) | 150 runtime·initsig(int32 queue) |
129 { | 151 { |
130 » static Sigaction sa; | 152 » int32 i; |
| 153 » void *fn; |
131 | 154 |
132 runtime·siginit(); | 155 runtime·siginit(); |
133 | 156 |
134 int32 i; | |
135 sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; | |
136 sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; | |
137 sa.sa_restorer = (void*)runtime·sigreturn; | |
138 for(i = 0; i<NSIG; i++) { | 157 for(i = 0; i<NSIG; i++) { |
139 if(runtime·sigtab[i].flags) { | 158 if(runtime·sigtab[i].flags) { |
140 if((runtime·sigtab[i].flags & SigQueue) != queue) | 159 if((runtime·sigtab[i].flags & SigQueue) != queue) |
141 continue; | 160 continue; |
142 if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) | 161 if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) |
143 » » » » sa.sa_handler = (void*)runtime·sigtramp; | 162 » » » » fn = runtime·sighandler; |
144 else | 163 else |
145 » » » » sa.sa_handler = (void*)runtime·sigignore; | 164 » » » » fn = runtime·sigignore; |
146 » » » if(runtime·sigtab[i].flags & SigRestart) | 165 » » » sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart)
!= 0); |
147 » » » » sa.sa_flags |= SA_RESTART; | |
148 » » » else | |
149 » » » » sa.sa_flags &= ~SA_RESTART; | |
150 » » » runtime·rt_sigaction(i, &sa, nil, 8); | |
151 } | 166 } |
152 } | 167 } |
153 } | 168 } |
| 169 |
| 170 void |
| 171 runtime·resetcpuprofiler(int32 hz) |
| 172 { |
| 173 Itimerval it; |
| 174 ········ |
| 175 runtime·memclr((byte*)&it, sizeof it); |
| 176 if(hz == 0) { |
| 177 runtime·setitimer(ITIMER_PROF, &it, nil); |
| 178 sigaction(SIGPROF, SIG_IGN, true); |
| 179 } else { |
| 180 sigaction(SIGPROF, runtime·sighandler, true); |
| 181 it.it_interval.tv_sec = 0; |
| 182 it.it_interval.tv_usec = 1000000 / hz; |
| 183 it.it_value = it.it_interval; |
| 184 runtime·setitimer(ITIMER_PROF, &it, nil); |
| 185 } |
| 186 m->profilehz = hz; |
| 187 } |
LEFT | RIGHT |