Disabling debug mode for system headers

Hi Clang people,

I was just having a discussion that involved someone complaining that when building his code in debug mode (-g and -O0 or -Og), the code from standard libraries, especially the STL, would become very slow as a result of the disabled optimizations and the general debug symbol overhead. Given that typical debugging tasks don’t involve digging into standard libraries or other “system-headers” (included with -isystem option), I thought that it might be a good idea for compilers to provide the option to disable debugging for anything that is from a system header. It would also have the practical benefit of avoiding having to link to debug-enabled libraries for those headers.

I just thought I should let you guys know about it. You certainly would know better than me if this is at all possible, and if it is, would know how to make it happen for Clang. What do you think?

Cheers,
Mikael.

I'm not sure that I agree with this premise. Most of the time when I'm debugging C++ code, I want to be able to inspect standard library types in the debugger. The presence of debug info isn't really the problem though, it's the optimisation level.

The real problem is that it's not contained. Even if you could say 'compile this with -O0, but treat everything from the system header as -O2' then it wouldn't do you much good. Part of the reason all of that stuff is in the headers, rather than in the library, is that it benefits a lot from inlining at point of use. The code where it's inlined at -O2 would not inline it at -O0 and you wouldn't benefit from any of the post-inlining optimisations, because they're not run at -O0.

David

Hi David,

I'm not sure that I agree with this premise. Most of the time when I'm

debugging C++ code, I want to be able to inspect standard library types in
the debugger.

I'm not trying argue that this would be super useful. Probably, most people
would never need or want to use this option (I cannot even see myself using
this option, I'm just relaying the idea of adding this option). But you
could say the same of most other options that compilers provide, most
compiler options are only used by a tiny fraction of the users. The
particular user interested in this was talking about a hard real-time
system where adding debug symbols made things so slow that it can't run
anymore, but most of the slow-down is attributable to the STL containers
and algorithms that do the grunt work, and doing so unnecessarily slowly,
because debugging the STL was never the point of the exercise.

The presence of debug info isn't really the problem though, it's the

optimisation level.

Right. When I say "disable debug mode", I'm lumping everything in one. The
two things that matter most are the limited level of optimization
associated to debugging (-Og) and the instrumentation that some STL and
std-lib implementations add to the classes and functions when it is being
compiled in debug (based on NDEBUG). For example, libstdc++ adds a lot of
additional code (not just asserts) and a lot of additional data members to
its STL containers when it's being compiled in debug mode.

The presence of the debug symbols limits the amount of optimization that
can be done, i.e., it can only debug between symbols. My understanding is
that fewer symbols means bigger gaps between symbols, which means more
optimization can be done (with the -Og option). For example, if you call
"push_back", in debug mode with the way compilers are currently, there will
be debug symbols at the point of the call, everywhere inside the code of
push_back, and right after the call, which allows the debugger to step into
the push_back function and go through its code's execution line by line by
going from symbol to symbol. If the function is inlined at the call-site,
all the symbols inside the push_back function are just migrated over to the
call-site along with the code (so the debugger can still make it look like
it's stepping into the function). But with this option that I'm proposing,
the push_back function would not generate any debug symbols, so, inlined or
not, and whether it calls other debug-enabled functions (e.g.,
copy-constructors of the elements), it will still result in much larger
gaps between symbols, and therefore, giving more opportunities for
optimization. At least, this is my understanding of things, but like I said
earlier, there could be technical issues that make this impossible or not
worth the trouble.

And the second important thing would be to automatically undefine the
NDEBUG macro (and any other macro like it) when the pre-processor enters
(from an include) a system header and to re-enable it when leaving that
system header. Sort of as if the compiler automatically did:

#undef NDEBUG
#include <vector>
#define NDEBUG

for every inclusion of a system-header. Which would have the result of
removing all the asserts and other debug-instrumentations that are added to
the standard classes and functions when in debug mode. That would have a
significant impact on the performance.

Cheers,
Mikael.