Как отладить один поток в Visual Studio? - PullRequest
230 голосов
/ 15 марта 2011

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

Я знаю, что это возможно через определение условия на точке останова, то есть имя потока = ... или идентификатор потока = ... но мой случай сильно загружен ASP.NET приложение, и как только я присоединяюсь к w3wp.exe, многие потоки достигнут точек останова. Мне нужно что-то вроде ThreadLocal<break-point>.

Возможно ли это? Если да, то как?

Ответы [ 8 ]

313 голосов
/ 29 июня 2011

Вот что я сделал:

  1. Установите условную точку останова, которая, как я знал, будет попадать только в поток, который я искал.

  2. После достижения точки останова и перехода в нужный поток в окне Потоки Visual Studio (при отладке, Отладка -> Windows -> Потоки) Ctrl + A (чтобы выбрать все темы), а затем Ctrl + щелкните по теме, в которой вы находитесь.У вас должны быть все потоки, кроме той, которую вы хотите отлаживать.

  3. Щелкните правой кнопкой мыши и выберите «Заморозить».

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

140 голосов
/ 15 мая 2014

Замораживание / оттаивание потоков - неправильный способ, потому что другие потоки не выполняют никакого кода.

Самый правильный и удобный способ:

  1. Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
  2. Щелкните правой кнопкой мыши и выберите «Фильтр ...».
  3. Введите "ThreadId = (текущий идентификатор потока)".

В Visual Studio 2015 и новее процесс аналогичен:

  1. Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
  2. Щелкните правой кнопкой мыши и выберите «Настройки ...».
  3. Отметьте «Условия» и выберите «Фильтр» в выпадающем списке
  4. Введите "ThreadId = (текущий идентификатор потока)".

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

13 голосов
/ 10 октября 2013

Я только что выпустил расширение Visual Studio 2010+, которое делает именно то, что вы ищете. И это бесплатно :).

Презентация

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

Это значительно снижает необходимость вручную заходить в окно «Потоки», чтобы заморозить / разморозить все потоки, кроме того, которое необходимо соблюдать, и, следовательно, помогает повысить производительность.

Особенности

Ограничить дальнейшее выполнение только текущим потоком. Заморозит все остальные темы. Сочетание клавиш: CTRL + T + T или кнопка Снежинка. Перейти к следующему отдельному потоку (на основе идентификатора). Изменит текущую тему и заморозит все остальные темы. Сочетание клавиш: CTRL + T + J или кнопка «Далее».

Проверьте это здесь, в Галерее , на официальной странице или в Github хранилище .

10 голосов
/ 18 ноября 2014

Если несколько потоков создаются как для веб-приложения, ответы @MattFaus не будут работать.Вместо этого я сделал следующее:

  • Настройка точки останова для прерывания потока в функции, которую я хочу.
  • Как только поток достигает точки останова и приостанавливается, я удаляюостановите и продолжайте отладку, используя F8, F10 и F11, чтобы другие потоки могли работать.
8 голосов
/ 30 сентября 2014

A слегка другой подход, который я использовал:

  1. Создайте нормальную точку останова и дайте ей попасть
  2. Посмотрите в окне ваших потоков дляID управляемого потока, который вы в данный момент отлаживаете
  3. Щелкните правой кнопкой мыши по точке останова в окне точек останова и выберите фильтр
  4. Введите ThreadId = xxx, где xxx - это идентификатор потока от 2
  5. Теперь вы можете выполнять отладку, не останавливая другие потоки и не затрагивая вашу точку останова

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

1 голос
/ 04 марта 2016

Я думаю, что это немного отличается в Visual Studio 2015. Они несколько изменили точки останова, но вот как применить принятый ответ от hzdbyte (выше):

В точке останова в поле кодирования щелкните правой кнопкой мыши> Условия> Изменить с «Условное выражение» на «Фильтр». Затем это позволяет вам фильтровать по ThreadId.

В качестве альтернативы в точке останова в окне «Точки останова» щелкните правой кнопкой мыши> Настройки>, отметьте поле «Условия» и выполните вышеуказанное.

1 голос
/ 20 ноября 2011

Если вы не хотите останавливать все остальные потоки (возможно, вы подключаете отладчик Visual Studio к работающему приложению, которому нужно отвечать на запросы), вы можете использовать макрос, который автоматически создает и удаляет точки останова.

Это предлагается в ответе на вопрос переполнения стека «Перешагнуть» при отладке многопоточных программ в Visual Studio .

Однако по ссылке только объясняется, какотладка построчно.Я предлагаю вам изменить макрос (если вам это удобно), чтобы он изменил все точки останова (например, в заданном диапазоне строк), чтобы останавливаться только на текущем потоке.

1 голос
/ 15 марта 2011

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

Однако, если это абсолютно необходимо и вам нужна статистика решения, я уверен, что вы можете добавить точку останова, которая прерывается, только если поступает запросс вашего IP-адреса.Это можно сделать, добавив условную точку останова, которая проверяет HttpContext.Request.UserHostAddress.Обратите внимание, что это значительно замедляет работу вашего приложения.

...