15

Summary of the problem

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.

Approach I have tried

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:

Python file

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:

C code

#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:

Setup file

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.

Launch JSON file

"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"
    }
]

Debug steps I follow

  1. Add a breakpoint in the python file, run the launch configuration “Python: Current File” and wait until the breakpoint is reached.
  2. Run the “(gdb) Attach” launch configuration, select the python interpreter whose path contains “/.vscode/”. In this case, in Windows, I am not getting prompted to enter my user password as it happens in Linux.
  3. Set breakpoints in the C++ Files
  4. The python debugger is currently stopped at a break point. Switch back from the debugger “(gdb) Attach” to the other debugger “Python: Current File” and press F5 (Continue).

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.

David Duran
  • 1,786
  • 1
  • 25
  • 36
  • Where do you face problem in this link [https://nadiah.org/2020/03/01/example-debug-mixed-python-c-in-visual-studio-code/] – Divyessh Feb 11 '21 at 06:11
  • Hi @Divyessh, it seems that the link you have passed is broken... I guess you are referring to the first link I provided in my post. Everything is fine until the last step (Step 5). There is the difference that, in Windows, I am not prompted to enter superuser password. Then, I am not able to stop at any breakpoint I set in the C code even though the (gdb) attach task is running. The link is Linux-based anyway, so there may be differences when debugging in Windows. – David Duran Feb 11 '21 at 08:14
  • I face a similar problem and I have tried most of the solutions that you have tried as well. Have you tried to adress the question to the vscode issues at github? – axel_ande Mar 08 '21 at 19:22
  • Hi @axel_ande. Yes, I opened two weeks ago an issue in the github of VsCode C++ extension (https://github.com/microsoft/vscode-cpptools/issues/6974). Let's see if somebody solves it. – David Duran Mar 09 '21 at 06:57
  • [`benjamin-simmonds.pythoncpp-debug`](https://marketplace.visualstudio.com/items?itemName=benjamin-simmonds.pythoncpp-debug)? – starball Apr 01 '23 at 04:23

2 Answers2

3

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.

BeniBenj
  • 41
  • 3
  • 1
    Hi @BeniBenj. I have upvoted since it seems promising. Let me test it in depth and I will come back to you. By the way, I am not using ctypes but C extension. Does it make any difference? Another sidenote, `(gdb)` should also work (when compiling with g++) since I have tested it alone in Windows (Launch mode) and it works... – David Duran Apr 13 '21 at 07:21
  • This solution may work with `ctypes`, but I have been unsuccessful to do it with `Cython`, which is how I have coded the C extension. – David Duran Jun 22 '22 at 09:31
0

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.

Divyessh
  • 2,540
  • 1
  • 7
  • 24
  • Check this out for more info [link](https://code.visualstudio.com/docs/cpp/cpp-debug) – Divyessh Feb 12 '21 at 08:33
  • I am not sure if this limitation is related to my problem... I mean, I can debug a standalone C/C++ application. Are you saying that is not possible to debug on Windows using the "(gdb) attach" mode? – David Duran Feb 12 '21 at 11:20
  • No , I am saying that we can not use breakpoints, in windows using gdb – Divyessh Feb 14 '21 at 06:13
  • Actually, I can indeed use breakpoints on Windows (using gdb) if I run only a standalone C/C++ application... The problem is only when trying to debug C attached to Python... – David Duran Feb 14 '21 at 12:34
  • visit the link in comment, I hope you will find some relevant information. – Divyessh Feb 14 '21 at 14:25
  • Yes, I visited the link in your comment. Unfortunately I could not solve my issue. Anyway, thanks for your help! – David Duran Feb 14 '21 at 15:33