Jump to content


Debugging Threads in VC++


9 replies to this topic

#1 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 23 June 2006 - 03:29 PM

If I place a breakpoint in code that is executed in a secondary thread and run my program, the VC7.1 IDE goes nuts (makes the whole system mostly unresponsive for a while). When I first break at the point were the thread is created and step over that call, then I can hit breakpoints in the other thread without any problems.

Has anyone else had this occur? I have the work-around above, but I'm curious why its locking up in the first place.

My first thought was that I was doing something strange, but I had a co-worker ask me about this same issue that he's having on an unrelated project... :blink: Also, I can't seem to find anything relevant on the web.

It's kind of hard to search on this topic, since the terminolgy to describe the symptoms is closely related to thread synchronization and debugging in general. :(
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#2 tbp

    Valued Member

  • Members
  • PipPipPip
  • 135 posts

Posted 23 June 2006 - 09:59 PM

MSVC's debugger does weird things with thread scheduling anyway.
#define BREAKPOINT() do { _asm { int 3 } } while (0)
is a sure shot which doesn't disrupt code around too much.

#3 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 24 June 2006 - 12:12 AM

Why the do..while?
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#4 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 24 June 2006 - 09:04 AM

.oisyn said:

Why the do..while?
That's the standard way to make sure a macro function is syntactically identical to a real function. It is a sentence, requires a trailing semicolon, can't confuse if/else nestings, can't have any other code added after it and before the semicolon, etc.

While it might seem to be ok to define this macro as:

#define BREAKPOINT() __asm int 3

In reality it's not:

blahblah();
BREAKPOINT() // compiles despite the lack of semicolon!!!
blahblah();

BREAKPOINT()+1 // compiles into "__asm int 4"!!!

It's never a bad idea to use the full-fledged do...while(0) harness. You don't want these kinds of potential inconsistencies and syntax errors silently lurking around your code. Finding bugs caused by such wrongful macro uses can take HUGE amounts of time for even the best programmers.

It's similar to the way some people recommend to always use braces around blocks even if they are only one sentence. In fact, enforcing the do...while in function macros may be more important because there are VERY FEW people who know the ins and outs of writing syntactically safe macros.

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 24 June 2006 - 11:34 PM

Jare said:

While it might seem to be ok to define this macro as:

#define BREAKPOINT() __asm int 3

In reality it's not:

I was talking more about the do..while itself rather than just putting the plain asm instruction in the macro. I usually just use curly braces myself, that will never give unexpected errors or plain wrong code, which is the most important part in my opinion. But I can see why you want to have compile errors where you would expect them, like in your first example (missing semicolon) or doing something like:
void foo()
    BREAKPOINT();  // compiles ok when just using curly braces

So fair enough :)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#6 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 25 June 2006 - 12:40 AM

Oh, it can be worse than wrong code compiling... it can be correct code compiling to something different than what you expect:
#define BREAKPOINT() { __asm int 3 }

if (gottaCheck)
  if (wannaBreak)
    BREAKPOINT();
  else
    blahblah();
Thanks to the braces and the semicolon, the else is matched to the outer if instead of the inner. It looks and acts like a compiler bug, and you know how hard that can be to track.

#7 STLDude

    Member

  • Members
  • PipPip
  • 59 posts

Posted 25 June 2006 - 12:41 AM

.oisyn said:

So fair enough :)

Actually not, if you try this you’ll see that it will give compiler error:

if (something)

    BREAKPOINT();

else

    do_something_else;


The do/while(0) loop around macro is old trick to fix above usage of macro.

#8 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 25 June 2006 - 09:50 AM

STLDude said:

The do/while(0) loop around macro is old trick to fix above usage of macro.

That's exactly Jare's point...you don't want to use just braces :)
reedbeta.com - developer blog, OpenGL demos, and other projects

#9 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 25 June 2006 - 10:19 AM

STLDude said:

Actually not
I actually meant: but fair enough :)

Quote

if you try this you’ll see that it will give compiler error:
Hmm indeed, never thought of that. Funny I never ran into errors like that (but then again, I'm not using macros much anyway).
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#10 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 26 June 2006 - 01:24 PM

That works much better tbp, thanks. I didn't think about compiling in a software interrupt.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users