How can I remove all debug & personal info from an executable? [duplicate] - c++

I use to take always a look at the final binary executable or DLL after debugging and creating a file with any IDE. Now I am trying Visual C++ 2010, in the search for the best release, without trash or unnecessary references.
So, I created a new solution with two projects: an executable and its DLL. VC++ created a lot of intermediary files between the code and the final file. I opened the .exe and the .dll with a hexadecimal editor and saw something that I don't like. Somewhere inside the file there's an absolute path to the .PDB file.
Why? How can I remove it from VC++?
There must be some pre-processor command for this. What is the use of an absolute path to a .PDB file, like "D:\My Projects\Project1\Release\Project1.pdb" inside the binary of a file that will be distributed on computers with different folders? Besides that, I don't like to see one of my drive's paths saved inside a binary file that I want to share with other people. I am in Release mode, I don't see the use of that unnecessary information. How could I remove it?

You can use /pdbpath:none (or /pdbaltpath:%_PDB% on newer versions of link.exe) to remove the full qualified path name of the PDB file, but keep the name and extension of the PDB only. Keeping the name (and extension) of the PDB for released images is your only way to debug an image that is buggy. Windows images almost always keep the name and extension of the PDBs!

Read the PDB Files documentation on MSDN:
A program database (PDB) file holds debugging and project state information that allows incremental linking of a Debug configuration of your program. A PDB file is created when you compile a C/C++ program with /ZI or /Zi or a Visual Basic/C#/JScript .NET program with /debug.
In Visual C++, the /Fd option names the PDB file created by the compiler. When you create a project in Visual Studio using wizards, the /Fd option is set to create a PDB named project.PDB.
Note that the absolute path is mentioned in the documentation:
The Visual Studio debugger uses the project.PDB file created by the linker directly and embeds the absolute path to the PDB in the EXE or DLL file.
You can always go to Project Properties > Linker > Debugging > Generate Debug Info and set it to No.

If you you cannot rebuild your module (i.e. using the linker switch /PDBPATH:NONE which Microsoft seems to have removed support for), I wrote the peupdate tool for this purpose, as long as you don't mind using a 3rd-party tool. Peupdate can be used to list, remove or change the PDB string in an executable module. Below are some examples:
peupdate -c <module_path> //clear entire PDB path
peupdate -k <module_path> //remove PDB path, but retain filename
peupdate -u <newpath> <module_path> //set your own path string

To remove the path of the PDB file out of the EXE file without loosing debug info, you could embed the PDB file inside the EXE file.
Properties => Build => Advanced (Build Settings) => Debuginfo => Embedded

Related

Attaching .pdb to a compiled .exe in Visual Studio 2022

