
Rodrigo Mesquita pushed to branch wip/romes/step-out-10 at Glasgow Haskell Compiler / GHC Commits: 4bf5eb63 by fendor at 2025-06-25T17:05:43-04:00 Teach `:reload` about multiple home units `:reload` needs to lookup the `ModuleName` and must not assume the given `ModuleName` is in the current `HomeUnit`. We add a new utility function which allows us to find a `HomeUnitModule` instead of a `Module`. Further, we introduce the `GhciCommandError` type which can be used to abort the execution of a GHCi command. This error is caught and printed in a human readable fashion. - - - - - b3d97bb3 by fendor at 2025-06-25T17:06:25-04:00 Implement `-fno-load-initial-targets` flag We add the new flag `-fno-load-initial-targets` which doesn't load all `Target`s immediately but only computes the module graph for all `Target`s. The user can then decide to load modules from that module graph using the syntax: ghci> :reload <Mod> This will load everything in the module graph up to `Mod`. The user can return to the initial state by using the builtin target `none` to unload all modules. ghci> :reload none Is in principle identical to starting a new session with the `-fno-load-initial-targets` flag. The `-fno-load-initial-targets` flag allows for faster startup time of GHCi when a user has lots of `Target`s. We additionally extend the `:reload` command to accept multiple `ModuleName`s. For example: ghci> :reload <Mod1> <Mod2> Loads all modules up to the modules `Mod1` and `Mod2`. - - - - - 49f44e52 by Teo Camarasu at 2025-06-26T04:19:51-04:00 Expose ghc-internal unit id through the settings file This in combination with the unit id of the compiler library allows cabal to know of the two unit ids that should not be reinstalled (in specific circumstances) as: - when using plugins, we want to link against exactly the compiler unit id - when using TemplateHaskell we want to link against exactly the package that contains the TemplateHaskell interfaces, which is `ghc-internal` See: https://github.com/haskell/cabal/issues/10087 Resolves #25282 - - - - - 499c4efe by Bryan Richter at 2025-06-26T04:20:33-04:00 CI: Fix and clean up capture of timings * Fixes the typo that caused 'cat ci-timings' to report "no such file or directory" * Gave ci_timings.txt a file extension so it may play better with other systems * Fixed the use of time_it so all times are recorded * Fixed time_it to print name along with timing - - - - - 86c90c9e by Bryan Richter at 2025-06-26T04:20:33-04:00 CI: Update collapsible section usage The syntax apparently changed at some point. - - - - - 04308ee4 by Bryan Richter at 2025-06-26T04:20:33-04:00 CI: Add more collapsible sections - - - - - 43b606bb by Florian Ragwitz at 2025-06-27T16:31:26-04:00 Tick uses of wildcard/pun field binds as if using the record selector function Fixes #17834. See Note [Record-selector ticks] for additional reasoning behind this as well as an overview of the implementation details and future improvements. - - - - - d4952549 by Ben Gamari at 2025-06-27T16:32:08-04:00 testsuite/caller-cc: Make CallerCc[123] less sensitive These were previously sensitive to irrelevant changes in program structure. To avoid this we filter out all by lines emitted by the -fcaller-cc from the profile. - - - - - 0f404726 by Rodrigo Mesquita at 2025-07-02T10:40:51+01:00 debugger/rts: Allow toggling step-in per thread The RTS global flag `rts_stop_next_breakpoint` globally sets the interpreter to stop at the immediate next breakpoint. With this commit, single step mode can additionally be set per thread in the TSO flag (TSO_STOP_NEXT_BREAKPOINT). Being able to toggle "stop at next breakpoint" per thread is an important requirement for implementing "stepping out" of a function in a multi-threaded context. And, more generally, having a per-thread flag for single-stepping paves the way for multi-threaded debugging. That said, when we want to enable "single step" mode for the whole interpreted program we still want to stop at the immediate next breakpoint, whichever thread it belongs to. That's why we also keep the global `rts_stop_next_breakpoint` flag, with `rts_enableStopNextBreakpointAll` and `rts_disableStopNextBreakpointAll` helpers. Preparation for #26042 - - - - - c727a0ff by Rodrigo Mesquita at 2025-07-02T10:40:51+01:00 docs: Case continuation BCOs This commit documents a subtle interaction between frames for case BCOs and their parents frames. Namely, case continuation BCOs may refer to (non-local) variables that are part of the parent's frame. The note expanding a bit on these details is called [Case continuation BCOs] - - - - - 1dc2b741 by Rodrigo Mesquita at 2025-07-02T10:40:53+01:00 debugger: Implement step-out feature Implements support for stepping-out of a function (aka breaking right after returning from a function) in the interactive debugger. It also introduces a GHCi command :stepout to step-out of a function being debugged in the interpreter. The feature is described as: Stop at the first breakpoint immediately after returning from the current function scope. Known limitations: because a function tail-call does not push a stack frame, if step-out is used inside of a function that was tail-called, execution will not be returned to its caller, but rather its caller's first non-tail caller. On the other hand, it means the debugger follows the more realistic execution of the program. In the following example: .. code-block:: none f = do a b <--- (1) set breakpoint then step in here c b = do ... d <--- (2) step-into this tail call d = do ... something <--- (3) step-out here ... Stepping-out will stop execution at the `c` invokation in `f`, rather than stopping at `b`. The key idea is simple: When step-out is enabled, traverse the runtime stack until a continuation BCO is found -- and enable the breakpoint heading that BCO explicitly using its tick-index. The details are specified in `Note [Debugger: Step-out]` in `rts/Interpreter.c`. Since PUSH_ALTS BCOs (representing case continuations) were never headed by a breakpoint (unlike the case alternatives they push), we introduced the BRK_ALTS instruction to allow the debugger to set a case continuation to stop at the breakpoint heading the alternative that is taken. This is further described in `Note [Debugger: BRK_ALTS]`. Fixes #26042 - - - - - caabafee by Rodrigo Mesquita at 2025-07-02T10:40:53+01:00 debugger: Filter step-out stops by SrcSpan To implement step-out, the RTS looks for the first continuation frame on the stack and explicitly enables its entry breakpoint. However, some continuations will be contained in the function from which step-out was initiated (trivial example is a case expression). Similarly to steplocal, we will filter the breakpoints at which the RTS yields to the debugger based on the SrcSpan. When doing step-out, only stop if the breakpoint is /not/ contained in the function from which we initiated it. This is especially relevant in monadic statements such as IO which is compiled to a long chain of case expressions. See Note [Debugger: Filtering step-out stops] - - - - - b3cb024a by Cheng Shao at 2025-07-02T10:57:13+01:00 compiler: make ModBreaks serializable - - - - - a8772d44 by Rodrigo Mesquita at 2025-07-02T10:57:13+01:00 refactor: "Inspecting the session" moved from GHC Moved utilities for inspecting the session from the GHC module to GHC.Driver.Session.Inspect Purely a clean up - - - - - 855417e1 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 cleanup: Pass the HUG to readModBreaks, not HscEnv A minor cleanup. The associated history and setupBreakpoint functions are changed accordingly. - - - - - 6ed3ad45 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 cleanup: Move readModBreaks to GHC.Runtime.Interpreter With some small docs changes - - - - - f0ed1d22 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 cleanup: Move interpreterProfiled to Interp.Types Moves interpreterProfiled and interpreterDynamic to GHC.Runtime.Interpreter.Types from GHC.Runtime.Interpreter. - - - - - 27330c5d by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 cleanup: Don't import GHC in Debugger.Breakpoints Remove the top-level import GHC from GHC.Runtime.Debugger.Breakpoints This makes the module dependencies more granular and cleans up the qualified imports from the code. - - - - - d5981938 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 refactor: Use BreakpointId in Core and Ifaces - - - - - 914cf7a7 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 stg2bc: Derive BcM via ReaderT StateT A small refactor that simplifies GHC.StgToByteCode by deriving-via the Monad instances for BcM. This is done along the lines of previous similar refactors like 72b54c0760bbf85be1f73c1a364d4701e5720465. - - - - - 25f7a096 by Rodrigo Mesquita at 2025-07-02T10:57:14+01:00 refact: Split InternalModBreaks out of ModBreaks There are currently two competing ways of referring to a Breakpoint: 1. Using the Tick module + Tick index 2. Using the Info module + Info index 1. The Tick index is allocated during desugaring in `mkModBreaks`. It is used to refer to a breakpoint associated to a Core Tick. For a given Tick module, there are N Ticks indexed by Tick index. 2. The Info index is allocated during code generation (in StgToByteCode) and uniquely identifies the breakpoints at runtime (and is indeed used to determine which breakpoint was hit at runtime). Why we need both is described by Note [Breakpoint identifiers]. For every info index we used to keep a `CgBreakInfo`, a datatype containing information relevant to ByteCode Generation, in `ModBreaks`. This commit splits out the `IntMap CgBreakInfo` out of `ModBreaks` into a new datatype `InternalModBreaks`. - The purpose is to separate the `ModBreaks` datatype, which stores data associated from tick-level information which is fixed after desugaring, from the unrelated `IntMap CgBreakInfo` information accumulated during bytecode generation. - We move `ModBreaks` to GHC.HsToCore.Breakpoints The new `InternalModBreaks` simply combines the `IntMap CgBreakInfo` with `ModBreaks`. After code generation we construct an `InternalModBreaks` with the `CgBreakInfo`s we accumulated and the existing `ModBreaks` and store that in the compiled BCO in `bc_breaks`. - Note that we previously only updated the `modBreaks_breakInfo` field of `ModBreaks` at this exact location, and then stored the updated `ModBreaks` in the same `bc_breaks`. - We put this new datatype in GHC.ByteCode.Breakpoints The rest of the pipeline for which CgBreakInfo is relevant is accordingly updated to also use `InternalModBreaks` - - - - - 7623dacb by Rodrigo Mesquita at 2025-07-02T10:57:15+01:00 cleanup: Use BreakpointIds in bytecode gen Small clean up to use BreakpointId and InternalBreakpointId more uniformly in bytecode generation rather than using Module + Ix pairs - - - - - 5d52d4c3 by Rodrigo Mesquita at 2025-07-02T10:57:15+01:00 ghci: Allocate BreakArrays at link time only Previously, a BreakArray would be allocated with a slot for every tick in a module at `mkModBreaks`, in HsToCore. However, this approach has a few downsides: - It interleaves interpreter behaviour (allocating arrays for breakpoints) within the desugarer - It is inflexible in the sense it is impossible for the bytecode generator to add "internal" breakpoints that can be triggered at runtime, because those wouldn't have a source tick. (This is relevant for our intended implementation plan of step-out in #26042) - It ties the BreakArray indices to the *tick* indexes, while at runtime we would rather just have the *info* indexes (currently we have both because BreakArrays are indexed by the *tick* one). Paving the way for #26042 and #26064, this commit moves the allocation of BreakArrays to bytecode-loading time -- akin to what is done for CCS arrays. Since a BreakArray is allocated only when bytecode is linked, if a breakpoint is set (e.g. `:break 10`) before the bytecode is linked, there will exist no BreakArray to trigger the breakpoint in. Therefore, the function to allocate break arrays (`allocateBreakArrays`) is exposed and also used in GHC.Runtime.Eval to allocate a break array when a breakpoint is set, if it doesn't exist yet (in the linker env). - - - - - 58798b64 by Rodrigo Mesquita at 2025-07-02T11:07:59+01:00 THE LAST PART - - - - - 135 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/common.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - + compiler/GHC/ByteCode/Breakpoints.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Core/FVs.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Map/Expr.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/Tidy.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Session.hs - + compiler/GHC/Driver/Session/Inspect.hs - compiler/GHC/HsToCore.hs - compiler/GHC/HsToCore/Breakpoints.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Types.hs - compiler/GHC/Runtime/Debugger/Breakpoints.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Eval/Types.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/Types.hs - compiler/GHC/Stg/BcPrep.hs - compiler/GHC/Stg/FVs.hs - compiler/GHC/StgToByteCode.hs - − compiler/GHC/Types/Breakpoint.hs - compiler/GHC/Types/Tickish.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/ModGuts.hs - compiler/Setup.hs - compiler/ghc.cabal.in - docs/users_guide/9.14.1-notes.rst - docs/users_guide/ghci.rst - ghc/GHCi/UI.hs - ghc/GHCi/UI/Exception.hs - ghc/GHCi/UI/Print.hs - hadrian/src/Rules/Generate.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc - libraries/ghc-heap/tests/parse_tso_flags.hs - + libraries/ghci/GHCi/Debugger.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/Run.hs - libraries/ghci/ghci.cabal.in - rts/Disassembler.c - rts/Exception.cmm - rts/Interpreter.c - rts/Interpreter.h - rts/RtsSymbols.c - rts/StgMiscClosures.cmm - rts/include/rts/Bytecodes.h - rts/include/rts/Constants.h - rts/include/rts/storage/Closures.h - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/ghc-e/should_fail/T18441fail5.stderr - + testsuite/tests/ghci.debugger/scripts/T26042b.hs - + testsuite/tests/ghci.debugger/scripts/T26042b.script - + testsuite/tests/ghci.debugger/scripts/T26042b.stdout - + testsuite/tests/ghci.debugger/scripts/T26042c.hs - + testsuite/tests/ghci.debugger/scripts/T26042c.script - + testsuite/tests/ghci.debugger/scripts/T26042c.stdout - + testsuite/tests/ghci.debugger/scripts/T26042d.hs - + testsuite/tests/ghci.debugger/scripts/T26042d.script - + testsuite/tests/ghci.debugger/scripts/T26042d.stdout - + testsuite/tests/ghci.debugger/scripts/T26042e.hs - + testsuite/tests/ghci.debugger/scripts/T26042e.script - + testsuite/tests/ghci.debugger/scripts/T26042e.stdout - + testsuite/tests/ghci.debugger/scripts/T26042f.hs - + testsuite/tests/ghci.debugger/scripts/T26042f.script - + testsuite/tests/ghci.debugger/scripts/T26042f1.stderr - + testsuite/tests/ghci.debugger/scripts/T26042f1.stdout - + testsuite/tests/ghci.debugger/scripts/T26042f2.stdout - + testsuite/tests/ghci.debugger/scripts/T26042g.hs - + testsuite/tests/ghci.debugger/scripts/T26042g.script - + testsuite/tests/ghci.debugger/scripts/T26042g.stdout - testsuite/tests/ghci.debugger/scripts/all.T - testsuite/tests/ghci/prog-mhu003/prog-mhu003.stderr - testsuite/tests/ghci/prog-mhu004/prog-mhu004a.stderr - + testsuite/tests/ghci/prog-mhu005/Makefile - + testsuite/tests/ghci/prog-mhu005/a/A.hs - + testsuite/tests/ghci/prog-mhu005/all.T - + testsuite/tests/ghci/prog-mhu005/b/B.hs - + testsuite/tests/ghci/prog-mhu005/prog-mhu005a.script - + testsuite/tests/ghci/prog-mhu005/prog-mhu005a.stderr - + testsuite/tests/ghci/prog-mhu005/prog-mhu005a.stdout - + testsuite/tests/ghci/prog-mhu005/unitA - + testsuite/tests/ghci/prog-mhu005/unitB - + testsuite/tests/ghci/prog021/A.hs - + testsuite/tests/ghci/prog021/B.hs - + testsuite/tests/ghci/prog021/Makefile - + testsuite/tests/ghci/prog021/all.T - + testsuite/tests/ghci/prog021/prog021a.script - + testsuite/tests/ghci/prog021/prog021a.stderr - + testsuite/tests/ghci/prog021/prog021a.stdout - + testsuite/tests/ghci/prog021/prog021b.script - + testsuite/tests/ghci/prog021/prog021b.stderr - + testsuite/tests/ghci/prog021/prog021b.stdout - + testsuite/tests/ghci/prog022/A.hs - + testsuite/tests/ghci/prog022/B.hs - + testsuite/tests/ghci/prog022/Makefile - + testsuite/tests/ghci/prog022/all.T - + testsuite/tests/ghci/prog022/ghci.prog022a.script - + testsuite/tests/ghci/prog022/ghci.prog022a.stderr - + testsuite/tests/ghci/prog022/ghci.prog022a.stdout - + testsuite/tests/ghci/prog022/ghci.prog022b.script - + testsuite/tests/ghci/prog022/ghci.prog022b.stderr - + testsuite/tests/ghci/prog022/ghci.prog022b.stdout - testsuite/tests/ghci/scripts/ghci021.stderr - + testsuite/tests/hpc/recsel/Makefile - + testsuite/tests/hpc/recsel/recsel.hs - + testsuite/tests/hpc/recsel/recsel.stdout - + testsuite/tests/hpc/recsel/test.T - testsuite/tests/profiling/should_run/caller-cc/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f9d327dfc8c752805be1d7c775895a... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f9d327dfc8c752805be1d7c775895a... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Rodrigo Mesquita (@alt-romes)