سؤال

In the MSVC++ debugger, is it possible to create a breakpoint in one function, whose condition depends on local variables from other stack frames? I often find myself creating a conditional breakpoint in one function, and when that breakpoint hits, I enable another breakpoint (which I expect to fire before exiting the current function invocation) and continue. It's time-consuming and error-prone.

One approach I've taken in the past is to write the variable in question to a global, and use that global as a condition. But that requires a recompile, and doesn't work with multithreaded code.

هل كانت مفيدة؟

المحلول

Yes, that's technically possible. No great joy, mind you, you'll have to tell the debugger to dereference a pointer to obtain the value of the local variable in the other stack frame.

A simple example:

#include "stdafx.h"
#include <iostream>

void foo() {
    for (int ix = 0; ix < 5; ++ix) {
        std::cout << ix << " ";                 // <=== Conditional breakpoint here
    }
}

void bar() {
    for (int jx = 0; jx < 5; ++jx) {
        std::cout << jx << ": ";                // <=== Start with a breakpoint here
        foo();
        std::cout << std::endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    bar();
    return 0;
}

You first need to obtain the address of the variable that you want to set the condition on. Set a breakpoint on the indicate line in bar(). When it hits, evaluate &jx and copy the value.

Now set the conditional breakpoint, using that value. I used:

  *(int*)0x0073fbc8 == 2 && ix == 3

Where 0x0073fbc8 was the value I obtained at the first breakpoint. Or you can make it relative from the base pointer register. Set an unconditional breakpoint and when it hits use Debug + Windows + Registers to look at the EBP value. Subtract it from the &jx value. I used:

  *(int*)(ebp+0xd8) == 2 && ix == 3

Both worked well. Note that you'll want to turn ASLR off for the Debug build to have some hope that these addresses are repeatable from one run to another. Project + Properties, Linker, Advanced, Randomized Base Address = No.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top