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