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