C++ adding Debugging code that only runs when Debugging - c++

As the question explains: I would like to add some debugging code that only runs when the program is attached to the debugger. I would imagine that this flag or pre-processor variable would be different for every compiler...
In my case I am using Microsoft Visual Studio 2010 with C++.
I also use Eclipse on another computer at home running Ubuntu 10.4 and again in C++.

This question could mean 1 of 2 things:
Code that only runs based on the build configuration (e.g. Release vs. Debug)
Code that only runs when the debugger is attached
Based on build configuration
This can be solved by using the pre-processor macro relevant to your compiler (e.g. _DEBUG for the Win32 CRT).
Based on whether debugger is attached
This can be solved in several different ways.
Global boolean variable
One way I find is to define a global boolean variable which is initialised to false, like this:
bool gDebug = false;
And when I have attached to the code with my debugger, break in the code and override gDebug with true via the Watch window. Then you can add code that runs conditionally if this is set is true:
if (gDebug)
{
// Debugger is attached, so run this code
// ...
}
Registry key
Define a DWORD registry value which is initialised to 0, but you can override to 1 via the registry editor.
You then make your debug code conditional on this registry value being set to 1. This may be a better alternative as you can control this value externally without have to break in your debugger to set a global variable at the appropriate time.

If you want to have some code included or not in debug/release builds, usually the _DEBUG preprocessor macro is defined for debug builds (at least, in MSVC++ CRT that is the convention), but it doesn't detect if a debugger is attached, it just let you include different code for debug/release builds.
If what you want is a runtime check for attached debuggers, you should use the IsDebuggerPresent API, which detects if a user-mode debugger is attached.
Notice that it's not 100% reliable since, with some not-so-difficult work, the debugger can make it lie to your application. In other terms, it's not good for security/anti-cheat protection and this kind of stuff, it's more to enable additional help to the debugger (e.g., as the page itself says, output more diagnostic info with OutputDeubgString, etc.). Moreover, it won't detect kernel-mode debuggers, that can do whatever they want anyway.
Anyhow, I advice you to avoid using this function for complicated stuff, since you're introducing different code paths when the debugger is attached, and this can make debugging "strange" bugs quite difficult. All the code I indirectly used which presented such behavior (e.g. the almost undocumented Windows debug heap) always gave me bad headaches.

Set a global variable in_debugger to false in your program. Condition all your debug-only code on this variable being true. Set the variable to true when you attach your debugger.

There is an even more direct approach to this. You can manually call a function of your choice during the debugger session:
http://sourceware.org/gdb/onlinedocs/gdb/Calling.html
Regards,
Marcin

Related

Why does my c++ program check not initialized variables?

I'm coding in c++ because I want my program to run fast (the faster the better).
But I am disapointed at the fact that it checks whether a variables is initialized or not...
I don't want it to lose time doing it, even if it is just a nanosecond.
I use VS, and I thought that maybe if I run my program in the not-debug mode it would avoid the check. But it does the check anyway, and shows me a window with this message:
Run-Time Check Failure #3 - The variable 'carryingResourceAux' is being used without being initialized.
This line that seems to be generating the error is:
carryingResource = carryingResourceAux;
Can I avoid this check to make my program run slightly faster??
This check is enabled by the /RTCu compiler option. In the IDE, under project properties -> C/C++ compiler -> Basic Runtime Checks, change the option to not include these checks. Note that they are only compatible with no optimization (debug builds).
You should optimize your release build, and leave this check in for debug builds.

Is there a difference in source code for release and debug compiled program? [C/C++]

