简体   繁体   English

我可以在基本 class 方法中设置条件断点,该方法仅在它是特定派生 class 的实例时触发?

[英]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.

相关问题 我无法重写基类的方法,因为我的派生类已被模板化 - I can't override Base class's method because my derived class is templatised 如何从 function 调用派生类的方法,期望基本 class 指针? - How can I call a derived class's method from a function expecting the a base class pointer? 我可以使用对派生类实例的基类引用来初始化派生类引用吗? - Can I Initialize a derived class reference with a base class reference to derived class instance? 使用派生类的对象访问基类的方法,该对象具有相同名称的方法 - Accessing base class's method with derived class's object which has a method of same name 基类中的派生类实例 - Derived class instance in the base class 为什么派生类的实例调用基类的方法? - Why does an instance of a derived class call a method from the base class? 从基类实例调用派生类方法 - Call derived class method from base class instance 从基础 class 实例调用派生的 class 方法而不进行强制转换 - Call derived class method from base class instance without casting 无法调用派生类的方法 - 编译器将对象实例标识为基类 - Can't call method of derived class - compiler identifies object instance as base class 将派生的 class 作为参数传递给方法,该参数是带有智能指针的基础 class - Passing derived class to method as argument which is base class with smart pointer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM