Stopping debugger at an optimized out line of code - c++

If I want to stop in an empty block of code it's always a problem.
if (...)
{ // I want the debugger to stop here!
}
If I add an arbitrary line of code which does not affect program behaviour it is likely to be optimized out, depending on the line
if (...)
{
int a;
a = a; // won't work
}
if (...)
{
int a;
int b = a; // will work
}
So the 2 questions arise here:
1) What is the simplest one-line code which will NOT be optimized out (but will really do nothing!), which I can use to stop the debugger?
2) Is there a way to switch all of optimizations so that to be able to stop at an arbitrary line of code? Compiler flag -O0 doesn't work.

A good enough one-line code could be some useful and interesting assert statement with a condition which would not be constant-folded by the compiler. Often some meaningful and useful assert (p!=NULL) orassert(i>0) where p is some existing pointer variable or formal, or i is some existing signed integer variable or formal, is enough.
BTW, you are in the debugging phase of your project, so adding good enough meaningful assert statements is helpful. Of course you want the <cassert> header to be included.
Don't forget that assert(3) statements are skipped if you compile with the -DNDEBUG flag.
You could also use (on Linux/x86) asm volatile ("nop"). Notice that the debugger needs some code to put a breakpoint at. You don't want an empty code.

What about using a static breakpoint?
#include <sys/sdt.h>
if (condition)
DTRACE_PROBE(myapp, foo);
Now you can set a breakpoint in GDB:
break -probe-stap myapp:foo
You can even use:
DTRACE_PROBE1(myapp, foo, condition);
with:
break -probe-stap myapp:foo if $_probe_arg0

Related

Is there a way to detect compiler -fxxxx flags in C++ code in clang?

Is there a way to detect compiler -fxxxx flags in C++ code in clang?
I don't want to store the whole command line in binary, I want to test an individual option.
I want it to provide compilation error or warning if some flag is specified to avoid the code crashing at runtime.
There is no good way of detecting the presence of the flag in C++ code.
The compiler does not communicate the presence of this flag to the code.
You could write some code that changes behavior based on the presence of the flag, but doing so is very fragile, and not guaranteed to actually work. Intentionally introducing UB into your program is not a particularly good idea. But if you want to do it, it would be something along these lines:
void mark_nonnull(__attribute__((nonnull)) int* p) {}
bool deletes_checks_2(int* p) __attribute__((noinline)) {
mark_nonnull(p);
if (p) return true;
else return false;
}
bool deletes_checks() { return deletes_checks_2(nullptr); }
A better idea is to intercept this at the build system level. You could add a rule that compiles a test file to LLVM IR similar to this: https://reviews.llvm.org/differential/changeset/?ref=1123266 And then you check the resulting IR if the checks are there and abort the build if they aren't.

how to know which statement got executed while debugging

In my code, sometimes when multiple function calls can be made in a single line. I do not get which function is running right now.
for example-
int foo(){
if(m==0||n==0) return 0;
return std::max(foo(a,b,m-1,n),foo(a,b,m,n-1));
}
While debugging, understanding which function was called based on all parameters becomes clumsy and sometimes doesn't even work. Is there any option to see processes within a line while debugging. I use codelite IDE.
When you are having difficulty debugging code, it usually means you are doing too much in a single line. This means you should split a complex statement into multiple statements. In your case, something like this:
int foo(){
if(m==0||n==0) return 0;
auto a = foo(a,b,m-1,n);
auto b = foo(a,b,m,n-1);
return std::max(a, b);
}
Alternatives to the current answer could be:
Stepping into statements. Not likely to work if foo calls are inlined
Debugging disassembly
These alternatives may not work, but if when they work, they allow debugging unaltered code.

Is it possible to set a multiple conditions Breakpoint in Visual Studio 2013?

