]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: do not display Windows Error Reporting dialogue
authorAlex Brainman <alex.brainman@gmail.com>
Wed, 31 Dec 2014 02:46:58 +0000 (13:46 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 6 Jan 2015 05:31:40 +0000 (05:31 +0000)
Fixes #9121

Change-Id: Id6ca9f259260310c4c6cbdabbc8f2fead8414e6a
Reviewed-on: https://go-review.googlesource.com/2202
Reviewed-by: Minux Ma <minux@golang.org>
src/runtime/export_windows_test.go [new file with mode: 0644]
src/runtime/os1_windows.go
src/runtime/os1_windows_386.go
src/runtime/os1_windows_amd64.go
src/runtime/syscall_windows_test.go

diff --git a/src/runtime/export_windows_test.go b/src/runtime/export_windows_test.go
new file mode 100644 (file)
index 0000000..61fcef9
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Export guts for testing.
+
+package runtime
+
+var TestingWER = &testingWER
index 9b7605163473f073b9f132e211c4f3f4298a7b41..7f860a37e1ab476afe5b0aa335f053444498d4af 100644 (file)
@@ -29,6 +29,7 @@ import (
 //go:cgo_import_dynamic runtime._NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
 //go:cgo_import_dynamic runtime._ResumeThread ResumeThread "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetEvent SetEvent "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority "kernel32.dll"
@@ -62,6 +63,7 @@ var (
        _NtWaitForSingleObject,
        _ResumeThread,
        _SetConsoleCtrlHandler,
+       _SetErrorMode,
        _SetEvent,
        _SetProcessPriorityBoost,
        _SetThreadPriority,
@@ -103,6 +105,13 @@ const (
        currentThread  = ^uintptr(1) // -2 = current thread
 )
 
+const (
+       SEM_FAILCRITICALERRORS     = 0x0001
+       SEM_NOGPFAULTERRORBOX      = 0x0002
+       SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
+       SEM_NOOPENFILEERRORBOX     = 0x8000
+)
+
 var (
        kernel32Name                    = []byte("kernel32.dll\x00")
        addVectoredContinueHandlerName  = []byte("AddVectoredContinueHandler\x00")
@@ -114,6 +123,10 @@ func osinit() {
 
        kernel32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32Name[0])))
 
+       // don't display the crash dialog
+       errormode := uint32(stdcall1(_SetErrorMode, SEM_NOGPFAULTERRORBOX))
+       stdcall1(_SetErrorMode, uintptr(errormode)|SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX)
+
        externalthreadhandlerp = funcPC(externalthreadhandler)
 
        stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
index 0afef91566590dd1a1daabc87a189f66bb88ff7c..7b4fdfe94a70003d776f65683960ebc4fef23d52 100644 (file)
@@ -73,9 +73,15 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
        return _EXCEPTION_CONTINUE_EXECUTION
 }
 
+var testingWER bool
+
 // lastcontinuehandler is reached, because runtime cannot handle
 // current exception. lastcontinuehandler will print crash info and exit.
-func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+       if testingWER {
+               return _EXCEPTION_CONTINUE_SEARCH
+       }
+
        _g_ := getg()
 
        if panicking != 0 { // traceback already printed
index 0d21b388128780f082e7374278fc10ff0c6d3154..c211f6fd919e92b496c859efa287e41d82ba6b81 100644 (file)
@@ -92,9 +92,15 @@ func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        return _EXCEPTION_CONTINUE_EXECUTION
 }
 
+var testingWER bool
+
 // lastcontinuehandler is reached, because runtime cannot handle
 // current exception. lastcontinuehandler will print crash info and exit.
 func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+       if testingWER {
+               return _EXCEPTION_CONTINUE_SEARCH
+       }
+
        _g_ := getg()
 
        if panicking != 0 { // traceback already printed
index c372d2434dbf7eb3114377a598949b3f06954b4a..c40641a0dd9d3abd54ea90817e373bb63470861c 100644 (file)
@@ -533,3 +533,21 @@ func main() {
        println(z)
 }
 `
+
+func TestWERDialogue(t *testing.T) {
+       if os.Getenv("TESTING_WER_DIALOGUE") == "1" {
+               defer os.Exit(0)
+
+               *runtime.TestingWER = true
+               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")
+               return
+       }
+       cmd := exec.Command(os.Args[0], "-test.run=TestWERDialogue")
+       cmd.Env = []string{"TESTING_WER_DIALOGUE=1"}
+       // Child process should not open WER dialogue, but return immediately instead.
+       cmd.CombinedOutput()
+}