Как отлаживать один поток в Visual Studio?
У меня есть решение с некоторыми проектами. В разных проектах есть несколько точек разрыва. Я хочу, чтобы первый поток попал в одну из этих точек останова и продолжал отслеживать этот единственный поток, несмотря на то, что другие потоки входили в одни и те же кодовые блоки.
Я знаю, что это возможно, определяя условие на точке прерывания, то есть имя потока =... или поток Id =... но мой случай - это тяжелая загруженная ASP.NET, и как только я присоединюсь к w3wp.exe
, многие потоки попадут в точки останова. Мне нужно что-то вроде ThreadLocal<break-point>
.
Возможно ли это? Если да, то как?
Ответы
Ответ 1
Потоки замораживания/отталкивания являются неправильным способом, поскольку другие потоки не выполняют никакого кода.
Самый правильный и полезный способ:
- Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
- Щелкните правой кнопкой мыши и выберите "Фильтр...".
- Введите "ThreadId = (текущий поток id)".
В Visual Studio 2015 и новее процесс похож:
- Нажмите Ctrl + A в окне точек останова (выберите все точки останова).
- Щелкните правой кнопкой мыши и выберите "Настройки...".
- Проверьте "Условия" и выберите "Фильтр" в раскрывающемся меню
- Введите "ThreadId = (текущий поток id)".
Итак, все потоки выполняются, но отладчик ударяет только по текущему потоку.
Ответ 2
Вот что я сделал:
-
Установите условную точку прерывания, чтобы я знал бы, только ударил по нитке что я искал.
-
Как только точка останова попадет в нужный вам поток, в окне "Темы Visual Studio" (при отладке, "Отладка" → "Windows → Темы" ), Ctrl + A (чтобы выбрать все потоки), а затем Ctrl + щелкните поток, в котором вы сейчас находитесь. У вас должны быть все потоки, кроме тех, которые вы хотите отлаживать.
- Щелкните правой кнопкой мыши и выберите "Заморозить".
Теперь Visual Studio будет только проходить через оттаиваемый поток. Похоже, что это происходит намного медленнее, по-видимому, потому, что ему нужно перебирать все замороженные потоки, но это привнесло некоторую здравомыслие в мою многопоточную отладку.
Ответ 3
Я только что выпустил расширение Visual Studio 2010+, которое делает именно то, что вы ищете.
И это бесплатно :).
Presentation
Это расширение Visual Studio добавляет два ярлыка и кнопки на панели инструментов, чтобы разработчики могли легко сосредоточиться на отдельных потоках при отладке многопоточных приложений.
Это значительно снижает необходимость вручную заходить в окно "Потоки", чтобы заморозить/разморозить все потоки, кроме того, которое необходимо соблюдать, и, следовательно, помогает повысить производительность.
Features
Ограничить дальнейшее выполнение только текущим потоком. Заморозит все остальные темы. Сочетание клавиш: CTRL + T + T или кнопка Снежинка. Перейти к следующему отдельному потоку (на основе идентификатора). Изменит текущую тему и заморозит все остальные темы. Сочетание клавиш: CTRL + T + J или следующая кнопка.
Проверьте это здесь, в галерее, на официальной странице или в репозитории Github.
Ответ 4
Если несколько потоков генерируются как для веб-приложения, ответ @MattFaus не будет работать. вместо этого я сделал следующее
- Настройте точку останова, чтобы прервать поток в функции, которую я хочу.
- Как только поток попадает в точку останова и приостанавливается, я удаляю точку останова и продолжаю отладку с помощью F8, F10 и F11, так что остальные потоки могут запускаться.
Ответ 5
Несколько иной подход, который я использовал:
- Создайте нормальную точку останова и пусть она попадет
- Посмотрите в окне ваших потоков идентификатор управляемого потока, который вы используете для текущей отладки
- Щелкните правой кнопкой мыши точку останова в окне точек останова и выберите фильтр
- Введите ThreadId = xxx, где xxx - это идентификатор потока из 2
- Теперь вы можете отлаживать, не останавливая другие потоки, и без их удара по точке останова.
Предполагается, что у вас есть время, чтобы сделать это, прежде чем второй поток попадет в точку останова. Если это не так, и другие потоки попали в точку останова до того, как вы сделали это, вы можете щелкнуть их правой кнопкой мыши в окне потоков и выбрать "заморозить".
Ответ 6
Я бы предложил добавить еще один экземпляр приложения на реальном сервере, либо на том же оборудовании, либо на новом компьютере (кластер), а затем отлаживать только этот экземпляр. Я бы не добавил точку останова в загрузке кода. Если это не вариант, я бы добавил больше трассировки.
Однако, если это абсолютно необходимо, и вам нужен stat решения, я уверен, вы можете добавить точку останова, которая ломается, только если запрос поступает с вашего IP-адреса. Вы сделали бы это, добавив условную точку останова, которая проверит HttpContext.Request.UserHostAddress
. Обратите внимание, что это значительно замедляет ваше приложение.
Ответ 7
Если вы не хотите останавливать все остальные потоки (возможно, вы прикрепляете отладчик Visual Studio к запущенному приложению, которое должно отвечать на запросы), вы можете использовать макрос, который автоматически создает и удаляет точки останова.
В предлагается ответ на вопрос "Переполнение стека" при отладке многопоточных программ в Visual Studio.
Однако ссылка только объясняет, как отлаживать строку за строкой. Я предлагаю вам изменить макрос (если вам удобно с ним), чтобы он изменял все точки останова (в данном диапазоне строк, например), чтобы останавливаться только на текущем потоке.
Ответ 8
Я думаю, что это немного отличается в Visual Studio 2015. Они изменили несколько вещей в точках прерывания, но здесь, как применить принятый ответ от hzdbyte (выше):
В точке останова в поле кодирования щелкните правой кнопкой мыши > Условия > Изменить с "Условное выражение" на "Фильтр". Затем вы можете фильтровать ThreadId.
В качестве альтернативы в точке останова в окне "Точки останова" щелкните правой кнопкой мыши > "Настройки" > отметьте поле "Условия" и выполните указанные выше действия.
Ответ 9
Установите условие точки останова, щелкнув правой кнопкой мыши на боковой панели линии. Выберите "Условие" и введите в кавычки следующее имя:
System.Threading.Thread.CurrentThread.Name == "name_of_your_thread"
В качестве альтернативы вы можете сделать то же самое, получив поток "Управляемый идентификатор" из окна "Потоки" и используя:
System.Threading.Thread.CurrentThread.ManagedThreadId == your_managed_thread_id