views:

323

answers:

9

Hi everyone,

I've stumbled onto a very interesting issue where a function (has to deal with the Windows clipboard) in my app only works properly when a breakpoint is hit inside the function. This got me wondering, what exactly does the debugger do (VS2008, C++) when it hits a breakpoint?

+2  A: 

http://en.wikipedia.org/wiki/Debugger

A debugger essentially allows you to step through your source code and examine how the code is working. If you set a breakpoint, and run in debug mode, your code will pause at that break point and allow you to step into the code. This has some distinct advantages. First, you can see what the status of your variables are in memory. Second, it allows you to make sure your code is doing what you expect it to do without having to do a whole ton of print statements. And, third, it let's you make sure the logic is working the way you expect it to work.

Edit: A debugger is one of the more valuable tools in my development toolbox, and I'd recommend that you learn and understand how to use the tool to improve your development process.

I'd recommend reading the Wikipedia article for more information.

JasCav
+3  A: 

The reason your app only works properly when a breakpoint is hit might be that you have some watches with side effects still in your watch list from previous debugging sessions. When you hit the break point, the watch is executed and your program behaves differently.

Adrian Grigore
+1  A: 

It stops the program counter for your process (the one you are debugging), and shows the current value of your variables, and uses the value of your variables at the moment to calculate expressions.

You must take into account, that if you edit some variable value when you hit a breakpoint, you are altering your process state, so it may behave differently.

Debugging is possible because the compiler inserts debugging information (such as function names, variable names, etc) into your executable. Its possible not to include this information.

Tom
+2  A: 

The debugger just halts execution of your program when it hits a breakpoint. If your program is working okay when it hits the breakpoint, but doesn't work without the breakpoint, that would indicate to me that you have a race condition or another threading issue in your code. The breakpoint is stopping the execution of your code, perhaps allowing another process to complete normally?

Bill the Lizard
+4  A: 

It might be a timing / thread synchronization issue. Do you do any multimedia or multithreading stuff in your program?

DrJokepu
+6  A: 

Typically, for software breakpoints, the debugger places an interrupt instruction at the location you set the breakpoint at. This transfers control of the program to the debugger's interrupt handler, and from there you're in a world where the debugger can decide what to do (present you with a command prompt, print the stack and continue, what have you.)

On a related note, "This works in the debugger but not when I run without a breakpoint" suggests to me that you have a race condition. So if your app is multithreaded, consider examining your locking discipline.

peterb
Race condition was my first thought too.
luke
+7  A: 

Without directly answering your question (since I suspect the debugger's internal workings may not really be the problem), I'll offer two possible reasons this might occur that I've seen before:

First, your program does pause when it hits a breakpoint, and often that delay is enough time for something to happen (perhaps in another thread or another process) that has to happen before your function will work. One easy way to verify this is to add a pause for a few seconds beforehand and run the program normally. If that works, you'll have to look for a more reliable way of finding the problem.

Second, Visual Studio has historically (I'm not certain about 2008) over-allocated memory when running in debug mode. So, for example, if you have an array of int[10] allocated, it should, by rights, get 40 bytes of memory, but Visual Studio might give it 44 or more, presumably in case you have an out-of-bounds error. Of course, if you DO have an out-of-bounds error, this over-allocation might make it appear to be working anyway.

VoteyDisciple
At least since 2008, the over allocated RAM is used for canaries. If your code overruns an array and blows up a canary, then the debugger stops and prompts you that you've corrupted the stack. The over allocation is to detect bugs, not hide them ;)
Billy ONeal
Note that this catches out-of-bound writes, but not out-of-bound reads. Those are equally buggy but far harder to debug.
MSalters
+1  A: 

Debuggers sometimes change the way the program behaves in order to work properly.

I'm not sure about Visual Studio but in Eclipse for example. Java classes are not loaded the same when ran inside the IDE and when ran outside of it.

You may also be having a race condition and the debugger stops one of the threads so when you continue the program flow it's at the right conditions.

More info on the program might help.

Gus
A: 

On Windows there is another difference caused by the debugger. When your program is launched by the debugger, Windows will use a different memory manager (heap manager to be exact) for your program. Instead of the default heap manager your program will now get the debug heap manager, which differs in the following points:

  • it initializes allocated memory to a pattern (0xCDCDCDCD comes to mind but I could be wrong)
  • it fills freed memory with another pattern
  • it overallocates heap allocations (like a previous answer mentioned)

All in all it changes the memory use patterns of your program so if you have a memory thrashing bug somewhere its behavior might change.

Two useful tricks:

  1. Use PageHeap to catch memory accesses beyond the end of allocated blocks
  2. Build using the /RTCsu (older Visual C++ compilers: /GX) switch. This will initialize the memory for all your local variables to a nonzero bit pattern and will also throw a runtime error when an unitialized local variable is accessed.
LaszloG
Actually, the changes to heap management come from the debug version of the CRT, not from the debugger itself. See http://msdn.microsoft.com/en-us/library/e5ewb1h3(VS.80).aspx
Adrian McCarthy