Может ли код одного класса C ++ случайно перезаписать приватную статическую переменную другого класса? - PullRequest
0 голосов
/ 17 ноября 2018

Я имею в виду такой сценарий: существует некоторый класс (я называю это victim) с личным членом данных и другой класс (с именем attacker) с некоторым методом, который, как правило, обычно не имеет доступак закрытым членам других классов и даже не содержит ссылки на экземпляр victim:

extern "C" {
#include <pigpiod_if2.h>
}

class victim {
private:
  static bool is_ready;
  static bool is_on;
public:
  static void init ()
    {
       is_ready = true;
       is_on    = true;
    }

  /* Some other public methods go here. */
}

class attacker {
private:
  static int last_read_pin;
public:
  static void run ()
  {
    while (true) {
      /* Some sensible code goes here. */
      last_read_pin = -1;
      time_sleep (0.01); // Using nanosleep () does not change behavior.
    }
  }
}

Это всего лишь фрагмент кода, иллюстрирующий следующий вопрос: возможно ли это, а не только теоретическино также практически, что attacker::run () может изменить значения двух частных статических переменных victim непреднамеренно, без обращения к какому-либо общедоступному члену victim, возможно, из-за неопределенного поведения или даже ошибки компилятора?Спасибо.

ОБНОВЛЕНИЕ: После подсказки от другого пользователя я полностью перестроил приложение, используя make clean и make.Кроме того, я добавил бесконечный цикл в мой пример.Изменение в is_ready происходит во время шестого цикла цикла.Однако изменение интервала сна не меняет поведения.

ОБНОВЛЕНИЕ № 2: Я пропустил свой код через gdb, наблюдая за переменной is_ready, и получил предупреждениекогда last_read_pin был установлен в –1:

Hardware watchpoint 1: is_ready

Old value = true
New value = false
attacker::Run ()
last_read_pin       = -1;

ОБНОВЛЕНИЕ № 3: Перемещение last_read_pin в сам метод Run (), что делает его внутренней переменной, не делаетhelp help.

ОБНОВЛЕНИЕ № 4: После простого закомментирования строки кода, которая создает много проблем, проблема все еще сохраняется, очевидно вызванная одной строкой выше, которая читается какэто:

keypad::last_levels [h] [k] = 0;

Мне также пришлось закомментировать эту строку, чтобы избавиться от проблемы с изменением is_ready.

Возможно ли использованиеpigpiod вызвать эту проблему?В более ранней версии я использовал pigpio напрямую и не сталкивался с этой проблемой.

Скомпилировано с gcc 4.9.2.

1 Ответ

0 голосов
/ 23 ноября 2018

Плавая вокруг рассматриваемой строки кода, я обнаружил, что ошибка была в строке перед , которая гласит:

last_levels [h] [l] = 0;

К сожалению, hможет быть <0. В этом случае следует выдать какое-то исключение (индекс массива за пределами границ), но, к сожалению, это не так (кто-нибудь знает, почему?).GDB дал мне неверную информацию о перезаписи <code>is_ready, которая произошла в следующей строке (возможно, это ошибка?), И я поверил этому без какой-либо критики.Как будто этого было недостаточно, эта ошибка не создавала проблем, пока я не изменил свой код в совершенно другом месте!

Эта ошибка стоила мне довольно много времени, но теперь, наконец, я знаю, в чем причинабыл, и я исправил это успешно.В любом случае, спасибо за ваши советы и комментарии!

...