如何跟踪 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
然后 运行 您的代码并记下它进入调试器的位置。
不要直接使用 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_;
}
假设我有一个这样的 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
然后 运行 您的代码并记下它进入调试器的位置。
不要直接使用 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_;
}