PDB debug symbols not loaded during hotload - c++

I'm trying to implement hot reloading for a C++ app that loads a DLL dynamically.
When the app runs (in debug mode), it will copy the DLL and associated PDB to an intermediate directory, and load that.
This is so that in subsequent compiles, the original files can be overwritten.
Since DLLs store the path to their PDB in the DLL header, the app patches the DLL header to point to the correct PDB.
To make sure the DLL size remains exactly the same, I only override 1 character of the PDB name.
When compiling the DLL, I set the PDB path to something like the following (using the /PDBALTPATH linker flag):
Z:/NGEN/Stage/Tmp/TheName._.pdb
Then, when copying the DLL to the Tmp directory, I patch the name to something like:
Z:/NGEN/Stage/Tmp/TheName.a.pdb
Z:/NGEN/Stage/Tmp/TheName.b.pdb
I verified that the DLLs have the correct patched PDB name after copying, using the dumpbin program.
Now, this works fine when I first run the app; the debug symbols are loaded correctly. However, when I rebuild the DLL (in another instance of MSVC) and the app loads the new DLL, MSVC doesn't load the debug symbol of the new DLL.
Instead, I get a message that different versions of the symbols have already been loaded.
Why does MSVC not load the PDB associated with the second DLL?

For your reference: Why does Visual Studio require debugger symbol files to exactly match the binary files that they were built with?
an internal time-stamp will be different. But even disregarding that,
the actual layout of the code could be
different.

Related

How do I control c++ DLL debug symbols loading?

