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

How to track all places where a class variable is modified by external code?

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

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

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

我们事先知道所有这些方法,如果被调用,都会修改 f。

假设您有一个意大利面条式的代码库。

您需要在运行时查找 f 是否以及在何处实际修改。

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

您可以注释掉所有此类方法并探索代码中编译器出错的所有地方。恕我直言,这比之前的要糟糕得多,而且它确实在运行时执行,因此更难确定实际将调用哪个方法。

和上面类似,你可以将上面的所有方法都标记为已弃用,但它或多或少存在相同的问题。

有人对确定字段实际修改的时间和地点有建议吗?

它是 f class A 的一个特定对象吗?

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

这可能会使您的程序变慢,但对您来说可能是值得的。

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

设置观察点的语法(没有方括号)是:

watch -location [expr]

所以在你的情况下,是这样的:

watch -location my_object.f

然后 运行 您的代码并记下它进入调试器的位置。

文档here and here

不要直接使用 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;
    }

And/or 或者:

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