]> Cypherpunks repositories - gostls13.git/commitdiff
undo CL 145150043 / 8b3d26697b8d
authorAlex Brainman <alex.brainman@gmail.com>
Thu, 9 Oct 2014 06:24:34 +0000 (17:24 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Thu, 9 Oct 2014 06:24:34 +0000 (17:24 +1100)
That was complete failure - builders are broken,
but original cl worked fine on my system.
I will need access to builders
to test this change properly.

««« original CL description
runtime: handle all windows exception

Fixes #8006.

LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews
https://golang.org/cl/145150043
»»»

TBR=rsc
R=golang-codereviews
CC=golang-codereviews
https://golang.org/cl/154180043

src/runtime/defs_windows.go
src/runtime/defs_windows_386.h
src/runtime/defs_windows_amd64.h
src/runtime/os_windows.c
src/runtime/os_windows_386.c
src/runtime/os_windows_amd64.c
src/runtime/sys_windows_386.s
src/runtime/sys_windows_amd64.s
src/runtime/syscall_windows_test.go

index c27cc41dc00e1999bd25ecc7c45db7f132344213..cb0f54d8abbd47e9ee68b593bd66937be9fb9d5f 100644 (file)
@@ -59,9 +59,6 @@ const (
 
        INFINITE     = C.INFINITE
        WAIT_TIMEOUT = C.WAIT_TIMEOUT
-
-       EXCEPTION_CONTINUE_EXECUTION = C.EXCEPTION_CONTINUE_EXECUTION
-       EXCEPTION_CONTINUE_SEARCH    = C.EXCEPTION_CONTINUE_SEARCH
 )
 
 type SystemInfo C.SYSTEM_INFO
index 67cac0f01e448ee916553ed6d799dec9685d2899..295e422c6bacac813953b200a18173b1ced6d3f7 100644 (file)
@@ -32,9 +32,6 @@ enum {
 
        INFINITE        = 0xffffffff,
        WAIT_TIMEOUT    = 0x102,
-
-       EXCEPTION_CONTINUE_EXECUTION    = -0x1,
-       EXCEPTION_CONTINUE_SEARCH       = 0x0,
 };
 
 typedef struct SystemInfo SystemInfo;
index 97cdb9ed15d425c004f7e3df52eb8e32f7c0a19e..2516c84128cba922aceace5468eb6a75f64147d2 100644 (file)
@@ -32,9 +32,6 @@ enum {
 
        INFINITE        = 0xffffffff,
        WAIT_TIMEOUT    = 0x102,
-
-       EXCEPTION_CONTINUE_EXECUTION    = -0x1,
-       EXCEPTION_CONTINUE_SEARCH       = 0x0,
 };
 
 typedef struct SystemInfo SystemInfo;
index 72108355039ed652f28e8fa692a02c102f0dcfc2..6337dde2af8d8bd0a12e5522d3ceed031ecf0b13 100644 (file)
@@ -34,7 +34,6 @@
 #pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
 #pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
 #pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
-#pragma dynimport runtime·SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
 #pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
 #pragma dynimport runtime·Sleep Sleep "kernel32.dll"
 #pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
@@ -66,7 +65,6 @@ extern void *runtime·SetConsoleCtrlHandler;
 extern void *runtime·SetEvent;
 extern void *runtime·SetProcessPriorityBoost;
 extern void *runtime·SetThreadPriority;
-extern void *runtime·SetUnhandledExceptionFilter;
 extern void *runtime·SetWaitableTimer;
 extern void *runtime·Sleep;
 extern void *runtime·SuspendThread;
@@ -79,9 +77,7 @@ void *runtime·GetQueuedCompletionStatusEx;
 
 extern uintptr runtime·externalthreadhandlerp;
 void runtime·externalthreadhandler(void);
-void runtime·exceptiontramp(void);
-void runtime·firstcontinuetramp(void);
-void runtime·lastcontinuetramp(void);
+void runtime·sigtramp(void);
 
 #pragma textflag NOSPLIT
 uintptr
@@ -110,28 +106,12 @@ void
 runtime·osinit(void)
 {
        void *kernel32;
-       void *addVectoredContinueHandler = nil;
-
-       kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
 
        runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
 
-       runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·exceptiontramp);
-       if(kernel32 != nil)
-               addVectoredContinueHandler = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"AddVectoredContinueHandler");
-       if(addVectoredContinueHandler == nil)
-               // use SetUnhandledExceptionFilter if VectoredContinueHandler is unavailable.
-               // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
-               runtime·stdcall1(runtime·SetUnhandledExceptionFilter, (uintptr)runtime·lastcontinuetramp);
-       else {
-               runtime·stdcall2(addVectoredContinueHandler, 1, (uintptr)runtime·firstcontinuetramp);
-               runtime·stdcall2(addVectoredContinueHandler, 0, (uintptr)runtime·lastcontinuetramp);
-       }
-
+       runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·sigtramp);
        runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
