Assuming you already know what ghc-debug
is about, and want to use it to debug the ghc
program itself.
A recent ghc-debug
checkout is required, since it contains important fixes not release on Hackage yet.
Apply the following patch:
diff --git a/stub/cbits/stub.cpp b/stub/cbits/stub.cpp
index c11fa94..62f7779 100644
--- a/stub/cbits/stub.cpp
+++ b/stub/cbits/stub.cpp
@@ -21,9 +21,9 @@
#include <stdarg.h>
#include <stdio.h>
-#if !defined(THREADED_RTS)
-#error You must use a patched version of cabal-install which includes - https://github.com/haskell/cabal/pull/7183
-#endif
+#include "ghcversion.h"
+
+#define THREADED_RTS
#if !defined(TABLES_NEXT_TO_CODE)
#error TABLES_NEXT_TO_CODE not defined
Apply the following patch:
diff --git a/ghc/Main.hs b/ghc/Main.hs
index 730a614839b..f3a62353c10 100644
--- a/ghc/Main.hs
+++ b/ghc/Main.hs
@@ -101,6 +101,8 @@ import Data.Bifunctor
import GHC.Data.Graph.Directed
import qualified Data.List.NonEmpty as NE
+import GHC.Debug.Stub
+
-----------------------------------------------------------------------------
-- ToDo:
@@ -114,7 +116,7 @@ import qualified Data.List.NonEmpty as NE
-- GHC's command-line interface
main :: IO ()
-main = do
+main = withGhcDebug $ do
hSetBuffering stdout LineBuffering
hSetBuffering stderr LineBuffering
diff --git a/ghc/ghc-bin.cabal.in b/ghc/ghc-bin.cabal.in
index bd49fd0e6f8..611cdde777d 100644
--- a/ghc/ghc-bin.cabal.in
+++ b/ghc/ghc-bin.cabal.in
@@ -39,6 +39,7 @@ Executable ghc
filepath >= 1 && < 1.5,
containers >= 0.5 && < 0.7,
transformers >= 0.5 && < 0.7,
+ ghc-debug-stub,
ghc-boot == @ProjectVersionMunged@,
ghc == @ProjectVersionMunged@
diff --git a/hadrian/src/Packages.hs b/hadrian/src/Packages.hs
index 37b793626c3..740741c6bd2 100644
--- a/hadrian/src/Packages.hs
+++ b/hadrian/src/Packages.hs
@@ -11,6 +11,7 @@ module Packages (
libffi, mtl, parsec, pretty, primitive, process, remoteIserv, rts,
runGhc, semaphoreCompat, stm, templateHaskell, terminfo, text, time, timeout, touchy,
transformers, unlit, unix, win32, xhtml,
+ ghcDebugConvention, ghcDebugStub,
lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace,
ghcPackages, isGhcPackage,
@@ -43,6 +44,7 @@ ghcPackages =
, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl
, parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell
, terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml
+ , ghcDebugConvention, ghcDebugStub
, timeout
, lintersCommon
, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace ]
@@ -60,6 +62,7 @@ array, base, binary, bytestring, cabalSyntax, cabal, checkPpr, checkExact, count
hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy, remoteIserv, libffi, mtl,
parsec, pretty, primitive, process, rts, runGhc, semaphoreCompat, stm, templateHaskell,
terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml,
+ ghcDebugConvention, ghcDebugStub,
timeout,
lintersCommon, lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace
:: Package
@@ -133,6 +136,9 @@ unix = lib "unix"
win32 = lib "Win32"
xhtml = lib "xhtml"
+ghcDebugConvention = lib "ghc-debug-convention"
+ghcDebugStub = lib "ghc-debug-stub"
+
lintersCommon = lib "linters-common" `setPath` "linters/linters-common"
lintNotes = linter "lint-notes"
lintCodes = linter "lint-codes"
diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs
index 11f69dd0c49..01d81abe2b9 100644
--- a/hadrian/src/Settings/Default.hs
+++ b/hadrian/src/Settings/Default.hs
@@ -113,6 +113,7 @@ stage0Packages = do
, hp2ps
, if windowsHost then win32 else unix
]
+ ++ [ ghcDebugConvention, ghcDebugStub ]
++ [ terminfo | not windowsHost, not cross ]
++ [ timeout | windowsHost ]
++ [ touchy | windowsHost ]
Suppose the ghc-debug
checkout is at /workspace/ghc-debug
, ghc
checkout is at /workspace/ghc
, copy the ghc-debug-convention
and ghc-debug-stub
packages to the ghc
tree: cp -r /workspace/ghc-debug/conv /workspace/ghc/libraries/ghc-debug-convention && cp -r /workspace/ghc-debug/stub /workspace/ghc/libraries/ghc-debug-stub
Run boot
, configure
and normal hadrian build process. The resulting in-tree _build/stage1/bin/ghc
and _build/stage1/bin/ghc-pkg
can be used to build cabal projects, put these in your cabal.project.local
file:
with-compiler: /workspace/ghc/_build/stage1/bin/ghc
with-hc-pkg: /workspace/ghc/_build/stage1/bin/ghc-pkg
-- the rest of https://gitlab.haskell.org/ghc/head.hackage#how-to-use follows
For instance, they can be used to build ghc-debug-brick
in the ghc-debug
tree, which can be used to check a ghc --interactive
session, pause the process and explore the default gc roots to see if ghc-debug
instrumentation works at all.
Some caveats to keep in mind:
- The
ghc
patch does not take cross compilation into account - You can use
GHC.Settings.Config.cStage == "2"
to only enablewithGhcDebug
for_build/stage1/bin/ghc
, instead of_build/stage0/bin/ghc
which builds it. This speeds up compilation quite a bit withGhcDebug
prints the debug socket address tostderr
, so you can’t run the ghc testsuite with instrumentedghc
since there will bestderr
content mismatches, unless you only enable it conditionally (e.g. via an environment variable)ghc-debug
already supports cost center profiling, but I have not verified yet whether it actually works withghc
built withprofiled_ghc
or if more hacks are needed