Depurar aplicativos multi-threaded no Visual Studio
Um thread é uma sequência de instruções para que o sistema operacional conceda tempo no processador. Cada processo que está em execução no sistema operacional consiste em pelo menos um thread. Os processos que têm mais de um thread são chamados multithread.
Os computadores com vários processadores, processadores de vários núcleos ou processos de hyperthreading podem executar vários threads simultâneos. O processamento paralelo usando muitos threads pode melhorar muito o desempenho do programa, mas também pode dificultar a depuração porque você está acompanhando muitos threads.
O processamento paralelo perfeito não é sempre possível. Às vezes os threads devem ser sincronizados. Um thread pode ter que aguardar um resultado de outro thread, ou um thread pode precisar de acesso exclusivo a um recurso que outro thread está usando. Problemas de sincronização são uma causa comum de erro em aplicativos com multithreads. Em alguns casos, os threads podem interromper espera de um recurso que nunca fica disponível. Isso resulta em uma condição chamada deadlock.
Threads e processos
Threads e processos são conceitos relacionados à ciência da computação. Ambos representam sequências de instruções que devem executar em uma ordem específica. Instruções em threads ou processos separados, entretanto, podem ser executados em paralelo.
Os processos existem no sistema operacional e correspondem ao que os usuários veem como programas ou aplicativos. Um thread, por outro lado, existe dentro de um processo. Por esse motivo, os threads são às vezes chamados de processos leves. Cada processo consiste em um ou mais threads.
A existência de vários processos permite que um computador execute mais de uma tarefa de cada vez. A existência de vários threads permite que um processo separe o trabalho a ser executado paralelamente. Em um computador com multiprocessadores, os processos ou threads podem ser executados em processadores diferentes. Isso permite o verdadeiro processamento paralelo.
Ferramentas para depurar aplicativos multithread
O Visual Studio fornece diferentes ferramentas para uso na depuração de aplicativos multithreaded.
Para threads, as principais ferramentas para depuração de threads são a janela Threads, os marcadores de thread nas janelas de origem, a janela Pilhas Paralelas, a janela Inspeção Paralela e a barra de ferramentas Local de Depuração. Para saber mais sobre o Threads janela e local de depuração barra de ferramentas, consulte passo a passo: Depuração com a janela Threads. Para saber como usar as janelas Pilhas Paralelas e Inspeção Paralela, consulte Introdução à depuração de um aplicativo multithreaded. Ambos os tópicos mostram como usar marcadores de thread.
Para o código que usa a TPL (Biblioteca Paralela de Tarefas) ou o Runtime de Simultaneidade, as principais ferramentas para depuração são a janela Pilhas Paralelas, a janela Inspeção Paralela e a janela Tarefas, que também dá suporte a JavaScript. Para começar, consulte Passo a passo: depurando um aplicativo paralelo e Passo a passo: depurando um aplicativo C++ AMP.
Para depurar threads na GPU, a ferramenta principal é a janela Threads de GPU. Consulte Como usar a janela Threads de GPU.
Para processos, as ferramentas principais são a caixa de diálogo Anexar ao processo, a janela Processos e a barra de ferramentas Local de depuração.
O Visual Studio também fornece os pontos de interrupção avançados e pontos de controle, que podem ser úteis quando você depura aplicativos multissegmentados. Use filtros e condições de ponto de interrupção para incluir pontos de interrupção em threads individuais. Os pontos de rastreamento permitem que você rastreie a execução do programa sem interromper, para estudar problemas como deadlocks. Para obter mais informações, consulte Ações de ponto de interrupção e pontos de rastreamento.
Depurar um aplicativo com vários thread que tenha uma interface de usuário pode ser especialmente difícil. Você poderá considerar a execução do aplicativo em um segundo computador e o uso da depuração remota. Para obter mais informações, confira Depuração remota.
A tabela a seguir mostra as informações disponíveis e as ações que você pode executar em cada um desses locais:
Interface do Usuário | Informação disponível | Ações que você pode executar |
---|---|---|
Caixa de diálogo Anexar ao Processo | Processos disponíveis você pode anexar: – Nome do Processo (.exe) – Número de identificação do processo – Título da barra de menus – Tipo (v4.0 gerenciado; v2.0 gerenciado, v1.1, v1.0; x86; x64; IA64) – Nome de usuário (nome de conta) – Número da sessão |
Selecione um processo anexar. Selecione um computador remoto Altere o tipo de transporte para se conectar a computadores remotos |
Janela Processos | Processos anexados: – Process Name – Número de identificação do processo – Caminho para o .exe do processo – Título da barra de menus – Estado (interrupção. em execução) – Depurando (nativo, gerenciado, etc.) – Tipo de transporte (padrão, nativo sem autenticação) – Qualificador de transporte (computador remoto) |
Ferramentas: – Anexar – Desanexar Terminate O menu de atalho: – Anexar – Desanexar – Desanexar quando a depuração for interrompida Terminate |
Janela Threads | Threads durante o processo atual: – ID de thread – ID gerenciada – Categoria (thread principal, thread de interface, manipulador de chamada de procedimento remoto ou thread de trabalho) – Nome do thread – Localização em que o thread é criado – Prioridade – Máscara de afinidade – Contagem suspensa – Process Name – Indicador de Sinalização – Indexador suspenso |
Ferramentas: – Pesquisar – Pesquisar pilha de chamadas – Sinalizar Apenas Meu Código – Sinalizar seleção de módulo personalizada – Agrupar por – Colunas – Expandir/recolher pilhas de chamadas – Expandir/recolher grupos – Congelar/descongelar threads O menu de atalho: – Mostrar threads na origem – Alternar para um thread – Congelar um thread em execução – Descongelar um thread congelado – Sinalizar um thread para estudos adicionais – Remover a sinalização de um thread – Renomear um thread – Exibir e ocultar threads Outras ações: – Exibir a pilha de chamadas para um thread em um DataTip |
Janela de origem | Indexadores de threads na medianiz esquerda indicam um ou vários segmentos (desativado por padrão, ativado usando o menu de atalho na janela Threads) | O menu de atalho: – Alternar para um thread – Sinalizar um thread para estudos adicionais – Remover a sinalização de um thread |
Barra de ferramentas Localização de Depuração | – Processo atual – Suspender o aplicativo – Retomar o aplicativo – Suspender e encerrar o aplicativo – Thread atual – Alternar o estado do sinalizador do thread atual – Mostrar somente threads sinalizados – Mostrar somente o processo atual – Registro de ativação atual |
– Alternar para outro processo – Suspender, retomar ou encerrar o aplicativo – Alternar para outro thread no processo atual – Alternar para outro registro de ativação no thread atual – Sinalizar ou remover sinalização de threads atuais – Mostrar somente threads sinalizados – Mostrar somente o processo atual |
Janela Pilhas Paralelas | – Pilhas de chamadas para vários threads em uma janela. – Registro de ativação ativo para cada thread. – Chamadores e receptores de qualquer método. – Detecção de deadlock |
– Remover threads especificados – Filtrar pilhas de código externo – Alternar para o Modo de Exibição de Tarefas – Sinalizar ou remover sinalização de um thread – Zoom – Copiar registro de ativação – Salvar/exportar todas as pilhas como imagem |
Janela Inspeção Paralela | – A coluna do sinalizador, na qual você pode marcar um thread ao qual deseja prestar atenção especial. – A coluna do quadro, na qual uma seta indica o quadro selecionado. – Uma coluna configurável que pode exibir o computador, o processo, o bloco, a tarefa e o thread. |
– Sinalizar ou remover sinalização de um thread – Exibir somente threads sinalizados – Quadros de opção – Classificar uma coluna – Agrupar threads – Congelar ou descongelar threads – Exportar os dados na janela Inspeção Paralela |
Janela Tarefas | – Exibir informações sobre os objetos de Task, incluindo ID de tarefa, status de tarefa (agendada, executando, em espera, em deadlock), bem como qual thread está atribuído à tarefa. – Localização atual na pilha de chamadas. – O delegado passado para a tarefa no horário de criação |
– Alternar para a tarefa atual – Sinalizar ou remover sinalização de uma tarefa – Congelar ou descongelar uma tarefa |
Janela Threads de GPU | – A coluna do sinalizador, na qual você pode marcar um thread ao qual deseja prestar atenção especial. - A coluna de thread atual, na qual uma seta amarela indica o thread atual. – A coluna Contagem de Threads, que exibe o número de segmentos na mesma localização. – A coluna de Linha, que exibe a linha de código em que cada grupo de segmentos está localizado. – A coluna de Endereço que exibe o endereço da instrução em que cada grupo de threads está localizado. – A coluna Localização, que é a localização no código do endereço. – A coluna Status, que mostra se o thread está ativo ou bloqueado. – A coluna Lado a lado, que mostra o índice lado a lado para os segmentos na linha. |
– Alternando para outro thread – Exibir um determinado bloco e thread – Exibir ou ocultar uma coluna – Classificar por coluna – Agrupar threads – Congelar ou descongelar threads – Sinalizar ou remover sinalização de um thread – Exibir somente threads sinalizados |