]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: fix abort handling on Windows
authorAustin Clements <austin@google.com>
Fri, 6 Jul 2018 13:50:05 +0000 (09:50 -0400)
committerAustin Clements <austin@google.com>
Sat, 7 Jul 2018 14:44:07 +0000 (14:44 +0000)
On Windows, the IP recorded in the breakpoint exception caused by
runtime.abort is actually one byte after the INT3, unlike on UNIX
OSes. Account for this in isgoexception.

It turns out TestAbort was "passing" on Windows anyway because abort
still caused a fatal panic, just not the one we were expecting. This
CL tightens this test to check that the runtime specifically reports a
breakpoint exception.

Fixing this is related to #21382, since we use runtime.abort in
reporting g0 stack overflows, and it's important that we detect this
and not try to handle it.

Change-Id: I66120944d138eb80f839346b157a3759c1019e34
Reviewed-on: https://go-review.googlesource.com/122515
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
src/runtime/crash_test.go
src/runtime/signal_windows.go

index 9f11aea4e9f5fc12b6860cfe216898e4c2d8dd24..b266d7b77ef71cf5e74417d17d5fbddbe99ebc00 100644 (file)
@@ -640,18 +640,21 @@ func TestTimePprof(t *testing.T) {
 
 // Test that runtime.abort does so.
 func TestAbort(t *testing.T) {
-       output := runTestProg(t, "testprog", "Abort")
+       // Pass GOTRACEBACK to ensure we get runtime frames.
+       output := runTestProg(t, "testprog", "Abort", "GOTRACEBACK=system")
        if want := "runtime.abort"; !strings.Contains(output, want) {
                t.Errorf("output does not contain %q:\n%s", want, output)
        }
        if strings.Contains(output, "BAD") {
                t.Errorf("output contains BAD:\n%s", output)
        }
-       // Check that it's a signal-style traceback.
-       if runtime.GOOS != "windows" {
-               if want := "PC="; !strings.Contains(output, want) {
-                       t.Errorf("output does not contain %q:\n%s", want, output)
-               }
+       // Check that it's a breakpoint traceback.
+       want := "SIGTRAP"
+       if runtime.GOOS == "windows" {
+               want = "Exception 0x80000003"
+       }
+       if !strings.Contains(output, want) {
+               t.Errorf("output does not contain %q:\n%s", want, output)
        }
 }
 
index 500b02880d47474077117d9289cc12c61dc7480b..fe5ff87cd67491a2425e4c3a283f8a9d5993f8f9 100644 (file)
@@ -46,7 +46,9 @@ func isgoexception(info *exceptionrecord, r *context) bool {
                return false
        }
 
-       if isAbortPC(r.ip()) {
+       // In the case of an abort, the exception IP is one byte after
+       // the INT3 (this differs from UNIX OSes).
+       if isAbortPC(r.ip() - 1) {
                // Never turn abort into a panic.
                return false
        }