Какие выражения допускаются в контрольных точках? - программирование
Подтвердить что ты не робот

Какие выражения допускаются в контрольных точках?

При создании точки трассировки в Visual Studio (щелкните правой кнопкой мыши точку останова и выберите "When Hit..." ), в диалоговом окне есть этот текст, на мой взгляд:

Вы можете включить в сообщение значение переменной или другое выражение, поместив ее в фигурные скобки...

Какие выражения разрешены?

4b9b3361

Ответ 1

Документация Microsoft довольно скудна в отношении точных сведений о том, что есть и что не допускается. Большинство из приведенных ниже было обнаружено методом проб и ошибок в окне Immediate. Обратите внимание, что этот список для С++, как и то, что я кодирую. Я верю в С#, некоторые из запрещенных элементов ниже разрешены.

Большинство базовых выражений могут быть оценены, включая кастинг, установку переменных и вызывающих функций.

Общие ограничения
  • Поддерживаются только C-стиль; нет static_cast, dynamic_cast, reinterpret_cast, const_cast
  • Невозможно объявить новые переменные или создать объекты
  • Нельзя использовать перегруженные операторы
  • Тернарный оператор не работает
  • Нельзя использовать оператор запятой, потому что Visual Studio использует его для форматировать результат выражения; использовать несколько наборов фигурных скобок для нескольких выражений
Вызов функций
  • Запрещенные вызовы:
    • Lambdas (не может определить или назвать их)
    • Функции в анонимном пространстве имен
    • Функции, которые принимают объекты по значению (потому что вы не можете создавать объекты)
  • Разрешенные звонки:
    • Функции-члены, как обычные, так и виртуальные
    • Функции, принимающие ссылки или указатели, как фундаментальные, так и типы классов
    • Передача переменных в области видимости
    • Использование "&" для передачи указателей на переменные в области видимости
    • Передача литералов "true", "false", numbers
    • Передача строковых литералов, если вы не запускаете правило "невозможно создать объекты"
    • Вызов нескольких функций с одной точкой трассировки с помощью нескольких наборов фигурных скобок
Назначение переменных
  • Запрещается:
    • Объекты
    • Строковые литералы
  • Разрешенные:
    • Переменные с фундаментальными типами, значения из литералов или других переменных
    • Адреса памяти после кастинга: { *(bool*)(0x1234) = true }
    • Регистры: { @eip = 0x1234 }

Использовать случаи

Функции вызова из точек трассировки могут быть достаточно мощными. Вы можете обойти большинство ограничений, перечисленных выше, с помощью тщательно настроенной функции и правильного вызова. Вот еще несколько конкретных идей.

Принудительно, если

Довольно просто: настройте точку трассировки, чтобы установить переменную, и принудительно выполните условие if в true или false, в зависимости от того, что вам нужно проверить. Все без добавления кода или выхода из отладочной сессии.

Переключение точки останова

Я несколько раз видел вопрос: "Мне нужно сломать место, которое попадает в много. Я бы просто включил эту точку останова из другой точки останова, поэтому один Я забочусь только о перерывах с определенного кода. Как я могу это сделать? С нашими знаниями выше, это легко, хотя вам нужна вспомогательная переменная.

  • Создать глобальное логическое значение, установленное на false.
  • Создайте точку останова в конечной точке назначения с условием разрыва только при наличии глобального флага.
  • Установить точки трассировки в критических точках, которые присваивают глобальный флаг true.

Хорошо, что вы можете перемещать точки трассировки, не выходя из сеанса отладки. Используйте окно Immediate или окно Watch to reset ваш глобальный флаг, если вам нужно сделать еще один запуск. Когда вы закончите, все, что вам нужно очистить, это глобальное логическое. Никакого другого кода для удаления.

Автоматически пропускать код

Регистр EIP (по крайней мере, на x86) является указателем инструкции. Если вы назначили ему, вы можете изменить поток своей программы.

  • Найдите адрес строки, в которой вы хотите перейти на, сломав ее один раз и посмотрев на значение EIP, либо в окне "Регистры", либо в окне "Часы" с "@eip, x", (Обратите внимание, что значение в окне "Регистры" является шестнадцатеричным, но без ведущего "0x".)
  • Добавьте точку трассировки на строку, которую хотите пропустить от, с выражением типа {@eip = address}, используя адрес с шага 1.
  • Назначение EIP произойдет до того, как что-либо на линии будет выполнено.

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

Ответ 2

Как говорит Курт Хатчинсон, назначение строк в контрольной точке запрещено. Вы можете обойти это, создав метод, который назначает строковую переменную и вызывает это.

public static class Helper
{
    public static void AssignTo(this string value, out string variable)
    {
        variable = value;
    }
}

Затем в сообщении вашей трассировки:

{"new string value".AssignTo(out stringVariable)}