Usar o tipo certo de ponto de interrupção
Este artigo mostra como usar diferentes tipos de pontos de interrupção no Visual Studio para melhorar a eficiência de depuração. Ele aborda vários cenários em que pontos de interrupção podem ser aplicados, como pausar a execução de código, registrar informações em log e controlar alterações em estados variáveis. O artigo explica como definir pontos de interrupção condicional, pontos de rastreamento, pontos de interrupção de dados, pontos de interrupção dependentes e pontos de interrupção temporários. Ele também inclui instruções detalhadas sobre como definir pontos de interrupção de função. Este guia é essencial para desenvolvedores que buscam aproveitar pontos de interrupção para depuração efetiva no Visual Studio.
Se você não estiver familiarizado com o uso de pontos de interrupção no Visual Studio, consulte Introdução aos pontos de interrupção antes de passar por este artigo.
Para obter a melhor experiência com esta documentação, escolha seu idioma de desenvolvimento preferido ou runtime na lista na parte superior do artigo.
Cenários
A tabela a seguir mostra cenários comuns de depuração para pontos de interrupção e o tipo de ponto de interrupção recomendado para o cenário.
Cenário | Descrição |
---|---|
Como fazer para pausar a execução de código para inspecionar uma linha de código que pode conter um bug? | Defina um ponto de interrupção. Para obter mais informações, consulte Introdução aos pontos de interrupção. |
Minha variável tem um valor inesperado? Ou quero inspecionar meu aplicativo quando ele atingir um estado específico? | Tente um ponto de interrupção condicional para controlar onde e quando um ponto de interrupção é ativado usando a lógica condicional. Clique com o botão direito do mouse em um ponto de interrupção para adicionar condições. Defina a condição como verdadeira quando a variável seja igual ao valor inesperado. Para obter mais informações, confira Condições de ponto de interrupção. |
Como fazer para registrar informações na janela Saída em condições configuráveis sem modificar ou interromper meu código? | Os pontos de rastreamento permitem que você registre informações na janela Saída em condições configuráveis sem modificar ou interromper seu código. Para obter mais informações, confira Usar pontos de rastreamento no depurador do Visual Studio. |
Como saber quando o valor da minha variável é alterado? | Para C++, defina um ponto de interrupção de dados . Para aplicativos que usam o .NET Core 3 e posteriores, você também pode definir um ponto de interrupção de dados . Caso contrário, somente para C# e F#, você pode rastrear uma ID de objeto com um ponto de interrupção condicional. |
Como interromper a execução somente se outro ponto de interrupção for atingido? | Defina um ponto de interrupção dependente que interrompe a execução somente se outro ponto de interrupção for atingido pela primeira vez. Para obter mais informações, confira Ponto de interrupção dependente. |
Posso atingir um ponto de interrupção apenas uma vez? | Defina um ponto de interrupção temporário que permite interromper o código apenas uma vez. Para obter mais informações, confira Ponto de interrupção temporário. |
Posso pausar o código dentro de um loop em uma determinada iteração? | Defina um ponto de interrupção dependente que interrompe a execução somente se outro ponto de interrupção for atingido pela primeira vez. Para obter mais informações, confira Contagem de ocorrências. |
Posso pausar o código no início de uma função quando souber o nome da função, mas não sua localização? | Você pode fazer isso com um ponto de interrupção de função. Para obter mais informações, consulte Definir pontos de interrupção de função. |
Posso pausar o código no início de várias funções com o mesmo nome? | Quando há várias funções com o mesmo nome (funções sobrecarregadas ou funções em projetos diferentes), você pode usar um ponto de interrupção de função . |
Ações de ponto de interrupção e pontos de rastreamento
Um tracepoint é um ponto de interrupção que imprime uma mensagem na janela de Saída. Um ponto de rastreamento pode agir como uma instrução de rastreamento temporário na linguagem de programação e não pausa a execução do código. Você cria um ponto de rastreamento definindo uma ação especial na janela Configurações do Ponto de Interrupção. Para obter instruções detalhadas, confira Usar pontos de rastreamento no depurador do Visual Studio.
Condições de ponto de interrupção
Você pode controlar quando e onde um ponto de interrupção é acionado definindo condições. A condição pode ser qualquer expressão válida que o depurador reconhece. (Para obter mais informações sobre expressões válidas, consulte Expressões no depurador.)
Para definir uma condição de ponto de interrupção:
Clique com o botão direito do mouse no símbolo do ponto de interrupção e selecione Condições (ou pressione Alt + F9, C). Ou passe o mouse sobre o símbolo do ponto de interrupção, selecione o ícone Configurações, e então selecione Condições na janela Configurações do Ponto de Interrupção.
Você também pode clicar com o botão direito do mouse na margem extrema esquerda, ao lado de uma linha de código, e selecionar Inserir Ponto de Interrupção Condicional no menu de contexto para definir um novo ponto de interrupção condicional.
Você também pode definir condições na janela Breakpoints clicando com o botão direito do mouse em um ponto de interrupção e selecionando Configurações, e então selecionando Condições.
Na lista suspensa, selecione Expressão Condicional, Contagem de Ocorrências ou Filtro e defina o valor adequadamente.
Selecione Fechar ou pressione Ctrl+Enter para fechar a janela Configurações do Ponto de Interrupção . Ou, na janela Pontos de Interrupção, selecione OK para fechar a caixa de diálogo.
Os pontos de interrupção com condições definidas aparecem com um símbolo + no código-fonte e nas janelas Pontos de Interrupção.
Criar uma expressão condicional
Ao selecionar Expressão Condicional, você pode escolher entre duas condições: É verdadeiro ou Quando alterado. Escolha É verdadeiro se quiser interromper quando a expressão for satisfeita ou escolha Quando alterado se quiser interromper quando o valor da expressão for alterado.
No exemplo a seguir, o ponto de interrupção é atingido somente quando o valor de testInt
é 4:
No exemplo a seguir, o ponto de interrupção é atingido somente quando o valor de testInt
é alterado:
Se você definir uma condição de ponto de interrupção com sintaxe inválida, uma mensagem de aviso será exibida. Se você especificar uma condição de ponto de interrupção com sintaxe válida, mas semântica inválida, uma mensagem de aviso será exibida na primeira vez em que o ponto de interrupção é atingido. Em ambos os casos, o depurador é interrompido quando atinge o ponto de interrupção inválido. O ponto de interrupção é ignorado somente se a condição é válida e avaliada como false
.
Nota
Para o campo Quando alterado, o depurador não considera a primeira avaliação da condição como uma alteração, portanto, não atinge o ponto de interrupção na primeira avaliação.
Usar IDs de objeto em expressões condicionais (somente C# e F#)
Há momentos em que você deseja observar o comportamento de um objeto específico. Por exemplo, talvez você queira descobrir por que um objeto foi inserido em uma coleção mais de uma vez. Em C# e F#, você pode criar IDs de objeto para instâncias específicas de tipos de referência e usá-las em condições de ponto de interrupção. A ID do objeto é gerada pelos serviços de depuração do Common Language Runtime (CLR) e associada ao objeto.
Criar uma ID de Objeto:
Defina um ponto de interrupção no código em algum lugar após a criação do objeto.
Inicie a depuração e, quando a execução for pausada no ponto de interrupção, selecione Depurar>Windows>Locais (ou pressione Ctrl + Alt + V, L) para abrir a janela Locais.
Localize a instância de objeto específica na janela Locais, clique com o botão direito do mouse nela e selecione Criar ID do Objeto.
Você verá um $ mais um número na janela Locais. Essa é a ID do objeto.
Adicione um novo ponto de interrupção no ponto que você deseja investigar; por exemplo, quando o objeto deve ser adicionado à coleção. Clique com o botão direito do mouse no ponto de interrupção e selecione Condições.
Use a ID do Objeto no campo Expressão Condicional. Por exemplo, se a variável
item
for o objeto a ser adicionado à coleção, selecione É verdadeiro e digite item == $<n>, em que <n> é o número da ID do objeto.A execução será interrompida no ponto em que esse objeto deve ser adicionado à coleção.
Para excluir a ID de Objeto, clique com o botão direito do mouse na variável na janela Locais e selecione Excluir ID de Objeto.
Nota
IDs de objeto criam referências fracas e não impedem que o objeto seja coletado pelo coletor de lixo. Eles são válidos apenas para a sessão de depuração atual.
Definir uma condição de contagem de ocorrências
Se você suspeitar que um loop em seu código começa a se comportar mal após um determinado número de iterações, você pode definir um ponto de interrupção para interromper a execução após esse número de ocorrências, em vez de ter que pressionar repetidamente F5 para alcançar essa iteração.
Em Condições, na janela Configurações do Ponto de Interrupção, selecione Contagem de Ocorrências e especifique o número de iterações. No exemplo a seguir, o ponto de interrupção é definido para ser atingido em todas as outras iterações:
BreakpointHitCount
BreakpointHitCount
Definir uma condição de filtro
Você pode restringir um ponto de interrupção a ser acionado somente em dispositivos especificados ou em processos e threads especificados.
Em Condições, na janela Configurações do Ponto de Interrupção, selecione Filtrar e insira uma ou mais das seguintes expressões:
- MachineName = "nome"
- ProcessId = valor
- ProcessName = "nome"
- ThreadId = valor
- ThreadName = "nome"
Coloque os valores da cadeia de caracteres entre aspas duplas. Você pode combinar cláusulas usando &
(AND), ||
(OR), !
(NOT) e parênteses.
Definir pontos de interrupção de função
Você pode interromper a execução quando uma função é chamada. Isso é útil, por exemplo, quando você sabe o nome da função, mas não sua localização. Também é útil se você tiver funções com o mesmo nome e quiser interromper todas elas (como funções sobrecarregadas ou funções em projetos diferentes).
Para definir um ponto de interrupção de função:
Selecione Depurar>Novo Ponto de Interrupção>Ponto de Interrupção da Função ou pressione Ctrl + K, B.
Você também pode selecionar Novo>Ponto de Interrupção de Função na janela Pontos de Interrupção.
Na caixa de diálogo Novo Ponto de Interrupção de Função, insira o nome da função na caixa Nome da Função.
Para restringir a especificação da função:
Use o nome da função totalmente qualificada.
Exemplo:
Namespace1.ClassX.MethodA()
Adicione os tipos de parâmetro de uma função sobrecarregada.
Exemplo:
MethodA(int, string)
Use o símbolo '!' para especificar o módulo.
Exemplo:
App1.dll!MethodA
Use o operador de contexto em C++ nativo.
{function, , [module]} [+<line offset from start of method>]
Exemplo:
{MethodA, , App1.dll}+2
Na lista suspensa Linguagem de programação, escolha a linguagem de programação da função.
Selecione OK.
Definir um ponto de interrupção de função usando um endereço de memória (somente C++ nativo)
Você pode usar o endereço de um objeto para definir um ponto de interrupção de função em um método chamado por uma instância específica de uma classe. Por exemplo, dado um objeto endereçável do tipo my_class
, você pode definir um ponto de interrupção de função no método my_method
que a instância chama.
Defina um ponto de interrupção em algum lugar depois que a instância da classe for instanciada.
Localize o endereço da instância (por exemplo,
0xcccccccc
).Selecione Depurar>Novo Ponto de Interrupção>Ponto de Interrupção da Função ou pressione Ctrl + K, B.
Adicione o seguinte à caixa Nome da Função e selecione a linguagem C++.
((my_class *) 0xcccccccc)->my_method
Definir pontos de interrupção de dados (.NET Core 3.x ou .NET 5+)
Os pontos de interrupção de dados interrompem a execução quando a propriedade de um objeto específico é alterada.
Para definir um ponto de interrupção de dados:
Em um projeto .NET Core ou .NET 5+, inicie a depuração e aguarde até que um ponto de interrupção seja atingido.
Na janela Automáticos, Inspeção ou Locais, clique com o botão direito do mouse em uma propriedade e selecione Interromper quando o valor for alterado no menu de contexto.
Os pontos de interrupção de dados para .NET Core e .NET 5+ não funcionarão para:
- Propriedades que não podem ser expandidas na dica de ferramenta, Locais, Autos ou janela Inspeção
- Variáveis estáticas
- Classes com o atributo DebuggerTypeProxy
- Campos dentro de estruturas
Para obter o número máximo que você pode definir, confira Limites de hardware do ponto de interrupção de dados.
Definir pontos de interrupção de dados (somente C++ nativo)
Os pontos de interrupção de dados interrompem a execução quando um valor armazenado em um endereço de memória especificado é alterado. Se o valor for lido, mas não alterado, a execução não será interrompida.
Para definir um ponto de interrupção de dados:
Em um projeto C++, inicie a depuração e aguarde até que um ponto de interrupção seja atingido. No menu Depurar, escolha Novo Ponto de Interrupção>Ponto de Interrupção de Dados.
Você também pode selecionar Novo>Ponto de Interrupção de Dados na janela Pontos de Interrupção ou clicar com o botão direito do mouse em um item na janela Autos, Inspeção ou Locais e selecionar Interromper quando o valor for alterado no menu de contexto.
Na caixa Endereço, digite um endereço de memória ou uma expressão que resulte em um endereço de memória. Por exemplo, digite
&avar
para interromper quando o conteúdo da variávelavar
for alterado.Na lista suspensa Contagem de Bytes, selecione o número de bytes que deseja que o depurador inspecione. Por exemplo, se você selecionar 4, o depurador observará quatro bytes começando em
&avar
e interromperá se algum desses bytes alterar de valor.
Os pontos de interrupção de dados não funcionam nas seguintes condições:
- Um processo que não estiver sendo depurado grava na localização da memória.
- O local da memória é compartilhado entre dois ou mais processos.
- O local da memória é atualizado no kernel. Por exemplo, se a memória for passada à função
ReadFile
do Windows de 32 bits, a memória será atualizada do modo kernel, então a atualização não causará interrupção do depurador. - Em que a expressão de inspeção é maior que 4 bytes em hardware de 32 bits e 8 bytes em hardware de 64 bits. Essa é uma limitação da arquitetura x86.
Nota
Os pontos de interrupção de dados dependem de endereços de memória específicos. O endereço de uma variável muda de uma sessão de depuração para a próxima, de modo que os pontos de interrupção de dados são desabilitados automaticamente no final de cada sessão de depuração.
Se você definir um ponto de interrupção de dados em uma variável local, o ponto de interrupção permanecerá habilitado quando a função terminar, mas o endereço de memória não será mais aplicável, portanto, o comportamento do ponto de interrupção será imprevisível. Se você definir um ponto de interrupção de dados em uma variável local, deverá excluir ou desabilitar o ponto de interrupção antes do término da função.
Limites de hardware do ponto de interrupção de dados
O kernel do Windows e o hardware subjacente têm os seguintes limites ao definir pontos de interrupção de dados. O limite refere-se ao número máximo de pontos de interrupção de dados que você pode definir.
Arquitetura do processador | Limite do ponto de interrupção de dados |
---|---|
x64 e x86 | 4 |
ARM64 | 2 |
ARM | 1 |
Definir um ponto de interrupção dependente
Pontos de interrupção dependentes interrompem a execução somente se outro ponto de interrupção for atingido pela primeira vez. Portanto, em um cenário complexo, como a depuração de um aplicativo multi-threaded, você pode configurar os pontos de interrupção adicionais depois que outro ponto de interrupção for atingido. Isso pode tornar muito mais fácil depurar o código em caminhos comuns, como o loop do jogo ou uma API utilitária, pois um ponto de parada nessas funções pode ser configurado para habilitar somente se a função for invocada a partir de uma parte específica do seu aplicativo.
Para definir um ponto de interrupção dependente:
Passe o mouse sobre o símbolo do ponto de interrupção, escolha o ícone Configurações e selecione Habilitar somente quando o ponto de interrupção a seguir for atingido na janela Configurações do Ponto de Interrupção.
Na lista suspensa, selecione o ponto de interrupção de pré-requisito do qual você deseja que o ponto de interrupção atual seja dependente.
Escolha Fechar ou pressione Ctrl+Enter para fechar a janela Configurações do Ponto de Interrupção. Ou, na janela Pontos de Interrupção, escolha OK para fechar a caixa de diálogo.
DependentBreakpoint
Você também pode usar o menu de contexto de clique com o botão direito do mouse para definir o ponto de interrupção dependente.
Clique com o botão direito do mouse na margem à extrema esquerda ao lado de uma linha de código e selecione Inserir Ponto de Interrupção Dependente no menu de contexto.
DependentBreakpointContext
- Os pontos de interrupção dependentes não funcionarão se houver apenas um ponto de interrupção em seu aplicativo.
- Os pontos de interrupção dependentes serão convertidos em um ponto de interrupção de linha normal se o ponto de interrupção de pré-requisito for excluído.
Definir um ponto de interrupção temporário
Esse ponto de interrupção permite que você interrompa o código apenas uma vez. Ao depurar, o depurador do Visual Studio pausa apenas o aplicativo em execução uma vez para esse ponto de interrupção e o remove imediatamente após ele ser atingido.
Para definir um ponto de interrupção temporário:
Passe o mouse sobre o símbolo do ponto de interrupção, escolha o ícone Configurações e, em seguida, selecione Remover ponto de interrupção uma vez atingido na janela Configurações do Ponto de Interrupção.
Escolha Fechar ou pressione Ctrl+Enter para fechar a janela Configurações do Ponto de Interrupção. Ou, na janela Pontos de Interrupção, escolha OK para fechar a caixa de diálogo.
Você também pode usar o menu de contexto de clique com o botão direito do mouse para definir o ponto de interrupção temporário.
Clique com o botão direito do mouse na margem esquerda ao lado de uma linha de código e selecione Inserir Ponto de Interrupção Temporário no menu de contexto.
TemporaryBreakpointContext
Ou, basta usar o atalho F9 + Shift + Alt, T e definir o ponto de interrupção temporário na linha desejada.