Partilhar via


Depuração no modo de origem

A depuração de um aplicativo será mais fácil se você puder analisar a origem do código, em vez dos binários desmontados.

WinDbg, CDB e KD podem usar o código-fonte na depuração, se a linguagem de origem for C, C++ou assembly.

Requisitos de compilação

Para usar a depuração de origem, você deve ter o compilador ou o vinculador para criar arquivos de símbolo (arquivos .pdb) quando os binários forem criados. Esses arquivos de símbolo mostram ao depurador como as instruções binárias correspondem às linhas de origem.

Além disso, o depurador deve ser capaz de acessar os arquivos de origem reais, pois os arquivos de símbolo não contêm o texto de origem real.

Se for possível, o compilador e o vinculador não deverão otimizar seu código. A depuração de origem e o acesso a variáveis locais são mais difíceis e, às vezes, quase impossíveis, se o código tiver sido otimizado. Se você estiver usando o utilitário Build como compilador e vinculador, defina a macro MSC_OPTIMIZATION como /Od /Oi para evitar a otimização.

Localizando os arquivos de símbolo e arquivos de origem

Para depurar no modo de origem, o depurador deve ser capaz de localizar os arquivos de origem e os arquivos de símbolo. Para obter mais informações, consulte Caminho de origem.

Iniciando a depuração de origem

O depurador pode exibir informações de origem sempre que tiver símbolos e arquivos de origem adequados para o thread que está sendo depurado no momento.

Se você iniciar um novo aplicativo de modo de usuário usando o depurador, a interrupção inicial ocorrerá quando Ntdll.dll carregar o aplicativo. Como o depurador não tem acesso aos arquivos de origem Ntdll.dll, você não pode acessar informações de origem para seu aplicativo neste momento.

Para mover o contador do programa para o início do aplicativo, adicione um ponto de interrupção no ponto de entrada ao binário. Na janela Comando do Depurador, digite o comando a seguir.

bp main
g

Em seguida, o aplicativo é carregado e interrompido quando a função main é inserida. (É claro que você pode usar qualquer ponto de entrada, não apenas main.)

Se o aplicativo gerar uma exceção, ele será dividido no depurador. As informações de origem estão disponíveis neste momento. No entanto, se você emitir uma interrupção usando CTRL+C, CTRL+BREAK ou Depurar | Comando Break, o depurador cria um novo thread, para que você não possa ver o código-fonte.

Depois de acessar um thread para o qual você tem arquivos de origem, você pode usar a janela Comando do Depurador para executar comandos de depuração de origem. Se você estiver usando o WinDbg, a janela Origem será exibida. Se você já abriu uma janela De origem clicando em Arquivo de Software Livre no menu Arquivo , o WinDbg normalmente cria uma nova janela para a origem. Você pode fechar a janela anterior sem afetar o processo de depuração.

Depuração de origem na GUI do WinDbg

Se você estiver usando o WinDbg, uma janela Origem será exibida assim que o contador do programa estiver no código para o qual o depurador tem informações de origem.

O WinDbg exibe uma janela Origem para cada arquivo de origem que você ou WinDbg abriu. Para obter mais informações sobre as propriedades de texto desta janela, consulte Janelas de origem.

Em seguida, você pode percorrer seu aplicativo ou executar para um ponto de interrupção ou para o cursor. Para obter mais informações sobre como percorrer e rastrear comandos, consulte Controlando o destino.

Se você estiver no modo de origem, a janela Origem apropriada passará para o primeiro plano à medida que você percorre seu aplicativo. Como também há rotinas do Microsoft Windows que são chamadas durante a execução do aplicativo, o depurador pode mover uma janela Desmontagem para o primeiro plano quando esse tipo de chamada ocorre (porque o depurador não tem acesso à origem dessas funções). Quando o contador do programa retorna a arquivos de origem conhecidos, a janela Origem apropriada fica ativa.

Conforme você percorre o aplicativo, o WinDbg realça sua localização na janela Origem e na janela Desmontagem. As linhas nas quais os pontos de interrupção são definidos também são realçadas. O código-fonte é colorido de acordo com a análise do idioma. Se a janela Origem tiver sido selecionada, você poderá passar o mouse sobre um símbolo com o mouse para avaliá-lo. Para obter mais informações sobre esses recursos e como controlá-los, consulte Janelas de origem.

Para ativar o modo de origem no WinDbg, use o comando l+t , clique no modo de origem no menu de depuração ou clique no modo de origem no botão. Quando o modo de origem está ativo, o indicador ASM aparece indisponível na barra de status.

