Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Assume I have a class definition like this:

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

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

We know before hand that all of these methods, if called, will modify f.

Assume you have a very spaghetti code base.

You need to find at runtime if and where f is actually modified.

You could use gdb, set a break point at every single method and see where execution stops and then unwind the stack to see which method called any of the m*() methods. This is very slow, prone to human error and not necessarily possible in a code base using emscripten, or where python calls the C++ binary after setting some state...

You could comment out all such methods and explore all places in the code where the compiler complains. This is, imho much worse than the prior, and it does do it at runtime, so it's harder to determine which method will ACTUALLY be called.

Similar as the above, you could mark all the above methods as deprecated, but it has more or less the same problems.

Does anyone have a suggestion on determining when and where the field actually gets modified?

like image 394
Makogan Avatar asked May 15 '19 16:05

Makogan


3 Answers

Instead of using Field directly, use a wrapper that lets you know whenever f is modified. Something like (very crudely):

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 perhaps:

    Field& operator=(const Field& new_data)
    {
        data_ = new_data;
        // log or alert user in some way
        return data_;
    }
like image 88
Paul Evans Avatar answered Nov 15 '22 05:11

Paul Evans


On Intel (and perhaps some other) platforms, gdb supports the notion of watchpoints, i.e. a hardware breakpoint that fires when a particular memory location is written to.

The syntax for setting a watchpoint (without the square brackets) is:

watch -location [expr]

so in your case, something like:

watch -location my_object.f

Then run your code and note where it breaks into the debugger.

Documentation here and here

like image 27
Paul Sanders Avatar answered Nov 15 '22 04:11

Paul Sanders


Is it f of one particular object of class A?

If yes, you can set up a memory watch. It will break the program whenever memory at a given address (occupied by your field f) is changed.

It may make your program go slower, but it may be worth it in your case.

like image 25
CygnusX1 Avatar answered Nov 15 '22 04:11

CygnusX1