[GHC] #15092: Optionally bounds-check primops

#15092: Optionally bounds-check primops -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 (CodeGen) | Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- It would be awfully nice if there were a way to optionally get bounds- checked versions of array primitives. The idea would be that if GHC is compiled with a bounds-checking option, then the code generator would use primops that verify indices are in bounds. Based on [https://mail.haskell.org/pipermail/haskell-cafe/2018-April/128992.html a question by Henning Thielemann], I suspect such a feature would get some use. The biggest challenge: `SomeException`, `Typeable`, `Show`, `String`, `CallStack`, etc., all live in an entirely different universe than the primops, so it's not exactly obvious how to get started. I don't know if it would be possible to inject references to such things into a lower level. Sounds hard, but maybe it's possible. An alternative, probably much simpler, approach would be to crash hard with an error message instead of trying to throw a proper exception. Ideally, the error message would include the name of the primop and (for modules compiled with profiling) some call stack info. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15092 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15092: Optionally bounds-check primops -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 (CodeGen) | Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Lemming): I think a hard crash is completely appropriate. Bound violations are programming errors thus there is no way to safely recover from them, anyway. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15092#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

I think a hard crash is completely appropriate. Bound violations are
#15092: Optionally bounds-check primops -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 (CodeGen) | Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by dfeuer): Replying to [comment:1 Lemming]: programming errors thus there is no way to safely recover from them, anyway. My concerns about the "hard crash" approach: the error messages may not be as informative as one might wish, it may be tough to get the error messages in some environments, and I don't know if there would be any challenges ensuring that other application threads get killed. But I do think it would be a lot better to have that as an option than to have nothing. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15092#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15092: Optionally bounds-check primops -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 (CodeGen) | Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by osa1): I also frequently need this when debugging memory corruptions (e.g. #15038).
The biggest challenge: SomeException, Typeable, Show, String, CallStack, etc.
I think a hard crash is completely appropriate. Bound violations are
Why is this a challenge? I don't see the relation between with these type classes and array operations. programming errors thus there is no way to safely recover from them, anyway. Agreed, but I think there's another approach: raising an exception. We already raise exceptions for runtime errors like non-exhaustive pattern mathing. We could do the same. We already have the type defined: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control- Exception.html#t:ArrayException For my use case, even just a "out of bounds access!" message would do it so I don't feel strongly either way. Note that currently GHC (in DWARF version) already prints the C stack trace on panic: {{{ Main: internal error: evacuate(static): strange closure type 16583 Stack trace: 0x4b4dfb set_initial_registers (rts/Libdw.c:288.0) 0x7f37ccfb3558 dwfl_thread_getframes (/usr/lib/x86_64 -linux-gnu/libdw-0.165.so) 0x7f37ccfb2faf (null) (/usr/lib/x86_64-linux- gnu/libdw-0.165.so) 0x7f37ccfb32d7 dwfl_getthreads (/usr/lib/x86_64-linux- gnu/libdw-0.165.so) 0x7f37ccfb38e0 dwfl_getthread_frames (/usr/lib/x86_64 -linux-gnu/libdw-0.165.so) 0x4b538d libdwGetBacktrace (rts/Libdw.c:259.0) 0x49ce1c rtsFatalInternalErrorFn (rts/RtsMessages.c:172.0) 0x49cfad barf (rts/RtsMessages.c:48.0) 0x4a162e evacuate (includes/rts/storage/Block.h:175.0) 0x4b765b scavenge_loop (rts/sm/Scav.c:1830.0) 0x4a0532 GarbageCollect (rts/sm/GC.c:1423.0) 0x49bb87 scheduleDoGC (rts/Schedule.c:1814.0) 0x49c8c4 scheduleWaitThread (rts/Schedule.c:558.0) 0x49d450 rts_evalLazyIO (rts/RtsAPI.c:531.0) 0x49d75b hs_main (rts/RtsMain.c:73.0) 0x40d6aa (null) (/home/omer/haskell/corrupted-memory- example/Main) 0x7f37ccbd7830 __libc_start_main (../csu/libc- start.c:325.0) 0x4042f9 _start (/home/omer/haskell/corrupted-memory- example/Main) (GHC version 8.4.2 for x86_64_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug [1] 3391 abort (core dumped) ./Main }}} So we get some information for free already.
My concerns about the "hard crash" approach: the error messages may not be as informative as one might wish
I'm curious what kind of error messages you'd like to get? I think the main problem is for "out of line" array operations like `copyArray#` we'll need one more variant of RTS, so longer GHC boot times, more code to distribute etc. Not sure how to avoid this. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15092#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC