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 definedApply 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
ghcpatch does not take cross compilation into account - You can use
GHC.Settings.Config.cStage == "2"to only enablewithGhcDebugfor_build/stage1/bin/ghc, instead of_build/stage0/bin/ghcwhich builds it. This speeds up compilation quite a bit withGhcDebugprints the debug socket address tostderr, so you can’t run the ghc testsuite with instrumentedghcsince there will bestderrcontent mismatches, unless you only enable it conditionally (e.g. via an environment variable)ghc-debugalready supports cost center profiling, but I have not verified yet whether it actually works withghcbuilt withprofiled_ghcor if more hacks are needed