]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: move all exception related code into signal_windows.go
authorAlex Brainman <alex.brainman@gmail.com>
Mon, 13 Apr 2015 02:02:44 +0000 (12:02 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Mon, 13 Apr 2015 07:04:21 +0000 (07:04 +0000)
Change-Id: I9654a5c85bd9b3ae9c7a9eddaef1ec752f42bd1b
Reviewed-on: https://go-review.googlesource.com/8840
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/os1_windows.go
src/runtime/os_windows.go
src/runtime/signal_windows.go

index 508c4951e8468f718dfce29510e67c6d7d587b32..1ab6ed1437872dcedd04717202a68469b5da6197 100644 (file)
@@ -117,12 +117,6 @@ func loadOptionalSyscalls() {
        }
 }
 
-// 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))
@@ -144,24 +138,15 @@ const (
        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))
 
@@ -173,21 +158,7 @@ func osinit() {
 
        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)
 
@@ -482,37 +453,6 @@ func usleep(us uint32) {
        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
 
@@ -604,35 +544,3 @@ func resetcpuprofiler(hz int32) {
 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.
-}
index 744dc66ccc9853065c4b949edf4e0f06c735c7d5..31df0649594c14ea0a5ae7e029b82e0a2b99f7df 100644 (file)
@@ -13,33 +13,6 @@ func os_sigpipe() {
        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")
index 110d37c4dffb4985b64b2e09808c87946989aff6..da8a1c58014b7a5fd7a173e6f85552204cc71025 100644 (file)
@@ -8,6 +8,40 @@ import (
        "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).
@@ -16,17 +50,26 @@ func isgoexception(info *exceptionrecord, r *context) bool {
                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
@@ -108,6 +151,51 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        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) {
 }
 
@@ -116,3 +204,14 @@ func sigdisable(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.
+}