Symbols files and debugging - c++

Assume i have a custom service written in VC++ 6.0 and i have shipped it as part of a particular release. Unfortunately i did not take the pdb while building the binary.
At a later point of time my customer reported a crash and i had to get the pdb to identify the crash cause. Will a pdb that i take now be enough to identify the point of crash.
In other words i have taken binary and pdb separately however i did not make any changes to the sourcecode after taking the binary.
My understanding is that even thought he symbols wont match in terms of date and time when they were built but in terms of the content it will match.
Is my understanding correct?

You'll need to make sure you compiled with exactly the same compiler version (patches could change code generation and addresses), set of compiler/linker options, the same library versions as well as the same source to make sure the addresses match. If you're able to do that then you should be able to take a pdb generated later.
However even if it doesn't match exactly it's possible that it gets you close enough to see the bug by inspection.

Yes, that should still work without a problem (though, if memory serves, you can expect a warning about the mismatched time-stamps).

The .pdb and the binary should be able to work together perfectly if the were built from the same source code even if not at the same time. However you will not be able to load this in any debugger. For example, the Visual Studio debugger will refuse to load it because it will say they are mismatched.
You need a debugger that can accept mismatched symbols such as WinDbg. To load with mismatched symbols type the magic command symopt +0x40.

Related

PDB corresponding to a binary

We have different versions of binary kept in SVN. We also keeps the pdb files corresponding to the binaries. Sometimes the developers check-in the wrong pdb files. This creates problems when an issue is reported by a client at a later point.
Is there any tools to check whether a pdb file corresponds to a binary?
Use this tool - ChkMatch. This both checks the match and also allows you to forcefully match(i.e. allow you to use wrong pdbs as long as they are not too different from the actual ones). Read through this page.

How do I analyze a crash dump from a binary built with optimizations enabled (release mode)?