-
        runtime·stdcall1(runtime·timeBeginPeriod, 1);
-
        runtime·ncpu = getproccount();
        
        // Windows dynamic priority boosting assumes that a process has different types
@@ -140,6 +120,7 @@ runtime·osinit(void)
        // In such context dynamic priority boosting does nothing but harm, so we turn it off.
        runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
 
+       kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
        if(kernel32 != nil) {
                runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
        }
@@ -494,14 +475,10 @@ runtime·issigpanic(uint32 code)
 void
 runtime·initsig(void)
 {
-       // following line keeps these functions alive at link stage
+       // following line keeps sigtramp 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);
+       void *p = runtime·sigtramp;
+       USED(p);
 }
 
 uint32
index 213582799b13604fc36a08cadfce9a9d603bbd89..e2ae8db277c55b0a72e57e49c64ee4f21cc808cf 100644 (file)
@@ -24,63 +24,45 @@ runtime·dumpregs(Context *r)
        runtime·printf("gs      %x\n", r->SegGs);
 }
 
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (-1)
+// or should be made available to other handlers in the chain (0).
+uint32
+runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
 {
+       bool crash;
+       uintptr *sp;
        extern byte runtime·text[], runtime·etext[];
 
        // Only handle exception if executing instructions in Go binary
        // (not Windows library code). 
        if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip)
-               return false;
-
-       if(!runtime·issigpanic(info->ExceptionCode))
-               return false;
-
-       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).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
-       uintptr *sp;
-
-       if(!runtime·isgoexception(info, r))
-               return EXCEPTION_CONTINUE_SEARCH;
-
-       // Make it look like a call to the signal func.
-       // Have to pass arguments out of band since
-       // augmenting the stack frame would break
-       // the unwinding code.
-       gp->sig = info->ExceptionCode;
-       gp->sigcode0 = info->ExceptionInformation[0];
-       gp->sigcode1 = info->ExceptionInformation[1];
-       gp->sigpc = r->Eip;
-
-       // Only push runtime·sigpanic if r->eip != 0.
-       // If r->eip == 0, probably panicked because of a
-       // call to a nil func.  Not pushing that onto sp will
-       // make the trace look like a call to runtime·sigpanic instead.
-       // (Otherwise the trace will end at runtime·sigpanic and we
-       // won't get to see who faulted.)
-       if(r->Eip != 0) {
-               sp = (uintptr*)r->Esp;
-               *--sp = r->Eip;
-               r->Esp = (uintptr)sp;
+               return 0;
+
+       if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
+               // Make it look like a call to the signal func.
+               // Have to pass arguments out of band since
+               // augmenting the stack frame would break
+               // the unwinding code.
+               gp->sig = info->ExceptionCode;
+               gp->sigcode0 = info->ExceptionInformation[0];
+               gp->sigcode1 = info->ExceptionInformation[1];
+               gp->sigpc = r->Eip;
+
+               // Only push runtime·sigpanic if r->eip != 0.
+               // If r->eip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to runtime·sigpanic instead.
+               // (Otherwise the trace will end at runtime·sigpanic and we
+               // won't get to see who faulted.)
+               if(r->Eip != 0) {
+                       sp = (uintptr*)r->Esp;
+                       *--sp = r->Eip;
+                       r->Esp = (uintptr)sp;
+               }
+               r->Eip = (uintptr)runtime·sigpanic;
+               return -1;
        }
-       r->Eip = (uintptr)runtime·sigpanic;
-       return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-       bool crash;
 
        if(runtime·panicking)  // traceback already printed
                runtime·exit(2);
@@ -106,7 +88,7 @@ runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
                runtime·crash();
 
        runtime·exit(2);
-       return 0; // not reached
+       return -1; // not reached
 }
 
 void
