You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: guide/src/debugging.md
+294-5
Original file line number
Diff line number
Diff line change
@@ -34,14 +34,303 @@ Run Valgrind with `valgrind --suppressions=valgrind-python.supp ./my-command --w
34
34
35
35
The best start to investigate a crash such as an segmentation fault is a backtrace. You can set `RUST_BACKTRACE=1` as an environment variable to get the stack trace on a `panic!`. Alternatively you can use a debugger such as `gdb` to explore the issue. Rust provides a wrapper, `rust-gdb`, which has pretty-printers for inspecting Rust variables. Since PyO3 uses `cdylib` for Python shared objects, it does not receive the pretty-print debug hooks in `rust-gdb` ([rust-lang/rust#96365](https://github.com/rust-lang/rust/issues/96365)). The mentioned issue contains a workaround for enabling pretty-printers in this case.
36
36
37
-
* Link against a debug build of python as described in the previous chapter
38
-
* Run `rust-gdb <my-binary>`
39
-
* Set a breakpoint (`b`) on `rust_panic` if you are investigating a `panic!`
40
-
* Enter `r` to run
41
-
* After the crash occurred, enter `bt` or `bt full` to print the stacktrace
37
+
* Link against a debug build of python as described in the previous chapter
38
+
* Run `rust-gdb <my-binary>`
39
+
* Set a breakpoint (`b`) on `rust_panic` if you are investigating a `panic!`
40
+
* Enter `r` to run
41
+
* After the crash occurred, enter `bt` or `bt full` to print the stacktrace
42
42
43
43
Often it is helpful to run a small piece of Python code to exercise a section of Rust.
One of the preferred ways by developers to debug their code is by setting breakpoints. This can be achieved in PyO3 by using a debugger like `rust-gdb` or `rust-lldb` with your Python interpreter.
52
+
53
+
For more information about how to use both `lldb` and `gdb` you can read the [gdb to lldb command map](https://lldb.llvm.org/use/map.html) from the lldb documentation.
54
+
55
+
### Common setup
56
+
57
+
1. Compile your extension with debug symbols:
58
+
59
+
```bash
60
+
# Debug is the default for maturin, but you can explicitly ensure debug symbols with:
61
+
RUSTFLAGS="-g" maturin develop
62
+
63
+
# For setuptools-rust users:
64
+
pip install -e .
65
+
```
66
+
67
+
> **Note**: When using debuggers, make sure that `python` resolves to an actual Python binary or symlink and not a shim script. Some tools like pyenv use shim scripts which can interfere with debugging.
68
+
69
+
### Debugger specific setup
70
+
71
+
Depeding on your OS and your preferences you can use two different debuggers, `rust-gdb` or `rust-lldb`.
72
+
73
+
{{#tabs }}
74
+
{{#tab name="Using rust-gdb" }}
75
+
76
+
1. Launch rust-gdb with the Python interpreter:
77
+
78
+
```bash
79
+
rust-gdb --args python
80
+
```
81
+
82
+
2. Once in gdb, set a breakpoint in your Rust code:
83
+
84
+
```bash
85
+
(gdb) break your_module.rs:42
86
+
```
87
+
88
+
3. Run your Python script that imports and uses your Rust extension:
89
+
90
+
```bash
91
+
# Option 1: Run an inline Python command
92
+
(gdb) run -c "import your_module; your_module.your_function()"
93
+
94
+
# Option 2: Run a Python script
95
+
(gdb) run your_script.py
96
+
97
+
# Option 3: Run pytest tests
98
+
(gdb) run -m pytest tests/test_something.py::TestName
This configuration supports multiple debugging scenarios:
189
+
* Attaching to a running Python process
190
+
* Launching the currently open Python file
191
+
* Running a specific script with command-line arguments
192
+
* Running pytest tests
193
+
194
+
3. Set breakpoints in your Rust code by clicking in the gutter next to line numbers.
195
+
196
+
4. Start debugging:
197
+
* For attaching to a running Python process: First start the process, then select the "Debug PyO3" configuration and click Start Debugging (F5). You'll be prompted to select the Python process to attach to.
198
+
* For launching a Python script: Open your Python script, select the "Launch Python with PyO3" configuration and click Start Debugging (F5).
199
+
* For running with arguments: Select "Debug PyO3 with Args" (remember to edit the configuration with your actual script path and arguments).
200
+
* For running tests: Select "Debug PyO3 Tests" (edit the test path as needed).
201
+
202
+
5. When debugging PyO3 code:
203
+
* You can inspect Rust variables and data structures
204
+
* Use the debug console to evaluate expressions
205
+
* Step through Rust code line by line using the step controls
206
+
* Set conditional breakpoints for more complex debugging scenarios
207
+
208
+
### Advanced Debugging Configurations
209
+
210
+
For advanced debugging scenarios, you might want to add environment variables or enable specific Rust debug flags:
211
+
212
+
```json
213
+
{
214
+
"name": "Debug PyO3 with Environment",
215
+
"type": "lldb",
216
+
"request": "launch",
217
+
"program": "${workspaceFolder}/.venv/bin/python",
218
+
"args": ["${file}"],
219
+
"env": {
220
+
"RUST_BACKTRACE": "1",
221
+
"PYTHONPATH": "${workspaceFolder}"
222
+
},
223
+
"sourceLanguages": ["rust"]
224
+
}
225
+
```
226
+
227
+
### Debugging from Jupyter Notebooks
228
+
229
+
For Jupyter Notebooks run from VS Code, you can use the following helper functions to automate the launch configuration:
0 commit comments