src/bindings/python/docs/debugging_python_api.md
This guide explains how to debug the OpenVINO Python API by setting breakpoints in the underlying C++ code. Since the Python API is implemented using pybind11 bindings over C++ code, debugging requires a special setup to step through both Python and C++ layers.
To debug C++ code, you need to build OpenVINO with debug symbols enabled. Add the following CMake flags:
cmake -DCMAKE_BUILD_TYPE=Debug \
-DENABLE_PYTHON=ON \
...
For complete build instructions, refer to Building the OpenVINO Python API.
pip install -r src/bindings/python/requirements_test.txt
The OpenVINO Python API is a thin wrapper around C++ implementation. When you call a Python method like tensor.get_size(), the execution flow is:
ov::Tensor::get_size() executesTo debug this, we need to:
.vscode/launch.jsonCreate a launch configuration in your workspace's .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python API Debug",
"type": "cppdbg",
"request": "launch",
"program": "/path/to/your/python",
"args": [
"-m", "pytest",
"tests/test_runtime/test_tensor.py::test_tensor_from_numpy",
"-v"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/src/bindings/python/tests",
"environment": [
{
"name": "PYTHONPATH",
"value": "${workspaceFolder}/bin/intel64/Debug/python"
},
{
"name": "LD_LIBRARY_PATH",
"value": "${workspaceFolder}/bin/intel64/Debug"
}
],
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
program: Path to your Python interpreter. Use which python or pyenv which python to find it.args: Arguments passed to Python. Here we're running pytest with a specific test.cwd: Working directory - set to the tests directory.PYTHONPATH: Points to the built Python bindings.LD_LIBRARY_PATH: Points to the built OpenVINO libraries.Replace the following in the configuration:
/path/to/your/python → Your Python executable path
~/.pyenv/versions/<env_name>/bin/python/usr/bin/python3${workspaceFolder} resolves to your OpenVINO repository rootLet's debug the ov::Tensor::get_size() method, which is a stable API unlikely to be removed.
Open the C++ source file:
src/bindings/python/src/pyopenvino/core/tensor.cpp
Find the get_size method binding:
cls.def("get_size",
&ov::Tensor::get_size,
R"(
Gets Tensor's size as total number of elements.
:rtype: int
)");
The actual implementation is in the core library. Set a breakpoint at line (&ov::Tensor::get_size), or better yet, find the implementation in:
src/core/include/openvino/core/tensor.hpp
And set a breakpoint in the get_size() method implementation.
You can use an existing test that calls get_size(). For example, tests/test_runtime/test_tensor.py contains:
def test_tensor_from_numpy():
arr = np.array([1, 2, 3])
ov_tensor = ov.Tensor(arr)
assert ov_tensor.get_size() == arr.size # This calls C++ code
Modify the args in your launch configuration to run this specific test:
"args": [
"-m", "pytest",
"tests/test_runtime/test_tensor.py::test_tensor_from_numpy",
"-v", "-s"
]
The -s flag disables output capturing, making debugging easier.
F5 or click "Run → Start Debugging"Once stopped at the breakpoint, you can:
You can also debug a standalone Python script:
{
"name": "Python Script Debug",
"type": "cppdbg",
"request": "launch",
"program": "/path/to/python",
"args": ["${workspaceFolder}/my_script.py"],
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PYTHONPATH",
"value": "${workspaceFolder}/bin/intel64/Debug/python"
}
],
"MIMode": "gdb"
}
This method does not use or require launch.json. It uses GDB directly from the command line as an alternative to the VS Code debugging setup.
You can attach GDB to an already running Python process:
Start your Python script with a pause:
import os
import time
print(f"PID: {os.getpid()}")
time.sleep(30) # Time to attach debugger
In another terminal, attach GDB using the process ID:
gdb -p <PID>
Set breakpoints and continue execution:
(gdb) break ov::Tensor::get_size
(gdb) continue