Visual Studio Breakpoint Macro для изменения значения? - PullRequest
6 голосов
/ 06 октября 2010

Я отлаживаю приложение (C ++), и я нашел в коде точку, где я хочу изменить значение (через отладчик).Итак, прямо сейчас у меня есть набор точек останова, после чего я делаю:

  • Отладчик достигает точки останова
  • Я изменяю переменную, которую хочу изменить
  • Я нажимаюF5 для продолжения работы
  • вспенить, промыть, повторить

Эта точка останова очень часто, поэтому я хотел бы автоматизировать это.Я хотел бы установить точку останова для запуска макроса и продолжения выполнения.

Однако у меня нет опыта написания макросов VisualStudio, поэтому я не знаю команд для изменения переменной исполняемой программы.Я посмотрел вокруг, но пока не нашел ничего полезного в Интернете.

Ответы [ 5 ]

12 голосов
/ 06 октября 2010

Я нашел, как это сделать с помощью макроса.Сначала я пытался использовать Ctrl-Shift-R для записи макроса нажатий клавиш, но он прекратил запись, когда я нажал Ctrl-Alt-Q.Но я смог отредактировать макрос, чтобы заставить его работать.Итак, вот что я сделал, если кто-то еще захочет сделать нечто подобное.

  • Инструменты -> Макросы -> Обозреватель макросов
  • Щелкните правой кнопкой мыши -> Новый макрос

    Public Module RecordingModule
        Sub setvalue()
            DTE.Debugger.ExecuteStatement("variable_name=0")
        End Sub
    End Module
    

Этот макрос выполнит оператор присваивания, установив мою переменную (в данном случае, сделав ее нулевым указателем).

  • Щелкните правой кнопкой мыши точку останова-> При нажатии ...
  • Проверка "Запуск макроса"
  • Выбор Macros.MyMacros.RecordingModule.setvalue
  • Проверка "Продолжить выполнение"
  • Нажмите OK

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

4 голосов
/ 14 марта 2013

Ищите подобное сегодня и обнаружили, что вы также можете использовать опцию «Напечатать сообщение:» вместо макроса. Значения из кода можно распечатать, поместив их внутри {}. Ключевым моментом является то, что VS также будет оценивать содержимое как выражение - поэтому {имя_переменной = 0} должно достичь того же, что и в примере с макросом.

0 голосов
/ 01 марта 2014

Выберите «Условие ...» и напишите присвоение для рассматриваемой переменной в текстовом поле «Условие:». Это естественным образом разрешит значение «истина», поскольку оно не является фактическим условным тестом. Поэтому точка останова никогда не достигается, и ваша переменная была установлена ​​соответствующим образом.

0 голосов
/ 06 октября 2010

Вы можете выполнить макрос VS при достижении точки останова (откройте окно точек останова, щелкните правой кнопкой мыши по рассматриваемой точке останова и выберите «При ударе ...» во всплывающем меню). Я менее уверен в написании макроса, который изменяет переменную отлаживаемой программы - я никогда этого не делал, и быстрая попытка записи макроса, чтобы сделать это, похоже, не работает (все это records активирует правое окно, не меняя значения).

0 голосов
/ 06 октября 2010

Если вы думаете о макросе так же, как Microsoft Excel, то вам не повезло. Это не совсем так работает.

В C ++ макрос ссылается на небольшую встроенную функцию, созданную с помощью #define. Это препроцессор, поэтому макрос похож на использование замены для всех своих ссылок со своим телом.

Например:

#define add(a,b) ((a)+(b))

int main() {
  int a=3, b=4, c=5, d=6, e, f;
  d = add(a,b);
  e = add(c,d);
}

Хотелось бы, чтобы компилятор c ++ был:

int main() {
  int a=3, b=4, c=5, ...;
  d = ((a)+(b));
  e = ((c)+(d));
}

Теперь вернемся к вашему вопросу. Если переменная находится в области видимости в этой точке останова, просто установите ее из своего кода:

myVar = myValue;

Если это не так, но он гарантированно существует, вам может понадобиться небольшой взлом. Скажите, что эта переменная является int, создайте глобальный указатель на int. Если эта переменная является статической, убедитесь, что для нее задан ее адрес, и обратно в NULL внутри ее области. Если он динамический, вам может потребоваться дополнительная работа. Вот пример:

int* globalIntPointer;

void func() {
  *globalIntPointer = 3;
  //...
}

int main() {
  int a = 5;
  globalIntPointer = &a;
  func();
  //...
  globalIntPointer = NULL; // for safety sake
  return 0;
}
...