Reputation: 1826
I am developing a self C extension for Python in order to improve the performance of a specific piece of code. I would like to debug this extension, but I have not succeeded so far. I have followed several links such as this from Nadiah or this from Bark, but I always have the same problem: I cannot stop at any breakpoint of the C code.
The idea is to run Python as the main process and attach the compiled C code to this main process. Following I leave a minimal reproducible example:
import os
import greet
pid = os.getpid()
test=2.2
greet.greet('World')
print("hi")
As you can see, I even retrieve the process ID in order to pick this ID in vscode when attaching the C code, which is as follows:
#include <Python.h>
static PyObject *
greet_name(PyObject *self, PyObject *args)
{
const char *name;
if (!PyArg_ParseTuple(args, "s", &name))
{
return NULL;
}
printf("Helllo %s!\n", name);
Py_RETURN_NONE;
}
static PyMethodDef GreetMethods[] = {
{"greet", greet_name, METH_VARARGS, "Greet an entity."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef greet =
{
PyModuleDef_HEAD_INIT,
"greet", /* name of module */
"", /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
GreetMethods
};
PyMODINIT_FUNC PyInit_greet(void)
{
return PyModule_Create(&greet);
}
I compile the C code with GCC 8.1 by running python setup.py install
:
import os
from setuptools import setup, Extension
os.environ["CC"] = "g++-8.1.0"
_DEBUG = True
_DEBUG_LEVEL = 0
# extra_compile_args = sysconfig.get_config_var('CFLAGS').split()
extra_compile_args = ["-Wall", "-Wextra"]
if _DEBUG:
extra_compile_args += ["-g3", "-O0", "-DDEBUG=%s" % _DEBUG_LEVEL, "-UNDEBUG"]
else:
extra_compile_args += ["-DNDEBUG", "-O3"]
setup(
name='greet',
version='1.0',
description='Python Package with Hello World C Extension',
ext_modules=[
Extension(
'greet',
sources=['greetmodule.c'],
py_limited_api=True,
extra_compile_args=extra_compile_args)
],
)
I even specify O0
option to have all debug symbols.
"configurations": [
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "venv/Scripts/python",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
// "miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
In this last step, vscode should automatically jump between the two debuggers between python and c++ code, but I cannot achieve this behavior.
I am able to debug Python and C programs alone, but not together.
Upvotes: 18
Views: 6731
Reputation: 11
Try with this minimum reproducible example on Windows + VSC.
Install the extension https://marketplace.visualstudio.com/items?itemName=benjamin-simmonds.pythoncpp-debug in VSC. Make sure to have C/C++ from Microsoft and Python extensions as well, and the gdb debugger installed.
Use the following files:
1)Python
import ctypes
my_dll = ctypes.CDLL("./my_cpp_file.dll")
my_dll.foo()
Place a breakpoint at the last line "my_dll.foo()"
2)C++ library
#include <iostream>
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
extern "C" {
DLLEXPORT int foo() {
int a = 0;
a++;
printf("Hello there\n");
return 0;
}
}
int main() {
return 0;
}
Place a breakpoint (red dot) inside the foo() function body. Open a terminal and compile with this directive:
g++ -g -shared -o my_cpp_file.dll -fPIC my_cpp_file.cpp
3)launch.json
Use default (gdb) Attach instead of default (win) Attach inside "cppConfig":
{
"version": "0.2.0",
"configurations": [
{
"name": "Python C++ Debug",
"type": "pythoncpp",
"request": "launch",
"pythonConfig": "default",
"cppConfig": "default (gdb) Attach",
}
]
}
4)Click F5 -> Debug using launch.json -> Select Python C++ debug
5)Now you are able to switch between Python Debugger and gdb C++ debugger through this selection: Switch_menu
Upvotes: 0
Reputation: 51
When debugging a Python C++ code on Windows you should use the configuration "(Windows) Attach" in your launch.json file. For simplifying the process of attaching the C++ debugger to the python debugger you can use the VScode extension "Python C++ Debug".
Both examples from Nidiah and Bark are based on Linux.
On Windows, you can compile your C/C++ code to a .dll file (with DEBUG info) and load it with ctypes in python.
Upvotes: 4
Reputation: 2721
Limitation of Windows :
GDB on Cygwin and MinGW cannot break a running process. To set a breakpoint when the application is running (not stopped under the debugger), or to pause the application being debugged, press Ctrl-C
in the application's terminal.
Upvotes: 0