Поделиться через


Неоднозначное разрешение точек останова

В версии 10.0.25310.1001 и более поздних версий обработчика отладчика теперь поддерживается неоднозначное разрешение точек останова.

Неоднозначные точки останова позволяют отладчику задавать точки останова в определенных сценариях, когда выражение точки останова разрешается в несколько расположений. Например, это может произойти, когда:

  • Несколько перегрузок функции.
  • Существует несколько символов, которые соответствуют выражению точки останова.
  • Одно и то же имя символа используется для нескольких расположений.
  • Символ был вложен.
  • Установка точки останова в функции шаблона с несколькими экземплярами в окне источника.

При включении отладчик устанавливает точку останова для каждого совпадения символов для заданного выражения точки останова. Отладчик также фильтрует символы, если выполнены определенные критерии.

Общие сведения об использовании точек останова см. в разделе "Использование точек останова".

Включение неоднозначного разрешения точек останова

По умолчанию неоднозначные точки останова отключены. Чтобы включить это в сеансе отладчика, выполните следующую команду в консоли WinDbg:

dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true;

Чтобы убедиться, что параметр неоднозначных точек останова активен:

0:010> dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints
@$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints                 : true

Дополнительные сведения об использовании команды dx см. в разделе dx (Выражение объектной модели отладчика отладчика).

Чтобы отключить функцию, задайте указанное выше значение false. Чтобы убедиться, что параметр сохраняется в сеансах, обязательно щелкните File -> Settings -> Debugger Settings и проверка полеPersist engine settings across debugger sessions.

Использование применяется к одной точке останова

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

Общие сведения о командах точки останова см. в разделе bp, bu, bm (Set Breakpoint).

Иерархические точки останова

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

Например, если команда bp foo!bar выполняется, в результате чего два совпадения с символом bar, то будет создана иерархическая точка останова, которая управляет двумя совпадениями. Если иерархический параметр включен/ отключен или очищается, то также будут соответствующие точки останова.

Bpcmds (Отображение команд точки останова) выводит список команды точки останова, которую можно запустить, чтобы задать каждую точку останова. Точки останова, принадлежащие иерархической точке останова, по-прежнему перечисляют действительную команду bp, которая установит точку останова на своем адресе. Иерархические точки останова также будут перечислены в выходных данных и будут отображаться команды, которые можно использовать для повторного создания всего набора точек останова вместо одной точки останова.

Неоднозначные символы

Установка точки останова для имени символа должна привести к следующему поведению, если символ:

  • Перегрузка: каждая перегрузка, соответствующая символу, должна иметь точку останова.

  • Функция шаблона:

    • Если выражение имеет все заданные параметры шаблона (например bp foo!bar<int>), то точка останова будет задана для конкретной реализации функции шаблона.

    • Если выражение не имеет указанной реализации типа (например bp foo!bar, то точки останова не будут заданы). В этом случае bm следует использовать для задания точек останова в функции шаблона.

    • Спецификации частичных шаблонов не поддерживаются отладчиком, и в этом случае точки останова не будут заданы.

  • Встроенная функция: каждое вложенное расположение имеет точку останова

Обратите внимание, что несколько точек останова не будут заданы, если выражение символа включает операторы или смещения, требующие дополнительной оценки отладчиком. Например, если символ foo разрешается в несколько расположений, но выражение foo+5 вычисляется, отладчик не попытается разрешить все расположения для заданных точек останова.

Примеры кода точки останова

Учитывая следующий фрагмент кода:

class BikeCatalog
{
public:
    void GetNumberOfBikes()
    {
        std::cout << "There are 42 bikes." << std::endl;
    }
    int GetNumberOfBikes(int num)
    {
        std::cout << "There are " << num << " bikes." << std::endl;
        return num;
    }
}; 

Вызов команды bu BikeCatalog::GetNumberOfBikes приведет к созданию двух точек останова, по одному для каждой перегрузки. Перечисление точек останова приведет к следующим выходным данным:

0:000> bl
     2 e Disable Clear  <hierarchical breakpoint>     0001 (0001)  0:**** {BikeCatalog!BikeCatalog::GetNumberOfBikes}
         0 e Disable Clear  00007ff6`c6f52200  [C:\BikeCatalog\BikeCatalog.cpp @ 13]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes
         1 e Disable Clear  00007ff6`c6f522a0  [C:\BikeCatalog\BikeCatalog.cpp @ 9]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes

Неоднозначные исходные строки

