отладка многопоточных приложений c
Практическое руководство. Отладка в высокопроизводительном кластере (C#, Visual Basic, C++)
Отладка многопроцессной программы на высокопроизводительном кластере аналогична отладке обычного приложения на удаленном компьютере. Однако, существуют некоторые дополнительные соображения. Общие требования к удаленной установке см. в разделе Удаленная отладка.
При отладке на кластере высокой производительности можно использовать все окна отладки Visual Studio и методы, которые доступны для удаленной отладки. Однако, так как отладка происходит удаленно, то внешнее окно консоли не доступно.
Окна Потоки и Процессы особенно полезны для отладки параллельных приложений. Советы по использованию этих окон см. в разделах Практическое руководство. Использование окна процессов и Пошаговое руководство. Отладка с помощью окна потоков.
Следующие процедуры показывают некоторые методы, которые особенно полезны для отладки на кластере высокой производительности.
При отладке параллельного приложения может потребоваться установить точку останова на определенном потоке, процессе или компьютере. Это можно сделать путем создания обычной точки останова и добавления затем фильтра точки останова.
Открытие диалогового окна фильтра точки останова
Щелкните правой кнопкой мыши глиф точки останова в окне исходного кода, окне Дизассемблированный код, окне Стек вызовов или в окне точки останова.
В контекстном меню выберите команду Фильтр. Этот параметр может появиться на верхнем уровне или в подменю точки останова.
Установка точки останова на определенном компьютере
Получите имя компьютера из окна Процессы.
Выберите точку останова и откройте диалоговое окно Фильтр точки останова, как описано в предыдущей процедуре.
В диалоговом окне Фильтр точки останова введите:
Нажмите кнопку ОК.
Установка точки останова на определенном процессе
Получите имя или идентификатор процесса из окна Процессы.
Выберите точку останова и откройте диалоговое окно Фильтр точки останова аналогично первой процедуре.
В диалоговом окне Фильтр точки останова введите:
Нажмите кнопку ОК.
Установка точки останова на определенном потоке
Получите имя или идентификатор потока из окна Потоки.
Выберите точку останова и откройте диалоговое окно Фильтр точки останова аналогично первой процедуре.
В диалоговом окне Фильтр точки останова введите:
Нажмите кнопку ОК.
Пример
(MachineName = marvin) & (ThreadName = fourier1)
Средства для отладки потоков и процессов в Visual Studio
Потоки и процессы — это связанные понятия в вычислительной технике. Оба представляют из себя последовательность инструкций, которые должны выполняться в определенном порядке. Инструкции в отдельных потоках или процессах, однако, могут выполняться параллельно.
Процессы существуют в операционной системе и соответствуют тому, что пользователи видят как программы или приложения. Поток, с другой стороны, существует внутри процесса. По этой причине потоки иногда называются облегченными процессами. Каждый процесс состоит из одного или более потоков.
Существование нескольких процессов позволяет компьютеру «одновременно» выполнять несколько задач. Существование нескольких потоков позволяет процессу разделять работу для параллельного выполнения. На многопроцессорном компьютере процессы или потоки могут работать на разных процессорах. Это позволяет выполнять реально параллельную работу.
Абсолютно параллельная обработка не всегда возможна. Потоки иногда должны синхронизироваться. Один поток может ожидать результата другого потока, или одному потоку может понадобиться монопольный доступ к ресурсу, который используется другим потоком. Проблемы синхронизации являются распространенной причиной ошибок в многопоточных приложениях. Иногда поток может закончиться, ожидая ресурс, который никогда не будет доступен. Это кончается состоянием, которое называется взаимоблокировкой.
Отладчик Visual Studio предоставляет мощные, но простые в использовании средства отладки потоков и процессов.
Инструменты и возможности
Средства, которые необходимо использовать в Visual Studio, зависят от типа кода, который вы пытаетесь отладить:
Основные средства для работы с процессами — это диалоговое окно Присоединение к процессу, окно Процессы и панель инструментов Место отладки.
Основные средства для отладки потоков — это окно Потоки, маркеры потоков в окнах исходного кода, окно Параллельные стеки, окно Контроль параллельных данных и панель инструментов Место отладки.
Для кода, использующего Task в библиотеке параллельных задач (TPL), среду выполнения с параллелизмом (машинный код), основными средствами отладки многопоточных приложений являются окно Параллельные стеки, окно Контроль параллельных данных и окно Задачи (окно Задачи также поддерживает объект promise JavaScript).
Основным средством отладки потоков в GPU является окно Потоки GPU.
В следующей таблице показаны доступные данные и действия, которые можно выполнять в каждом из этих мест:
Пользовательский интерфейс | Доступные сведения | Действия, которые можно выполнять |
---|---|---|
Диалоговое окно Присоединение к процессу | Доступные процессы для присоединения: — Имя процесса (EXE) | Выберите процесс для присоединения Выберите удаленный компьютер Измените тип транспортного протокола для подключения к удаленным компьютерам |
Окно процессов | Присоединенные процессы: — Имя процесса | Средства: — Присоединить — Присоединить |
Окно Потоки | Потоки текущего процесса: — Идентификатор потока | Средства: — Поиск — Показать потоки в исходном коде Отладка нескольких процессов (C#, Visual Basic, C++)В Visual Studio можно выполнять отладку решения, имеющего несколько процессов. Можно запускать несколько процессов, переключаться между ними, прерывать и возобновлять их выполнение, пошагово проходить исходный код, останавливать отладку, завершать отдельные процессы или отсоединяться от них. Запуск отладки с несколькими процессамиЕсли в решении Visual Studio могут независимо выполняться несколько проектов, можно выбрать проект, запускаемый отладчиком. Текущий запускаемый проект отображается полужирным шрифтом в обозревателе решений. Чтобы изменить запускаемый проект, правой кнопкой мыши щелкните имя другого проекта в обозревателе решений и выберите Назначить запускаемым проектом. Чтобы начать отладку проекта из обозревателя решений без его назначения запускаемым, щелкните проект правой кнопкой мыши и выберите Отладка > Запустить новый экземпляр или Шаг с заходом в новый экземпляр. Назначение запускаемого проекта или нескольких проектов на странице свойств решения Выберите решение в обозревателе решений и щелкните значок Свойства на панели инструментов либо щелкните это решение правой кнопкой мыши и выберите пункт Свойства. На странице Свойства выберите Общие свойства > Запускаемый проект. Выберите Текущий выбор, Один запускаемый проект и файл проекта либо выберите Несколько запускаемых проектов. Если выбран параметр Несколько запускаемых проектов, можно изменить порядок запуска и действие для каждого проекта: Запустить, Запустить без отладки или Нет. Нажмите Применить или OK, чтобы применить изменения и закрыть диалоговое окно. Присоединение к процессуОтладчик также может присоединяться к приложениям, выполняемым в процессах вне Visual Studio, включая процессы на удаленных устройствах. После присоединения к приложению можно использовать отладчик Visual Studio. Функции отладки могут быть ограничены. Это зависит от того, было ли приложение построено с отладочной информацией, есть ли у вас доступ к исходному коду приложения и отслеживает ли JIT-компилятор отладочную информацию. Присоединение к выполняющемуся процессу: После запуска приложения выберите Отладка > Присоединить к процессу. В диалоговом окне Присоединение к процессу выделите процесс в списке Доступные процессы и щелкните Присоединить. Отладчик не присоединяется автоматически к дочернему процессу, который запущен отлаживаемым процессом, даже если дочерний проект находится в том же решении. Чтобы выполнить отладку дочернего процесса, подключитесь к дочернему процессу после его запуска или настройте редактор реестра Windows для запуска дочернего процесса в новом экземпляре отладчика. Использование редактора реестра для автоматического запуска процесса в отладчикеВ некоторых случаях может потребоваться отладить код запуска для приложения, которое запускается другим процессом. К ним относятся службы и действия пользовательской настройки. Можно запустить отладчик и автоматически присоединить его к приложению. Запустите редактор реестра Windows с помощью regedit.exe. В редакторе реестра перейдите к параметрам выполнения файла HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image. Выберите папку приложения, которое требуется запустить в отладчике. Если приложение не указано в качестве дочерней папки, щелкните правой кнопкой мыши Параметры выполнения файла образа, выберите Создать > Раздел и введите имя приложения. Или щелкните правой кнопкой мыши новый раздел в дереве, выберите команду Переименовать, а затем введите имя приложения. Щелкните правой кнопкой мыши новый раздел в дереве и выберите Создать > Строковое значение. Щелкните debugger правой кнопкой мыши и выберите Изменить. В диалоговом окне Изменение строки введите vsjitdebugger.exe в поле Данные значения, а затем нажмите кнопку OK. Отладка с несколькими процессамиПри отладке приложения с несколькими процессами команды прерывания, пошагового выполнения и продолжения выполнения затрагивают все процессы по умолчанию. Например, когда процесс приостанавливается в точке останова, выполнение всех остальных процессов также приостанавливается. Можно изменить это принимаемое по умолчанию поведение, чтобы обрести больший контроль над целевыми объектами команд выполнения. Включение или отключение приостановки всех процессов при прерывании одного процесса Команды прерывания, пошагового выполнения и продолжения выполненияВ следующей таблице описано действие команд отладки при установке или снятии флажка Прерывать все процессы при прерывании одного процесса. Поиск исходных файлов и файлов символов (PDB)Для перехода по исходному коду процесса отладчику требуется доступ к исходным файлам и файлам символов процесса. Дополнительные сведения см. в разделе Указание файлов символов (PDB) и исходных файлов. Если не удается получить доступ к файлам процесса, для перемещения можно воспользоваться окном Дизассемблирование. Дополнительные сведения см. в разделе Практическое руководство. использовать окно дизассемблирования. Переключение между процессамиВо время отладки можно подключиться к нескольким процессам, но в любой момент времени только один из них будет активным в отладчике. Активный или текущий процесс можно выбрать с помощью панели инструментов Место отладки или в окне Процессы. Для переключения между процессами оба процесса должны находиться в режиме приостановки выполнения. Установка текущего процесса на панели инструментов «Место отладки» Чтобы открыть панель инструментов Место отладки, выберите Вид > Панели инструментов > Место отладки. Во время отладки на панели инструментов Место отладки в раскрывающемся списке Процесс выберите процесс, который необходимо задать в качестве текущего. Установка текущего процесса в окне «Процессы» Чтобы открыть окно Процессы, во время отладки выберите Отладка > Окна > Процессы. В окне Процессы текущий процесс будет отмечен желтой стрелкой. Дважды щелкните процесс, который необходимо задать в качестве текущего. Переключение к процессу делает этот процесс текущим процессом для отладки. Статус текущего процесса отображается в окнах отладчика, и все команды пошагового выполнения влияют только на текущий процесс. Остановка отладки с несколькими процессамиПо умолчанию при выборе Отладка > Остановить отладку отладчик завершается или отсоединяется от всех процессов. Если в отладчике был запущен текущий процесс, этот процесс завершается. Если отладчик был присоединен к текущему процессу, отладчик отсоединяется от процесса, не прекращая его выполнение. Если отладка процесса запущена из решения Visual Studio, присоединитесь к другому уже запущенному процессу, затем выберите Остановить отладку и сеанс отладки завершится. Процесс, запущенный в Visual Studio, завершится, а процесс, к которому вы присоединились, продолжит выполняться. Чтобы управлять влиянием параметра Остановить отладку на отдельный процесс, в окне Процессы щелкните процесс правой кнопкой мыши и выберите или снимите флажок Отсоединиться при остановке отладки. Параметр отладчика Прерывать все процессы при прерывании одного не влияет на поведение остановки, завершения процессов и отсоединения от процессов. Команды остановки, окончания и отсоединенияВ следующей таблице описаны действия команд отладчика по остановке, завершению и отсоединению с несколькими процессами. Отладка многопоточных приложений в Visual StudioПоток — это последовательность инструкций, которой операционная система предоставляет время процессора. Каждый процесс, выполняющийся в операционной системе, состоит по крайней мере из одного потока. Процессы, имеющие более одного потока, называются многопоточными. Компьютеры с несколькими процессорами, с многоядерными процессорами или процессами с технологией Hyper-Threading могут выполнять несколько одновременных потоков. Параллельная обработка с использованием нескольких потоков может значительно повысить производительность программы, но также может сделать отладку намного сложнее, так как появляется необходимость следить за несколькими потоками Кроме того, многопоточность связана с возникновением новых типов потенциальных ошибок. Например, двум потокам или более может потребоваться доступ к ресурсу, но в каждый момент времени только один может делать это безопасно. Необходимо взаимное исключение для того, чтобы только один поток имел доступ к ресурсу в каждый момент времени. Если взаимное исключение реализуется неверно, может случиться взаимоблокировка, когда ни один поток не будет выполняться. Взаимоблокировки часто являются серьезной проблемой, которую сложно устранить. Средства отладки многопоточных приложенийВ Visual Studio доступны различные средства для отладки многопоточных приложений. Основные средства для отладки потоков — это окно Потоки, маркеры потоков в окнах исходного кода, окно Параллельные стеки, окно Контроль параллельных данных и панель инструментов Место отладки. Сведения об окне Потоки и панели инструментов Место отладки см. в статье Пошаговое руководство. отладка с помощью окна потоков. Сведения об использовании окон Параллельные стеки и Контроль параллельных данных см. в статье Начало отладки многопоточных приложений. В обеих статьях рассматривается использование маркеров потоков. Для кода, использующего библиотеку параллельных задач (TPL) или среду выполнения с параллелизмом, основными средствами отладки являются окно Параллельные стеки, окно Контроль параллельных данных и окно Задачи, которое также поддерживает JavaScript. Чтобы начать работу, см. статьи Пошаговое руководство. Отладка параллельного приложения и Пошаговое руководство. Отладка приложения C++ AMP. Основным средством отладки потоков в GPU является окно Потоки GPU. См. практическое руководство по Использование окна потоков GPU. Основные средства для работы с процессами — это диалоговое окно Присоединение к процессу, окно Процессы и панель инструментов Место отладки. Visual Studio также предоставляет эффективные средства для работы с точками останова и трассировки, что может быть полезно при отладке многопоточных приложений. Используйте условия и фильтры точек останова для установки точек останова в отдельных потоках. Точки трассировки дают возможность отслеживать выполнение программы без прерывания ее выполнения. Это может быть полезно для изучения неполадок, таких как взаимоблокировки. Дополнительные сведения см. в статье Действия точки останова и точки отслеживания. Отладка многопоточного приложения, которое имеет пользовательский интерфейс, может быть особенно сложной. Можно рассмотреть выполнение приложения на втором компьютере и использовать удаленную отладку. Дополнительные сведения см. в статье Удаленная отладка. Статьи об отладке многопоточных приложенийОбзор функций отладки потоков с акцентом на возможности в окне Параллельные стеки и окне Контроль параллельных данных. Перечень функций средств для отладки потоков и процессов в Visual Studio. Поясняет принципы отладки нескольких процессов. Пошаговое руководство по использованию окна Потоки и панели инструментов Место отладки. Пошаговое руководство по использованию окон Параллельные стеки и Задачи. Несколько способов переключения контекста отладки на другой поток. Пометка флагом потоков, которым нужно уделить особое внимание на время отладки. Методы отладки приложения, запущенного на высокопроизводительном кластере. Простые методы, которые могут быть полезны для отладки потока машинного кода. Дайте потоку имя, которое будет отображаться в окне Потоки. Дайте потоку имя, которое будет отображаться в окне Потоки. Руководство по отладке многопоточных приложений в Visual Studio 2010В этой статье я расскажу, как отлаживать многопоточные приложения в Visual Studio 2010, используя окна Parallel Tasks и Parallel Stacks. Эти окна помогут понять структуру выполнения многопоточных приложений и проверить правильность работы кода, который использует Task Parallel Library. Осторожно, много картинок ПодготовкаДля тестов нам потребуется VS 2010. Изображения в этой статье получены с использованием процессора Intel Core i3 Код проектаКод для языков VB и C++ можно найти на этой странице
static void A( object o) //after Task.Factory.StartNew(T, i + 1 + 5, TaskCreationOptions.AttachedToParent); //scheduled Parallel Stacks Window: Threads View (Потоки)Шаг 1Копируем код в студию в новый проект и запускаем в режиме отладки (F5). Программа скомпилируется, запустится и остановится в первой точке остановки. На картинке 4 потока сгруппированы вместе, потому что их стек фреймы (stack frames) принадлежат одному контексту метода (method context), это значит, что это один и тот же метод (А, B, C). Чтобы посмотреть ID потока нужно навести на заголовок «4 Threads». Текущий поток будет выделен жирным. Желтая стрелка означает активный стек фрейм в текущем потоке. Чтобы получить дополнительную информацию нужно навести мышкой. Чтобы убрать лишнюю информацию или включить (например название модуля, сдвиг, имена параметров и их типы и пр.) нужно щелкнуть правой кнопкой мышки по заголовку таблицы в окошке Call Stack (аналогично делается во всем окружении Windows). Голубая рамка вокруг означает, что текущий поток (который выделен жирным) является частью этих потоков. Шаг 2Продолжаем выполнение программы до второй точки остановки (F5). На следующем слайде видно состояние потоков во второй точке. На первом шаге 4 потока пришли из методов A, B и C. Эта информация до сих пор доступна в окне Parallel Stacks, но теперь эти 4 потока получили развитие дальше. Один поток продолжился в D, затем в E. Другой в F, G и потом в H. Два остальных в I и J, а оттуда один из них направился в K а другой пошел своим путем в non-user External Code. Можно переключиться на другой поток, для этого двойной щелчек на потоке. Я хочу посмотреть метод K. Для этого двойной клик по MyCalss.K Parallel Stacks покажет информацию, а отладчик в студии покажет код этого места. Нажимаем Toggle Method View и наблюдаем картину истории (иерархии) методов до K. Шаг 3Продолжаем отладку до 3 прерывания. Когда несколько потоков приходят в один и тот же метод, но метод не в начале стека вызовов – он появляется в разных рамках, как это произошло с методом L. Метод L выделен жирным так же в двух других рамках, так что можно видеть где он еще появится. Чтобы увидеть какие фреймы вызывают метод L переключаем режим отображения (Toggle Method View). Получаем следующее: В контекстном меню есть такие пункты как «Hexadecimal Display» и «Show External Code». При включении последнего режима диаграмма получается больше чем предыдущая и содержит информацию о non-user code. Шаг 4Продолжаем выполнение программы до четвертого прерывания. В этот раз диаграмма получится очень большой и на помощь приходит автоскролл, который сразу переводит на нужное место. The Bird’s Eye View также помогает быстро ориентироваться в больших диаграммах. (маленькая кнопочка справа внизу). Авто зум и прочие радости помогают ориентироваться в действительно больших многопоточных приложениях. Parallel Tasks Window и Tasks View в окне Parallel StacksШаг 1Завершаем работу программы (Shift + F5) или в меню отладки. Закрываем все лишние окошки с которыми мы экспериментировали в прошлом примере и открываем новые: Debug→Windows→Threads, Debug→Windows→Call Stack и лепим их к краям студии. Также открываем Debug→Windows→ Parallel Tasks. Вот что получилось в окне Parallel Tasks Для каждого запущенного задания есть ID который возвращает значение одноименного свойства задания, местоположение задания (если навести мышь на Console, то появится целый стек вызовов) а также метод, который был принят как отправная точка задания (старт задания). Шаг 2В предыдущий раз все задания были отмечены как выполняемые, сейчас 2 задания заблокированы по разным причинам. Чтобы узнать причину нужно навести мышь на задание. Задание можно отметить флагом и следить за дальнейшим состоянием. В окне Parallel Stack, которое мы использовали в предыдущем примере, есть переключатель просмотра с потоков на задания (слева вверху). Переключаем вид на Tasks Шаг 3Как видно из скриншота – новое задание 5 выполняется, а задачи 3 и 4 остановлены. Также можно изменить вид таблицы – правая кнопка мыши по заголовкам колонок. Если включить отображение предка задачи (Parent) то мы увидим, кто является предком задачи номер 5. Но для лучшей визуализации отношений можно включить специальный вид – ПКМ по колонке Parent→Parent Child View. Окна Parallel Tasks и Parallel Stack – синхронизированы. Так что мы можем посмотреть какая задача в каком потоке выполняется. Например задача 4. Двойной клик по задаче 4 в окне Parallel Tasks, с этим кликом выполнится синхронизация с окном Parallel Stack и мы увидим такую картину В окне Parallel Stack, в режиме задач можно перейти к поток. Для этого ПКМ на методе и Go To Thread. В нашем примере мы посмотрим что происходит с методом O. Шаг 4Продолжаем выполнение до следующей точки. Затем сортируем задачи по ID и видим следующее В списке нет задачи 5, потому что она уже завершена. Задачи 3 и 4 ждут друг друга и зашли в тупик. Есть еще 5 новых задач от задачи 2, которые теперь запланированы на исполнение. Вернемся в Parallel Stack. Подсказка в заголовке каждой таблички скажет, сколько задач заблокировано, сколько ожидают и сколько выполняется. Задачи в списке задач можно сгруппировать. Например сгруппируем по статусу – ПКМ на колонке статус и Group by Status. Результат на скриншоте: Еще несколько возможностей окошка Parallel Tasks: в контекстном меню можно заморозить задачи, можно заморозить основной поток задачи. ЗаключениеС помощью этих двух мощных инструментов можно отлаживать большие и сложные, многопоточные приложения. Смотреть за результатом и порядком выполнения задач. Планировать правильный порядок выполнения задач. Строить программы с минимальным количеством ошибок, связанных с непониманием работы многопоточных программ. ЛитератураВидеоБлог Daniel MothСпасибо за внимание и поменьше вам ошибок в многопоточных приложениях 🙂
|