[GHC] #14825: Access violation on Windows is not propagated to the OS

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: Runtime | Version: 8.2.2 System | Keywords: | Operating System: Windows Architecture: x86_64 | Type of failure: Debugging (amd64) | information is incorrect Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- We're using Haskell in production environment. Some times we get exceptions, like this: "Access violation in generated code when reading 0000000000000000" and nothing more. This is extremely hard and time consuming to debug where this exception came from. There is no information about at which address was the exception thrown. The correct way on Windows is such exceptions to be propagated to the operating system. This way we will attach a debugger to the process and it'll get and visualize where the exception happened. Currently GHC runtime is catching the exception, skip its source information and present that uninformative message to the user. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * cc: Phyx- (added) Comment: I believe Phyx- was working on having proper Windows stack traces whenever access violations are reported. Is this correct, Phyx-? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: #13911 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by Phyx-): * status: new => closed * resolution: => duplicate * related: => #13911 Comment: Hi, I'm closing this as a dupe. Couple of things however:
The correct way on Windows is such exceptions to be propagated to the operating system.
No it's not. An application is perfectly fine handling it's own exceptions. That's why the OS makes a distinction between `Unhandled` and `Handled` exceptions.
This way we will attach a debugger to the process and it'll get and visualize where the exception happened.
This is also not accurate, first chance exceptions are always handled before all user exception handlers. GHC uses `VEH` handlers up to 8.4 and from then on `VCH`. The documentation clearly states `Vectored handlers are called in the order that they were added, after the debugger gets a first chance notification, but before the system begins unwinding the stack.` (see https://msdn.microsoft.com/en- us/library/windows/desktop/ms681420(v=vs.85).aspx) If a debugger is attached, it will *always* get the first chance to handle exceptions! If it wants to. For instance {{{ module Main where import Foreign main :: IO () main = do x <- peek nullPtr print (x :: Int) }}} compiling and attaching a debugger {{{ Tamar@Rage ~/ghc2> ghc noexception.hs -fforce-recomp [1 of 1] Compiling Main ( noexception.hs, noexception.o ) Linking noexception.exe ... Tamar@Rage ~/ghc2> gdb --ex r --args noexception.exe GNU gdb (GDB) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-msys". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/. Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/. For help, type "help". Type "apropos word" to search for commands related to "word"... Traceback (most recent call last): File "<string>", line 3, in <module> ImportError: No module named libstdcxx.v6.printers /etc/gdbinit:6: Error in sourced command file: Error while executing Python code. Reading symbols from noexception.exe...done. Starting program: /home/Tamar/ghc2/noexception.exe [New Thread 47004.0x7284] [New Thread 47004.0xb4ac] [New Thread 47004.0x5580] [New Thread 47004.0x9d40] [New Thread 47004.0x1b38] Thread 1 received signal SIGSEGV, Segmentation fault. 0x0000000000402879 in c6BK_info () (gdb) }}} as you can see the debugger clearly breaks. {{{ Tamar@Rage~/ghc2> ./noexception.exe Segmentation fault/access violation in generated code }}} without the debugger the exception handler runs.
Currently GHC runtime is catching the exception, skip its source information and present that uninformative message to the user.
The reason the error is uninformative is because the location of your segfault occurred in a location for which there is no source information. The Haskell compiler can only emit DWARF at best so debugging is just more difficult on Windows. When running in ghci GHC 8.4 and newer will attempt to reconstruct a stack. It will also allow you to opt out of exception handling all together. For older (and compatible with newer) GHCs you can reasonably easily opt- out using FFI: {{{ module Main where import Foreign foreign import ccall "__unregister_hs_exception_handler" disableExceptionHandler :: IO () main :: IO () main = do disableExceptionHandler x <- peek nullPtr print (x :: Int) }}} and you clearly get a second chance exception now {{{ Tamar@Rage ~/ghc2> ./noexception.exe fish: “./noexception.exe” terminated by signal SIGSEGV (Address boundary error) }}} This isn't supported, but it's an easy way to disable the handling on older compilers. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: #13911 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by varosi): Thank you first for the thorough answer!
The reason the error is uninformative is because the location of your segfault occurred in a location for which there is no source information.
Is it possible to give some stack trace in such situation instead just "Segmentation fault/access violation in generated code"? I mean even if exact throwing place is not known, but only partial stack trace information. Or you mean that in GHC 8.4 partial stack information will be possible? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: #13911 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Phyx-): Replying to [comment:3 varosi]:
Is it possible to give some stack trace in such situation instead just
"Segmentation fault/access violation in generated code"? I mean even if exact throwing place is not known, but only partial stack trace information. Or you mean that in GHC 8.4 partial stack information will be possible? yup, GHC 8.4 will give an attempt, see https://phabricator.haskell.org/D3913 If you're running the code in GHCi I have information from the runtime's symbol table to help out, but when running compiled I don't have this. Eventually (when I get some time) I want to add the ability to use STABS information if available. That should help a bit. Also the stack tracer in GHC 8.4 cannot unwind between Haskell and C stacks. Since I don't know where I am when the segfault occurs I don't know which way to unwind (should be possible though). So for now I assume it's C code. GHC 8.4 also supports creating crash dumps https://phabricator.haskell.org/D3912 So you can just attach a debugger later and inspect the dump manually. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: #13911 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Phyx-): That said, the exception handler in pre `8.4` is a bit *too* aggressive in that it catches things it shouldn't. like C++ exceptions. That's also fixed in `8.6`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14825: Access violation on Windows is not propagated to the OS -------------------------------------+------------------------------------- Reporter: varosi | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: Runtime System | Version: 8.2.2 Resolution: duplicate | Keywords: Operating System: Windows | Architecture: x86_64 Type of failure: Debugging | (amd64) information is incorrect | Test Case: Blocked By: | Blocking: Related Tickets: #13911 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by varosi): Great work! Thanks! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14825#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC