What's a practical use of .PDB files? - c++

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...

Related

Visual Studio (C++) debugging in debug mode vs release mode

I'm new to windows development, and my programming skills are not that strong (I'm with EE background, major is semiconductor), but at least I understand the fundamental of C/C++.
Regarding Windows C++ project, I found that I can debug under both debug and release builds (by adding break points, and reading the value of variables) in visual studio. I did some research, and I found that as long as there is a PDB file, I can do the debugging. However, will the "debug-able" release build impact the performance?
I also read about disabling debug in visual C++ projects. If I disable debugging, will the performance of a release build be better than a debug-enabled release build?
Sorry for my broken English.
No, it makes no difference. The linker's /DEBUG option is simply turned off by default for the Release build. The PDB it generates isn't all that useful for debugging, the optimizer that's turned on for the Release build makes a big ole mess of your debugging session. You'll have trouble setting breakpoints on some statements, see single-stepping acting weird (the code highlight moving around unpredictably) and the debugger not being able to show you variable values.
Still, sometimes you really need the PDB file, invaluable when you get a minidump back. Recorded by a customer when your program crashed and burned a thousand miles away. You need to plan for that, pretty important to generate the PDBs and store them so you'll have them available when you analyze the minidump.
Enabling PDB generation doesn't affect code generation, so the performance of your Release code won't change if you enable PDBs.
(Do note that debugging of optimised code is not as reliable as debugging non-optimised code... you'll find that the current line seems to jump around, and that you can't always rely on the reported values of variables.)
A binary can be debugged in windows with or without a PDB file. A PDB is a database of sort which provides information to the debugger such as the name of locals, the type of locals, offset to source mapping, etc .... None of this is strictly necessary to debug it just makes it a whole lot nicer. If you were so inclined you could debug the assembly directly with no PDB.
Hence there is really no concept of "disabling debugging". Really it comes down to whether you build a Debug / Release build. A Debug build is generally much more debuggable than a Release build because the compiler will take care to keep interesting locals around and insert no-ops to make stepping nicer. Release builds are all about performance of the final output and will sacrifice easy debugging to achieve it

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.

Debugging c++ core files for released software

I'm trying to find a way to debug core files sent to me from released versions of my software (c++ code compiled with gcc). Ideally, I'd like to be able to deploy release builds, and keep debug builds on hand to use for debugging, so I have symbol tables, etc.
My problem is that (as I understand it) the debug and release builds are not guaranteed to be the same - so a core file from the field may just look like garbage when I fire up gdb and point to my debug executable.
Is there a way around this (and here's the catch) without impacting size or performance of my released software? It's a large application, and performance of the debug build is probably not acceptable to customers. I've looked at suggestions to build once (debug), then strip symbol tables and ship that as the release build, but I'm going to see a performance hit with that approach, won't I?
Does anyone have suggestions for things they've tried or currently use that address this problem?
Thanks!
You can compile and link with optimization turned on and still generate debug symbols (-O3 -g) and then extract the debug symbols. This way you'd have the debug symbols around but can ship without them, and you won't have a performance penalty or something. See How to generate gcc debug symbol outside the build target? on how to do that.

Symbols files and debugging

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.

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.