I have some C++ code that I'd like to debug. As it's often the case, my bug appears only in certain conditions that cannot be reproduced with tiny datasets, and it appears after going through multiple functions that I am sure work.
In particular, I first need to put all my data in an std::set which is very slow in debug mode (and reasonable in release), even when using an _ITERATOR_DEBUG_LEVEL 0 preprocessor directive. As such, I was thinking that there might have been a way to execute part of the code in release while only executing the relevant buggy part of the code in debug mode.
I tried doing something like :
#ifdef _DEBUG
#undef _DEBUG
#define MODIFIED_DEBUG
#define NDEBUG
#endif
// build my expensive datastructure etc. etc.
#ifdef MODIFIED_DEBUG
#undef MODIFIED_DEBUG
#undef NDEBUG
#define _DEBUG
#endif
// execute my buggy code
However, this is still as slow as in debug mode. I there any (easy) way to get the speed of the release mode only for part of my code ? Especially, since the slowness is mostly due to the STL.
(I guess I could compile a .lib that builds the data structure in release and use the library in my code in debug mode, but that's quite a pain just to debug a program!).
Alternatively, is there any trick like the _ITERATOR_DEBUG_LEVEL 0 definition to speed up the STL in debug mode ? I am using Visual Studio 2010.
You can build in release mode and surround the suspect code with
#pragma optimize("",off)
//...
#pragma optimize("",on)
or do it old-school - debug statements.
Related
Does anyone know of a fix for an MSVC compiler bug/annoyance where SIMD Extension settings get "stuck" on AVX?
The context of this question is coding up SIMD CPU dispatchers, closely following Agner's well-known dispatch_example2.cpp project. I've been going back and forth in three different MSVC projects and have dead-ended with this issue in two of them, after which one of those two "fixed itself" somehow.
The question is pretty simple: To compile the dispatchers I need to compile 4 times with
/arch:AVX512 /DINSTRSET=10
/arch:AVX2 /DINSTRSET=8
/arch:AVX /DINSTRSET=7
/arch:SSE2 /D__SSE4_2__
While I'm doing this I'm watching the value of INSTRSET and this code:
#if defined ( __AVX512VL__ ) && defined ( __AVX512BW__ ) && defined ( __AVX512DQ__ )
#define AVX512_FLAG 1
#else
#define AVX512_FLAG 2
#endif
#if defined ( __AVX2__ )
#define AVX2_FLAG 1
#else
#define AVX2_FLAG 2
#endif
#if defined ( __AVX__ )
#define AVX_FLAG 1
#else
#define AVX_FLAG 2
#endif
The behavior is like this: For the three AVX compiles everything is exactly as expected. When the problem is not happening, the SSE2 compile shows as expected (AVX512_FLAG, AVX2_FLAG, AVX_FLAG == 2) and the final code runs fine.
When the problem is happening, for the /arch:SSE2 /D__SSE4_2__ compile the code above shows AVX512_FLAG == 2 but AVX2_FLAG == AVX_FLAG == 1 and INSTRSET == 8, and the compiler thinks the AVX2 instructions are enabled - the project compiles, but crashes on an SSE4.2 machine.
If I try /arch:SSE2 /DINSTRSET=6 then I get INSTRSET == 6 for the compile, but the code above still shows AVX2_FLAG == 1 and AVX_FLAG == 1, and the final project still crashes on an SSE4.2 machine.
The crashes happen even if I don't run any vector code - anything that calls into the dispatcher crashes immediately even if all vector code is short circuited.
FYI, trying /DINSTRSET=6 is just an act of desperation - I've never gotten anything to work with SSE4.2 without using /D__SSE4_2__
Does anyone know how to fix this problem that is completely halting my progress? Tried "Clean Solution" already.
If you want a single binary which works on SSE-only computers, but can leverage AVX when available, you need to do following.
At the project level, set “Enable enhanced instruction set: Not set” if you’re building for Win64, or “SSE2” if you’re building for Win32.
Set “Enable enhanced instruction set: AVX” or AVX2 only on the *.cpp files which contain AVX version of your functions.
Make sure to never call these AVX functions unless both CPU and OS (see GetEnabledXStateFeature WinAPI) actually have the support.
Practically speaking, instead of compiling same source file multiple times with different settings, compile 4 different source files. They can contain the same code, C++ has #include preprocessor directive. If you have a single implementation dispatched with these macros, move that implementation into *.inl or *.hpp file, and include that file into 4 different *.cpp files for different CPUs.
I figured this out (it's simple and boring). For the incremental object files I'm compiling 3 .obj files from the same .cpp (the .cpp with the vector code). When the MSVC SIMD settings are changed in the project level Properties, they may or may not get inherited in the .cpp file Properties. This is where the project gets "stuck" on AVX (sometimes, not always). Just need to check the .cpp file properties and make sure they are correct.
BTW I'm using VS 2019, /std:c++17 and the context above is the 32-bit build.
Is it possible to define something when building in debug mode?
For example:
...
#ifdef ENABLE_DEBUG
/* This line will be executed if the program is built in debug mode */
#endif
...
This is indeed possible, because it's you who defines what "debug mode" means. There is no "standard" way to do this, because there is no such thing as "standard" debug mode. You, as the author of the buildsystem, are in control of all build settings. If you decide that you will define the macro DEBUG if and only if building in debug mode, you can of course use #ifdef DEBUG in your code to distinguish between debug and non-debug builds.
The closest "standard" thing you can get is that the macro assert is specified to do its check when macro NDEBUG is not defined, and do nothing when NDEBUG is defined. For this reason, IDEs normally set up build configurations so that debug builds do not define NDEBUG and optimised builds do.
In a large C++/Qt/QMake/qtcreator project I would like to perform some tests, but only when I am compiling with the debug flag.
Is there a way to tell g++ that some small parts of the code have to be compiled only in debug mode ?
The standard way to do this is to depend on the macro NDEBUG, which is used by the macro assert() defined in <cassert>:
#ifdef NDEBUG
// release mode code
#else
// debug mode code
#endif
The opposite of #ifdef is #ifndef, and of course #else branches are optional.
If this macro doesn't work (for whatever reason), you
can try the macro QT_NO_DEBUG, which Qt uses for a similar purpose with Q_ASSERT(); and
should fix it so that NDEBUG is (un)defined correctly; it's required for <cassert> to work properly, and code you use may depend on it.
I have been using something like this:
int main(int argc, char *argv[])
{
#ifdef DEBUG
printf("RUNNING DEBUG BUILD");
#else
printf("Running... this is a release build.");
#endif
...
However this requires me to compile with -DDEBUG for the debug build. Does GCC give me some way for me to determine when I am compiling with debug symbols (-g flag) such as defining its own preprocessor macro that I can check for?
Answer is no. Usually these macros (DEBUG, NDEBUG, _DEBUG) are set by the IDE/make system depending on which configuration (debug/release) you have active. I think these answers can be of help:
C #define macro for debug printing
Where does the -DNDEBUG normally come from?
_DEBUG vs NDEBUG
I think the answer that I was looking for was essentially what Adam posted as a comment, which is:
The compiler's job does not include preprocessing, and in fact the compiler will choke on any preprocessor switches not handled by the preprocessor that make their way into code.
So, because the way to branch code has to leverage the preprocessor, it means by the time the compiler gets any code it's already one or the other (debug code or release code), so it's impossible for me to do what my question asks at this stage (after preprocessor).
So it is a direct consequence of the preprocessor being designed as a separate process for feeding the code through.
Is there a standardized (e.g. implemented by all major compilers) #define that will allow me to distinguish between debug and release builds?
if believe
#ifdef NDEBUG
// nondebug
#else
// debug code
#endif
is the most portable.
But no compiler knows whether you are compiling debug or release, so this isn't automatic. But this one is used by assert.h in the c-runtime, so it's quite common. Visual Studio will set it, and I'm sure most other IDE's will as well.
Since there is no standard definition of debug or release, there isn't a way to do this. I can think of at least four different things that could be meant, and they can all be changed independently. Only two can be tested from within the code.
Compiler optimization level
Debugging symbols included in binary (these can even be removed at a later date)
assert() enabled (NDEBUG not defined)
logging turned off
Edit: I misread the question and waffled off on a different tangent!!! Apologies...
The macro _NDEBUG is used on Linux as well as on Windows...
If the binary is built and you need to determine if the build was release/debug, you can get a hexadecimal dump, if you see loads of symbols in it that would be debugging information...for example, under Linux, using the strings utility. There is a version available for Windows by SysInternals, available here on technet. Release versions of binary executables would not have the strings representing different symbols...
strings some_binary
Hope this helps,
Best regards,
Tom.
Best I could come with is
#ifndef NDEBUG
// Production builds should set NDEBUG=1
#define NDEBUG false
#else
#define NDEBUG true
#endif
#ifndef DEBUG
#define DEBUG !NDEBUG
#endif
Then you can wrap your debug code in if(DEBUG) { ... }.