Till now I was using debug mode binaries in project. So it was easy to analyze crash dump using symbol files preserved.
Now i have to ship binaries in Release mode. How we can analyze dump files generated by release mode binary.
Is it possible at all ?
How i identify functions in release mode ? (Do in need to generate and preserve map file)
You need the .pdb file that corresponds to the executable. That'll give you the symbols.
There are a couple tricky parts to debugging a release build:
The order of operations may be off due to optimizations
Whole functions/variables/etc. may be optimized away
In particular, the arguments passed into functions may not exist (for example, 'this' may be a register, not a spot in memory). Windbg is pretty good about getting the stack track from that though, including figuring out the arguments.
There is no need to have MAP files. You need to enable "Generate Debug Info" /DEBUG flag, even for Release build. On VS2008 and higher, the /DEBUG flag is set even for Release builds. On earlier versions you need to explicitly do it.
This will generate .PDB files for your .EXE/.DLL and you must keep them along with your executables/DLLS (You may or may not give to clients, that's your choice). When the crash dump occurs, you should have/get the .DMP file. Just load that DMP file in Visual Studio, from the location where you have stored the PDB files. This will show the call stack where the crash occurred.
If there are multiple threads, you need to switch to 'Threads' window and look for 'Suspended' column. The column having suspended as 1 is the thread that caused the crash.
Using this you can see the proper call stack for ALL running threads. But you will also need to have correct copy of source-code to see the code! Otherwise it would just be assembly. Partial source code of MFC/ATL/STL etc might be visible, but not your code, unless you do have correct source code in place.
PDB files do store the path of source code, and they would enable the debugger to load the source files, even if source is not from the location where you have placed PDB and the DMP file.

Breakpoint not hitting

I ported an application from VC6 to VS 2008. I rebuilt the application in release build. The Pdb file is available in the folder where exe is located. But when I loaded the application and put break point I am getting the following message
"The breakpoint will not currently be hit.No symbols have been loaded for this document"
What would be the cause of the issue?
The debugger could not find either the application or the PDBs.
When you start the program, exactly which binaries are loaded are shown in the Output window. Make sure the right files are being loaded. When everything loads properly, the output looks something like this:
'hacks_vs10.exe': Loaded
'C:\Users\john\Documents\Visual Studio
2010\Projects\hacks_vs10\x64\Debug\hacks_vs10.exe',
Symbols loaded.
When the PDB is not found, instead of saying "Symbols loaded" it says:
Cannot find or open the PDB file
Make sure that you are first running the correct version of your application (check the running path), and then make sure that the PDB is in that directory. You can change where the PDB is generated to by tweaking "Project>Properties...>Linker>Generate Program Database File"
The debugger could not find code associated with the source location you put the breakpoint at.
There can be a number of reasons for this. The one I've most often found was a section of code that was truly not compiled in. (either because of preprocessor conditionals or dead-code removal).
I imagine there can be other reasons too (e.g. inlining, though in theory, the compiler could generate the proper mapping for all the inlines. I don't know what VS2008 does here).
Are you sure you're putting the breakpoint in a code path that is supposed to be executed ?
The PDB file you mention is probably not related to the release build,
Debug information is normally absent in the release build (though you can enable it if you have to but should anticipate surprising effects due to compiler optimizations).
Therefore, you can only set breakpoints on known DLL entry points (possible via the Module List view - it has been a while since I used Visual Studio intensively) or directly on assembly instructions.
Note that you could perhaps compile part of your application with debug symbols.
I have just solved a similar problem
I re-referenced all my DLL's
went to (Tools->Options, "Projects and Solutions", "Build and Run") and set "On Run when projects are out of date" to 'Prompt to build'
I'm not sure which of these fixed the problem, but it did!

What's a practical use of .PDB files?

I have been reading about PDB files and how they have to do with debugging but why would I want to keep a pdb file after I ship? If there is a problem, I can just debug on my machine. What am I missing?
PDB files contain debugging information. If you keep them around at least for released versions of your software, you can debug any crashes a customer may have. You don't need to send them the PDB, simply have them collect a crash dump (.dmp) using Windows. Then, you can open up the dump in for example WinDbg and debug the issue.
To be able to properly debug, you need the symbols which are maintained in the PDB file. PDB can also be kept for release builds.
The reason it is recommended to keep PDBs is so that entire projects need not be rebuilt once again which is actually a multi day process typically on a build server. In very large projects this could be very cumbersome. Maintaining PDBs will help you to retrieve the binaries and symbols quickly from the SCM and bugs filed (if any) can be resolved faster.
We live and die by our PDB's when reconstructing, or debugging, customer crashes at my job. I have checked out crash dump files for binaries that were years and years old. Thank goodness we kept our PDB's over all those years. Without PDB's you are just going to kiss your time goodbye as you spend months debugging one crash dump. Whereas if you do have PDB's than it becomes very easy to navigate the stack while debugging a minidump.
And be sure to keep a copy of the source that corresponds with the binaries and PDB's. It's nice to use version control for that. But sometimes you don't always have that luxury for aligning everything.
.pdb files can be shipped to the customer to get accurate stack traces. Without the .pdb, all your stack traces just contain memory addresses and it's a pain to work out "manually" which functions those addresses correspond to. If you have the .pdb files, though, the debugger can reconstruct the stack trace with symbols and it makes life much easier.
Also, sometimes you can't reproduce a problem on your machine, and the only way to see what's wrong is to debug the customer's machine. It depends on your particular relationship with the customer whether that's possible, of course...

Visual C++ 2008 'Release' build contains debug information

I've noticed that when generating a new C++ project using MS Visual Studio 2008, the Release build contains debugging symbols - specifically the following settings are enabled:
The C++/General/Debug Information Format is set to Program Database.
The Linker/Debugging/Generate Debug Info setting is set to Yes.
I have never noticed this on earlier releases of Visual Studio.
So, other than generating a larger EXE file, is there any downside to leaving these settings enabled?
We have turned on those settings in our commercial releases for years now with no apparent downside. The upsides are enormous,though.
We have integrated a crash dump packager that packages the dump along with some other information and emails it (with the user's consent) to a company inbox. This has helped us find problems that would have taken us forever to reproduce and find otherwise.
Although it's slightly off topic, here's a link to an excellent contribution someone made that gives you an easy way to include a crash reporter to a C++/Windows app:
http://www.codeproject.com/KB/debug/crash_report.aspx
Note: It would be wise, though, not to include the PDB file with your release. That said, you must keep the PDB file that matches your released version so that you can correctly debug the problem in the future. If a PDB file is used that wasn't built with the same code that built the exe, the stack you see when you try to debug the dmp will be wrong.
They're turned on by default because:
If you don't create them now, you can't create them later.
You need them.
Enabling debug info in Visual C++ causes a small entry to be added to the binary header, identifying the PDB for this binary. It's too small to be of any size concern, and doesn't contain any useful secrets that you might be concerned about sharing.
(The header entry is labeled RSDS: who can guess why?)
Of course, those PDBs will use more disk space on your build machine / in your backups. Deal with it. You need those PDBs when it comes time to debug something.
Well, you might deliver this debug information and someone might use it to disassemble your code. For some fearful people this alone might be a reason not to leave it this way.
Personally, I think sometimes it's helpful to have debug information available for the release version - this way it is far easier to analyse a crashdump, that will be stored by Dr. Watson in case of application crashes.
I did find some really obscure bugs this way.
Having these options on do not necessarily make your executables bigger. Debug information is stored in a separate file, with the extension PDB. Having debug information available is never a bad idea, unless you're really really short on free storage space.
Perhaps that's why they're on by default: they don't harm your executables. Release builds do use optimizations such as function inlining and generating optimized code, which makes it harder to step through, while Debug builds have these options turned off.
No downside here.
Dave
Add the /Zi switch does make a larger .exe file in addition to the PDB. However you can seperately link with /OPT:REF to keep the .exe file size to a minimum.
The .exe will be slightly larger due to a reference to the .pdb file (i.e., an extra path). That's about it.