index b96cf70d1ec0726ee4930e87e2043c722d0a4bf7..261880d450115adfde677aceafda87b21be72472 100644 (file)
@@ -32,76 +32,45 @@ runtime·dumpregs(Context *r)
        runtime·printf("gs      %X\n", (uint64)r->SegGs);
 }
 
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (-1)
+// or should be made available to other handlers in the chain (0).
+uint32
+runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
 {
+       bool crash;
+       uintptr *sp;
        extern byte runtime·text[], runtime·etext[];
 
        // Only handle exception if executing instructions in Go binary
        // (not Windows library code). 
        if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip)
-               return false;
-
-       if(!runtime·issigpanic(info->ExceptionCode))
-               return false;
-
-       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).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
-       uintptr *sp;
-
-       if(!runtime·isgoexception(info, r))
-               return EXCEPTION_CONTINUE_SEARCH;
-
-       // Make it look like a call to the signal func.
-       // Have to pass arguments out of band since
-       // augmenting the stack frame would break
-       // the unwinding code.
-       gp->sig = info->ExceptionCode;
-       gp->sigcode0 = info->ExceptionInformation[0];
-       gp->sigcode1 = info->ExceptionInformation[1];
-       gp->sigpc = r->Rip;
-
-       // Only push runtime·sigpanic if r->rip != 0.
-       // If r->rip == 0, probably panicked because of a
-       // call to a nil func.  Not pushing that onto sp will
-       // make the trace look like a call to runtime·sigpanic instead.
-       // (Otherwise the trace will end at runtime·sigpanic and we
-       // won't get to see who faulted.)
-       if(r->Rip != 0) {
-               sp = (uintptr*)r->Rsp;
-               *--sp = r->Rip;
-               r->Rsp = (uintptr)sp;
+               return 0;
+
+       if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
+               // Make it look like a call to the signal func.
+               // Have to pass arguments out of band since
+               // augmenting the stack frame would break
+               // the unwinding code.
+               gp->sig = info->ExceptionCode;
+               gp->sigcode0 = info->ExceptionInformation[0];
+               gp->sigcode1 = info->ExceptionInformation[1];
+               gp->sigpc = r->Rip;
+
+               // Only push runtime·sigpanic if r->rip != 0.
+               // If r->rip == 0, probably panicked because of a
+               // call to a nil func.  Not pushing that onto sp will
+               // make the trace look like a call to runtime·sigpanic instead.
+               // (Otherwise the trace will end at runtime·sigpanic and we
+               // won't get to see who faulted.)
+               if(r->Rip != 0) {
+                       sp = (uintptr*)r->Rsp;
+                       *--sp = r->Rip;
+                       r->Rsp = (uintptr)sp;
+               }
+               r->Rip = (uintptr)runtime·sigpanic;
+               return -1;
        }
-       r->Rip = (uintptr)runtime·sigpanic;
-       return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// It seems Windows searches ContinueHandler's list even
-// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
-// firstcontinuehandler will stop that search,
-// if exceptionhandler did the same earlier.
-uint32
-runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-       USED(gp);
-       if(!runtime·isgoexception(info, r))
-               return EXCEPTION_CONTINUE_SEARCH;
-       return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
-       bool crash;
 
        if(runtime·panicking)  // traceback already printed
                runtime·exit(2);
@@ -128,7 +97,7 @@ runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
                runtime·crash();
 
        runtime·exit(2);
-       return 0; // not reached
+       return -1; // not reached
 }
 
 void
index 932fe9dd2450c0eee0082d2b109d63080af3965e..1bf4d062acdaffade513fdac55b4e2ff71cd14c0 100644 (file)
@@ -73,7 +73,6 @@ TEXT runtime·setlasterror(SB),NOSPLIT,$0
 // Called by Windows as a Vectored Exception Handler (VEH).
 // First argument is pointer to struct containing
 // exception record and context pointers.
-// Handler function is stored in AX.
 // Return 0 for 'not handled', -1 for handled.
 TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVL    ptrs+0(FP), CX
@@ -85,8 +84,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVL    SI, 20(SP)
        MOVL    DI, 24(SP)
 
-       MOVL    AX, SI  // save handler address
-
        // find g
        get_tls(DX)
        CMPL    DX, $0
@@ -126,10 +123,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
 sigtramp_g0:
        MOVL    0(CX), BX // ExceptionRecord*
        MOVL    4(CX), CX // Context*
+       // call sighandler(ExceptionRecord*, Context*, G*)
        MOVL    BX, 0(SP)
        MOVL    CX, 4(SP)
        MOVL    DX, 8(SP)
