16

假设我有一些基类 A 和两个派生类 B 和 C。类 A 有一些称为 f() 的方法。

有没有办法在 Visual Studio 的 A::f() 中设置条件断点,只有当我的“this”实际上是 C 类的实例时才会被命中?

例如


    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
    }

我已经设法通过在断点条件下测试虚拟表指针来实现它,但必须有更好(更简单)的方法。

提前致谢。

编辑:按照评论中的建议修改源代码并不是我正在寻找的解决方案。它只能通过 VC++ 调试器来完成。

4

4 回答 4

6

你可以。首先,确定要检查的类型的虚拟表的地址。然后使用 (arg).__vfptr != 0x01188298 之类的条件设置断点,其中 0x01188298 是您的类型 vtable 的地址。而已。

于 2011-09-13T12:41:23.760 回答
3

这是dynamic_cast为了什么。

void A::f() {
    ...
    if (dynamic_cast<C*>(this)) {
        __debugbreak();
    }
    ...
}

如果您必须通过调试器执行此操作,那么您将不得不中断,dynamic_cast在“立即”窗口中使用检查类型,如果没有,则继续。

于 2011-07-09T15:08:09.073 回答
1

在呼叫站点(即进行foo呼叫的地方),几乎不可能做到这一点。在函数本身中,您可以通过拥有一个虚函数来做到这一点,其中一个将返回true。所有其他人都会回来false。如果函数返回true,您可以调用DebugBreak函数本身。或者将其返回值放入某个bool变量中,并设置条件断点。是的,当然,这需要在所有类(或某些类)中添加一个虚函数。此外,您可以在基类中拥有一个简单bool的变量,该变量将由派生类分配。适当的派生类(C在您的情况下)可以将其分配为true. 您只能使用_DEBUG宏在调试模式下执行此虚拟/变量操作。

另一种解决方案是有一个宏,它会调用foo函数。如上所述,该实现需要基类中的虚函数/成员变量,但foo不会被修改。

#define CALL_FOO(obj) \
  if(obj->member_variable_test) DebugBreak(); \
  foo(&obj);

CALL_FOO代替foo

CALL_FOO(&c); // breakpoint is hit

虽然,这可能是不可接受的,但有效。断点正好在你需要的地方!您可以使此宏仅在调试构建中工作。

于 2011-07-09T04:43:48.527 回答
1

这篇文章似乎暗示了在 Visual Studio 中进行编程调试的可能性。

或者,如果您能够在 gcc 中编译源代码或以某种方式使用 gdb,则可以利用 python 脚本功能来创建复杂的条件断点。

这里有一些 gdb python 教程。 这是相关的 gdb 文档。

于 2011-07-09T14:45:15.833 回答