Skip to content

[Fix #365] not in scope error for getClosureData crashes debugger - #368

Merged
Saizan merged 6 commits into
masterfrom
wip/andrea/365
Sep 16, 2026
Merged

Saizan merged 6 commits into
masterfrom
wip/andrea/365

Conversation

@Saizan

@Saizan Saizan commented Sep 9, 2026 •

Copy link
Copy Markdown
Collaborator

Fix #365.
TODO:

  • Made errors in parsers not fatal, only reported to client and logged.
  • Made setLineBuffering and UnpackStackFields into custom commands
  • Added GHC.Debugger.Runtime.Internal for helpers we need at runtime. See Note [debuggerInternal unit]

@Saizan Saizan changed the title Fix #365: not in scope error for getClosureData crashes debugger Fix #365 : not in scope error for getClosureData crashes debugger Sep 9, 2026
@Saizan Saizan changed the title Fix #365 : not in scope error for getClosureData crashes debugger [Fix #365] not in scope error for getClosureData crashes debugger Sep 9, 2026
@Saizan
Saizan force-pushed the wip/andrea/365 branch 9 times, most recently from 646b930 to a2e2a0b Compare September 15, 2026 08:24
guard on .Legacy module in .cabal now matches
`#if MIN_VERSION_ghc(9,14,2)` check in code
1. `liftDebuggerOrFail` converts `Left`s into `TermParserError` for local recovery.
2. `expectRight` throws new `NonFatalException`.
3. `debuggerThread` catches `NonFatalException`,
    then sends `NonFatalError` as `Response` and keeps going.
4. `NonFatalError` leads to an error response without killing the debug session.

expectRight seems to be used for errors that can be survived (in parsers and so on),
so NonFatalException seems a good default.
@Saizan
Saizan force-pushed the wip/andrea/365 branch 3 times, most recently from cdcfd51 to b45ffbc Compare September 15, 2026 15:06
@Saizan
Saizan marked this pull request as ready for review September 15, 2026 15:18
@Saizan
Saizan requested a review from alt-romes September 15, 2026 15:18

@alt-romes alt-romes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I like the overall approach moving less thing from hardcoded strings into just a module which is compiled and loaded at runtime all at once.

I just did a first quick pass, I'll need to look again better.

Comment thread haskell-debugger/GHC/Debugger/Runtime/Internal.hs
@alt-romes

Copy link
Copy Markdown
Collaborator

IIRC you previously introduced an in-memory-"FFI"-module. Could that be merged into this one perhaps?

Could we make somehow the distinction between a module that is used for the compilation of the debugger vs a module used only at runtime?

There is also one module which I think is all specified as a string or something which is also loaded at runtime. Or is just listed in extra-source-files and then inserted into the program using TH? In any case, it would be good to consolidate all these competing methods and make it clear the distinction between runtime vs compile-time modules (e.g. use a fully distinct module Namespace)

@Saizan

Saizan commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator Author

@alt-romes

I don't really see "competing methods", tbf. The contents of all the modules you mentioned are bound to a StringBuffer CAF each via TH at compile time (the haskell-debugger-view ones need to be in extra-source-dirs so the files are in the haskell-debugger's sdist).
They are all also built statically regardless of when they are used, which keeps the dev experience saner.

If you prefer, what we can do is have one module that exports all the things from haskell-debugger for sure needed at runtime. Under ghc < 9.14.2 the module will also re-export definitions that are from modules that are imported statically with ghc >= 9.14.2 (to implement custom commands), which means those re-exported modules will also be loaded at runtime (and must only depend on libraries shipped with ghc).

The haskell-debugger-view in-memory unit has to stay separate though, because that one depends on the debuggee units (both as home unit dependencies and whether we load it or not).

More details on how things are used atm:

  • In extra-source-files we include the modules (and .cabal? that does not seem useful) from haskell-debugger-view. That's only conditionally an in-memory unit, depending on the debuggee, and we want to release the library anyway.
  • GHC.Debugger.Runtime.FFIInspect is used statically with Custom Commands (c.f. stackFrameInfo) and at runtime without. The unit is loaded at runtime only if ghc < 9.14.2. Hopefully this whole module goes away after we implement the better CgModInfo, which is why it's kept separate.
  • GHC.Debugger.Runtime.Internal has two more functions like above (static with Custom Commands, runtime otherwise), and the rest are unconditionally used at Runtime. These definitions we will keep needing in the future.

@alt-romes alt-romes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work!

I've got a few comments on a few things, but it's almost ready to land. Minimal changes needed.

Comment thread haskell-debugger/GHC/Debugger/Runtime/Eval/RemoteExpr/Builtin.hs
Comment thread haskell-debugger/GHC/Debugger/Runtime/Interpreter/Legacy.hs
Comment thread haskell-debugger/GHC/Debugger/Runtime/Interpreter/Custom.hs Outdated
Comment thread haskell-debugger/GHC/Debugger/Runtime/Internal.hs
Comment thread haskell-debugger/GHC/Debugger/Runtime/Eval/RemoteExpr/Builtin.hs
Comment thread haskell-debugger/GHC/Debugger/Runtime/Internal.hs
Comment thread haskell-debugger/GHC/Debugger/Breakpoint.hs Outdated
Comment thread haskell-debugger/GHC/Debugger/Monad.hs Outdated
References to external packages and injected code in general are fragile if
compiled using the `interactiveGhcDebugger` unit, which depends on all the
debuggee ones.

See Note [debuggerInternal unit] for how to use it to mitigate the issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression in debugging HLS

2 participants