Skip to content

--jit-native: debug JIT runs in WinDbg and Visual Studio - #629

Merged
ASDAlexander77 merged 1 commit into
mainfrom
jit-native-dll
Oct 20, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
jit-native-dll

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

On Windows, WinDbg and Visual Studio can't debug --emit=jit: the JIT registers its code only through the GDB JIT interface, and its objects carry CodeView, which nothing reads from there. --emit=jit --jit-native links the JIT cache's objects into one DLL with a PDB in __jit and loads it with the system loader instead of RTDyld. The debugger then sees an ordinary module with symbols and source lines.

  • linkBinary (link.h, exe.cpp): the link line buildExe built, now taking its objects, output, "shared" and extra arguments as parameters, so it can be called mid-run. buildExe keeps InitLLVM and the command-line globals and calls it. A quiet link shows the linker's output only if the link fails.

  • jitnative.cpp: the link, plus a small generated object of host functions:

    • init sends assert/abort reports to stderr (no modal dialogs) and flushes on SIGABRT;
    • flush is called after the program and before TerminateProcess, because the DLL's static C runtime owns the program's stdout buffer.

    The DLL and PDB are reused while the objects and options are the same. Earlier ones, and stale temporary files from killed links, are removed.

  • The static default library is linked into the DLL. Through the default library DLL's import library, a program that reads the library's data doesn't link: Map reads PrimeHelpers.hashCollisionThreshold by its plain name, and only an __imp_ reference resolves a DLL data export. AOT --emit=dll has the same failure today, which will be fixed separately.

  • jit.cpp: one runner for both loaders. In this mode neither the default library's DLL nor TypeScriptRuntime.dll is loaded.

  • --jit-native implies --di unless --opt is given. It is an error without the JIT cache, and is ignored with a warning off Windows.

Design and as-built notes: tslang/docs/jit-native-dll-debugging-design.md.

Testing

  • New test-jit-native-dll (test/tester/jit-native.cmake, Windows): a two-module program runs, its DLL and PDB are reused on the next run and relinked after the module changes, and exit code, uncaught exception, failing assert and the no-cache error are checked. Where cdb is installed, a breakpoint in the imported module is hit at its source line. With the flush disabled the test fails (output lost).
  • ctest -C Release -R "test-jit-|test-compile-": 4463/4463 passed (Windows, release build).
  • By hand: rc and gc (gc with --opt, and with --di against a debug runtime library), with the default library, cdb breakpoints by function and by source line.
  • Not built on Linux: there the option only warns.

🤖 Generated with Claude Code

`--emit=jit --jit-native` (Windows) links the JIT cache's objects into one
DLL with a PDB and loads it with the system loader instead of RTDyld, so a
debugger sees the program as a module with symbols and source lines. The DLL
and PDB live in __jit, are reused while the objects and options are the
same, and earlier ones are removed.

- exe.cpp: the link line is linkBinary (link.h), taking its objects,
  output, "shared" and extra arguments as parameters; buildExe calls it.
  A quiet link shows the linker's output only if it fails.
- jitnative.cpp: the link, with a small object of host functions: init
  sends assert/abort reports to stderr (no dialogs) and flushes on
  SIGABRT; flush is called after the program, before TerminateProcess -
  the DLL's static C runtime owns the program's stdout buffer.
- The DLL links the static default library: through its DLL's import
  library a program reading the library's data (Map reads
  PrimeHelpers.hashCollisionThreshold) does not link.
- jit.cpp: one runner for both loaders; in this mode neither the default
  library's DLL nor TypeScriptRuntime.dll is loaded.
- test-jit-native-dll (jit-native.cmake): reuse, relink after a change,
  exit code, uncaught exception, failing assert, no-cache error, and a
  cdb breakpoint where cdb is installed.

See docs/jit-native-dll-debugging-design.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 6d131d5 into main Oct 20, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the jit-native-dll branch October 20, 2026 22:40
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.

1 participant