No more "int 3"


Today a colleague came by to ask about how to get “int 3” functionality on the 64bit platforms.  What is “int 3”? It’s the assembly instruction that is used to create a breakpoint.  At least that’s the instruction for the x86 processor, and as you can imagine it is very platform specific.


On the 64bit platforms there is no inline assembly, so there goes your “__asm int 3”.  What to do now?  Well there’s a lesser known construct which is actually much better to use in that it works across all platforms (x64, Itanium, and x86), which is __debugbreak().  This is a Visual C++ compiler intrinsic (defined in Visual C++ 2005 under vc\include\intrin.h, with tons of other cool intrinsics) that will effectively act “int 3” across all platforms. 


DebugBreak, the Win32 function call is still around, but in general using __debugbreak() is my preference, if for no other reason than it’s not a function call (it’s a compiler intrinsic), and you don’t need debug symbols to get a readable call stack.


If you’re writing C++ you probably don’t want to write non-portable assembly, and this is just one less place where you would have to.


Comments (8)

  1. So this ties your code to visual studio 2005? What if I’m developing with another compile (gcc, open watcom, intel, etc).

    Is this "intrinsic" thing some sort of C++ only thing or is this just a fancy word for some complex preprocessor macro.

  2. Jamal says:

    Justin, the compiler intrinsics are just microsofts answer to extending C++ keywords without lobbying the standard!

    I will admit, some of its intrinsics are usefull, but i dont usually use them to cross compiling with GCC (mingw). For that reason i prefer DebugBreak().

  3. Madman says:

    Well, the int 3 is one of the best functions around. It’s in __asm block, so it doesn’t get optimized, it’s easy to add, and who cares about cross platform when this code shouldn’t be in final code anyway???

    What I do not understand, is why on earth there is no __asm keyword in VS for x64?

    I will not agree that some intrinsic with weirdo name that compiles and works on all VS03/05, "which among other things is only cross-platform solution in the world", is better than well understood and accounted inline assembly.

  4. MSDNArchive says:

    Madman, there is a combination of reasons why __asm does not exist, but the main one is that it really is the cross architecture solution on Windows.  While it may not help going across platforms, it is beneficial for developers building apps that run on x64, Itanium, and x86.  

    I have had some thoughts recently though of starting an community project to write an inline assembler for Phoenix.  Could be educational as well as useful for some people.

  5. Phil Deets says:

    I’m glad I saw this. I just had to debug a program with __asm int 3 and it worked for me, but it is good to see this for future reference if I get a 64 bit system. Thanks.

    It turned out I had forgot to initialize a class scope variable. Launching the program from VS in release mode had the variable initialize to NULL anyway, but running the release mode .exe file gave it some other value. __asm int 3 helped me location the exact line of code where the error occurred then I realized what happened.

  6. Johnny D says:

    > While it may not help going across platforms,

    > it is beneficial for developers building

    > apps that run on x64, Itanium, and x86.  

    So this is more of "we know what’s best for you"? Personally, I’d rather see it available with a warning that its not portable and let me do what I want.

  7. Alan says:

    I think it is pretty ridiculous that MS thinks we can’t figure out #ifdef __WIN32 etc pragmas for inline assembly.

    What I really don’t like about MS these days is that they are removing functionality left and right.  I see it in Vista and I see it in VS 2008 and I don’t like it.  I think it is safe to say that for the past several years MS is reducing themselves to commodity software.