Improve access violation reporting on Windows
authorRyan Scott <ryan.gl.scott@gmail.com>
Sun, 15 Jan 2017 16:54:41 +0000 (11:54 -0500)
committerRyan Scott <ryan.gl.scott@gmail.com>
Sun, 15 Jan 2017 16:54:41 +0000 (11:54 -0500)
Summary:
This patch is courtesy of @awson.

Currently, whenever GHC catches a segfault on Windows, it simply reports the
somewhat uninformative message
`Segmentation fault/access violation in generated code`. This patch adds to
the message the type of violation (read/write/dep) and location information,
which should help debugging segfaults in the future.

Fixes #13108.

Test Plan: Build on Windows

Reviewers: austin, erikd, bgamari, simonmar, Phyx

Reviewed By: bgamari, Phyx

Subscribers: awson, thomie, #ghc_windows_task_force

Differential Revision: https://phabricator.haskell.org/D2969

GHC Trac Issues: #13108

rts/win32/veh_excn.c
testsuite/tests/rts/all.T
testsuite/tests/rts/derefnull.stdout-i386-unknown-mingw32
testsuite/tests/rts/derefnull.stdout-x86_64-unknown-mingw32

index bf2151a..c94dc5a 100644 (file)
@@ -32,6 +32,7 @@ PVOID __hs_handle = NULL;
 long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data)
 {
     long action = EXCEPTION_CONTINUE_SEARCH;
+    ULONG_PTR what;
 
     // When the system unwinds the VEH stack after having handled an excn,
     // return immediately.
@@ -49,7 +50,12 @@ long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data)
                 action = EXCEPTION_CONTINUE_EXECUTION;
                 break;
             case EXCEPTION_ACCESS_VIOLATION:
-                fprintf(stdout, "Segmentation fault/access violation in generated code\n");
+                what = exception_data->ExceptionRecord->ExceptionInformation[0];
+                fprintf(stdout, "Access violation in generated code"
+                                " when %s %p\n"
+                                , what == 0 ? "reading" : what == 1 ? "writing" : what == 8 ? "executing data at" : "?"
+                                , (void*) exception_data->ExceptionRecord->ExceptionInformation[1]
+                                );
                 action = EXCEPTION_CONTINUE_EXECUTION;
                 break;
             default:;
index cf8e904..14f0cec 100644 (file)
@@ -13,6 +13,12 @@ test('testmblockalloc',
 # See bug #101, test requires +RTS -c (or equivalently +RTS -M<something>)
 # only GHCi triggers the bug, but we run the test all ways for completeness.
 test('bug1010', normal, compile_and_run, ['+RTS -c -RTS'])
+
+def normalise_address(str):
+    return re.sub('Access violation in generated code when reading [0]+',
+                  'Access violation in generated code when reading ADDRESS',
+                  str)
+
 test('derefnull',
      [# LLVM Optimiser considers dereference of a null pointer
       # undefined and marks the code as unreachable which means
@@ -29,7 +35,7 @@ test('derefnull',
       when(platform('i386-apple-darwin'), [ignore_stderr, exit_code(139)]),
       when(platform('x86_64-apple-darwin'), [ignore_stderr, exit_code(139)]),
       when(platform('powerpc-apple-darwin'), [ignore_stderr, exit_code(139)]),
-      when(opsys('mingw32'), exit_code(1)),
+      when(opsys('mingw32'), [exit_code(1), normalise_fun(normalise_address)]),
       # since these test are supposed to crash the
       # profile report will be empty always.
       # so disable the check for profiling
@@ -180,7 +186,7 @@ def checkDynAsm(actual_file, normaliser):
 # to somehow extract out the name of DLLs to do that
 
 test('T5435_v_asm', when(arch('powerpc64') or arch('powerpc64le'),
-     expect_broken(11259)), 
+     expect_broken(11259)),
      run_command, ['$MAKE -s --no-print-directory T5435_v_asm'])
 test('T5435_v_gcc', when(arch('powerpc64') or arch('powerpc64le'),
      expect_broken(11259)),
@@ -371,7 +377,7 @@ test('T10296b', [only_ways('threaded2')], compile_and_run, [''])
 
 test('numa001', [ extra_run_opts('8'), extra_ways(['debug_numa']) ]
                 , compile_and_run, [''])
-                
+
 test('T12497', [ unless(opsys('mingw32'), skip)
                ],
                run_command, ['$MAKE -s --no-print-directory T12497'])
index 5f2034d..4541b7f 100644 (file)
@@ -1 +1 @@
-Segmentation fault/access violation in generated code
+Access violation in generated code when reading ADDRESS
index 5f2034d..4541b7f 100644 (file)
@@ -1 +1 @@
-Segmentation fault/access violation in generated code
+Access violation in generated code when reading ADDRESS