Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(677)

Side by Side Diff: src/pkg/runtime/signal_386.c

Issue 7565048: code review 7565048: runtime: refactor os-specific code (Closed)
Patch Set: diff -r 74da57c3abfe https://go.googlecode.com/hg Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/runtime/os_windows_amd64.c ('k') | src/pkg/runtime/signal_amd64.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2013 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 // +build darwin freebsd linux netbsd openbsd
6
5 #include "runtime.h" 7 #include "runtime.h"
6 #include "defs_GOOS_GOARCH.h" 8 #include "defs_GOOS_GOARCH.h"
7 #include "os_GOOS.h" 9 #include "os_GOOS.h"
10 #include "signal_GOOS_GOARCH.h"
8 #include "signals_GOOS.h" 11 #include "signals_GOOS.h"
9 12
10 void 13 void
11 runtime·dumpregs(Regs32 *r) 14 runtime·dumpregs(Siginfo *info, void *ctxt)
12 { 15 {
13 » runtime·printf("eax %x\n", r->eax); 16 » USED(info);
14 » runtime·printf("ebx %x\n", r->ebx); 17 » USED(ctxt);
15 » runtime·printf("ecx %x\n", r->ecx); 18 »·······
16 » runtime·printf("edx %x\n", r->edx); 19 » runtime·printf("eax %x\n", SIG_EAX(info, ctxt));
17 » runtime·printf("edi %x\n", r->edi); 20 » runtime·printf("ebx %x\n", SIG_EBX(info, ctxt));
18 » runtime·printf("esi %x\n", r->esi); 21 » runtime·printf("ecx %x\n", SIG_ECX(info, ctxt));
19 » runtime·printf("ebp %x\n", r->ebp); 22 » runtime·printf("edx %x\n", SIG_EDX(info, ctxt));
20 » runtime·printf("esp %x\n", r->esp); 23 » runtime·printf("edi %x\n", SIG_EDI(info, ctxt));
21 » runtime·printf("eip %x\n", r->eip); 24 » runtime·printf("esi %x\n", SIG_ESI(info, ctxt));
22 » runtime·printf("eflags %x\n", r->eflags); 25 » runtime·printf("ebp %x\n", SIG_EBP(info, ctxt));
23 » runtime·printf("cs %x\n", r->cs); 26 » runtime·printf("esp %x\n", SIG_ESP(info, ctxt));
24 » runtime·printf("fs %x\n", r->fs); 27 » runtime·printf("eip %x\n", SIG_EIP(info, ctxt));
25 » runtime·printf("gs %x\n", r->gs); 28 » runtime·printf("eflags %x\n", SIG_EFLAGS(info, ctxt));
29 » runtime·printf("cs %x\n", SIG_CS(info, ctxt));
30 » runtime·printf("fs %x\n", SIG_FS(info, ctxt));
31 » runtime·printf("gs %x\n", SIG_GS(info, ctxt));
26 } 32 }
27 33
28 void 34 void
29 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) 35 runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
30 { 36 {
31 Ucontext *uc;
32 Mcontext32 *mc;
33 Regs32 *r;
34 uintptr *sp; 37 uintptr *sp;
35 byte *pc;
36 SigTab *t; 38 SigTab *t;
37 39
38 uc = context;
39 mc = uc->uc_mcontext;
40 r = &mc->ss;
41
42 if(sig == SIGPROF) { 40 if(sig == SIGPROF) {
43 if(gp != m->g0 && gp != m->gsignal) 41 if(gp != m->g0 && gp != m->gsignal)
44 » » » runtime·sigprof((uint8*)r->eip, (uint8*)r->esp, nil, gp) ; 42 » » » runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_E SP(info, ctxt), nil, gp);
45 return; 43 return;
46 } 44 }
47 45
48 t = &runtime·sigtab[sig]; 46 t = &runtime·sigtab[sig];
49 if(info->si_code != SI_USER && (t->flags & SigPanic)) { 47 if(info->si_code != SI_USER && (t->flags & SigPanic)) {
50 if(gp == nil || gp == m->g0) 48 if(gp == nil || gp == m->g0)
51 goto Throw; 49 goto Throw;
52 // Work around Leopard bug that doesn't set FPE_INTDIV.
53 // Look at instruction to see if it is a divide.
54 // Not necessary in Snow Leopard (si_code will be != 0).
55 if(sig == SIGFPE && info->si_code == 0) {
56 pc = (byte*)r->eip;
57 if(pc[0] == 0x66) // 16-bit instruction prefix
58 pc++;
59 if(pc[0] == 0xF6 || pc[0] == 0xF7)
60 info->si_code = FPE_INTDIV;
61 }
62 50
63 // Make it look like a call to the signal func. 51 // Make it look like a call to the signal func.
64 // Have to pass arguments out of band since 52 // Have to pass arguments out of band since
65 // augmenting the stack frame would break 53 // augmenting the stack frame would break
66 // the unwinding code. 54 // the unwinding code.
67 gp->sig = sig; 55 gp->sig = sig;
68 » » gp->sigcode0 = info->si_code; 56 » » gp->sigcode0 = SIG_CODE0(info, ctxt);
69 » » gp->sigcode1 = (uintptr)info->si_addr; 57 » » gp->sigcode1 = SIG_CODE1(info, ctxt);
70 » » gp->sigpc = r->eip; 58 » » gp->sigpc = SIG_EIP(info, ctxt);
71 59
72 » » // Only push runtime·sigpanic if r->eip != 0. 60 #ifdef GOOS_darwin
73 » » // If r->eip == 0, probably panicked because of a 61 » » // Work around Leopard bug that doesn't set FPE_INTDIV.
62 » » // Look at instruction to see if it is a divide.
63 » » // Not necessary in Snow Leopard (si_code will be != 0).
64 » » if(sig == SIGFPE && gp->sigcode0 == 0) {
65 » » » byte *pc;
66 » » » pc = (byte*)gp->sigpc;
67 » » » if(pc[0] == 0x66)» // 16-bit instruction prefix
68 » » » » pc++;
69 » » » if(pc[0] == 0xF6 || pc[0] == 0xF7)
70 » » » » gp->sigcode0 = FPE_INTDIV;
71 » » }
72 #endif
73
74 » » // Only push runtime·sigpanic if eip != 0.
75 » » // If eip == 0, probably panicked because of a
74 // call to a nil func. Not pushing that onto sp will 76 // call to a nil func. Not pushing that onto sp will
75 // make the trace look like a call to runtime·sigpanic instead. 77 // make the trace look like a call to runtime·sigpanic instead.
76 // (Otherwise the trace will end at runtime·sigpanic and we 78 // (Otherwise the trace will end at runtime·sigpanic and we
77 // won't get to see who faulted.) 79 // won't get to see who faulted.)
78 » » if(r->eip != 0) { 80 » » if(SIG_EIP(info, ctxt) != 0) {
79 » » » sp = (uintptr*)r->esp; 81 » » » sp = (uintptr*)SIG_ESP(info, ctxt);
80 » » » *--sp = r->eip; 82 » » » *--sp = SIG_EIP(info, ctxt);
81 » » » r->esp = (uintptr)sp; 83 » » » SIG_ESP(info, ctxt) = (uintptr)sp;
82 } 84 }
83 » » r->eip = (uintptr)runtime·sigpanic; 85 » » SIG_EIP(info, ctxt) = (uintptr)runtime·sigpanic;
84 return; 86 return;
85 } 87 }
86 88
87 if(info->si_code == SI_USER || (t->flags & SigNotify)) 89 if(info->si_code == SI_USER || (t->flags & SigNotify))
88 if(runtime·sigsend(sig)) 90 if(runtime·sigsend(sig))
89 return; 91 return;
90 if(t->flags & SigKill) 92 if(t->flags & SigKill)
91 runtime·exit(2); 93 runtime·exit(2);
92 if(!(t->flags & SigThrow)) 94 if(!(t->flags & SigThrow))
93 return; 95 return;
94 96
95 Throw: 97 Throw:
96 runtime·startpanic(); 98 runtime·startpanic();
97 99
98 » if(sig < 0 || sig >= NSIG){ 100 » if(sig < 0 || sig >= NSIG)
99 runtime·printf("Signal %d\n", sig); 101 runtime·printf("Signal %d\n", sig);
100 » }else{ 102 » else
101 runtime·printf("%s\n", runtime·sigtab[sig].name); 103 runtime·printf("%s\n", runtime·sigtab[sig].name);
102 }
103 104
104 » runtime·printf("PC=%x\n", r->eip); 105 » runtime·printf("PC=%x\n", SIG_EIP(info, ctxt));
105 if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { 106 if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
106 runtime·printf("signal arrived during cgo execution\n"); 107 runtime·printf("signal arrived during cgo execution\n");
107 gp = m->lockedg; 108 gp = m->lockedg;
108 }······· 109 }·······
109 runtime·printf("\n"); 110 runtime·printf("\n");
110 111
111 if(runtime·gotraceback()){ 112 if(runtime·gotraceback()){
112 » » runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp); 113 » » runtime·traceback((void*)SIG_EIP(info, ctxt), (void*)SIG_ESP(inf o, ctxt), 0, gp);
113 runtime·tracebackothers(gp); 114 runtime·tracebackothers(gp);
114 » » runtime·dumpregs(r); 115 » » runtime·dumpregs(info, ctxt);
115 } 116 }
116 117
117 runtime·exit(2); 118 runtime·exit(2);
118 } 119 }
119
120 void
121 runtime·signalstack(byte *p, int32 n)
122 {
123 StackT st;
124
125 st.ss_sp = p;
126 st.ss_size = n;
127 st.ss_flags = 0;
128 if(p == nil)
129 st.ss_flags = SS_DISABLE;
130 runtime·sigaltstack(&st, nil);
131 }
132
133 void
134 runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
135 {
136 Sigaction sa;
137
138 // If SIGHUP handler is SIG_IGN, assume running
139 // under nohup and do not set explicit handler.
140 if(i == SIGHUP) {
141 runtime·memclr((byte*)&sa, sizeof sa);
142 runtime·sigaction(i, nil, &sa);
143 if(*(void**)sa.__sigaction_u == SIG_IGN)
144 return;
145 }
146
147 runtime·memclr((byte*)&sa, sizeof sa);
148 sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
149 if(restart)
150 sa.sa_flags |= SA_RESTART;
151 sa.sa_mask = ~0U;
152 sa.sa_tramp = (void*)runtime·sigtramp; // runtime·sigtramp's job is to call into real handler
153 *(uintptr*)sa.__sigaction_u = (uintptr)fn;
154 runtime·sigaction(i, &sa, nil);
155 }
OLDNEW
« no previous file with comments | « src/pkg/runtime/os_windows_amd64.c ('k') | src/pkg/runtime/signal_amd64.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b