[GHC] #13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: | Version: 8.1 libraries/base | 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: -------------------------------------+------------------------------------- In #12096 it is requested that we add CallStack to SomeException. This is a more conservative request for adding CallStack to IOError only. IOError is already an abstract data type, so it is a simple matter to augment it with space for a CallStack. The main design flex point is whether or not a `CallStack` should be associated with an IOError when it is constructed, or when it is thrown. There are pros and cons to both: 1. If it is associated at construction time, the call stack will reflect when the IOError was constructed, not when it was thrown. This could be arbitrarily far away from the actual throw site. I've been mostly using CallStack for monadic code, and so my primary concern is with where in the monadic code the exception was thrown, so this info isn't really what I want. 2. If it is associated at throw time, there are a few other problems. First, if someone uses throwIO rather than ioError, we won't actually associate a CallStack with the value. Second, if a user is rethrowing an exception, they may accidentally overwrite the old stack trace; but it was the original one that I wanted. For now, I suggest going with (1). Here is the proposal: * Add `ioeGetCallStack` and `ioeSetCallStack`, for setting and getting the `CallStack` recorded in `IOError` * `userError` and `mkIOError` gain a `HasCallStack` constraint. We have a choice for `annotateIOError`, but my suggestion is to NOT annotate it. * Let's annotate all functions that (transitively) may raise an IOError in base with `HasCallStack`. The primary benefit is now if I have a "file not found" exception or similar, I automatically get a stack trace saying exactly what code was run where the file was not found. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 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 mnislaih): Both choices are viable, I think Java does (1), whereas C# goes with (2) but keeps a list of call stacks to avoid losing the original stack on rethrow. If we later wanted to add a call stack to SomeException, would (2) become the more natural choice ? If so, would it be worth adapting the proposal to add the call stack to SomeException now, but only surface it in IOError ? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 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 ezyang): I've mentioned on the other ticket that I don't think adding call stacks to the SomeException type is wise (since you lose the callstacks when you unwrap SomeException and work with `Exception e => e`). So, if the best you can do is add call stack manipulating functions to the Exception type class, (2) can be made to work, since the Exception generic functions can use the methods in the type class to attach a call stack. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 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 mnislaih): I think there might be a way to add call stacks at the top level, see my reply in the other ticket. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 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: | -------------------------------------+------------------------------------- Changes (by erikd): * cc: erikd (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #12096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * related: => #12096 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13372: Attach CallStack to IOError, add CallStack constraints to relevant functions in base -------------------------------------+------------------------------------- Reporter: ezyang | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #12096 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by saurabhnanda): Commenting to be notified of future discussion. (is there a better way to do this?) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13372#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC