How to break in at the call site that invokes the break point

I think everyone at some point in time wants to embed a break point in there code, whether it be for debugging purposes, path tracing, or detecting edge conditions that have not yet been tested. When I hit a break point, I would prefer that the debugger break in at the call frame which needs the break point and not another function which implements the break point. I have seen two different patterns over the years.

The first pattern is to call DbgBreakPoint(). This works well enough. It is portable across different processor architectures so you don't have to worry about new platforms, but it has one major problem. When you break into the debugger, you are in the wrong call site! You end up in the middle of DbgBreakPoint() itself and not the caller. You can use the gu command, but that requires typing ;).

The second pattern is to create a #define for some inline assembly, something akin to:

 #define TRAP __asm { int 3 }

This satisfies my requirement that the point of execution when we stop is in the function of interest, but this solution is platform specific. You would need enough knowledge per supported platform for this to work and that platform must support inline assembly (which x64 does not for our compilers). You could compromise and #define TRAP to DbgBreakPoint() for those platforms, but then you have a satisfactory solution on a subset of platforms.

Enter the __debugbreak() intrinsic that I just learned about this weekend from the OSR WinDBG mailing list (courtesy of Pavel A.) Yes, it is a Microsoft specific extension, but generating a break point is inheritly platform specific already. __debugbreak() is the best of both patterns. You get platform independence and when you break in to the debugger, you are sitting at the right call frame and not inside a system routine. That rocks in my book!

PS: I don't know which version of the compiler this intrinsic was introduced, but it is used in the Server 2003 SP1 DDK, so I know it has been implemented for awhile.

PPS:  I never call __debugbreak() in production code, and IMHO, neither should you.  To control this in a DDK build environment, I do the following

 #if DBG
  #define TRAP() __debugbreak()
#else  // DBG
  #define TRAP()
#endif // DBG