13

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.

Neal Kruis
  • 2,055
  • 3
  • 26
  • 49
  • cant you build with and without and see the difference? – 463035818_is_not_an_ai Dec 07 '17 at 21:02
  • I can figure out empirically, but my question is more about the theory. Is there SUPPOSED to be a difference? – Neal Kruis Dec 07 '17 at 21:05
  • Very close, if not an outright duplicate: https://stackoverflow.com/q/947401/10077 – Fred Larson Dec 07 '17 at 21:07
  • 5
    @FredLarson Releasing software in debug mode is not the same as releasing software with debug info. – user7860670 Dec 07 '17 at 21:10
  • 3
    The only reason I can think of is that generating debug info takes time. So building with debug information is slower. But other than that, code size and performance are the same with/without debug info. – geza Dec 07 '17 at 21:56
  • 1
    Thanks, @geza. That's the answer I was looking for (and confirms my suspicion). – Neal Kruis Dec 07 '17 at 22:04
  • yes really. When I dropped the comment there was zero evidence of any research from your side. Not sure what it has to do with eagerness, actually I am rather hesitant to use those links and I think it is the first time it did so. – 463035818_is_not_an_ai Dec 07 '17 at 22:26
  • 1
    Fair enough. I posted a little hastily, but your rationale wasn't very fair either. A test build would not be conclusive. – Neal Kruis Dec 07 '17 at 22:36

4 Answers4

7

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.

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • So do you only build RelWithDebInfo and Debug (or their equivalents for non-cmake build systems)? Are there other configurations you use? Would your answer change for gcc since it makes the executable larger? – Neal Kruis Dec 07 '17 at 22:21
  • @NealKruis: the best way in my opinion is to generate with debug info. And then create a without-debug info executable from the with-debug info executable. Check out the like VTT provided in the answer. A without debug info build is only useful in the case when the debug info is surely not needed. – geza Dec 08 '17 at 00:04
  • @NealKruis: note: even, if the executable is larger, the code is not. Furthermore, the OS will only load parts from the exe which are needed for execution. So the debug info won't be loaded. – geza Dec 08 '17 at 00:16
  • @NealKruis Even if I have to use cmake I typically don't rely on build-in configurations and manually write all the compiler options. – user7860670 Dec 09 '17 at 17:47
5

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.

  1. Release means no debugging symbols at all, and MAY also means build with optimizations.
  2. RelWithDebugInfo means build with debug symbols, with or without optimizations. Anyway, the debug symbols can be stripped later, both using strip and/or obj-copy. If you use strip, the output can be saved. I guess the format is DWARF, version 4 or 5.

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.

0

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.

0

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.

qwark
  • 493
  • 1
  • 4
  • 15