runtime: do not crash in lastcontinuehandler when running as DLL

If Go DLL is used by external C program, and lastcontinuehandler
is reached, lastcontinuehandler will crash the process it is
running in.

But it should not be up to Go runtime to decide if process to be
crashed or not - it should be up to C runtime. This CL adjusts
lastcontinuehandler to not to crash when running as DLL.

Fixes #32648.

Change-Id: Ia455e69b8dde2a6f42f06b90e8af4aa322ca269a
GitHub-Last-Rev: dbdffcb432
GitHub-Pull-Request: golang/go#32574
Reviewed-on: https://go-review.googlesource.com/c/go/+/181839
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Simon Ferquel 2019-08-05 11:28:52 +00:00 committed by Alex Brainman
parent 1786ecd502
commit e5e5fb024a
4 changed files with 152 additions and 0 deletions

View file

@ -0,0 +1,61 @@
// +build windows
package runtime_test
import (
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestVectoredHandlerDontCrashOnLibrary(t *testing.T) {
if *flagQuick {
t.Skip("-quick")
}
if runtime.GOARCH != "amd64" {
t.Skip("this test can only run on windows/amd64")
}
testenv.MustHaveGoBuild(t)
testenv.MustHaveExecPath(t, "gcc")
testprog.Lock()
defer testprog.Unlock()
dir, err := ioutil.TempDir("", "go-build")
if err != nil {
t.Fatalf("failed to create temp directory: %v", err)
}
defer os.Remove(dir)
// build go dll
dll := filepath.Join(dir, "testwinlib.dll")
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlib/main.go")
out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
if err != nil {
t.Fatalf("failed to build go library: %s\n%s", err, out)
}
// build c program
exe := filepath.Join(dir, "test.exe")
cmd = exec.Command("gcc", "-L"+dir, "-I"+dir, "-ltestwinlib", "-o", exe, "testdata/testwinlib/main.c")
out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
if err != nil {
t.Fatalf("failed to build c exe: %s\n%s", err, out)
}
// run test program
cmd = exec.Command(exe)
out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
if err != nil {
t.Fatalf("failure while running executable: %s\n%s", err, out)
}
expectedOutput := "exceptionCount: 1\ncontinueCount: 1\n"
// cleaning output
cleanedOut := strings.ReplaceAll(string(out), "\r\n", "\n")
if cleanedOut != expectedOutput {
t.Errorf("expected output %q, got %q", expectedOutput, cleanedOut)
}
}