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.
Related
I am writing a program using OSG and I would like to step through it to see how stuff works, change a few lines and debug again. However every time I need to load a file using osgDB plugin for openflight. The debug version of the plugin works quite slow. I have no intention of debugging the plugin itself, so I figured I might as well use the release dll. I read that I can do this as long as there are no memory allocation in program and freeing in dll or visa versa and if the dll was designed to avoid problems that might occur with release/debug mixing. I'm not sure if osgdb_openflight.dll was designed like that.
My question: can I use the release plugin dll in my debug build, and how can I make my program use it?
UPD: I achieved my goal following the #XenonofArcticus's advice.
Some additional thoughts on the topic for the sake of better understanding:
I also tried to simply rename the release dll, so it would get loaded in the debug build. (I thought this would work, because I usually use release dlls in debug builds - Windows's, SQL's and other 3rd party dlls, that do not come with debug info. Also see Igor Tandetnik's comments on this question). It did and the program didn't crash, however it also didn't load the file. Apparently this particular dll wasn't designed to be used in debug builds. Any other explanation?
I'm not sure you're going to achieve what you want trying to mix debug and release. However, perhaps it would work to build a release with debug symbols target? This can allow you to do SOME debugging, but it's still a release build and behaves like one.
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
In MS Visual C++ 2008 is there any reason to disable incremental linking in debug builds?
From my limited reading enabling incremental builds gives me faster linking and edit & continue.
I'm at a loss to find any reason why you'd disable this great feature. What are disadvantages? Is it flakey?
EDIT:
I'm working with a solution with multiple projects (a handful of dlls linking to a couple of exes) and most (but not all) have incremental linking disabled in debug.
Where does the question come from? You just saw the option and decided to ask?
Generally it should work pretty well, and unless it doesn't - no reason to disable it. But sometimes the dependencies don't work properly and you need to rebuild all manually. If this happens often in your project - then you should disable it.
In complex solutions with many dependencies it sometimes can get flakey. For example, changing a file in library won't trigger relinking of the executable for whatever reason, or something like that. Obviously it's not a normal course of events, disabling the feature makes it easier to avoid the problem if it occurs.
What are the 'best practices' when it comes to debugging core dumps using GDB?
Currently, I am facing a problem:
The release version of my application is compiled without the '-g' compiler flag.
The debug version of my application (compiled with '-g') is archived (along with the source code, and a copy of the release binary).
Recently, when a user gave me a core dump, I tried debugging it using
gdb --core=./core.pid ./my_app_debug-bin
The core was created by my_app_release-bin. There seems to be some kind of mismatch between the core file and the binary.
On the other hand, if I try
gdb --core=./core.pid ./my_app_release-bin
the core matches but I am unable to get source code line numbers (although I get the function names).
Is this what is practised? Because I feel I am missing something here.
It sounds like there are other differences between your release and debug build then simply the absence/presence of the -g flag. Assuming that's the case, there is nothing you can do right now, but you can adjust your build to handle this better:
Here's what we do at my place of work.
Include the -g flag when building the release version.
Archive that version.
run strip --strip-unneeded on the binary before shipping it to customers.
Now, when we get a crash we can use the archived version with symbols to do debugging.
One thing to note is that if your release version includes optimization, debugging may be difficult even with symbols. For example, the optimizer can reorder your code so even though the debugger will say you crashed on line N, you can't assume that the code actually executed line N-1.
You need to do some additional stuff to create binaries with stripped debug information that you can then debug from cores. Best description I could find is here
No, you don't miss anything. debug and release are just different binaries, so the core files of release don't match the debug binary. You have to look at machine code to get something from the release core dump.
You probably have to ask your user how the crash happened and collect additional log information or whatever you app produces.
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.