pythonc++windowsvisual-studiodebugging

No symbols loaded for c++ in mixed debugging (from Python)


I have a large project where the major part computation-heavy stuff is written in C++, and the "glue code" and the start script are written in Python. The code has been compiled with the VS 2017 compiler (V141) and Python 3.7.0-32bit for a few years now, and I want to upgrade to V143 and Python 3.10-64. I can build and run the code with the new environment. I get some small errors when I run the test suite (probably due to the change from 32-bit to 64-bit).

The issue occurs when I try to debug the C++ code in Visual Studio 2022. I can debug the Python code without any errors, but when I want to debug the code, I can't get any symbols from the C++ to load.

I've tried to follow this guide: https://learn.microsoft.com/en-us/visualstudio/python/debugging-mixed-mode-c-cpp-python-in-visual-studio?view=vs-2022 (But I fail to enable both Native and Python in step 2 of Enable mixed-mode debugging in a Python project. When I select Python in the Select Code type, I get this error: "Python debugging is not compatible with Native. Would you like to uncheck Native?" Similarly, I don't find the option Python/Native debugging in step 2 of "Enable mixed-mode debugging in a C/C++ project," and I've installed Python native development tools using the VS installer, etc.)

Update:

To simplify and show a simple case, I followed this tutorial https://www.youtube.com/watch?v=9q-LHP7cMfg&ab_channel=MichaelVanslembrouck and was able to build and set breakpoints when I started the debugging with the C++ project as the startup project (as described in the YouTube tutorial). The issue occurs when I try to do it with the PythonApplication as a startup project. (I have tried to use both Python39-64 and Python310-64)

I added the content of the necessary files to reproduce the issue. This is the solution file:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spam", "spam\spam.vcxproj", "{18FA7E0B-56F8-433D-ABCC-523E412FFB83}"
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "PythonApplication", "PythonApplication\PythonApplication.pyproj", "{DD2AA21D-1713-4B24-AB58-2695C05684C1}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Debug|x64 = Debug|x64
        Debug|x86 = Debug|x86
        Release|Any CPU = Release|Any CPU
        Release|x64 = Release|x64
        Release|x86 = Release|x86
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|Any CPU.ActiveCfg = Debug|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|Any CPU.Build.0 = Debug|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|x64.ActiveCfg = Debug|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|x64.Build.0 = Debug|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|x86.ActiveCfg = Debug|Win32
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Debug|x86.Build.0 = Debug|Win32
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|Any CPU.ActiveCfg = Release|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|Any CPU.Build.0 = Release|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|x64.ActiveCfg = Release|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|x64.Build.0 = Release|x64
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|x86.ActiveCfg = Release|Win32
        {18FA7E0B-56F8-433D-ABCC-523E412FFB83}.Release|x86.Build.0 = Release|Win32
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Debug|x64.ActiveCfg = Debug|Any CPU
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Debug|x86.ActiveCfg = Debug|Any CPU
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Release|x64.ActiveCfg = Release|Any CPU
        {DD2AA21D-1713-4B24-AB58-2695C05684C1}.Release|x86.ActiveCfg = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {A9526BE0-4988-4327-B7A0-AFD3DF109D47}
    EndGlobalSection
EndGlobal