Установка точки останова в исходной строке должна привести к следующему поведению, если исходная строка:

  • Оптимизированная для компилятора функция: если строка разделена в нескольких расположениях из-за оптимизации компилятора, точка останова будет задана в нижнем расположении в функции, соответствующей указанной строке.
  • Встроенная функция: точка останова устанавливается для каждого из сайтов вызовов, если только указанная строка не оптимизирована в рамках встраивание.
  • Разрешено в несколько расположений: если указанные выше условия не выполнены, точка останова будет задана для каждого адреса со следующими условиями:
    • Если в выражении есть набор N-адресов , соответствующих исходной строке, и подмножество M этих N-адресов имеет нулевое перемещение исходной строки из исходной строки в выражении, то только адреса M будут иметь точки останова.
    • Если в наборе N-адресов нет адресов, которые имеют нулевое перемещение исходной строки из исходной строки в выражении, все N-адреса будут иметь точки останова.

Фильтрация на основе индекса символов

Каждый символ должен иметь уникальный индекс символов. Подробные сведения о структуре символов см. в статье SY МБ OL_INFO структура.

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

Примеры шаблонов и перегруженных функций

Функции шаблона

Установка точки останова в исходной строке определения функции шаблона приведет к точке останова для каждой реализации функции шаблона. Учитывая следующую функцию шаблона в строке 19 BikeCatalog.cpp:

template <class T>
void RegisterBike(T id)
{
    std::cout << "Registered bike " << id << std::endl;
}

И его использование:

catalog.RegisterBike("gravel bike");
catalog.RegisterBike(1234);

При вызове команды bp `BikeCatalog.cpp:19` будут заданы две точки останова, которые разрешаются реализации функции шаблона, используемой далее в файле. Если вместо этого пользователь хотел задать одну точку останова для функции, необходимо задать точку останова в конкретной исходной строке реализации функции шаблона или задать точку останова для символа функции шаблона с соответствующими сведениями о типе (например. bp BikeCatalog::RegisterBike<int>

Перечисление точек останова приводит к следующим выходным данным:

0:000> bl
     2 e Disable Clear  <hierarchical breakpoint>     0001 (0001)  0:**** {BikeCatalog!BikeCatalog::RegisterBike&lt;int&gt;}
         0 e Disable Clear  00007ff7`6b691dd0  [C:\BikeCatalog\BikeCatalog.cpp @ 20]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::RegisterBike<int>
         1 e Disable Clear  00007ff7`6b691e60  [C:\BikeCatalog\BikeCatalog.cpp @ 20]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::RegisterBike<char const *>

Перегруженные функции

Установка точки останова в исходной строке для определения перегруженной функции приведет только к одной точке останова для этого определения перегруженной функции. Повторное использование фрагмента кода из выше с первой строкой, начинающейся с строки 5:

class BikeCatalog
{
public:
    void GetNumberOfBikes()
    {
        std::cout << "There are 42 bikes." << std::endl;
    }
    int GetNumberOfBikes(int num)
    {
        std::cout << "There are " << num << " bikes." << std::endl;
        return num;
    }
}; 

При вызове команды bp `BikeCatalog.cpp:9` будет задана одна точка останова в строке для void реализации GetNumberOfBikes. Перечисление точек останова приводит к следующим выходным данным:

0:000> bl
     0 e Disable Clear  00007ff7`6b691ec0  [C:\BikeCatalog\BikeCatalog.cpp @ 9]     0001 (0001)  0:**** BikeCatalog!BikeCatalog::GetNumberOfBikes

встроенные функции

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

Несколько иерархических точек останова

Иерархические точки останова будут принадлежать каждой точке останова в его наборе, если только:

Точка останова в наборе очищается

  • Иерархическая точка останова очищается.
  • Другая иерархическая точка останова создается, которая включает точку останова в наборе иерархических точек останова.

Другой способ подумать об этом заключается в том, что точки останова могут иметь только одного иерархического владельца точки останова и что самая последняя команда точки останова определит состояние списка точек останова.

Кроме того, иерархическая точка останова не может принадлежать другой иерархической точке останова.

Вложенные точки останова

Если точка останова A существует самостоятельно, а затем неоднозначное выражение точки останова разрешается для создания точек останова A, B, то A будет включен в новый набор точек останова с B.

Вложенные иерархические пересечения точек останова

Если иерархическая точка останова A владеет точками останова B, C, а затем неоднозначным выражением точки останова разрешается для создания точек останова:

  • B, C, D: точки останова B, C присоединит новую иерархическую группу точек останова с точкой останова D, а иерархическая точка останова А будет снята.

  • C, D или B: одна из точек останова присоединится к новой иерархической группе точек останова с точкой останова D, а иерархическая точка останова A будет продолжать существовать с одной оставшейся точкой останова, которая не присоединилась к новой группе.

См. также

Использование точек останова

Синтаксис точки останова

bp, bu, bm (Установка точки останова)

Неразрешенные точки останова (бу точки останова)