如何跟踪由外部代码修改类变量的所有地方?

时间:2019-05-15 16:32:21

标签: c++ debugging runtime

假设我有一个这样的类定义:

class A {
private:
    Field f;
public:
   /*A hundred methods all of which modify f*/

    m1();
    m2();
    ...
    m100();
}

我们事先知道,所有这些方法(如果调用)将修改f。

假设您有一个非常意大利面的代码库。

您需要在运行时查找是否实际修改了f。

您可以使用gdb,在每个方法上设置一个断点,查看执行在哪里停止,然后展开堆栈以查看哪个方法调用了任何m *()方法。这非常慢,容易发生人为错误,在使用emscripten的代码库中或在设置某些状态后python调用C ++二进制文件的地方不一定能实现。

您可以注释掉所有这些方法,并探索代码在编译器抱怨的所有位置。这比以前的方法差很多,并且它在运行时执行,所以很难确定将实际调用哪种方法。

与上述类似,您可以将所有上述方法标记为不赞成使用,但是它或多或少都具有相同的问题。

有人对确定何时实际修改字段的建议吗?

3 个答案:

答案 0 :(得分:3)

使用包装程序,而不是直接使用Field,只要您修改了f,就可以让您知道。类似于(非常粗略):

class FieldLogWhenModified
{
    Field data_;
public:
    FieldLogWhenModified(Field f) : data_(f) {}
    FieldLogWhenModified& operator=(const FieldLogWhenModified& new_f)
    {
        data_ = new_f.data_;
        // log or alert user in some way
        return *this;
    }

和/或也许:

    Field& operator=(const Field& new_data)
    {
        data_ = new_data;
        // log or alert user in some way
        return data_;
    }

答案 1 :(得分:2)

在Intel(可能还有其他一些)平台上,gdb支持监视点的概念,即当写入特定内存位置时触发的硬件断点。

设置观察点(不带方括号)的语法为:

watch -location [expr]

所以在您的情况下,类似:

watch -location my_object.f

然后运行您的代码,并记下它在调试器中的位置。

文档herehere

答案 2 :(得分:1)

f类的一个特定对象的A吗?

如果是,则可以设置一个memory watch。只要更改了给定地址(由您的字段f占用)的内存,程序就会中断。

这可能会使您的程序运行速度变慢,但对于您来说还是值得的。