This is the PythonApplication.pyproj file:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>dd2aa21d-1713-4b24-ab58-2695c05684c1</ProjectGuid>
    <ProjectHome>.</ProjectHome>
    <StartupFile>PythonApplication.py</StartupFile>
    <SearchPath>
    </SearchPath>
    <WorkingDirectory>.</WorkingDirectory>
    <OutputPath>.</OutputPath>
    <Name>PythonApplication</Name>
    <RootNamespace>PythonApplication</RootNamespace>
    <InterpreterId>MSBuild|venv10|$(MSBuildProjectFullPath)</InterpreterId>
    <LaunchProvider>Standard Python launcher</LaunchProvider>
    <EnableNativeCodeDebugging>True</EnableNativeCodeDebugging>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DebugSymbols>true</DebugSymbols>
    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <DebugSymbols>true</DebugSymbols>
    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="PythonApplication.py" />
  </ItemGroup>
  <ItemGroup>
    <Interpreter Include="venv10\">
      <Id>venv10</Id>
      <Version>3.10</Version>
      <Description>venv10 (Python 3.10 (64-bit))</Description>
      <InterpreterPath>Scripts\python.exe</InterpreterPath>
      <WindowsInterpreterPath>Scripts\pythonw.exe</WindowsInterpreterPath>
      <PathEnvironmentVariable>PYTHONPATH</PathEnvironmentVariable>
      <Architecture>X64</Architecture>
    </Interpreter>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
  <!-- Uncomment the CoreCompile target to enable the Build command in
       Visual Studio and specify your pre- and post-build commands in
       the BeforeBuild and AfterBuild targets below. -->
  <!--<Target Name="CoreCompile" />-->
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
</Project>

This is the PythonAppliction.py file:

import spam
print(spam.add_one(123))

This is my spam.vcxproj file:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <VCProjectVersion>16.0</VCProjectVersion>
    <Keyword>Win32Proj</Keyword>
    <ProjectGuid>{18fa7e0b-56f8-433d-abcc-523e412ffb83}</ProjectGuid>
    <RootNamespace>spam</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v143</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <IncludePath>c:\Python310-64\include;$(IncludePath)</IncludePath>
    <OutDir>$(SolutionDir)\PythonApplication\</OutDir>
    <TargetExt>.pyd</TargetExt>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <AdditionalLibraryDirectories>C:\Python310-64\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="include.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

My main.cpp:

#include "include.h"


PyObject* some_function(PyObject* self, PyObject* args)
{
    __int64 input_value;
    if (!PyArg_ParseTuple(args, "L", &input_value))
    {
        goto error;
    }
    return PyLong_FromLongLong(input_value + 1);
error:
    return 0;

}

PyMethodDef SpamMethods[] =
{
    {"add_one",(PyCFunction)some_function, METH_VARARGS, 0},
    {0,0,0,0}
};


static struct PyModuleDef spammodule = {
    PyModuleDef_HEAD_INIT,
    "spam",   /* name of module */
    "spam_doc", /* module documentation, may be NULL */
    -1,       /* size of per-interpreter state of the module,
                 or -1 if the module keeps state in global variables. */
    SpamMethods
};

PyMODINIT_FUNC
PyInit_spam(void)
{
    return PyModule_Create(&spammodule);
}

Finally, here is my include.h file:

#if defined(_MSC_VER) && defined(_DEBUG)
#undef _DEBUG
#include <Python.h>
#define _DEBUG 1
#else
#include <Python.h>
#endif

So when I debug the C++ project as a startup project, I can set (and hit) breakpoints in the main.cpp. When I try to run the code with PythonApplication as a startup project, I can use breakpoints in my Python code until I activate Native debugging, then the symbols for the C++ project do not get loaded, the program runs and prints the result and ends, but does not hit any breakpoints in Python or C++. Any ideas what I'm missing?

**My original text: **

I've built the code with debug info, etc., and enabled Native debugging in the Python project in VS 2022, and when I run the code with debugging, the break points in the C++ don't get hit. (The pdb, pyd, lib, and exp files should have the extension project_name.cp310-win_amd64.pdb for Python 3.10-64, right?)

I can also see that it doesn't load the Symbols for my 4 C++ projects (Screenshot of the loaded modules after pausing the debugging while running the code): Print screen when paused debugging with Python 3.10-64

Compared to the list of modules when I run the project with Python 3.7.0:

Print screen when paused debugging with python 3.7.0-32

I've tried to run the project in vscode but I can't get it to load the debugging there either. Any suggestions on how to get the symbols loaded?


Solution

  • Woho! I finally figured it out. The issue was connected to the venv. Running from the global Python works but if you need to run it from a venv you need to create it with --symlinks like this C:\Python310-64\python.exe -m venv venv --symlinks. You also need to run this command as administrator in the cmd or from PowerShell to get it to work!