Can I set a conditional breakpoint in base class method which triggers only if it's an instance of specific derived class?
Let's say I have some base class A and two derived classes B and C. Class A has some method called f().
Is there a way to set a conditional breakpoint in A::f() in visual studio which will be hit only when my 'this' is actually an instance of class C?
For example
void A::f()
{
some code and a breakpoint
}
void foo(A* a)
{
a->f();
}
void bar()
{
A a;
B b;
C c;
foo(&a); // breakpoint isn't hit
foo(&b); // breakpoint isn't hit
foo(&c); // breakpoint is hit
}
I've managed to achieve it by testing virtual table pointer in breakpoint's condition but there's got to be a better(more easy) way.
Thanks in advance.
EDIT: Modifying 开发者_如何学编程source code as was suggested in comments is not kind of a solution I'm looking for. It has to be done only by means of VC++ debugger.
You can. First of all, determine address of virtual table of type you wish to check against. Then setup a breakpoint with condition like (arg).__vfptr != 0x01188298 where 0x01188298 is your type vtable's address. That's it.
This is what dynamic_cast
is for.
void A::f() {
...
if (dynamic_cast<C*>(this)) {
__debugbreak();
}
...
}
If you have to do it by the debugger, then you will have to break, check the type using dynamic_cast
in the Immediate window, and then continue if not.
At the call site (i.e. where foo
call is being made), it is nearly impossible to do that.
In the function itself, you may do this by having a virtual function, one of them would return true
. All others would return false
. If function returns true
, you can call DebugBreak
function itself. Or put its return value into some bool
variable, and set conditional breakpoint. Yes, of course, this requires a virtual function to be added in all classes (or some). Additionally you can have one simple bool
variable in base class, which will be assigned by derived class. The appropriate derived class (C
in your case) can assign it as true
. You can do this virtual/variable stuff in debug mode only using _DEBUG
macro.
Another solution is to have a macro, which would call foo
function. The implementation requires a virtual-function/member-variable in base class as described above, but foo
won't be modified.
#define CALL_FOO(obj) \
if(obj->member_variable_test) DebugBreak(); \
foo(&obj);
And call CALL_FOO
in place of foo
:
CALL_FOO(&c); // breakpoint is hit
Though, this maybe unacceptable, but works. And breakpoint is hit exactly where you need! You can make this macro work only in debug-build.
This post seems to hint at the possibility of programmatic debugging in Visual Studio.
Alternatively, if you are able to compile the source in gcc or somehow utilize gdb, you may take advantage of the python scripting functionality to create complex conditional breakpoints.
Here are some gdb python tutorials. Here is the relevant gdb documentation.
精彩评论