diff --git a/doc/DEVFAQ.md b/doc/DEVFAQ.md index d0e158609..5043345b2 100644 --- a/doc/DEVFAQ.md +++ b/doc/DEVFAQ.md @@ -55,18 +55,25 @@ $ cabal install all:exes ### How do I build/run with ghc-debug support ? ```cli -$ stack build --flag hledger:ghcdebug --flag hledger-ui:ghcdebug --flag hledger-web:ghcdebug +$ stack build --flag hledger-lib:ghcdebug --flag hledger:ghcdebug --flag hledger-ui:ghcdebug --flag hledger-web:ghcdebug ``` -You can check it in the --version output, which should mention "ghc-debug": +Use --flag to enable `ghcdebug` for hledger-lib and any of the executables you want to build, as above. +You might need to stop background builders like HLS while you do this, to avoid a fight over the build flag +(in VS Code, do Haskell: Stop Haskell LSP Server). + +Your --version output should now say "supports ghc-debug": ``` $ stack exec -- hledger --version ``` -With such a build, you can enable the ghc-debug listener by running hledger with a negative --debug level. Eg: + +When a hledger executable supports ghc-debug, you can enable the ghc-debug listener by running with a negative --debug level. Eg: ```cli -$ hledger ... --debug=-1 # run normally, while also listening for ghc-debug commands -$ hledger ... --debug=-2 # pause for ghc-debug commands at program start -$ hledger ... --debug=-3 # pause for ghc-debug commands at program end +$ hledger CMD --debug=-1 # run normally, while also listening for ghc-debug commands +$ hledger CMD --debug=-2 # pause for ghc-debug commands at program start +$ hledger CMD --debug=-3 # pause for ghc-debug commands at program end ``` -Then you can pause/resume hledger's execution and inspect memory and profile information -with the interactive `ghc-debug-brick` client, -or extract specific information with a custom ghc-debug script. +You should see "Starting ghc-debug on socket: ..." output. + +Then in another window, run the interactive `ghc-debug-brick` client, select the running hledger process, +and explore memory/profile information, resume/pause execution, etc. +Or you can write a custom ghc-debug-client script to extract specific information. diff --git a/hledger-lib/Hledger/Utils/Debug.hs b/hledger-lib/Hledger/Utils/Debug.hs index 59f380a26..5e60165bd 100644 --- a/hledger-lib/Hledger/Utils/Debug.hs +++ b/hledger-lib/Hledger/Utils/Debug.hs @@ -163,6 +163,7 @@ module Hledger.Utils.Debug ( ,dbg9With -- * Utilities + ,ghcDebugSupportedInLib ,GhcDebugMode(..) ,ghcDebugMode ,withGhcDebug' @@ -238,20 +239,28 @@ data GhcDebugMode = | GDPauseAtStart | GDPauseAtEnd -- keep synced with ghcDebugMode - deriving (Eq,Ord) + deriving (Eq,Ord,Show) + +-- | Is the hledger-lib package built with ghc-debug support ? +ghcDebugSupportedInLib :: Bool +ghcDebugSupportedInLib = +#ifdef GHCDEBUG + True +#else + False +#endif -- | Should the program open a socket allowing control by ghc-debug-brick or similar ghc-debug client ? -- See GhcDebugMode. ghcDebugMode :: GhcDebugMode ghcDebugMode = case debugLevel of - -- keep synced with GhcDebugMode -#ifdef GHCDEBUG + _ | not ghcDebugSupportedInLib -> GDNotSupported (-1) -> GDNoPause (-2) -> GDPauseAtStart (-3) -> GDPauseAtEnd -#endif _ -> GDDisabled + -- keep synced with GhcDebugMode -- | When ghc-debug support has been built into the program and enabled at runtime with --debug=-N, -- this calls ghc-debug's withGhcDebug; otherwise it's a no-op. diff --git a/hledger-lib/package.yaml b/hledger-lib/package.yaml index 558cf0010..76d555f14 100644 --- a/hledger-lib/package.yaml +++ b/hledger-lib/package.yaml @@ -85,11 +85,6 @@ dependencies: - extra >=1.6.3 - Glob >= 0.9 -when: -- condition: (!(os(windows))) - dependencies: - - pager >=0.1.1.0 - ghc-options: - -Wall - -Wno-incomplete-uni-patterns @@ -98,6 +93,21 @@ ghc-options: - -Wno-type-defaults - -Wno-unused-do-bind +flags: + ghcdebug: + description: Build with support for attaching a ghc-debug client + default: false + manual: true + +when: +- condition: (!(os(windows))) + dependencies: + - pager >=0.1.1.0 +- condition: (flag(ghcdebug)) + cpp-options: -DGHCDEBUG + dependencies: + - ghc-debug-stub >=0.6.0.0 && <0.7 + source-dirs: #- other/ledger-parse - . diff --git a/hledger/Hledger/Cli/Version.hs b/hledger/Hledger/Cli/Version.hs index 8e0ef190d..363b64a06 100644 --- a/hledger/Hledger/Cli/Version.hs +++ b/hledger/Hledger/Cli/Version.hs @@ -18,7 +18,7 @@ import System.Info (os, arch) import Data.List (intercalate) import Data.Maybe (fromMaybe) -import Hledger.Utils (splitAtElement) +import Hledger.Utils (ghcDebugSupportedInLib, splitAtElement) type ProgramName = String type PackageVersion = String @@ -38,9 +38,9 @@ packageversion = packagemajorversion :: PackageVersion packagemajorversion = intercalate "." $ take 2 $ splitAtElement '.' packageversion --- | Given possible git state info from the build directory (or an error message, which is ignored), --- the name of a program (executable) in the currently building package, --- and the package's version, make a complete version string. Here is the logic: +-- | Given possible git state info from the build directory (or a git error, which is ignored), +-- and the ghcdebug build flag, executable name and package version for the package being built, +-- make the best version string we can. Here is the logic: -- -- * Program name, OS and architecture are always shown. -- * The package version is always shown. @@ -50,7 +50,8 @@ packagemajorversion = intercalate "." $ take 2 $ splitAtElement '.' packageversi -- * (TODO, requires adding --match support to githash: -- If there are tags matching THISPKG-[0-9]*, the latest one is used to calculate patch level -- (number of commits since tag), and if non-zero, it and the branch name are shown.) --- * If the ghcdebug build flag was enabled, "ghc-debug support" is shown. +-- * If the ghcdebug build flag was enabled for the package being built, and for hledger-lib (both are needed), +-- "ghc-debug support" is shown. -- -- Some example outputs: -- @@ -70,10 +71,10 @@ packagemajorversion = intercalate "." $ take 2 $ splitAtElement '.' packageversi -- so output should be suitable for all of those. -- versionStringWith :: Either String GitInfo -> Bool -> ProgramName -> PackageVersion -> VersionString -versionStringWith egitinfo ghcdebug progname packagever = +versionStringWith egitinfo ghcDebugSupportedInThisPackage progname packagever = concat $ [ progname , " " , version , ", " , os' , "-" , arch ] - ++ [ " with ghc-debug support" | ghcdebug ] + ++ [ " with ghc-debug support" | ghcDebugSupportedInThisPackage && ghcDebugSupportedInLib ] where os' | os == "darwin" = "mac" | os == "mingw32" = "windows"