I have an EXE application running in debug mode that loads a DLL at runtime.
When I load the dll it automatically loads the dll's debug symbols for it.
But when I call FreeLibrary() on the dll the symbols won't get unloaded.
That is a problem for me because I use cl.exe to rebuild the DLL while the EXE is running so it needs to be freed and unloaded before I rebuild it.
here is the visual studio runtime debug console output when I load and unload the DLL
'Editor.exe' (Win32): Loaded GameAssembly.dll'. Symbols loaded. <--- automatically loads the symbols when I load the dll
'Editor.exe' (Win32): Unloaded GameAssembly.dll' <--- Dosen't unload the symbols (I know so because when I try to rebuild the dll I get the error (LNK1201 error writing to program database 'GameAssembly.pdb'; check for insufficient disk space, invalid path, or insufficient privilege)
and the functions I use to load and free the dll:
m_DLL = LoadLibraryA("GameAssembly.dll");
FreeLibrary((HMODULE)m_DLL);
now I want a way to unload the symbols when I free the dll, Any idea on how it's done ?
The symbols are not loaded in the app itself, they are loaded in Visual Studio's debugger. The good news is that what you are trying to do works just fine as long as you are not debugging the application.
Unfortunately, there is no way to unload symbols from a debugging session (as far as I know).
One way to fix this would be to tell Visual Studio to simply not load those symbols in the first place. You can do that from the modules window. However, this will prevent you from debugging GameAssembly.dll.
So the only alternative is to not be debugging when you rebuild/reload the dll. To do this, you have to create multiple debugging sessions for a single run of your app. Here's how you go about it
Start debugging the application as you normally would.
When you want to rebuild the dll:
Unload the dll
Detach the debugger by using Debug -> Detach All
Rebuild the DLL
Restart debugging the app by using Debug -> Attach to process
Reload the DLL
The order of the steps can be swapped around a bit, of course. As long as you detach before rebuilding, and don't reload the dll until after the build is done, you should be ok.

Remote DLL Debugging from ctypes in Visual Studio

I'm making a dll for python using c++ and importing functions using ctypes library.
I know that to do remote debugging you go to Debug -> Attach to Process.
I put a breakpoint in python code before imported function is called, but I don't know what process to attach to. I tried attaching to python.exe, but that didn't work.
What process should I attach to or do I need to do remote debugging differently and if so then how?
Thanks
The process which need to be attached to is the process that needs to call the dll. If you want to remote debug dll, I suggest that you could refer to this link about Remote Debugging a C++ Project in Visual Studio. Also, you could refer to this link about Debug DLLs in Visual Studio.
I suggest that you could look in the modules windows. There are several situations:
1.No Symbols have been loaded for this document
Go to the Modules window (Debug > Windows > Modules) and check whether your module is loaded.
If your module is loaded, check the Symbol Status column to see
whether symbols have been loaded.
a.If symbols are not loaded, check the symbol status to diagnose the issue. From the context menu on a module in the Modules window, click Symbol Load Information... to see where the debugger looked to try and load symbols. For more information about loading symbols, see Specify Symbol (.pdb) and Source Files.
b.If symbols are loaded, the PDB does not contain information about your source files. These are a few possible causes:
If your source files were recently added, confirm that an up-to-date version of the module is being loaded.
It is possible to create stripped PDBs using the /PDBSTRIPPED linker option. Stripped PDBs do not contain source file information. Confirm you are working with a full PDB and not a stripped PDB.
The PDB file is partially corrupted. Delete the file and perform a clean build of the module to try to resolve the issue.
If your module is not loaded, check the following to find the cause:
a.Confirm that you are debugging the right process.
b.Check to see that you are debugging the right kind of code. You can find out what type of code the debugger is configured to debug in the Processes window (Debug > Windows > Processes). For example, if you are trying to debug C# code, confirm that your debugger is configured for the appropriate type and version of .NET (for example, Managed (v4*) versus Managed (v2*/v3*) versus Managed (CoreCLR)).
2.… the current source code is different from the version built into...
You could go to Debug > Options and Settings. On the Debugging/General page, clear the Require source files that exactly match the original version option. Make sure to reenable this option when you are finished debugging.
In addition, it may be that the dll has not been loaded into the .exe. You could set Properties->Debugging->Working Directory.

VS2015 "no symbols loaded for this document" for .lib file

I have an issue where I have a .dll file that is compiled in debug. It statically links with a .lib file, which is also compiled in debug. The source is available for all of them. However when I run the .dll and attach VS to the process it can only step through the .dll's own function but not the ones in the .lib.
In the module view I can see that symbols are loaded for all the modules. How can ensure that .lib has symbols associated with it as well? As I understand because it is linked statically the symbols for it should be generated when compiling the "parent" .dll, is that correct? So is there something I need to do when building the .dll to make sure that ALL functions can be stepped through?
You need to add the location of the pdb file of the LIB you just built for the debugger to find the symbols in the appropriate Tools/Options section (usually the same directory as the output LIB).
Then, you can add the location of the source files in the according Solution Property page :
Then, Visual Studio debugger will find all appropriate information. It will load symbols and be able to jump into the LIB source code when appropriate.

Is it possible to debug into a DLL with only a PDB and no source code?

I'm trying to debug an exe that calls a dll, in Visual Studio. I made sure I had the corresponding pdb in the same path as the dll.
But I cannot get into the functions that the dll is offering.
I get a message that says "xyz.c was not found"
Why am I getting this message?
Does this mean that I can't get into the source code just from a DLL + .PDB?
What about a static library (.lib) built using the /Z7 option?
No, you need to have source code to be able to see the source code.
pdb (or /Z7) contains debug information which is like mapping between executable code and your source code. With pdb VS debugger knows where in source files each instruction is located, but it still needs to have source files to show you the code.
Usually pdb file stores location of source files and VS debugger knows where to find them. If you move src files somewhere else then AFAIK VS will show a popup dialog to browse for .c/.cpp file that it cannot find.
Yes, you need the source code to source debug. The .PDB only contains symbols so you will be able, for example, to view a stack trace or determine the source file name and line number of a crash. Otherwise, you need the source code.

Injected DLL can't use Symbols pdb unless it's in the same directory as build

I have an issue where I'm trying to selectively distribute my pdb(symbol) file so I can have users give me more detailed crash reports.
So... my DLL is injected into another exe (in another folder). And from everything I've tested, my PDB file has to be located in the exact same directory on the users machine that it is on my machine for it to be found correctly.
IE... When I build I place the PDB in C:\PDB\Mypdb.pdb
If the user creates the exact folder and places the pdb there, the injected dll will show him line numbers on crash. However, if he places the mypdb.pdb with the dll, or with the target of the injection, they receive nothing in terms of symbols.
Any ideas on how I can force my DLL to use a symbols file at a custimizable location?
This is because by default the linker uses an absolute path to the location where it generates PDB file and stores it in the DLL itself. You can change the path to the PDB file by passing the /PDBALTPATH option and a relative path to the linker.