I've been getting more into C++ programming as of late and keep running into the whole 'debug vs release' compiled versions. Now I feel like I've got a pretty decent understanding of some of the differences between released and debug versions of compiled code. For the debug version of code, the compiler doesn't attempt to optimize the code such that you can run a debugger and step through your program line by line. Essentially the compiled code closely resembles your source code in how it is executed. When compiling in release mode, the compiler attempts to optimize the program such that it has the same functionality, but is more efficient.
However, I'm curious as to whether or not there are instances where the source code between release and debug version can be different. That is, when we refer to debug vs release, are we always just talking about the compiled code, or can there exist differences in the source code?
This question arises due to me working in a proprietary programming language in which a formal, step by step debugger doesn't exist, yet serial monitors do exist. Thus a lot of our 'debug' vs 'release' code is implemented via #defines which look something like this:
#ifdef _DEBUG
check that error didn't occur...
SerialPrint("Error occurred")
#endif
So to summarize my question, depending on your IDE, are there often settings for implementing what I've illustrated? That is, when you attempt to compile to a debug version, can it be integrated with changes in the source code? Or does release vs debug typically just refer to the compiled binaries?
Thank you!
Is there a difference in source code for release and debug compiled program?
It depends on the source code, and the options used to compile the library or program. Below are a few differences I am aware of.
ASSERTS
The simplest of "debugging and diagnostics" is an assert. They are in effect when NDEBUG is not defined. Asserts create self-debugging code, and they snap when an unexpected condition is encountered. The trick is you have to assert everything. Everywhere you validate parameters and state, you should see an assert. Everywhere there's an assert, you should see an if to validate parameters and state.
I laugh when I see a code base without asserts. I kind of say to myself, the devs have too much time on their hands if they are wasting it under the debugger. I often ask why thy don't use asserts, and they usually answer with the following...
Posix assert sucks because it calls abort. If you are debugging a program, then you usually want to step the code to see how the code handles negative conditions that caused the assert to fire. Terminating the program runs foul with the "debugging and diagnostic" purpose. It has got to be one of the dumbest decisions in the history of C/C++. No one seems to recall the reasoning for the abort (a few years ago I tried to track down the pedigree on various C/C++ standards lists).
Usually you replace the useless Posix assert with something more useful, like an assert that raises a SIGTRAP on Linux or calls DebugBreak on Windows. See, for example, a sample trap.h. You replace the Posix assert with your assert to ensure libraries you are using get the updated behavior (if they have already been compiled, then its too late).
I also laugh when projects like ISC's BIND (the DNS server that powers the Internet) DoS's itself with its asserts (they have their own assert; they don't use Posix assert). There's a number of CVE's against BIND for its self-inflicted DoS. DoS'ing yourself is right up there with "lets abort a program being debugged".
For completeness, Microsoft Foundation Classs (MFC) used to have something like 16,000 or 20,000 asserts to help catch mistakes early. That was back in the late 1990s or mid 2000s. I don't what the state is today.
APIs
Some APIs exist that are purposefully built for "debugging and diagnostics". Other APIs can be used for it even though they are not necessarily safe to use in production.
An example of the former (purposefully built) is a Logging and DebugPrint API. Apple successfully used it to egress a user's FileVault passwords and keys. Also see os x filevault debug print.
An example of the latter (not safe for production) is Windows IsBadReadPointer and IsBadWritePointer. Its not safe for production because it suffers a race condition. But its usually fine for development because you want the extra scrutiny.
When we perform security reviews and audits, we often ask/recommend removing all non-essential logging; and ensure the logging level cannot be changed at runtime. When an app goes production, the time for debugging is over. There's no reason to log everything.
Libraries
Sometimes there are special libraries to use to help with debugging a diagnostics. Linux's Electric Fence and Microsoft's CRT Library come to mind. Both are memory checkers with APIs. In this case, you link command will be different, too.
Options
Sometimes you need additional options or defines to help with debugging and diagnostics. Glibc++ and -D_GLIBCXX_DEBUG comes to mind. Another one is concept checking, which used to be enabled by the define -D_GLIBCXX_CONCEPT_CHECKS. Its Boost code and its broken, so you should not use it. In these cases, your compile flags will be different.
Another one I often laugh at is a Release build that lacks the NDEBUG define. That includes Debian and Ubuntu as a matter of policy. The NSA, GHCQ and other 3-letter agencies thanks them for taking the sensitive information (like server keys), stripping the encryption (writing it to a file unprotected), and then egressing the sensitive information (sending them Windows Error Reporting, Apport Error Reporting, etc).
Initialization
Some development environments perform initialization with special bit patterns when a value is not explicitly initialized. Its really just a feature of the tools, like the compiler or linker. Microsoft's tools come to mind; see When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete? GCC had a feature request for it, but I don't think anything was ever done with it.
I often laugh when I disassemble a production DLL and see the Microsoft debug bit patterns bcause I know they are shipping a Debug DLL. I laugh because it often indicates the Release DLL has a memory error that the dev team was not able to clear. Adobe is notorious for doing this (not surprisingly, Adobe supplies some of the most insecure software on the planet, even though they don't supply an Operating System like Apple or Microsoft).
#ifdef _DEBUG
check that error didn't occur...
SerialPrint("Error occurred")
#endif
It makes me want to cry, but you still have to do this in 2016. GDB is (was?) broken under Aarch64, X32 and S/390, so you have to use printf's to debug your code.
The C++ standard supports a kind of debug versus release via the assert macro, whose behavior is governed by whether the NDEBUG macro symbol is defined. But this is not intended as an application wide setting. The standard explicitly notes that each time <assert.h> or <cassert> is included, regardless of how many times it's already been included, it changes the effective definition of assert according to the current definitional state of NDEBUG.
The compiler vendor's implementation of the standard library may rely on other symbols.
And application frameworks may rely on yet other symbols, e.g. _DEBUG, which is a symbol defined by the Visual C++ compiler when you specify the (debug library) /MTd or /MDd option.
In regards to IDE settings, you're free to do what you want. Yes, some IDEs (like MS Visual Studio) or tools like CMake add _DEBUG macro definition specifically for debug configurations, but you could also define one yourself if it's missing. Also, _DEBUG name is not set in stone, you could define MY_PROJECT_DEBUG or whatever instead.
If release and debug versions stay identical in regards to their primary functionality, you're fine. You could add any code wrapped in #ifdef _DEBUG (or otherwise #ifndef _DEBUG) as long as the end result produced by the program is the same.
The usual mistake there is when debug code, which is considered optional, produces side effects. Consider assert example given by others; approximate implementation looks like this:
#ifdef NDEBUG
#define assert(x) ((void)0)
#else
#define assert(x) ((x) ? (void)0 : abort())
#endif
Notice how assert doesn't evaluate the x when in release mode (provided that NDEBUG is only defined in release mode). This means that if condition passed as macro argument has side effects, you code will behave differently in debug and release modes:
#include <assert.h>
int main()
{
int x = 5;
assert(x-- == 5);
return x; // returns 5 in release mode, 4 in debug mode
}
The behavior above is not something you want, as it changes the end result. Real-world code may be more complex and less evident to introduce side effects, e.g. assert(SomeFunctionCall()) and the like.
Note that asserts may not be the best example though, as some people like to have them enabled even in release builds.

Why is it that debugging in release mode hides information?

When debugging in release, c++ code doesn't expand certain variables. What are the kind of variables that cant be expanded and why so? I can understand that a release dll has been packaged with extra optimizations but not quite sure if this is the only reason. Also is there anything that can be done to view those values
Even assuming that you have debug information in the build, debugging a release build (optimized) is hard in general. The optimizer can mangle the result of the code up to a point you might not recognize it.
It will remove variables altogether and hide them from the debugger (since the variable is not there, the debugger cannot show them). It might not remove it, but reuse the space for register spills temporarily and you will see the value of the memory where your variable is jumping to some random value. The flow might be reordered and the variable might be and have the right value once initialized, but initialization might have been pushed further down and not yet executed...
If you can reproduce the issue in a debug build, I'll start there. If not, good luck. Don't trust anything you see, but try to extract as much information as you can from the data points you have available.
When you build in "Debug" mode, then the compiler (and linker) adds extra information about things like variables, their names, the source files used, line number information, etc. This is missing when compiling in "Release" mode. It can be added though, by changing it in the project settings.

What's the reason to use DEBUG macro in C++?

I'm working on C++ program built by other people, and saw a lot of uses of DEBUG like this
#ifdef DEBUG
cout << "Value is "<< value << endl;
#endif
I myself am still in the learning process to become an affluent C++ programmer, and I majorly use Visual Studio and breakpoints to debug. So I'm wondering, if I'm able to step through the code to debug values, is there any other reason to use these kind of macros?
Tried to google but didn't find much useful page.
Thanks.
Sometimes you don't want to step through the whole code, but just inspect the output in the terminal.
If the code is compiled with DEBUG defined, probably in a debug build, you see the output. For a release build, you don't. If you go to project settings -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions, you'll see that DEBUG is defined for the debug build, but it's not for release. (I actually have _DEBUG)
Imagine you have a huge function, and what you're interested in is at the 1000th line (it's old code, can't change it). Would you rather step through all of that messy legacy code or have helpful debug statements at key points? Would you rather the console tell you where something went wrong, or set breakpoints at each of the 237 return statements at fail locations?
While you're debugging, it is a common practice to dump some intermediate values on the screen. The visual debugger is not always helping, because you waste a lot of time manipulating with mouse.
The need for "text-mode debugging" and logging also frequently comes from the embedded systems experience, where you don't have much visual aid and all you can do is to dump a byte or two to serial port or something like that. When you get used to quickly finding critical debug points, you just insert some printing code there whose value checks the program correctness.
The "DEBUG" macro is defined by MSVC++ compiler while your project is compiled in Debug mode. When you're making the Release version, all the code which is actually useless for the end-users gets "stripped away" by the preprocessor.
Typical snippet
#ifdef DEBUG
Some code
#endif
is removed by the preprocessor if the DEBUG is not defined.
It can be handy to use console output rather than a debugger for identifying multithreading bugs. Interrupting the flow of the program via a breakpoint often stops the bug from occurring because it stops the threads stepping on each other's toes. The same is true of other timing-based bugs.
"I majorly use Visual Studio and breakpoints to debug"
Debugging your code by watching its behaviour step by step is quite hard or even impossible in some situations. Sometimes it's just easier to create this kind of "debug output" so that you see what's going on from these logs instead of trying to step through it in real time.
Checking whether DEBUG symbol is defined is to make sure that your release version doesn't make this kind of output. Note that Visual Studio defines _DEBUG for debug configuration. More specifically: "The compiler defines _DEBUG when you specify the /MTd or /MDd option. These options specify debug versions of the C run-time library."
There is also NDEBUG that disables C-style assertions when defined. For more information check _DEBUG vs NDEBUG.
It's for debugging, by wrapping the code in preprocessor commands you can turn that code on or off.
Take a look here: C++ Notes: Preprocessor
Easy, when you want to get some messages that may help you to make a "soft" debug you just define DEBUG and the sentences between #ifdef DEBUG and #endif will make effect and in your case get some useful messages.
This way, when you finished developing and you want to make a release you just undefine debug and the messages will appear no more.
You may think yes, it is a good idea, but is more code for the app but the good point is that those are macros and are evaluated at compile time, therefore, the app will be the same that if you delete all of them :)
I'd recommend not using a DEBUG macro. Instead, use the standard NDEBUG macro, which is defined when debugging code is not wanted, rather than defined when debugging code is wanted. That is, have debugging code active by default. You will find that only a small core of performance critical code needs to have debugging checks switched off to get adequate performance.

C++ / VS 2010: Bug(s) occur only when running without a debugger

This is a twisted problem. When I run my program using F5 in Visual Studio, everything works fine. If I start it without the debugger, or from outside VS, a few nasty bugs which I can't locate occur.
I suspect this is caused by the debugger randomizing all uninitialized variables, wheras "outside", they are set to 0. I must be using a variable without initing it somewhere...
Are there other possible explanations?
What should I do to find the bug - I can't use a debugger for it can I
How come the debugger in VS doesn't detect the use of an unitialized variable, if that's the case
As Hans Passant says, you have it the wrong way round. In Debug, memory is initialised, but in release it could be anything.
In general, if you have something going wrong in release that doesn't happen in debug then it could be down to a few things:
Relying on uninitialised variables as you said.
Optimisations changing the semantics of your code. This will only happen if you write code that is relying on ill-defined behaviour. For example, assuming that function arguments are evaluated in a specific order, or relying on signed integer overflow, or any number of things.
It's a timing issue that shows up more often in release builds due to the better performance. These most often occur in multithreaded applications.
You use different libraries in debug and release and rely on the different behaviour between them.
You can use the debugger to attach to a running program. I think it's in the 'Debug' menu in VS and is called 'Attach to process...'. Make sure that you generate debug symbols for release builds so that you get a usable call stack.
I had a similar problem recently except it was even weirder. The code worked fine when I ran release in visual studio, but when I ran the program outside visual studio (just clicked the .exe) it would do this very big bug.
Turned out it was because of:
angle = MathHelper.ToRadians(angle);
When ever angle was 0 it would fail and produce some weird results.
I fixed it by simply changing it to:
angle = MathHelper.ToRadians(angle+.01f);
Very very annoying problem for something so small. Hopefully this helps others find similar errors.