[Native]: visualCpp pdb's incompatible with binaries

I’ve been having problems getting a debuggable executable for the visualCpp toolchain. For generating debug info, I have tried both the /Zi and /Z7 compiler options to no avail. In all cases, attempting to run the built executable with the Visual Studio debugger, I’m getting the warning:

Debugging information for "project-x.exe" cannot be found or does not match.
Binary was not built with debug information.

My initial hypothesis was that, since originally I was building using /Zi, and the library PDB files are getting put together in a separate directory from the directory used to link together the executable, that the difference in paths for these two operations was making the debug info to be mismatched.

But, on that hypothesis, I went back and built all dependencies using /Z7 instead, but I’m still getting the same error.

Is anyone else having this same problem? How do I fix it?

@Kevin2: have you run into this?

I believe you should be using /Zi and /Fd. The resulting PDB file should be located in the same directory as the EXE before you attach Visual Studio to the process.

I was using /Zi and /Fd previously. But, gradle generates the PDB’s for libraries and executables in different folders under the build/objs folder, and then creates the executable file in yet a third different directory, under build/exe.

I can inspect the options provided to each compilation step and see that /Zi and /Fd were correctly specified and passed in, but when I first copy all PDB’s and runtime dependencies into the same directory as the executable, I get this error when attempting to run in the debugger.

Are you able to successfully debug from within Visual Studio using the solution file generated by gradlew <component>VisualStudio?

I have not yet invested a lot of time into using the Visual Studio plugin. However, have you looked solution and project files that Gradle generates? I didn’t think the Visual Studio plugin translated the software model into different build configurations. You may have to create the build configurations manually for Visual Studio using the plugin.

<Project>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DEBUG|Win32'">
    <ClCompile>
      <!-- Compiler options here -->
    </ClCompile>
    <Link>
      <!-- Linker options here -->
      <ProgramDatabaseFile>C:\path\to\file.pdb</ProgramDatabaseFile>
    </Link>
  </ItemDefinitionGroup>
</Project>

The generated solution files do create different configurations that match the platform/build-type settings in the build script. The generated project files use nmake to forward build requests to gradle so there aren’t multiple places where compile/link settings have to be managed.

@kevin2: if you haven’t looked into using the visual studio files generated by gradle, have you been able to successfully get debug executables and PDB files produced by gradle to work with the Visual Studio debugger?

@Daniel_L: I’ve created the simplest possible executable project with no dependencies, including both a release and debug variant. I’ve ensured that compiler options to produce debug information for the executable are getting passed to the compiler.

However, when I load the solution files generated by the <component>VisualStudio task, set a breakpoint, set the starting project to point to the executable produced by gradle under build/exe/component/windows_x86/debug and attempt to run the executable in the debugger, Visual Studio complains that the executable was not built with debug information.

But, I know this is false, because I can see the command line arguments passed to the compiler, and I can see the options for generating debug information getting passed in correctly.

Any ideas? It doesn’t seem to matter whether I compile with /Zi or /Z7, I get the same result.

I pretty sure I know what is the problem.

The Visual Studio solution/project files generated by VisualStudio is only used for the IDE capability of VS. It setup the project file in such a way that you can use VS with Gradle as if it was a ordinary VS project. That’s for development only (coding and debugging). As soon as VS wants to build, it will invoke Gradle and let it do his things just as you would invoke in through the command line. Any modification to the VS project file for compiling/linking is useless as Gradle doesn’t receive any information from VS.

Gradle native compilation tries to be as verbose as possible and, to do so, Gradle always do the compilation in two step, first the compilation (cl.exe) then linking (link.exe). The side effect of this is every flag specified to the compiler won’t be propagated to the linker automatically (by default). Compiler and linker flags needs to be align with what you want to do.

In your case, you are using /Zi option to produce a PDB. This is a compiler flag and will effectively generate the PDB for the .o files. In order to enable debugging in the final binary, you also need to specify the /DEBUG flag on the linker. This will fill in the Debug Directory of the PE and will enable VS to find the PDB and use it. Without the /DEBUG flag on the linker, all you are going to have is PDB information for the .o which can be used by any other project that would want to use those .o and link with /DEBUG.

I hope this is clear, don’t hesitate to ask me more question.

1 Like

Sheesh. Sure enough that was it. I mistook my cppCompiler.define 'DEBUG' for the linker config.

Thanks!