I am trying to debug a .exe file with a .pdb. The project is using SCons, and here is the part where it compiles in sconstruct:
env.Append( CCFLAGS=["/EHsc"])
env.Append( CCFLAGS=["/DEBUG", "/Zi", "/Fdgame.pdb"])
env.Program('game', ['game.cpp', Glob('feather/*.cpp')], LIBS=['SDL2', 'SDL2_image', 'SDL2_ttf', 'SDL2_mixer', 'SDL2main'], LIBPATH='lib/Windows/lib')
So I'm adding the flags that are correct (I think) to generate the .pdb. The pdb shows up in my project directory, in the same location where the .exe is. After looking at its contents, I'm pretty sure that it has the correct information to work (at least, it is not empty). I am setting game.exe as the startup item, then running it from VS 2022. However, after running the .exe, Visual Studio claims that the "Binary was not built with debug information."
Modules tab showing this message under "Symbol Status."
According this page on the Microsoft VS documentation, it says:
The debugger searches for symbol files in the following locations:
The project folder.
The location that is specified inside the DLL or the executable (.exe) file. By default, if you have built a DLL or an .exe file on
your computer, the linker places the full path and filename of the
associated .pdb file in the DLL or .exe file. The debugger checks to
see if the symbol file exists in that location.
The same folder as the DLL or .exe file.
My .pdb should fulfill conditions 1 and 3, so I'm confused as to why it can't be found (if that's the issue). The docs do mention that this applies when you build a project, but I've seen other video tutorials online where they just attach .pdbs to running processes and it still works. Is there anything I'm missing?
Try changing to
env.Append( CCFLAGS=["/EHsc"])
env.Append( CCFLAGS=["/DEBUG", "/Zi"])
env.Program('game',
['game.cpp', Glob('feather/*.cpp')],
LIBS=['SDL2', 'SDL2_image', 'SDL2_ttf', 'SDL2_mixer', 'SDL2main'],
LIBPATH='lib/Windows/lib', PDB="game.pdb")
If that's still not in the correct location then change to
PDB="${TARGET.dir}/game.pdb"
See the manpage for info on the PDB environment variable:
https://scons.org/doc/production/HTML/scons-man.html#cv-PDB

What does it mean for a C++ error to say a "Symbol file could not be found"? [duplicate]

I copied an existing project and renamed the folder. Now I get this error when I try to compile the application
debugging information cannot be found or does not match. No symbols loaded.
Do you want to continue debugging ?
If I click yes, it compiles and runs fine. But now I have to deal with that message. Just curious about what I change in the projects properties to get it to stop.
You probably have deactivated the debugging information for your project:
Right click on your project -> Properties
Configuration properties -> Linker -> Debugging
Switch "Generate Debug Info" from No to Yes
Rebuild your project and retry, it should now run without the message :)
The main reason is that you don't have a matching pdb and exe.
Some possible solutions:
You are compiling in release instead of debug
You need to clean/build or rebuild
You don't have your pdb files being generated in the same directory as the exe
You have a mismatching pdb, maybe the copied source is newer than today's date and something isn't building properly.
Try cleaning out all debug object files
You are attaching to a process that you started from a different location from where your build exe and pdb exist
Restart Visual Studio
This happens to me every now and then, while debugging code and making changes it seems like visual studio caches the pdb information and sometimes it gets stuck. Doing a Rebuild solution, deleting the pdb and creating a new one doesn't fix the problem.
Of course I do have the generate debug information on and all that it's needed, specially since this happens while debugging the code several times.
Visual Studio seems to be happy with the in-memory pdb and refuses to update it, regardless of time-stamps or even size changes in the pdb.
The only way to reset this is to exit Visual Studio (the IDE) and restart it again.
In some rare occurrences, the IDE might be still running in the background (process explorer shows it there) and might hold the handle to the file open. You can kill the process before restarting the IDE.
Good Luck
I just encountered this error in VS2012. It is definitely caused by a bug in Visual Studio, which reveals itself in situations when the local PDB file of the main project has the same name as the final PDB file for the entire executable (even if the two are located in different directories!)
Consider this example.
Solution consists of three projects: main, a, and b. main is the top-level project for the executable, while a and b are libraries linked into main.
In all three projects $(IntDir) variable is set to $(SolutionDir)\$(Configuration)\$(ProjectName)\. This means that project main dumps its intermediate files to Debug\main\, project a - to Debug\a\ and so on.
In C/C++ -> Output Files settings all three projects have Program Database File Name value set to $(IntDir)$(TargetName).pdb. This means that project main generates its local PDB file as Debug\main\main.pdb, project b as Debug\b\b.pdb and so on.
Finally, in Linker -> Debugging settings of project main the Generate Program Database File value is set to $(OutDir)$(TargetName).pdb. This means that the global PDB file for the entire executable will be generated as Debug\main.pdb.
Note that in this setup each PDB file is generated in its own, separate directory.
In this setup you will get Debugging information cannot be found or does not match error if you attempt to run the program under the debugger. And if you take a look at the Debug\main.pdb file (which will exist), you will notice that it is exactly the same as Debug\main\main.pdb file! I.e. somehow the local PDB for main managed to overwrite what was supposed to be the global PDB for the final executable. I.e. the debugger is right to complain that the PDB file is "wrong". It is indeed wrong.
Again, in the above setup the final global PDB somehow gets overwritten by local PDB of the top project. I don't know why it happens. It appears to be a bug. (Note that even though these PDB files have the same name, they are generated in different directories, i.e. they should not conflict.)
A workaround that fixes this issue is to give the local PDB of project main a different name. For example, just go to C/C++ -> Output Files for the main project and change Program Database File Name value to $(IntDir)$(TargetName)_local.pdb (or to $(IntDir)12345.pdb if you so desire). This will eliminate the conflict and solve the problem.
Enable PDB creation by:
Right click on MyProject > Properties > Debugging:
C/C++ > General > Debug Information Output = Program Database (/Zi)
Linker > Debugging > Generate Debug Info = Yes (/DEBUG)
Clean MyProject, restart Visual Studio (just to be sure), rebuild MyProject.
The output folder should then contain *.pdb files.
If you debug optimized/release code consider switching off optimization via
C++ > Optimization > Optmization = Disabled (/Od)
I faced the same problem and tried all above mentioned solutions but it couldn't help me.
Then I found a new solution randomly and it worked.
Solution is that,in case you are having many projects in a solution then you should mark any one (specific one which you have to decide) project as a "Set as Startup Project".
Right click on that specific project and click "Set as Startup Project".
It worked for me.
The pdb or Program Database file appears to be missing (basically, the path has changed and can no longer be found by the compiler). See this related post for additional information.
I had a similar problem and the reason was that I had run one of the projects of my solution in a different process and that process couldn't be killed. I didn't think much of it. So when I was building the solution in a separate environment one of the pdb files didn't match so at the end I couldn't load any of the pdb files. I just restarted my computer and that fixed it.
Good luck
Restarting Visual Studio can fix one instance of this problem.
Right click on your project in the solution browser => Clean => Build.
That is if your build generates a .pdb at all (look in your target dir)
If not, you should enable debug by the steps mentioned in other posts
Most probably there are other reasons like .pdb / .exe file mismatch, something were not built / rebuilt, but I had similar case in Visual studio 2013 -
Something to do with virtual inline function - so I suspect.
In my case debugger were jumping in a middle of another C++ function, not the one which was called. Jump was off source code by 11 source code lines, but I cannot explain why much miscalculation happened. By simple rearranging functions I've got rid of this problem.
May be needs more detailed analysis why 11 lines shift happened originally.
Haven't seen this kind of behavior in any other visual studio.
This problem has bothered me for a long time. AnT's anwser is very helpful. The main idea is Don't have any two pdb files have the same name, even they are not in the same directory.
This is my situation: I have tow projects name "FooBar" and "FooBarDll", the first one is an exe, and the second one is a dll. I set both projects Target Name to be "FooBar", so that they will generate "FooBar.exe" and "FooBar.dll" respectively.
Then I set
"General -> Intermediate Directory" to be "$(OutDir)\$(ProjectName)\"
"C/C++ -> Output Files -> Program Database File Name" to be "$(IntDir)$(TargetName).pdb"
"Linker -> Debugging -> Generate Program Database File" to be "$(OutDir)$(TargetName).pdb"
So I get these files:
Debug\FooBar.exe
Debug\FooBar.pdb //C++ pdb
Debug\FooBar\FooBar.pdb //Linker pdb
Debug\FooBar.dll
Debug\FooBar.pdb // C++ pdb again!
Debug\FooBarDll\FooBar.pdb // Linker pdb
My solution is replacing every "TargetName" with "ProjectName", then I will get:
Debug\FooBar.exe
Debug\FooBar.pdb //C++ pdb
Debug\FooBar\FooBar.pdb //Linker pdb
Debug\FooBar.dll
Debug\FooBarDll.pdb // C++ pdb
Debug\FooBarDll\FooBarDll.pdb // Linker pdb
Then there is no conflict!
Give C/C++ pdb a suffix may be better, like: "C/C++ -> Output Files -> Program Database File Name" to be "$(IntDir)$(ProjectName)_C.pdb"
I had the same issue, and this link helped me solved the problem, by rename "symsrv.no" to "symsrv.yes" in VS IDE folder.
Curious, it happens to me that I needed to change the folder name from:
...\Custom Librarry (MyDll.dll(
to
...\Custom Librarry (MyDll.dll)
just by closing the parenthesis it worked !

VSPerf VS2010 and other profiling tools not picking up pdb

trying to profile with VSPerfCmd (VS2010 profiler), and also with Intel VTune Amplifier XE 2013: some results are available, for VsPerfCmd in .vsp file. However, profier is not picking up pdb. no code is available for some parts of the application.
Did this happened to you already, and do you know if some compiler options should be turned on so as to get complete profile?
in which directory does profiler go to find .pdb info ?
thanks
The profilers and debuggers on Windows by default look up the PDB files by the path written in the executable. So the first thing to do is to open the executable in some hex editor and search for ".pdb" string and check whether file mentioned there exists on disk. If that is not the case, check that you specify /Zi or /ZI option to the compiler and /debug option to the linker.
If symbolic names are missing for SOME parts of the application, check whether those parts are separate dynamic or static libraries and whether you generate debug information for those. In case of static libraries it's easy to get the debug information lost along the linking way since by default /Zi flag embeds the debug information into the vc*.pdb file (e.g. vc90.pdb for VS 2008) and that file is usually not exported into SDK by build systems. For static libraries I personally find the most instrumental to use /Z7 option for debug information since that embeds it into the object files themselves and then to the *.lib file and then it propagates to the final *.exe / *.dll binary's PDB file.

Debug in VS C++ with dll, pdb files and source

A question about pdb file. Is pdb file for debugging in Visual Studio? If so, why do they also exist in my Release folder? It's normal that pdb files are in Debug folder, but why they are also in Release folder.
So I have now a Release folder build by Integration team with all the pdb files. Now I can load all the corresponding source (in GIT) so I'm sure that the binaries correspond to the source. Then do I need to build again in order to debug in Visual Studio? If not, what I have to do in order to get thing done quickly?
As mentioned above, PDBs are as much important as release binaries! Once a software is released, you can debug it afterwards (depending on whether public and private symbols are available). Should the PDBs contain private symbols, please keep in mind that these describe your code (parameters, types, return values, symbols...). Here an article explaining the logical link that exists between an executable and its PDBs.
Actually you can debug your release build too - if you have the PDB files. So it's a good idea to keep the PDB files of your shipped product (release build).
For debugging you need the executable and the matching PDB and the matching source files. That's it.
You can debug a release build as well, it's just that it's not that useful because of all the extra optimizations. If you don't want a pdb file, you can specify it in the project properties for the release build.
Is pdb file for debugging in Visual Studio?
YES.
why do they also exist in my Release folder?
Go to "your project" Property Page (target release) -> Linker -> Debugging.
Set the option Generate Program Database File. i.e. Release/myExe.pdb

debugging information cannot be found or does not match visual studio's

I copied an existing project and renamed the folder. Now I get this error when I try to compile the application
debugging information cannot be found or does not match. No symbols loaded.
Do you want to continue debugging ?
If I click yes, it compiles and runs fine. But now I have to deal with that message. Just curious about what I change in the projects properties to get it to stop.
You probably have deactivated the debugging information for your project:
Right click on your project -> Properties
Configuration properties -> Linker -> Debugging
Switch "Generate Debug Info" from No to Yes
Rebuild your project and retry, it should now run without the message :)
The main reason is that you don't have a matching pdb and exe.
Some possible solutions:
You are compiling in release instead of debug
You need to clean/build or rebuild
You don't have your pdb files being generated in the same directory as the exe
You have a mismatching pdb, maybe the copied source is newer than today's date and something isn't building properly.
Try cleaning out all debug object files
You are attaching to a process that you started from a different location from where your build exe and pdb exist
Restart Visual Studio
This happens to me every now and then, while debugging code and making changes it seems like visual studio caches the pdb information and sometimes it gets stuck. Doing a Rebuild solution, deleting the pdb and creating a new one doesn't fix the problem.
Of course I do have the generate debug information on and all that it's needed, specially since this happens while debugging the code several times.
Visual Studio seems to be happy with the in-memory pdb and refuses to update it, regardless of time-stamps or even size changes in the pdb.
The only way to reset this is to exit Visual Studio (the IDE) and restart it again.
In some rare occurrences, the IDE might be still running in the background (process explorer shows it there) and might hold the handle to the file open. You can kill the process before restarting the IDE.
Good Luck
I just encountered this error in VS2012. It is definitely caused by a bug in Visual Studio, which reveals itself in situations when the local PDB file of the main project has the same name as the final PDB file for the entire executable (even if the two are located in different directories!)
Consider this example.
Solution consists of three projects: main, a, and b. main is the top-level project for the executable, while a and b are libraries linked into main.
In all three projects $(IntDir) variable is set to $(SolutionDir)\$(Configuration)\$(ProjectName)\. This means that project main dumps its intermediate files to Debug\main\, project a - to Debug\a\ and so on.
In C/C++ -> Output Files settings all three projects have Program Database File Name value set to $(IntDir)$(TargetName).pdb. This means that project main generates its local PDB file as Debug\main\main.pdb, project b as Debug\b\b.pdb and so on.
Finally, in Linker -> Debugging settings of project main the Generate Program Database File value is set to $(OutDir)$(TargetName).pdb. This means that the global PDB file for the entire executable will be generated as Debug\main.pdb.
Note that in this setup each PDB file is generated in its own, separate directory.
In this setup you will get Debugging information cannot be found or does not match error if you attempt to run the program under the debugger. And if you take a look at the Debug\main.pdb file (which will exist), you will notice that it is exactly the same as Debug\main\main.pdb file! I.e. somehow the local PDB for main managed to overwrite what was supposed to be the global PDB for the final executable. I.e. the debugger is right to complain that the PDB file is "wrong". It is indeed wrong.
Again, in the above setup the final global PDB somehow gets overwritten by local PDB of the top project. I don't know why it happens. It appears to be a bug. (Note that even though these PDB files have the same name, they are generated in different directories, i.e. they should not conflict.)
A workaround that fixes this issue is to give the local PDB of project main a different name. For example, just go to C/C++ -> Output Files for the main project and change Program Database File Name value to $(IntDir)$(TargetName)_local.pdb (or to $(IntDir)12345.pdb if you so desire). This will eliminate the conflict and solve the problem.
Enable PDB creation by:
Right click on MyProject > Properties > Debugging:
C/C++ > General > Debug Information Output = Program Database (/Zi)
Linker > Debugging > Generate Debug Info = Yes (/DEBUG)
Clean MyProject, restart Visual Studio (just to be sure), rebuild MyProject.
The output folder should then contain *.pdb files.
If you debug optimized/release code consider switching off optimization via
C++ > Optimization > Optmization = Disabled (/Od)
I faced the same problem and tried all above mentioned solutions but it couldn't help me.
Then I found a new solution randomly and it worked.
Solution is that,in case you are having many projects in a solution then you should mark any one (specific one which you have to decide) project as a "Set as Startup Project".
Right click on that specific project and click "Set as Startup Project".
It worked for me.
The pdb or Program Database file appears to be missing (basically, the path has changed and can no longer be found by the compiler). See this related post for additional information.
I had a similar problem and the reason was that I had run one of the projects of my solution in a different process and that process couldn't be killed. I didn't think much of it. So when I was building the solution in a separate environment one of the pdb files didn't match so at the end I couldn't load any of the pdb files. I just restarted my computer and that fixed it.
Good luck
Restarting Visual Studio can fix one instance of this problem.
Right click on your project in the solution browser => Clean => Build.
That is if your build generates a .pdb at all (look in your target dir)
If not, you should enable debug by the steps mentioned in other posts
Most probably there are other reasons like .pdb / .exe file mismatch, something were not built / rebuilt, but I had similar case in Visual studio 2013 -
Something to do with virtual inline function - so I suspect.
In my case debugger were jumping in a middle of another C++ function, not the one which was called. Jump was off source code by 11 source code lines, but I cannot explain why much miscalculation happened. By simple rearranging functions I've got rid of this problem.
May be needs more detailed analysis why 11 lines shift happened originally.
Haven't seen this kind of behavior in any other visual studio.
This problem has bothered me for a long time. AnT's anwser is very helpful. The main idea is Don't have any two pdb files have the same name, even they are not in the same directory.
This is my situation: I have tow projects name "FooBar" and "FooBarDll", the first one is an exe, and the second one is a dll. I set both projects Target Name to be "FooBar", so that they will generate "FooBar.exe" and "FooBar.dll" respectively.
Then I set
"General -> Intermediate Directory" to be "$(OutDir)\$(ProjectName)\"
"C/C++ -> Output Files -> Program Database File Name" to be "$(IntDir)$(TargetName).pdb"
"Linker -> Debugging -> Generate Program Database File" to be "$(OutDir)$(TargetName).pdb"
So I get these files:
Debug\FooBar.exe
Debug\FooBar.pdb //C++ pdb
Debug\FooBar\FooBar.pdb //Linker pdb
Debug\FooBar.dll
Debug\FooBar.pdb // C++ pdb again!
Debug\FooBarDll\FooBar.pdb // Linker pdb
My solution is replacing every "TargetName" with "ProjectName", then I will get:
Debug\FooBar.exe
Debug\FooBar.pdb //C++ pdb
Debug\FooBar\FooBar.pdb //Linker pdb
Debug\FooBar.dll
Debug\FooBarDll.pdb // C++ pdb
Debug\FooBarDll\FooBarDll.pdb // Linker pdb
Then there is no conflict!
Give C/C++ pdb a suffix may be better, like: "C/C++ -> Output Files -> Program Database File Name" to be "$(IntDir)$(ProjectName)_C.pdb"
I had the same issue, and this link helped me solved the problem, by rename "symsrv.no" to "symsrv.yes" in VS IDE folder.
Curious, it happens to me that I needed to change the folder name from:
...\Custom Librarry (MyDll.dll(
to
...\Custom Librarry (MyDll.dll)
just by closing the parenthesis it worked !