What is the best way to bind a debugger to a process in VC ++ at the right time?

When debugging, sometimes you need to attach an already running process, and not just run the application in the debugger.

Usually for me there is a call to Sleep () or MessageBox, so it’s easier for you to connect a debugger. I worry that some of them may ultimately be directed to source control.

What is the best thing to do to avoid this situation while still delaying enough time so that you can connect your debugger to a running process?

#ifdef _DEBUG a sleep or message box using #ifdef _DEBUG is one way, but I wonder if there is a better way.

With sleep, you also have a problem that you cannot attach on time. With MessageBox, you have a problem in that you can remotely debug or debug a process that does not have a visible GUI (the example works as a service in Vista)

+6
c ++ debugging visual-c ++ debugbreak
source share
7 answers

To attach a debugger to a specific point, you have several options:

The easiest way is to just call DebugBreak , which is pretty much equivalent to __asm int 3 , but it also works with other architectures (MSVC for x64 does not allow inline assembly, if I remember correctly). This will bring up the debug window just in time, and you can choose from registered debuggers (for example, Visual Studio) to join the process.

Alternatively, you can enter a Sleep call, giving you the option to hook up a debugger. You should use #ifdef _DEBUG around this to make sure you are not really sending this code.

One question: why can't you run code from the IDE? Is this a service or a downloadable IIS DLL or similar?

In this case, you can check the ImageFileExecutionOptions registry ImageFileExecutionOptions , which allows you to attach a debugger at the start of the process.

If you use cdb for this, you can configure it as a server or client for the WinDbg instance and debug this path. I have done this in the past, using WinDbg as a kernel debugger, and using ImageFileExecutionOptions to run ntsd -d using the specified process. This causes WinDbg to enter user mode. This is sometimes a useful method.

+9
source share

Freddy and Reoa have the right solutions. But I wanted to add a reason not to use MessageBox.

Displaying a MessageBox only partially stops your application. Since you are showing the user interface, at least one message flow is still running in your program. Therefore, if your code does any of the following:

  • Communication via Windows Messages
  • Has a non-trivial interface
  • Multithreaded

In fact, you will request a debugger in one state, but you will join your program in a completely different state. This can lead to confusing situations and errors.

We recently made changes to our code base to never show the MessageBox, to ease the break for this very reason. This is very bad behavior for a non-trivial application.

+6
source share

another option that I sometimes use

 while( !::IsDebuggerPresent() ) ::Sleep( 100 ); // to avoid 100% CPU load 

it should just silently wait until you attach your debugger to the process.

+3
source share

Attaching at the “right-point only” is a pain ... one option is to explicitly express DebugBreak () statements in the code to cause the problem, and protect them with #ifdef _DEBUG would be a good idea. We use the ASSERT macro, which can call DebugBreak (), so you can just write ASSERT (false)

Another option to consider is to use “image file execution options” to automatically launch the debugger. See the blog and MSDN documentation.

+2
source share

Take a look:

DebugBreak, __debugbreak and friends

or

static void timeToChase () {__asm ​​{int 3; }; }

+1
source share
 __asm int 3 

This complex breakpoint will trigger a debug dialog that allows you to connect to the process. Wrap this in #ifdef _DEBUG, and you will only end up in debug builds.

+1
source share

All Articles