Você pode exibir ou alterar os valores de qualquer variável local à medida que percorre uma função no modo de origem. Para obter mais informações, consulte Leitura e gravação de memória.

Depuração de origem na janela Comando do Depurador

Se você estiver usando o CDB, não terá uma janela De origem separada. No entanto, você ainda pode exibir seu progresso enquanto percorre a origem.

Antes de fazer a depuração de origem no CDB, você precisa carregar símbolos de linha de origem emitindo o comando .lines (Alternar Suporte à Linha de Origem) ou iniciando o depurador com a opção de linha de comando -lines.

Se você executar um comando l+t , todas as etapas do programa serão executadas uma linha de origem por vez. Use l-t para executar uma instrução de assembly por vez. Se você estiver usando o WinDbg, esse comando terá o mesmo efeito que selecionar ou limpar o Modo de Origem no menu Depurar ou usar os botões da barra de ferramentas.

O comando l+s exibe a linha de origem atual e o número de linha no prompt. Se você quiser ver apenas o número de linha, use l+l .

Se você usar l+o e l+s, somente a linha de origem será exibida enquanto você percorrer o programa. O contador do programa, o código de desmontagem e as informações de registro estão ocultos. Esse tipo de exibição permite que você percorra rapidamente o código e exiba nada além da origem.

Você pode usar o comando lsp (Definir Número de Linhas de Origem) para especificar exatamente quantas linhas de origem são exibidas ao percorrer ou executar o aplicativo.

A sequência de comandos a seguir é uma maneira eficaz de percorrer um arquivo de origem.

.lines        enable source line information
bp main       set initial breakpoint
l+t           stepping will be done by source line
l+s           source lines will be displayed at prompt
g             run program until "main" is entered
pr            execute one source line, and toggle register display off
p             execute one source line 

Como ENTER repete o último comando, agora você pode percorrer o aplicativo usando a tecla ENTER. Cada etapa faz com que a linha de origem, o deslocamento de memória e o código do assembly apareçam.

Para obter mais informações sobre como interpretar a exibição de desmontagem, consulte Depuração no Modo de Assembly.

Quando o código do assembly é exibido, qualquer local de memória que está sendo acessado é exibido na extremidade direita da linha. Você pode usar os comandos d* (Exibir Memória) e e* (Inserir Valores) para exibir ou alterar os valores nesses locais.

Se você precisar exibir cada instrução de assembly para determinar deslocamentos ou informações de memória, use l-t para executar instruções de assembly em vez de linhas de origem. As informações da linha de origem ainda podem ser exibidas. Cada linha de origem corresponde a uma ou mais instruções de assembly.

Todos esses comandos estão disponíveis no WinDbg e no CDB. Você pode usar os comandos para exibir informações de linha de origem na janela Comando do Depurador do WinDbg em vez de na janela Origem.

Linhas e deslocamentos de origem

Você também pode executar a depuração de origem usando o avaliador de expressão para determinar o deslocamento que corresponde a uma linha de origem específica.

O comando a seguir exibe um deslocamento de memória.

? `[[module!]filename][:linenumber]` 

Se você omitir filename, o depurador pesquisa o arquivo de origem que corresponde ao contador do programa atual.

O depurador lê linenumber como um número decimal, a menos que você adicione 0x antes dele, independentemente do radix padrão atual. Se você omitir linenumber, a expressão será avaliada como o endereço inicial do arquivo executável que corresponde ao arquivo de origem.

Essa sintaxe será compreendida no CDB somente se o comando .lines ou a opção de linha de comando -lines tiver carregado símbolos de linha de origem.

Essa técnica é muito versátil, pois você pode usá-la independentemente de onde o contador do programa está apontando. Por exemplo, essa técnica permite que você defina pontos de interrupção com antecedência, usando comandos como o seguinte.

bp `source.c:31` 

Para obter mais informações, consulte Sintaxe de linha de origem e Usando pontos de interrupção.

Passo a passo e rastreamento no modo de origem

Quando você está depurando no modo de origem, pode haver várias chamadas de função em uma única linha de origem. Você não pode usar os comandos p e t para separar essas chamadas de função.

Por exemplo, no comando a seguir, o comando t entra em GetTickCount e printf, enquanto o comando p percorre as duas chamadas de função.

printf( "%x\n", GetTickCount() );

Se você quiser percorrer determinadas chamadas durante o rastreamento em outras chamadas, use .step_filter (Definir Filtro de Etapa) para indicar quais chamadas devem ser seguidas.

Você pode usar _step_filter para filtrar funções de estrutura (por exemplo, chamadas MFC (Microsoft Foundation Classes) ou ATL (Biblioteca de Modelos Ativos).