}
}
-// in sys_windows_386.s and sys_windows_amd64.s
-func externalthreadhandler()
-func exceptiontramp()
-func firstcontinuetramp()
-func lastcontinuetramp()
-
//go:nosplit
func getLoadLibrary() uintptr {
return uintptr(unsafe.Pointer(_LoadLibraryW))
currentThread = ^uintptr(1) // -2 = current thread
)
-func disableWER() {
- // do not display Windows Error Reporting dialogue
- const (
- SEM_FAILCRITICALERRORS = 0x0001
- SEM_NOGPFAULTERRORBOX = 0x0002
- SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
- SEM_NOOPENFILEERRORBOX = 0x8000
- )
- errormode := uint32(stdcall1(_SetErrorMode, SEM_NOGPFAULTERRORBOX))
- stdcall1(_SetErrorMode, uintptr(errormode)|SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX)
-}
-
func getVersion() (major, minor byte) {
v := uint32(stdcall0(_GetVersion))
low := uint16(v)
return byte(low), byte(low >> 8)
}
+// in sys_windows_386.s and sys_windows_amd64.s
+func externalthreadhandler()
+
func osinit() {
asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
externalthreadhandlerp = funcPC(externalthreadhandler)
- major, _ := getVersion()
-
- stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
- if _AddVectoredContinueHandler == nil || unsafe.Sizeof(&_AddVectoredContinueHandler) == 4 || major < 6 {
- // use SetUnhandledExceptionFilter for windows-386 or
- // if VectoredContinueHandler is unavailable or
- // if running windows-amd64 v5. V5 appears to fail to
- // call the continue handlers if windows error reporting dialog
- // is disabled.
- // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
- stdcall1(_SetUnhandledExceptionFilter, funcPC(lastcontinuetramp))
- } else {
- stdcall2(_AddVectoredContinueHandler, 1, funcPC(firstcontinuetramp))
- stdcall2(_AddVectoredContinueHandler, 0, funcPC(lastcontinuetramp))
- }
+ initExceptionHandler()
stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
usleep1(10 * us)
}
-func issigpanic(code uint32) uint32 {
- switch code {
- default:
- return 0
- case _EXCEPTION_ACCESS_VIOLATION:
- case _EXCEPTION_INT_DIVIDE_BY_ZERO:
- case _EXCEPTION_INT_OVERFLOW:
- case _EXCEPTION_FLT_DENORMAL_OPERAND:
- case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case _EXCEPTION_FLT_INEXACT_RESULT:
- case _EXCEPTION_FLT_OVERFLOW:
- case _EXCEPTION_FLT_UNDERFLOW:
- case _EXCEPTION_BREAKPOINT:
- }
- return 1
-}
-
-func initsig() {
- /*
- // TODO(brainman): I don't think we need that bit of code
- // following line keeps these functions alive at link stage
- // if there's a better way please write it here
- void *e = runtime·exceptiontramp;
- void *f = runtime·firstcontinuetramp;
- void *l = runtime·lastcontinuetramp;
- USED(e);
- USED(f);
- USED(l);
- */
-}
-
func ctrlhandler1(_type uint32) uint32 {
var s uint32
func memlimit() uintptr {
return 0
}
-
-var (
- badsignalmsg [100]byte
- badsignallen int32
-)
-
-func setBadSignalMsg() {
- const msg = "runtime: signal received on thread not created by Go.\n"
- for i, c := range msg {
- badsignalmsg[i] = byte(c)
- badsignallen++
- }
-}
-
-const (
- _SIGPROF = 0 // dummy value for badsignal
- _SIGQUIT = 0 // dummy value for sighandler
-)
-
-func raiseproc(sig int32) {
-}
-
-func crash() {
- // TODO: This routine should do whatever is needed
- // to make the Windows program abort/crash as it
- // would if Go was not intercepting signals.
- // On Unix the routine would remove the custom signal
- // handler and then raise a signal (like SIGABRT).
- // Something like that should happen here.
- // It's okay to leave this empty for now: if crash returns
- // the ordinary exit-after-panic happens.
-}
throw("too many writes on closed pipe")
}
-func sigpanic() {
- g := getg()
- if !canpanic(g) {
- throw("unexpected signal during runtime execution")
- }
-
- switch uint32(g.sig) {
- case _EXCEPTION_ACCESS_VIOLATION:
- if g.sigcode1 < 0x1000 || g.paniconfault {
- panicmem()
- }
- print("unexpected fault address ", hex(g.sigcode1), "\n")
- throw("fault")
- case _EXCEPTION_INT_DIVIDE_BY_ZERO:
- panicdivide()
- case _EXCEPTION_INT_OVERFLOW:
- panicoverflow()
- case _EXCEPTION_FLT_DENORMAL_OPERAND,
- _EXCEPTION_FLT_DIVIDE_BY_ZERO,
- _EXCEPTION_FLT_INEXACT_RESULT,
- _EXCEPTION_FLT_OVERFLOW,
- _EXCEPTION_FLT_UNDERFLOW:
- panicfloat()
- }
- throw("fault")
-}
-
// Stubs so tests can link correctly. These should never be called.
func open(name *byte, mode, perm int32) int32 {
throw("unimplemented")
"unsafe"
)
+func disableWER() {
+ // do not display Windows Error Reporting dialogue
+ const (
+ SEM_FAILCRITICALERRORS = 0x0001
+ SEM_NOGPFAULTERRORBOX = 0x0002
+ SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
+ SEM_NOOPENFILEERRORBOX = 0x8000
+ )
+ errormode := uint32(stdcall1(_SetErrorMode, SEM_NOGPFAULTERRORBOX))
+ stdcall1(_SetErrorMode, uintptr(errormode)|SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX)
+}
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func exceptiontramp()
+func firstcontinuetramp()
+func lastcontinuetramp()
+
+func initExceptionHandler() {
+ major, _ := getVersion()
+ stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
+ if _AddVectoredContinueHandler == nil || unsafe.Sizeof(&_AddVectoredContinueHandler) == 4 || major < 6 {
+ // use SetUnhandledExceptionFilter for windows-386 or
+ // if VectoredContinueHandler is unavailable or
+ // if running windows-amd64 v5. V5 appears to fail to
+ // call the continue handlers if windows error reporting dialog
+ // is disabled.
+ // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
+ stdcall1(_SetUnhandledExceptionFilter, funcPC(lastcontinuetramp))
+ } else {
+ stdcall2(_AddVectoredContinueHandler, 1, funcPC(firstcontinuetramp))
+ stdcall2(_AddVectoredContinueHandler, 0, funcPC(lastcontinuetramp))
+ }
+}
+
func isgoexception(info *exceptionrecord, r *context) bool {
// Only handle exception if executing instructions in Go binary
// (not Windows library code).
return false
}
- if issigpanic(info.exceptioncode) == 0 {
+ // Go will only handle some exceptions.
+ switch info.exceptioncode {
+ default:
return false
+ case _EXCEPTION_ACCESS_VIOLATION:
+ case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case _EXCEPTION_INT_OVERFLOW:
+ case _EXCEPTION_FLT_DENORMAL_OPERAND:
+ case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case _EXCEPTION_FLT_INEXACT_RESULT:
+ case _EXCEPTION_FLT_OVERFLOW:
+ case _EXCEPTION_FLT_UNDERFLOW:
+ case _EXCEPTION_BREAKPOINT:
}
-
return true
}
// Called by sigtramp from Windows VEH handler.
// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-
func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
if !isgoexception(info, r) {
return _EXCEPTION_CONTINUE_SEARCH
return 0 // not reached
}
+func sigpanic() {
+ g := getg()
+ if !canpanic(g) {
+ throw("unexpected signal during runtime execution")
+ }
+
+ switch uint32(g.sig) {
+ case _EXCEPTION_ACCESS_VIOLATION:
+ if g.sigcode1 < 0x1000 || g.paniconfault {
+ panicmem()
+ }
+ print("unexpected fault address ", hex(g.sigcode1), "\n")
+ throw("fault")
+ case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+ panicdivide()
+ case _EXCEPTION_INT_OVERFLOW:
+ panicoverflow()
+ case _EXCEPTION_FLT_DENORMAL_OPERAND,
+ _EXCEPTION_FLT_DIVIDE_BY_ZERO,
+ _EXCEPTION_FLT_INEXACT_RESULT,
+ _EXCEPTION_FLT_OVERFLOW,
+ _EXCEPTION_FLT_UNDERFLOW:
+ panicfloat()
+ }
+ throw("fault")
+}
+
+var (
+ badsignalmsg [100]byte
+ badsignallen int32
+)
+
+func setBadSignalMsg() {
+ const msg = "runtime: signal received on thread not created by Go.\n"
+ for i, c := range msg {
+ badsignalmsg[i] = byte(c)
+ badsignallen++
+ }
+}
+
+// Following are not implemented.
+
+func initsig() {
+}
+
func sigenable(sig uint32) {
}
func sigignore(sig uint32) {
}
+
+func crash() {
+ // TODO: This routine should do whatever is needed
+ // to make the Windows program abort/crash as it
+ // would if Go was not intercepting signals.
+ // On Unix the routine would remove the custom signal
+ // handler and then raise a signal (like SIGABRT).
+ // Something like that should happen here.
+ // It's okay to leave this empty for now: if crash returns
+ // the ordinary exit-after-panic happens.
+}