visual-studio-codegdbmingw-w64pythonpathopenocd

Run & Debug depends on Windows PYTHONPATH/HOME environment variables


I'm working on a project where I debug with GDB and OpenOCD. Sometimes we use VS Code for this purpose and I encountered an issue that the Run & Debug session won't launch when PYTHONHOME/PYTHONPATH are set to another Python installation. If I set the paths empty or to the correct mingw path in the current environment, it works.

Here is my launch.json config

"name": "GDB-Launch OpenOCD",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/output/openocd_debug.exe",
"args": [ 
    "-f${workspaceFolder}/output/openocd_debug.cfg" 
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/output/",
"environment": [
    {"name": "PYTHONHOME", "value": "${config:mingw_path}\\mingw64\\bin"},
    {"name": "PYTHONPATH", "value": "${config:mingw_path}\\mingw64\\lib\\python3.7"}
],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "${config:mingw_path}\\mingw64\\bin\\gdb.exe",
"setupCommands": [
    {
        "description": "Enable pretty-printing for gdb",
        "text": "-enable-pretty-printing",
        "ignoreFailures": true
    }
],

I have a workaround where I put

"terminal.integrated.env.windows": {
    "PYTHONHOME": "",
    "PYTHONPATH": ""
}

inside of settings.json (either project settings or user settings works). But I still want to know why and how there is an issue.

I do not get an error message or some weird output. When I want to start the Debug session, WindowsDebugLauncher gets called, changes compiler paths and then it freezes. In a working setup this process is the same but after that GDB (Debug console) and OpenOCD get called and open up.


Solution

  • GDB has a Python interpreter embedded within it which is used to run some extensions, this is documented here.

    This embedded interpreter will check for and use the PYTHONHOME and PYTHONPATH environment variables, which can be useful in some cases where (maybe) GDB wasn't build against the default system Python. It is important that the Python libraries that GDB finds, whether via it's default search path, or via the environment variables, matches the version of Python GDB was built against.

    So, if you set PYTHONHOME and/or PYTHONPATH to point to a different Python version than the one GDB is built against, things aren't going to work; GDB will likely throw some errors during its initial startup (as some Python scripts are shipped with GDB and loaded when GDB is initially started).

    There are a couple of possible solutions to this problem.

    As you have figured out, if you can set PYTHONHOME/PYTHONPATH to point to the version of Python that GDB is expecting, or just unset these variables and let GDB figure it out (GDB will use its default search path), then this is perfect.

    But, if you need to have these environment variables set, maybe the application you are debugging depends on them, then you can use set python ignore-environment on. GDB will then ignore these environment variables and just use its default search path. This is documented here. However, you need to change this setting super early during GDB's startup, either from the GDB command line as -eiex 'set python ignore-environment on', or by placing the command into a ~/.gdbearlyinit (or whatever the MinGW equivalent is).

    Given you are able to start GDB with the environment variables set to the empty string then I think one of the above should work fine for you, this would imply that GDB's default search logic is able to locate the required Python libraries.

    But what if this wasn't the case? What if GDB needed PYTHONHOME/PYTHONPATH set and the inferior also needed these set, but to different values?

    In that case you'd need you'd need to set the environment for GDB in your shell, start GDB, and then use set environment PYTHONHOME=.... and set environment PYTHONPATH=... within GDB to setup the environment for the inferior before issuing the run command.