如何在Haskell中打印调用栈?求助解决实现失败问题
Fixing Call Stack Printing in Haskell-Language-Server
Let’s walk through why your current approach isn’t working and how to fix it:
Why Your Current Methods Aren’t Producing Output
traceStack: This function only appends a stack trace when an exception is thrown. SinceputStrLndoesn’t throw an error, nothing gets logged here.emptyCallStack: As the name suggests, this is an empty stack—callinggetCallStackon it will always return an empty list.currentCallStack: Without proper function annotations or compiler flags, this might return an incomplete or empty stack because GHC isn’t tracking the necessary stack info.
Required Compiler & Runtime Setup
First, update your .cabal file’s ghc-options for the executable to include these flags (in addition to -fprof-auto):
ghc-options: -fprof-auto -rtsopts -fprof-cafs
-rtsopts: Lets you pass runtime system (RTS) options when running the program.-fprof-cafs: Enables profiling of constant applicative forms, which helps capture more complete stack traces.
When running HLS, use this command to ensure profiling is active and stack traces are enabled:
cabal run haskell-language-server-wrapper --enable-profiling --enable-executable-dynamic +RTS -xc
+RTS -xc: Forces GHC to print a stack trace whenever an exception is thrown—great for debugging crashes.
Corrected Code to Print Call Stacks
Modify your defaultMain function to use GHC’s proper call stack utilities. You’ll need to import GHC.Stack and add a HasCallStack constraint:
import GHC.Stack (HasCallStack, callStack, getCallStack, currentCallStack, traceStack) defaultMain :: HasCallStack => Recorder (WithPriority Log) -> Arguments -> IdePlugins IdeState -> IO () defaultMain recorder args idePlugins = do -- Print stack using the HasCallStack annotation putStrLn "=== Call stack from HasCallStack ===" mapM_ print $ getCallStack callStack -- Print current stack via IO putStrLn "\n=== Current runtime call stack ===" stack <- currentCallStack mapM_ putStrLn stack -- Trigger a stack trace with traceStack (requires an exception) putStrLn "\n=== Exception stack trace ===" _ <- traceStack "Error context" $ error "Intentional error to show stack trace" exitFailure
Key Fixes:
HasCallStackconstraint: This tells GHC to track the call stack up todefaultMain, making thecallStackvariable available.getCallStack callStack: Uses the actual stack from the current context instead of an empty one.- Exception with
traceStack: By throwing an error, you triggertraceStackto log the stack trace.
Extra Tips
- If stacks are still incomplete, make sure all dependencies are built with profiling. Run this to rebuild everything with profiling flags:
cabal build --enable-profiling --enable-executable-dynamic --ghc-options="-fprof-auto" - Remember to remove profiling flags for production builds, as they add overhead.
内容的提问来源于stack exchange,提问作者zichao liu
相关产品推荐
相关产品推荐

