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.
Related
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
When building a static library (.LIB) in MS Visual Studio 10 with debug information,
the .PDB is always named vc100.pdb.(as opposed to building a .DLL, where the debug info is [MyProjectName].pdb)
This is a problem for me because I'm trying to copy several different libraries (and their debug symbols) to a directory of "PublishedLibraries", but all the vc100.pdb names obviously collide.
I'm sure I can change the names of each .PDB to match its .LIB, but for me the bigger question is why does Visual Studio think vc100.pdb is a better name than projectA.pdb??How are we intended to work with Debug Info from multiple libraries if all the names conflict?
If you use /Z7 (instead of /ZI or /Zi) [ in the UI C/C++ -> General -> Debug Information Format] then the debug information is embedded in the lib file itself, instead of a separate pdb, which means you don't need to worry about the same name.
When you build your final executable (.exe or .dll) then you'll get a merged pdb from all the little embedded pdbs.
see this question for more info
Its the way I've always managed this issue on my team, as you can't lose the debug information during the build process. It bloats the libs somewhat [but no more in total than having both lib and pdb], but as you probably don't ship libs you shouldn't worry to much about this.
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
In VS2010 there is an option to generate debug info for exes/dlls under linker but no such option under librarian for libs. Is the debug info embedded in the static library?
There is an option in the C/C++ properties for Program Database File Name for libs, exes, and dlls. By default it goes into my intermediate directory and is named the project name for libs, but is named vc$(PlatformToolsetVersion).pdb for exes/dlls. What's the pdb from this option and how does it differ from the pdb in the linker option?
If I am supplying a library with libs and headers how do I supply debug symbols to a user of my library?
If you use /ZI or /Zi (C/C++ -> General -> Debug Information Format), then the vc$(PlatformToolsetVersion).pdb is created, which contains the debug info for all of the .obj files created. If alternately you use /Z7, the debug info will be embedded into the .obj file, and then embedded into the .lib. This is probably the easiest way to distribute the debug info for a static library.
I wouldn't advise distributing a static library, however, since it's generally tied to a specific version of the compiler.
Expanding upon previous answers, for those who need the full how-to (VS 2013 minimum).
Note that this should address comments ^^above regarding VS2013 issues.
Method 1: The Program Database (.pdb) Way (/Zi or /ZI)
Static Lib Project: Generate a pdb with same name as your static lib:
Open Solution Explorer from the View menu.
Right click your static lib project, select Properties
Edit Configuration Properties->C/C++->General->Debug Information to /Zi or /ZI
Note that /ZI allows "Edit and Continue" editing during debugging
Edit Configuration Properties->C/C++->Output Files->Program Database File Name to $(OutDir)$(TargetName).pdb
Now compile it, and note where YourLib.lib and YourLib.pdb are.
Application Project: Link your executable with the static lib, and new PDB file:
Again, navigate to project properties, but this time, for your Application project
Again, edit Debug Information property as needed.
Edit Configuration Properties->Linker->General->Additional Library Directories, adding your own "libs" directory, or whatever directory you plan to keep/copy your YourLib.lib and YourLib.pdb files.
Edit Configuration Properties->Linker->Input->Additional Dependencies, adding YourLib.lib (no path in front)
Now copy both YourLib.lib and YourLib.pdb to the directory you specified above.
Method 2: The Embedded Symbols (no .pdb) Way (/Z7)
Static Lib Project: Generate a static lib with embedded debug symbols
As in Method 1, navigate to project properties
As in Method 1, modify your Debug Information, but this time to/Z7
As in Method 1, compile and note where YourLib.lib is generated.
Application Project: Link you executable with the static lib
As in Method 1, navigate to project properties
As in Method 1, modify your Debug Information property as needed
As in Method 1, edit Additional Library Directories
As in Method 1, edit Additional Dependencies
Now copy YourLib.lib to the directory specified in Additional Library Directories
Discussion:
Advantages of Z7? It's simpler, and the "Single-file" way of doing it. All the debug info is in the lib file.
Disadvantages of Z7? File size on-disk, link times, incompatible with "Minimal rebuild" (/Gm) feature, does not allow "Edit and Continue", older format (e.g. older paradigm)
Why don't I specify Debug Information Setting for Application Project? This post is concerned with how to get debug working in static lib code. The same "Method 1 vs Method 2" choice applies for the Application project as well.
I notice in VS2013 it is possible to set the program database file name in the C/C++ Output Files tab. Changing it from the default to something like $(OutDir)$(TargetName).pdb resolves the issue
Static libraries are implemented into the programs that use them.
If the program that uses them is using debug symbols, the compiled library code in that program will have symbols too.
PDB info from wikipedia:
When debug symbols are embedded in the binary itself, the file can
then grow significantly larger (sometimes by several megabytes). To
avoid this extra size, modern compilers and early mainframe debugging
systems output the symbolic information into a separate file; for
Microsoft compilers, this file is called a PDB file.
Weird behavior in VS2012. Building from scratch (or with /A option in nmake) will produce a .pdb file. Now delete the .lib and .pdb and rerun nmake (without /A of course, to run only link) and no .pdb file is output.
Visual Studio compiles the projects into dlls as I want it to, but when I inspect these dlls with dumpbin, then they do not have an entry for their pdbs, which is probably the reason why I cannot debug any of those dlls if I load them at runtime and their pdbs are never loaded. How can I get VS to write these paths?
Visual Studio, C++.
Edit:
C++/General/Debug Information format ist set to "Program Database (/Zi)" and Linker/Debugging/Generate Debug Info are on "Yes (/DEBUG)", which I believe are correct.
If dumpbin /headers shows no entry in the Debug Directories, it is probably because you did not enable debug information generation at compile and link time. You should check the C++/General/Debug Information format and the Linker/Debugging/Generate Debug Info options.
If these options are set, you may check if the dll and the pdb in the output directory of Visual match. With the Debugging Tools for Windows, you can use the command symchk /v yourdll /s folder_containing_pdb to verify if the pdb can be found by the debugger engine. It will check if the dll does not contain debug information, in which case you are missing an option in Visual Studio, or if the pdb file is not complete.
You can also use Windbg with the command !sym noisy. See here for detailed instructions.
The pdbs aren't referenced in the dll, they get searched by Visual Studio. If they are in the same directory, it should find them.
You can direct Visual Studio on where to look for your symbols per this article. In summary:
Click Symbol File Path on the File
menu to display, set, or append to the
symbol path.
A more comprehensive overview of how symbols get used is here.
There should be info in the Output window on what happened when your DLL got loaded. Perhaps it's not the version you expected?