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.
Related
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
I've been running and compiling a program on my Windows 7 64-bit machine for several months now, but recently I had to change several VC project settings of the static libs that it uses and now the generated executable file requires me to run it in "Windows XP Compatibility Mode".
Compiled on Windows7 64-bit machine with Visual Studio 2010 SP1
The program I am generating is being built in Win32, debug mode.
The static lib projects specify Target Machine /X86.
When I run the program from the debugger, it start up and runs, however if running via the windows icon, it requires XP compatibility mode.
When trying to start outside of the debugger the EXE shows up in task manager for a second then goes away.
I've tried using Microsoft Application Verifier on it, however I don't know what to look for in the output.
I've been unable to find any details on how to troubleshoot this issue so if anyone has any ways if finding what could be causing this recent Compatibility Mode requirement I'd love to hear how it was fixed.
I have the source/projects/solutions for the majority of the static libs that I link against, as well as the exe file generated, however some of the external dependencies I only have the .lib,.dll, and .h files for. This means I can change (most) of the project settings for the dependencies if neccessary, but I need to know which ones to look for.
Thanks
To be honest, don't be afraid to make another project and copy the code files, even if it's 5 projects. You need to cut the problem in half. If it works with the new projects then it's the project files, if not, it's the code. Making projects isn't that hard really, though I'm sure a source of much consternation and something people avoid. If its the projects you can diff the files and see what happened by process of elimination. If you are really worried, copy the entire solution to another folder; always make backups.
The problem is that you probably won't be able to hoist enough information up to us to get a meaningful answer unless get lucky, and all the answers will be shots in the dark.
So I'm goign to take this question as "this happens, what can I do about it". The strategy above will get you out of it, if this used to work before. This exercise will arm you for the future and will be more productive in the long term. Go look at UAC and manifest files, aka Vista+ difference tht dramatically changes load and run behaviour (Linker Commands, Vista Migration Guide) if you need one thing to look at, but try the above process.
----
Other generic things to try:
1) another machine
2) another install of VS
3) a simple project with one window that does nothing to prove everything else in your tool chain and environment is ok.
4) planting message boxes along the code path with different messages so you know where its crapping out.
5) turing on pdb in release and runnign outside of debugger. If craps out, then try debugging and see if still craps out, but you get to see where.
6) assume that your code is unstable and you were getting lucky when it used to work. (this one is no fun). Many times things work in debug and not in release due to mem layout being different. If your progam is large you can find creative ways to use #if's whatever to elimitate code from running while haivng the whole thing still load. You can find the code that causes the bad behaviour.
7) turn off UAC and error reporting if its on, see if changes.
8) go find the "run without debugging" menu button in Visual Studio, so you don't have to go run it with the icon. That's an accident waiting to happen, and eliminates one more environmental difference. It looks like the run with debugging button, but it's hollow, a plain green triangle. It's under debug menu set. My oppinion is that it has done more harm than good to not have that on the bar by default as its confused many many people to think launching wiht VS means always using the debugger.
and so on....
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.
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...
I am analyzing a .dmp file that was created and I have a call stack which gives me a lot of info. But I'd like to double click on the call stack and have it bring me to the source code.
I can right click on the call stack and select symbol settings.. where I can put the location to the PDB. But there is no option for the source code directory.
The source code directory is unfortunately hard coded into the pdb's however if you know the folders required you can use windows concept of symbolic links, junctions.
I use the tool Junction Link Magic
Read this article about how to set up a Source Server (aka SrcSrv) integration at your site.
I took the time to follow these steps for our codebase, and now we are able to take a .dmp file from any build of our software in the past 6 months... get a stack trace with symbols... and view the exact source code lines in the debugger. Since the steps are integrated into our automated builds, there's very little overhead now.
I did need to write a custom indexer for ClearCase, but they have pre-existing ones for Perforce, TFS, and maybe others.
It is worth noting that the .dmp support in VS2005 is a little shaky.. it's quite a bit more stable in VS2008.
You'll also need to configure Visual Studio to grab the symbols for the MS products from here in addition to your own symbol server:
http://msdl.microsoft.com/download/symbols
That is described in a few places such as on the Debugging Tools for Windows site.
Windbg allows you to setup source paths same as PDB's paths.
After loading the PDB, manually navigate to the source file that matches the current execution location. A PDB contains the path and filename of the source files that built its associated binary, and I suspect the debugger is smart enough to hook things up when it notices that the filename being displayed and the filename associated with with current binary location, match.