Reputation: 2277
If debug information is stored in a program database (not as part of an executable), is there any reason not to always build with it (e.g., MSVC's /Zi
)?
In CMake, the default configurations are, "Release", "Debug", "RelWithDebInfo", and "MinSizeRel". Is there a reason not to only use "Debug" and "RelWithDebInfo" (perhaps renamed to "Release")?
Does it have any impacts on the size or performance of the code? Is the answer different for gcc or clang than it is for Visual C++?
Update
I did come across these posts that are similar:
However, neither of these get to the question of Release vs. RelWithDebInfo.
Yes. I could do a test on an executable with Release vs. RelWithDebInfo. That would definitely give me the answer about the size of the code, but would be very difficult to conclude that it has NO impact on performance if my test case showed similar performance. How would I know if I exercised aspects of the language that might be impacted by the change? That is, empirical testing could produce a false negative.
Upvotes: 20
Views: 14831
Reputation: 1030
I have come here with the same question in 2024, more than 6 years after the original post. However I'm slightly dissatisfied with the current answers, as they leave out the (very relevant) flip side of RelWithDebInfo
: The resulting executable may be considerably slower.
This slowdown can be both measured in benchmarks but also understood from a simple consideration: In order to allow for useful debugging, the compiler can not optimize as aggressively, because i.e. function names need to remain (mostly) available.
To summarize a number of arguments regarding a build with RelWithDebInfo
:
Pro:
Debug
builds.ProgramDatabase
), at least on Windows
Con:
Release
builds, due to the required additional information about i.e. function names etc.
RelWithDebInfo
vs Release
(compiled for x64
with clang-cl
16.0.6 against Visual Studio 2022 17.9.5).Debug
build:
DEBUG
are disabled, and NDEBUG
enabled.Summary
My personal summary is that there is a relevant trade-off between the various build modes. Developers should evaluate their options. If the application is not runtime critical, then RelWithDebInfo
has many good arguments on its side, foremost to ability to debug the exact same application shipped to customers, possibly even on customer hardware. However, dedicated Release
and Debug
builds also have their benefits, for example the possibly better runtime performance of dedicated Release
builds, or the better debugging behavior in dedicated Debug
builds.
Further considerations
As of summer 2024, there is still debate about the most suitable compiler flags for the various compiler flags in RelWithDebInfo
vs Release
, at least when cmake is used as a build tool. Most of above considerations reflect the current default compiler flags, and with modifications of those flags, the behavior may (significantly) change. See for example the discussion about RelWithDebInfo should use /Ob2 for more aggresive inlining in MariaDB, which would reduce the ability to debug, but in turn would increase the runtime performance.
Upvotes: 0
Reputation: 523
This is a bit old but I was asking myself the same.
It should be basically the same but it is not. You need to look at the different Compiler flags set in your CMake defaut conf for Release or ReleaseDbgInfo. For example for msvc Release is Ob2 and DbgInfo Ob1. Meaning with DbgInfo inlining will be less aggressive as not all functions are considered. That way you can pretty much get the exact line of crash in your source code file from the mem dump, thats nice, but that could mean also missed inlining opportunities so less perf.
I'd argu thats negligible in most cases and I saw almost no difference while debug info in prod is huge help . But still, you want to know the difference ? Look at the compiler flags difference.
Upvotes: 2
Reputation: 61
If you build as Release, surely you won't have Debug Info in the binary. I could see a lot of cases on Windows that people build "Release", but add flags to have debug info. So, i think the default real-life case for most Windows Users, even without knowing that, is Release With Debug Info.
With CMake, you have all three options and one more.
So, RelWithDebugInfo gives you Release mode binaries, and symbols can be stripped and kept apart. In some projects i have worked, that was the ONLY configuration used.
We must not forget about ASSERTS, at least for C/C++. Building with DEBUG, all Asserts are enabled, so they are not removed from the code during preprocessing. Release and RelwithDebugInfo remove the Asserts, so you won't have them. Some projects nowadays prefer to keep Asserts while developing (so that tests can catch "software" errors during development), and then finally remove in Production Code. Some other projects, for whom Fault-Tolerance is a must, may want to keep Asserts even in production code, so that software cannot execute with wrong Assertions about the software itself.
So,
RelWithDebugInfo: Optimized Build, With Symbols to be stripped, no Asserts
Debug: Not optimized, With Symbols that CAN be stripped, With Asserts.
Release: Optimized, No Symbols, No Asserts.
Upvotes: 6
Reputation: 31
Recently we have cases on Release vs RelWithDebInfo, we compile a shared lib, and found either the performance and the lib file size has a significant difference, Release is much more runtime faster and less file size.
So it looks like Release should be used when shipping on production.
Upvotes: 0
Reputation: 37468
Releasing with debug info is mandatory for real-life development. When shit happens your primary tool would be a crash dump analysis that would be rather pointless without debug information. Note that this does not imply shipping debug info with product.
As for "little differences" between vc++ and gcc I would like to mention that by default vc++ emits debug information in a separate file while gcc will squeeze it into executable. It is possible to separate debug information on gcc as well, however doing so is not as convenient and requires some extra steps.
Upvotes: 9