...
Source file src/runtime/signal_windows.go
1
2
3
4
5 package runtime
6
7 import (
8 "unsafe"
9 )
10
11 func disableWER() {
12
13 const (
14 SEM_FAILCRITICALERRORS = 0x0001
15 SEM_NOGPFAULTERRORBOX = 0x0002
16 SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
17 SEM_NOOPENFILEERRORBOX = 0x8000
18 )
19 errormode := uint32(stdcall1(_SetErrorMode, SEM_NOGPFAULTERRORBOX))
20 stdcall1(_SetErrorMode, uintptr(errormode)|SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX)
21 }
22
23
24 func exceptiontramp()
25 func firstcontinuetramp()
26 func lastcontinuetramp()
27
28 func initExceptionHandler() {
29 stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
30 if _AddVectoredContinueHandler == nil || GOARCH == "386" {
31
32
33
34 stdcall1(_SetUnhandledExceptionFilter, funcPC(lastcontinuetramp))
35 } else {
36 stdcall2(_AddVectoredContinueHandler, 1, funcPC(firstcontinuetramp))
37 stdcall2(_AddVectoredContinueHandler, 0, funcPC(lastcontinuetramp))
38 }
39 }
40
41
42
43
44
45 func isAbort(r *context) bool {
46 switch GOARCH {
47 case "386", "amd64":
48
49
50 return isAbortPC(r.ip() - 1)
51 case "arm":
52 return isAbortPC(r.ip())
53 default:
54 return false
55 }
56 }
57
58
59
60
61
62
63
64
65 func isgoexception(info *exceptionrecord, r *context) bool {
66
67
68
69 if r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip() {
70 return false
71 }
72
73 if isAbort(r) {
74
75 return false
76 }
77
78
79 switch info.exceptioncode {
80 default:
81 return false
82 case _EXCEPTION_ACCESS_VIOLATION:
83 case _EXCEPTION_INT_DIVIDE_BY_ZERO:
84 case _EXCEPTION_INT_OVERFLOW:
85 case _EXCEPTION_FLT_DENORMAL_OPERAND:
86 case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
87 case _EXCEPTION_FLT_INEXACT_RESULT:
88 case _EXCEPTION_FLT_OVERFLOW:
89 case _EXCEPTION_FLT_UNDERFLOW:
90 case _EXCEPTION_BREAKPOINT:
91 }
92 return true
93 }
94
95
96
97
98
99
100
101
102
103
104 func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
105 if !isgoexception(info, r) {
106 return _EXCEPTION_CONTINUE_SEARCH
107 }
108
109
110
111 if gp.throwsplit {
112
113
114 return _EXCEPTION_CONTINUE_SEARCH
115 }
116
117
118
119
120
121 gp.sig = info.exceptioncode
122 gp.sigcode0 = uintptr(info.exceptioninformation[0])
123 gp.sigcode1 = uintptr(info.exceptioninformation[1])
124 gp.sigpc = r.ip()
125
126
127
128
129
130
131
132 if r.ip() != 0 {
133 sp := unsafe.Pointer(r.sp())
134 sp = add(sp, ^(unsafe.Sizeof(uintptr(0)) - 1))
135 r.set_sp(uintptr(sp))
136 switch GOARCH {
137 default:
138 panic("unsupported architecture")
139 case "386", "amd64":
140 *((*uintptr)(sp)) = r.ip()
141 case "arm":
142 *((*uintptr)(sp)) = r.lr()
143 r.set_lr(r.ip())
144 }
145 }
146 r.set_ip(funcPC(sigpanic))
147 return _EXCEPTION_CONTINUE_EXECUTION
148 }
149
150
151
152
153
154
155
156
157
158 func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
159 if !isgoexception(info, r) {
160 return _EXCEPTION_CONTINUE_SEARCH
161 }
162 return _EXCEPTION_CONTINUE_EXECUTION
163 }
164
165 var testingWER bool
166
167
168
169
170
171
172
173 func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
174 if testingWER {
175 return _EXCEPTION_CONTINUE_SEARCH
176 }
177
178 _g_ := getg()
179
180 if panicking != 0 {
181 exit(2)
182 }
183 panicking = 1
184
185
186
187
188 _g_.stack.lo = 0
189 _g_.stackguard0 = _g_.stack.lo + _StackGuard
190 _g_.stackguard1 = _g_.stackguard0
191
192 print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
193
194 print("PC=", hex(r.ip()), "\n")
195 if _g_.m.lockedg != 0 && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
196 if iscgo {
197 print("signal arrived during external code execution\n")
198 }
199 gp = _g_.m.lockedg.ptr()
200 }
201 print("\n")
202
203
204 if GOARCH == "arm" {
205 _g_.m.throwing = 1
206 _g_.m.caughtsig.set(gp)
207 }
208
209 level, _, docrash := gotraceback()
210 if level > 0 {
211 tracebacktrap(r.ip(), r.sp(), r.lr(), gp)
212 tracebackothers(gp)
213 dumpregs(r)
214 }
215
216 if docrash {
217 crash()
218 }
219
220 exit(2)
221 return 0
222 }
223
224 func sigpanic() {
225 g := getg()
226 if !canpanic(g) {
227 throw("unexpected signal during runtime execution")
228 }
229
230 switch g.sig {
231 case _EXCEPTION_ACCESS_VIOLATION:
232 if g.sigcode1 < 0x1000 || g.paniconfault {
233 panicmem()
234 }
235 print("unexpected fault address ", hex(g.sigcode1), "\n")
236 throw("fault")
237 case _EXCEPTION_INT_DIVIDE_BY_ZERO:
238 panicdivide()
239 case _EXCEPTION_INT_OVERFLOW:
240 panicoverflow()
241 case _EXCEPTION_FLT_DENORMAL_OPERAND,
242 _EXCEPTION_FLT_DIVIDE_BY_ZERO,
243 _EXCEPTION_FLT_INEXACT_RESULT,
244 _EXCEPTION_FLT_OVERFLOW,
245 _EXCEPTION_FLT_UNDERFLOW:
246 panicfloat()
247 }
248 throw("fault")
249 }
250
251 var (
252 badsignalmsg [100]byte
253 badsignallen int32
254 )
255
256 func setBadSignalMsg() {
257 const msg = "runtime: signal received on thread not created by Go.\n"
258 for i, c := range msg {
259 badsignalmsg[i] = byte(c)
260 badsignallen++
261 }
262 }
263
264
265
266 func initsig(preinit bool) {
267 }
268
269 func sigenable(sig uint32) {
270 }
271
272 func sigdisable(sig uint32) {
273 }
274
275 func sigignore(sig uint32) {
276 }
277
278 func badsignal2()
279
280 func raisebadsignal(sig uint32) {
281 badsignal2()
282 }
283
284 func signame(sig uint32) string {
285 return ""
286 }
287
288
289 func crash() {
290
291
292
293
294
295
296
297
298 }
299
300
301 type gsignalStack struct{}
302
View as plain text