does anyone knows if its possible to set a multiple condition breakpoint on a specific line in Visual Studio 2013 (C++) ?
I was trying using the '&&' but it didn't worked. I also couldn't find an answer on MSDN.
the breakpoint that i wanna set is inside the WindowProc, the condition that i wanna set is - message = WM_MOUSEMOVE, WPARAM = MK_LBUTTON
thanks in advace, Igor.
WM_MOUSEMOVE is a macrodefinition and gets replaced in the source code by the compiler during compilation. It is unknown to the debugger, so you can't use it in a breakpoint condition expression; use explicit number constant instead.
BTW, are you aware you used operator '=', which is not the same as '=='...?
Using && is allowed and should work. What's more, a lot of common C++ expressions are allowed. This page lists what is and what isn't allowed.
Note that using this kind of breakpoint will considerably slow down your application. To the point where debugging is no longer feasible. This might be what has led you to believe && isn't allowed. To overcome this particular problem you might want to use a construct like this:
//untested code
#ifdef _DEBUG
if(condition a && condition b)
{
//either output something (option A)
std::cout << "condition a and b are true"
//or create a nop statement (option B)
__nop(); //and set a breakpoint
//or create a 'nop statement' with compiler warning (option C)
int breakpoint = 0;
}
#endif
This will yield much better performance.
Since this code is only compiled in when you are compiling in debug, you can leave this bit of code in (and option B would therefore be the best). If you however want to be reminded to remove the debugging clause, option C is probably the way you wanna go. As this will generate a variable breakpoint is declared but never used warning. As kindly suggested by borisbn.
If you are using this statement a lot it's probably most useful to wrap it into a precompiler macro.

C++ variable address does not match

class CCtrl
{
...Other Members...
RankCache m_stRankCache;
uint32 m_uSyncListTime;
};
int CCtrl::UpdateList()
{
uint32 tNow = GetNowTime();
for (uint8 i = 0; i < uRankListNum; i++)
{
m_stRankCache.Append(i);
}
m_uSyncListTime = tNow;
return 0;
}
Here are two weired things:
When step into Append(), p this = 0x7f3f467edfdc, but in UpdateGuildList(), p &m_stRankCache = 0x7f3f067edfdc, these two pointers are different.
tNow = 1418916316, after executing m_uSyncListTime = tNow, m_uSyncListTime is still 0.
How could this happen? I've used a whole day for debugging. And I checked my code there is no pack(1) and pack() mismatch.
The issue is more than likely that you're using your debugger to debug code that has been optimized. As your comment suggested, you are debugging code that has been compiled with the -O3 flag, denoting optimization.
Even though you're using gdb, the Visual Studio and other debuggers also have the same issue, and that issue is debugging optimized code and having the debugger "work" in the sense that the debugger follows along with the lines in the source code, along with the variables that have been declared.
A debugger assumes that the lines of the source code match up with the generated assembly code. With optimizations turned on, this can no longer be the case. Code and variables are eliminated, moved, etc. Therefore the lines in the code (including variable declarations) you believe should be there at a certain location may not be there in the final optimized build.
The debugger cannot discern these changes, thus you get erroneous values used for variables, or in some cases, you get "variable doesn't exist" errors reported by your debugger.
Also, it may also serve as a good check to do a simple cout or log of the values in question if there is a problem with the debugging environment. There are situations where even debuggers may get things wrong, so a backup verification system (i.e. logging, printf() or cout statements, etc.) should be used.

Will A Compiler Remove An If Block That Always Evaluates to Zero?

Will the compiler remove this if statement?
#define DEBUG 0
int main(int argc, char ** argv)
{
if(DEBUG)
{
...
}
return 0;
}
I tried to google this, and search stackoverflow but I think my search terms were bad because I couldn't find the information.
If this is optimized what would I want to read about to learn about the optimization?
Constantin
Yes, any decent C/C++ compiler will remove such if block.
I'm not sure if a compiler can optimize it away. I guess yes since in this situation you couldn't have any side effect, so it can be safely removed without changing semantics of the code.
In any case guessing is not nice and relying on an optimization is not nice too.
Why don't you use a #ifdef .. #endif block instead that a code block?
#define DEBUG
#ifdef DEBUG
...
#endif
In this way you will have a sure outcome.
You don't need to guess. Compile and step with debugger watching assembly instructions. You don't even need to be well familiar with assembly to see if there is actual code generated for lines in question or not.
You cannot make the universal statement that every compiler will optimize the same things the same way. Likewise any compiler that might happen to do it today might not in some future version.
Yes, a number of compilers today can and will do that but that doesnt mean you should plan for it or expect it. If you dont want that code there, comment it out, ifdef it out or remove it.
As mentioned by others, try it and find out for yourself. If you are debugging something and suspect that this has or has not happened, simply look and find out...
You got good answers to check it in your compiler assembly output. I would like to share similar idiom that is very usefull to me sometimes:
int main(int argc, char ** argv)
{
const bool bDebug = false;
if(bDebug)
{
...
LOG(""); /// some heavy loging here
}
return 0;
}
so I leave such if-s in some relevant places in my code, and when I get a bug report that something bad happend I step through code and when I need to ouput some large arrays/data structures, I modify from debugger bDebug variable (actually I name them bVerbose), and then allow code to enter such IF-s. You dont have to recompile code to add heavy logging.