Repository navigation
Add experimental debugger support for JIT-compiled C++ - #167
conrade-ctc wants to merge 2 commits into
Conversation
|
Nice! So that your changes are tested on the CI, can you add a commit like cc7edf7 pointing to your CppInterOp remote and branch? That would stack your changes and any iterations on compiler-research/CppInterOp#1156 will automatically reflect here |
Vipul-Cariappa
left a comment
There was a problem hiding this comment.
I have only looked through some of the READMEs. I wanted to know why GDB? I believe LLDB provides better API support than GDB. With GDB, you are working with pipes and parsing the output as though you are running it in a shell.
| @@ -0,0 +1,26 @@ | |||
| """gdb extension for processes that run cppjit. | |||
There was a problem hiding this comment.
Can we have type hints for all the Python files in python/cppjit-debugger folder?
Will make it a bit easier to maintain and review the code.
There was a problem hiding this comment.
Done: all the files in python/cppjit-debugger have type hints now, and mypy finds no issues. The files use from __future__ import annotations, because gdb can embed an older Python.
c0b4377 to
4031ac2
Compare
|
Thanks for the review! The extension does not use pipes. gdb embeds Python, so the API calls run in the gdb process: a frame filter shows the Python frames, and the commands and pretty printers read the memory of the inferior. One place parses text, the output of I chose gdb because it is the default debugger on Linux, and it has the JIT interface and DAP built in. I agree that LLDB has a good API. The CPython decoder ( |
4031ac2 to
4b14d6c
Compare
The support is off by default. Build with -DCPPJIT_ENABLE_DEBUGGER_SUPPORT=ON to get it. Without the option, the build has no new code, symbols or files. In a build with the support, CPPJIT_DEBUGGER_SUPPORT=1 starts a debug session: - The JIT compiles with -g -O0. CppInterOp writes each C++ input to a file in CPPINTEROP_JIT_SOURCE_DIR, so gdb shows the source and binds FILE:LINE breakpoints. - cppjit.debugger copies in-memory Python source to files, and adds Python line breakpoints and steps through sys.monitoring. - A gdb extension shows the Python frames between the C++ frames, with the variables of both. It reads CPython's _Py_DebugOffsets, so CPython needs no debug information. - examples/vscode-gdb uses it from VS Code through gdb's DAP server. A DAP proxy adds Python breakpoints and steps between Python and C++. Co-developed-with-the-help-of: Claude Code (Opus 5.5, human in the loop)
Co-developed-with-the-help-of: Claude Code (Opus 5.5, human in the loop)
4b14d6c to
4e894a9
Compare
This adds experimental support to debug JIT-compiled C++ at the source level with gdb, from Python and from VS Code. It is off by default: only a build with
-DCPPJIT_ENABLE_DEBUGGER_SUPPORT=ONhas it. Without the option, the build has no new code, exported symbols or package files, andpython/cppjitdoes not change.In a build with the support,
CPPJIT_DEBUGGER_SUPPORT=1starts a debug session:-g -O0. With Write interpreter inputs to files for debuggers (experimental) CppInterOp#1156, each C++ input goes to a file, so gdb shows the source and bindsfile:linebreakpoints, also in headers thatcppjit.includeloads.cppjit.debuggeradds Python line breakpoints and steps throughsys.monitoring.cppjit/debugger/gdb) shows the Python frames between the C++ frames, with the variables of both. It reads CPython's_Py_DebugOffsets, so CPython needs no debug information (3.13 or later).examples/vscode-gdbuses it from VS Code through gdb's DAP server (gdb 16 or later). A small DAP proxy adds Python breakpoints, and steps between Python and C++.Notes for review:
CPPJIT_WITH_DEBUGGER_SUPPORT: a hook pair around each JIT call inWrapperCall, a few exported variables for the debugger, and the import ofcppjit.debuggerin the module init.CPPInstancefields. I think that is acceptable for an experimental feature, but a change of these layouts needs an update here.debuggerCI job builds with the option and runstest/test_debugging.pywith gdb. It fails if a test skips. The other cells skip the gdb tests, but run the two decoder tests from the source tree. Locally (Linux, gdb 16.3, CPython 3.13), all 21 tests pass with the option.file:linebreakpoints need the CppInterOp change and a pin that has it. Breakpoints by function name work without it.🤖 Done with the help of Claude Code (Opus 5.5, human in the loop)