[英]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 和两个派生类 B 和 C。 Class A has some method called f(). Class A 有一些称为 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?有没有办法在 Visual Studio 的 A::f() 中设置条件断点,只有当我的“this”实际上是 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.它只能通过 VC++ 调试器来完成。
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.然后使用 (arg).__vfptr.= 0x01188298 之类的条件设置断点,其中 0x01188298 是您的类型 vtable 的地址。 That's it.而已。
This is what dynamic_cast
is for.这就是dynamic_cast
的用途。
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.如果你必须通过调试器来做,那么你将不得不中断,使用即时 window 中的dynamic_cast
检查类型,如果没有,则继续。
This post seems to hint at the possibility of programmatic debugging in Visual Studio. 这篇文章似乎暗示了在 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.或者,如果您能够在 gcc 中编译源代码或以某种方式利用 gdb,您可以利用 python 脚本功能来创建复杂的条件断点。
Here are some gdb python tutorials. 这里有一些 gdb python 教程。 Here is the relevant gdb documentation. 这是相关的 gdb 文档。
At the call site (ie where foo
call is being made), it is nearly impossible to do that.在呼叫站点(即进行foo
呼叫的地方),几乎不可能做到这一点。 In the function itself, you may do this by having a virtual function, one of them would return true
.在 function 本身中,您可以通过拥有一个虚拟 function 来做到这一点,其中一个将返回true
。 All others would return false
.所有其他人都会返回false
。 If function returns true
, you can call DebugBreak
function itself.如果 function 返回true
,您可以调用DebugBreak
function 本身。 Or put its return value into some bool
variable, and set conditional breakpoint.或者将其返回值放入某个bool
变量中,并设置条件断点。 Yes, of course, this requires a virtual function to be added in all classes (or some).是的,当然,这需要在所有类(或某些类)中添加一个虚拟 function。 Additionally you can have one simple bool
variable in base class, which will be assigned by derived class.此外,您可以在基础 class 中拥有一个简单的bool
变量,它将由派生的 class 分配。 The appropriate derived class ( C
in your case) can assign it as true
.适当的派生C
(在您的情况下为 C )可以将其分配为true
。 You can do this virtual/variable stuff in debug mode only using _DEBUG
macro.您只能使用_DEBUG
宏在调试模式下执行此虚拟/变量操作。
Another solution is to have a macro, which would call foo
function.另一种解决方案是有一个宏,它会调用foo
function。 The implementation requires a virtual-function/member-variable in base class as described above, but foo
won't be modified.如上所述,该实现需要基础 class 中的虚函数/成员变量,但foo
不会被修改。
#define CALL_FOO(obj) \
if(obj->member_variable_test) DebugBreak(); \
foo(&obj);
And call CALL_FOO
in place of foo
:并调用CALL_FOO
代替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.您可以使此宏仅在调试构建中工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.