Как отследить все места, где переменная класса модифицируется внешним кодом? - PullRequest
5 голосов
/ 15 мая 2019

Предположим, у меня есть определение класса, подобное этому:

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 ]

3 голосов
/ 15 мая 2019

Вместо непосредственного использования 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_;
    }
2 голосов
/ 15 мая 2019

На платформах Intel (и, возможно, некоторых других) gdb поддерживает понятие watchpoints , то есть аппаратную точку останова, которая срабатывает при записи в определенную ячейку памяти.

Синтаксис дляустановка точки наблюдения (без квадратных скобок):

watch -location [expr]

, в вашем случае что-то вроде:

watch -location my_object.f

Затем запустите ваш код и обратите внимание, где он ломается в отладчик.

Документация здесь и здесь

1 голос
/ 15 мая 2019

Это f одного конкретного объекта класса A?

Если да, вы можете настроить часы памяти . Он будет прерывать программу всякий раз, когда память по заданному адресу (занятая вашим полем f) изменяется.

Это может замедлить работу вашей программы, но в вашем случае оно того стоит.

...