-       CALL    SI      // call handler
+       CALL    runtime·sighandler(SB)
        // AX is set to report result back to Windows
        MOVL    12(SP), AX
 
@@ -151,18 +149,6 @@ done:
        // RET 4 (return and pop 4 bytes parameters)
        BYTE $0xC2; WORD $4
        RET // unreached; make assembler happy
-TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
-       MOVL    $runtime·exceptionhandler(SB), AX
-       JMP     runtime·sigtramp(SB)
-
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
-       // is never called
-       INT     $3
-
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
-       MOVL    $runtime·lastcontinuehandler(SB), AX
-       JMP     runtime·sigtramp(SB)
 
 TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
        PUSHL   $runtime·ctrlhandler1(SB)
index e6190ce684d70e7b4a7bea86e09bc8194178568f..05750398eaed1a655e02f416ad3390017bec4bc5 100644 (file)
@@ -99,7 +99,6 @@ TEXT runtime·setlasterror(SB),NOSPLIT,$0
 // Called by Windows as a Vectored Exception Handler (VEH).
 // First argument is pointer to struct containing
 // exception record and context pointers.
-// Handler function is stored in AX.
 // Return 0 for 'not handled', -1 for handled.
 TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        // CX: PEXCEPTION_POINTERS ExceptionInfo
@@ -117,8 +116,6 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
        MOVQ    R14, 32(SP)
        MOVQ    R15, 88(SP)
 
-       MOVQ    AX, R15 // save handler address
-
        // find g
        get_tls(DX)
        CMPQ    DX, $0
@@ -160,10 +157,11 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
 sigtramp_g0:
        MOVQ    0(CX), BX // ExceptionRecord*
        MOVQ    8(CX), CX // Context*
+       // call sighandler(ExceptionRecord*, Context*, G*)
        MOVQ    BX, 0(SP)
        MOVQ    CX, 8(SP)
        MOVQ    DX, 16(SP)
-       CALL    R15     // call handler
+       CALL    runtime·sighandler(SB)
        // AX is set to report result back to Windows
        MOVL    24(SP), AX
 
@@ -189,18 +187,6 @@ done:
 
        RET
 
-TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
-       MOVQ    $runtime·exceptionhandler(SB), AX
-       JMP     runtime·sigtramp(SB)
-
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
-       MOVQ    $runtime·firstcontinuehandler(SB), AX
-       JMP     runtime·sigtramp(SB)
-
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
-       MOVQ    $runtime·lastcontinuehandler(SB), AX
-       JMP     runtime·sigtramp(SB)
-
 TEXT runtime·ctrlhandler(SB),NOSPLIT,$8
        MOVQ    CX, 16(SP)              // spill
        MOVQ    $runtime·ctrlhandler1(SB), CX
index ce8a9ec1ba9e974b9f270fa2f59c331b42df74ff..9ed016ccc8f7f9755e0f18ef86f15641f23f5c1e 100644 (file)
@@ -494,42 +494,3 @@ func TestOutputDebugString(t *testing.T) {
        p := syscall.StringToUTF16Ptr("testing OutputDebugString")
        d.Proc("OutputDebugStringW").Call(uintptr(unsafe.Pointer(p)))
 }
-
-func TestRaiseException(t *testing.T) {
-       o := executeTest(t, raiseExceptionSource, nil)
-       if strings.Contains(o, "RaiseException should not return") {
-               t.Fatalf("RaiseException did not crash program: %v", o)
-       }
-       if !strings.Contains(o, "Exception 0xbad") {
-               t.Fatalf("No stack trace: %v", o)
-       }
-}
-
-const raiseExceptionSource = `
-package main
-import "syscall"
-func main() {
-       const EXCEPTION_NONCONTINUABLE = 1
-       mod := syscall.MustLoadDLL("kernel32.dll")
-       proc := mod.MustFindProc("RaiseException")
-       proc.Call(0xbad, EXCEPTION_NONCONTINUABLE, 0, 0)
-       println("RaiseException should not return")
-}
-`
-
-func TestZeroDivisionException(t *testing.T) {
-       o := executeTest(t, zeroDivisionExceptionSource, nil)
-       if !strings.Contains(o, "panic: runtime error: integer divide by zero") {
-               t.Fatalf("No stack trace: %v", o)
-       }
-}
-
-const zeroDivisionExceptionSource = `
-package main
-func main() {
-       x := 1
-       y := 0
-       z := x / y
-       println(z)
-}
-`