bp, bu, bm (Definir ponto de interrupção)
Os comandos bp, bu e bm definem um ou mais pontos de interrupção de software. Você pode combinar locais, condições e opções para definir diferentes tipos de pontos de interrupção de software.
Modo de usuário
[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]
Modo kernel
bp[ID] [Options] [Address [Passes]] ["CommandString"]
bu[ID] [Options] [Address [Passes]] ["CommandString"]
bm [Options] SymbolPattern [Passes] ["CommandString"]
Parâmetros
Fio
Especifica o thread ao qual o ponto de interrupção se aplica. Para obter mais informações sobre a sintaxe, confira Sintaxe do thread. Você pode especificar threads somente no modo de usuário. Se você não especificar um thread, o ponto de interrupção se aplicará a todos os threads.
ID
Especifica um número decimal que identifica um ponto de interrupção.
O depurador atribui a ID quando cria o ponto de interrupção, mas você pode alterá-la usando o comando br (Renumeração do Ponto de Interrupção). Você pode usar a ID para se referir ao ponto de interrupção em comandos posteriores do depurador. Para exibir o ID de um ponto de interrupção, use o comando bl (Lista de pontos de interrupção).
Ao usar ID em um comando, não digite um espaço entre o comando (bp ou bu) e o número de ID.
O parâmetro ID é sempre opcional. Se você não especificar a ID, o depurador usará o primeiro número de ponto de interrupção disponível. No modo kernel, você pode definir apenas 32 pontos de interrupção. No modo de usuário, você pode definir qualquer número de pontos de interrupção. Em ambos os casos, não há restrição quanto ao valor do número de identificação . Se você colocar ID entre colchetes ([]), ID poderá incluir qualquer expressão. Para obter mais informações sobre a sintaxe, consulte Sintaxe de expressão numérica.
Options Especifica as opções de ponto de interrupção. Você pode especificar qualquer número das seguintes opções, exceto conforme indicado:
/1
Cria um ponto de interrupção "de uso único". Depois que esse ponto de interrupção é disparado, ele é excluído da lista de pontos de interrupção.
/p EProcess
(Somente no modo kernel) Especifica um processo associado a esse ponto de interrupção. EProcess deve ser o endereço real da estrutura do EPROCESS, não o PID. O ponto de interrupção será acionado somente se for encontrado no contexto desse processo.
/t EThread
(Somente no modo kernel) Especifica um thread associado a esse ponto de interrupção. EThread deve ser o endereço real da estrutura ETHREAD, não o ID do thread. O ponto de interrupção será acionado somente se for encontrado no contexto desse thread. Se você usar /p EProcess e /t EThread, poderá inseri-los em qualquer ordem.
/c MaxCallStackDepth
Ativa o ponto de interrupção somente quando a profundidade da pilha de chamadas é menor que MaxCallStackDepth. Você não pode usar essa opção junto com /C.
/C MinCallStackDepth
Ativa o ponto de interrupção somente quando a profundidade da pilha de chamadas é maior que MinCallStackDepth. Você não pode usar essa opção junto com /c.
/a
(Somente para bm) Define pontos de interrupção em todos os locais especificados, estejam eles no espaço de dados ou no espaço de código. Como os pontos de interrupção nos dados podem causar falhas no programa, use essa opção somente em locais conhecidos por serem seguros.
/d
(Somente para bm ) Converte os locais dos pontos de interrupção em endereços. Portanto, se o código for movido, os pontos de interrupção permanecerão no mesmo endereço, em vez de serem definidos de acordo com SymbolPattern. Use /d para evitar a reavaliação de alterações nos pontos de interrupção quando os módulos são carregados ou descarregados.
/(
(Somente para bm ) Inclui informações da lista de parâmetros na cadeia de caracteres de símbolo que SymbolString define.
Esse recurso permite que você defina pontos de interrupção em funções sobrecarregadas que têm o mesmo nome, mas listas de parâmetros diferentes. Por exemplo, bm /( myFunc define pontos de interrupção em myFunc(int a) e myFunc(char a). Sem "/(", um ponto de interrupção definido em myFunc falha porque não indica para qual função myFunc o ponto de interrupção se destina.
/w expressão de objeto dx Define um ponto de interrupção condicional com base no valor booleano retornado pela expressão de objeto dx. O argumento é uma expressão de modelo de dados (dx) que é avaliada como true (corresponde a condição – interrupção) ou false (não corresponde à condição – sem interrupção).
Este exemplo define um ponto de interrupção condicional com base no valor de localVariable.
bp /w "localVariable == 4" mymodule!myfunction
O exemplo mostra como definir um ponto de interrupção usando JavaScript.
bp /w "@$scriptContents.myFunc(localVariable)" @rip
Para obter mais informações sobre objetos do depurador, consulte dx (Expressão para exibir modelo de objeto de depurador).
Para obter mais informações sobre pontos de interrupção condicionais, consulte Como definir um ponto de interrupção condicional.
Endereço
Especifica o primeiro byte da instrução em que o ponto de interrupção é definido. Se você omitir Endereço, o ponteiro de instrução atual será usado. Para obter mais informações sobre a sintaxe, consulte Endereço e sintaxe de intervalo de endereços.
Passa
Especifica o número da passagem de execução em que o ponto de interrupção é ativado. O depurador ignora o local do ponto de interrupção até atingir a passagem especificada. O valor de Passes pode ser qualquer valor de 16 bits ou 32 bits.
Por padrão, o ponto de interrupção está ativo na primeira vez que o aplicativo executa o código que contém o local do ponto de interrupção. Essa situação padrão é equivalente a um valor de 1 para Passes. Para ativar o ponto de interrupção somente depois que o aplicativo executar o código pelo menos uma vez, insira um valor de 2 ou mais. Por exemplo, um valor de 2 ativa o ponto de interrupção na segunda vez que o código é executado.
Esse parâmetro cria um contador que é decrementado em cada passagem pelo código. Para ver os valores iniciais e atuais do contador de passagens, use bl (Lista de pontos de interrupção).
O contador Passes é diminuído somente quando o aplicativo é executado após o ponto de interrupção em resposta a um comando g (Go). O contador não será diminuído se você estiver percorrendo o código ou rastreando além dele. Quando o contador de Passes atinge 1, você pode redefini-lo apenas limpando e redefinindo o ponto de interrupção.
Sequência de comandos
Especifica uma lista de comandos que são executados sempre que o ponto de interrupção é encontrado o número especificado de vezes. Você deve colocar o parâmetro CommandString entre aspas. Use ponto-e-vírgula para separar vários comandos.
Os comandos do depurador em CommandString podem incluir parâmetros. Você pode usar caracteres de controle C padrão (como \n e \"). Os ponto-e-vírgulas contidos entre aspas de segundo nível (\") são interpretados como parte da cadeia de caracteres entre aspas incorporada.
Os comandos CommandString serão executados somente se o ponto de interrupção for atingido enquanto o aplicativo estiver sendo executado em resposta a um comando g (Go ). Os comandos não serão executados se você estiver percorrendo o código ou rastreando além desse ponto.
Qualquer comando que retome a execução do programa após um ponto de interrupção (como g ou t) encerra a execução da lista de comandos.
Padrão de símbolos
Especifica um padrão. O depurador tenta corresponder esse padrão aos símbolos existentes e definir pontos de interrupção em todas as correspondências de padrão. SymbolPattern pode conter uma variedade de caracteres curinga e especificadores. Para obter mais informações sobre essa sintaxe, consulte Sintaxe curinga de cadeia de caracteres. Como esses caracteres estão sendo correspondidos a símbolos, a correspondência não diferencia maiúsculas de minúsculas e um único sublinhado à esquerda (_) representa qualquer quantidade de sublinhados à esquerda.
Ambiente
Item | Descrição |
---|---|
Modos | modo de usuário, modo kernel |
Destinos | somente depuração ao vivo |
Plataformas | all |
Informações Adicionais
Para obter mais informações e exemplos de como usar pontos de interrupção, outros comandos de ponto de interrupção e métodos de controle de pontos de interrupção e como definir pontos de interrupção no espaço do usuário de um depurador de kernel, consulte Usando pontos de interrupção. Para obter mais informações sobre pontos de interrupção condicionais, consulte Como definir um ponto de interrupção condicional.
Comentários
Os comandos bp, bu e bm definem novos pontos de interrupção, mas têm características diferentes:
O comando bp (Definir Ponto de Interrupção) define um novo ponto de interrupção no endereço do local do ponto de interrupção especificado no comando. Se o depurador não puder resolver a expressão de endereço do local do ponto de interrupção quando o ponto de interrupção for definido, o ponto de interrupção bp será convertido automaticamente em um ponto de interrupção bu . Use um comando bp para criar um ponto de interrupção que não estará mais ativo se o módulo for descarregado.
O comando bu (Definir ponto de interrupção não resolvido) define um ponto de interrupção adiado ou não resolvido . Um ponto de interrupção bu é definido em uma referência simbólica para o local do ponto de interrupção especificado no comando (não em um endereço) e é ativado sempre que o módulo com a referência é resolvido. Para obter mais informações sobre esses pontos de interrupção, consulte Pontos de interrupção não resolvidos (bu Pontos de interrupção).
O comando bm (Definir ponto de interrupção do símbolo) define um novo ponto de interrupção em símbolos que correspondem a um padrão especificado. Esse comando pode criar mais de um ponto de interrupção. Por padrão, depois que o padrão é correspondido, os pontos de interrupção bm são os mesmos que os pontos de interrupção bu . Ou seja, os pontos de interrupção bm são pontos de interrupção adiados definidos em uma referência simbólica. No entanto, um comando bm /d cria um ou mais pontos de interrupção bp . Cada ponto de interrupção é definido no endereço de um local correspondente e não rastreia o estado do módulo.
Se você não tiver certeza de qual comando foi usado para definir um ponto de interrupção existente, use .bpcmds (Exibir Comandos de Ponto de Interrupção) para listar todos os pontos de interrupção junto com os comandos que foram usados para criá-los.
Há três diferenças principais entre os pontos de interrupção bp e bu:
Um local de ponto de interrupção bp é sempre convertido em um endereço. Se uma alteração de módulo mover o código no qual um ponto de interrupção bp foi definido, o ponto de interrupção permanecerá no mesmo endereço. Por outro lado, um ponto de interrupção bu permanecerá associado ao valor simbólico (geralmente, um símbolo mais um deslocamento) que foi usado, e ele rastreará esse local simbólico mesmo se seu endereço mudar.
Se um endereço de ponto de interrupção bp for encontrado em um módulo carregado e se esse módulo for descarregado posteriormente, o ponto de interrupção será removido da lista de pontos de interrupção. Por outro lado, os pontos de interrupção bu persistirão após carregamentos e descarregamentos repetidos.
Os pontos de interrupção que você define bp não são salvos em espaços de trabalho do WinDbg. Os pontos de interrupção definidos com bu são salvos nos espaços de trabalho.
O comando bm é útil quando você deseja usar caracteres curinga no padrão de símbolo para um ponto de interrupção. A sintaxe bm SymbolPattern é equivalente a usar x SymbolPattern e, em seguida, usar bu em cada resultado. Por exemplo, para definir pontos de interrupção em todos os símbolos no módulo Myprogram que começam com a cadeia de caracteres "mem", use o comando a seguir.
Exemplo
0:000> bm myprogram!mem*
4: 0040d070 MyProgram!memcpy
5: 0040c560 MyProgram!memmove
6: 00408960 MyProgram!memset
Como o comando bm define pontos de interrupção de software (não pontos de interrupção do processador), ele exclui automaticamente o local dos dados quando define pontos de interrupção para evitar corromper os dados.
É possível especificar um endereço de dados, em vez de um endereço de programa, ao usar os comandos bp ou bm /a. No entanto, mesmo que um local de dados seja especificado, esses comandos criam pontos de interrupção de software, não pontos de interrupção do processador. Se um ponto de interrupção de software for colocado nos dados do programa em vez do código executável, isso pode levar à corrupção de dados. Portanto, você deve usar esses comandos em um local de dados somente se tiver certeza de que a memória armazenada nesse local será usada como código executável e não como dados do programa. Caso contrário, você deve usar o comando ba (Interromper no Acesso). Para obter mais detalhes, consulte Pontos de interrupção do processador (pontos de interrupção ba).
Para obter detalhes sobre como definir um ponto de interrupção em um local especificado por uma sintaxe mais complicada, como um membro de uma classe pública C++ ou uma cadeia de caracteres de texto arbitrária contendo caracteres restritos, consulte Sintaxe de ponto de interrupção.
Se uma única linha de origem lógica abranger várias linhas físicas, o ponto de interrupção será definido na última linha física da instrução ou chamada. Se o depurador não puder definir um ponto de interrupção na posição solicitada, ele colocará o ponto de interrupção na próxima posição permitida.
Se você especificar Thread, os pontos de interrupção serão definidos nos threads especificados. Por exemplo, o comando ~*bp define pontos de interrupção em todos os threads, ~#bp define um ponto de interrupção no thread que causa a exceção atual e ~123bp define um ponto de interrupção no thread 123. Os comandos ~bp e ~.bp definem um ponto de interrupção no thread atual.
Quando você está depurando um sistema multiprocessador no modo kernel, os pontos de interrupção definidos usando bp ou ba (Interromper no Acesso) se aplicam a todos os processadores. Por exemplo, se o processador atual for 3 e você digitar bp MemoryAddress para colocar um ponto de interrupção em MemoryAddress. Qualquer processador que esteja sendo executado nesse endereço (não apenas o processador 3) causa uma interceptação de ponto de interrupção.
Os comandos bp, bu e bm definem pontos de interrupção de software substituindo a instrução do processador por uma instrução de interrupção. Para depurar código somente leitura ou código que não pode ser alterado, use um comando ba e, em que e representa o acesso somente execução.
O comando a seguir define um ponto de interrupção 12 bytes após o início da função MyTest. Esse ponto de interrupção é ignorado nas primeiras seis passagens pelo código, mas a execução é interrompida na sétima passagem pelo código.
0:000> bp MyTest+0xb 7
O comando a seguir define um ponto de interrupção em RtlRaiseException, exibe o registro eax , exibe o valor do símbolo MyVar e continua.
kd> bp ntdll!RtlRaiseException "r eax; dt MyVar; g"
Os dois comandos bm a seguir definem três pontos de interrupção. Quando os comandos são executados, o resultado exibido não distingue entre pontos de interrupção criados com a opção /d e aqueles criados sem ela. O .bpcmds (Exibir Comandos de Ponto de Interrupção) pode ser usado para distinguir entre esses dois tipos. Se o ponto de interrupção foi criado por bm sem a opção /d , a exibição .bpcmds indicará o tipo de ponto de interrupção como bu, seguido pelo símbolo avaliado entre o token @!"" (que indica que é um símbolo literal e não uma expressão numérica ou registro). Se o ponto de interrupção foi criado por bm com a opção /d , a exibição .bpcmds indicará o tipo de ponto de interrupção como bp.
0:000> bm myprog!openf*
0: 00421200 @!"myprog!openFile"
1: 00427800 @!"myprog!openFilter"
0:000> bm /d myprog!closef*
2: 00421600 @!"myprog!closeFile"
0:000> .bpcmds
bu0 @!"myprog!openFile";
bu1 @!"myprog!openFilter";
bp2 0x00421600 ;