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.

User-Mode

[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]

Kernel-Mode

bp[ID] [Options] [Address [Passes]] ["CommandString"] 
bu[ID] [Options] [Address [Passes]] ["CommandString"] 
bm [Options] SymbolPattern [Passes] ["CommandString"]

Parâmetros

Thread
Especifica o thread ao qual o ponto de interrupção se aplica. Para obter mais informações sobre a sintaxe, consulte Sintaxe de 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á-lo usando o comando br (Breakpoint Renumber). Você pode usar a ID para se referir ao ponto de interrupção em comandos posteriores do depurador. Para exibir a ID de um ponto de interrupção, use o comando bl (Lista de Pontos de Interrupção).

Ao usar a ID em um comando, não digite um espaço entre o comando (bp ou bu) e o número da 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á nenhuma restrição no valor do número de ID . Se você colocar a ID entre colchetes ([]), a ID poderá incluir qualquer expressão. Para obter mais informações sobre a sintaxe, consulte Sintaxe de expressão numérica.

Opções 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 "one-shot". Depois que esse ponto de interrupção é disparado, ele é excluído da lista de pontos de interrupção.

/pEProcess
(Somente modo kernel) Especifica um processo associado a esse ponto de interrupção. EProcess deve ser o endereço real da estrutura EPROCESS, não o PID. O ponto de interrupção será disparado somente se for encontrado no contexto desse processo.

/tEThread
(Somente modo kernel) Especifica um thread associado a esse ponto de interrupção. EThread deve ser o endereço real da estrutura ETHREAD, não a ID do thread. O ponto de interrupção será disparado somente se for encontrado no contexto desse thread. Se você usar /pEProcess e /tEThread, poderá inseri-los em qualquer ordem.

/cMaxCallStackDepth
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.

/CMinCallStackDepth
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.

/Um
(Somente para bm ) Define pontos de interrupção em todos os locais especificados, independentemente de estarem 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 como seguros.

/d
(Somente para bm ) Converte os locais do ponto 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 em pontos de interrupção quando os módulos são carregados ou descarregados.

/(
(Somente para bm ) Inclui informações de lista de parâmetros na cadeia de caracteres de símbolo definida por SymbolString .

Esse recurso permite definir 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.

Expressão de objeto /w dx Define um ponto de interrupção condicional com base no valor booliano retornado pela expressão de objeto dx. O argumento é uma expressão de modelo de dados (dx) que é avaliada como true (corresponde à condição – quebra) ou false (não corresponde à condição – não quebra).

Este exemplo define um ponto de interrupção condicional com base no valor de localVariable.

bp /w "localVariable == 4" mymodule!myfunction

Este 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 (Exibir expressão de modelo de objeto do depurador).

Para obter mais informações sobre pontos de interrupção condicionais, consulte Configurando um ponto de interrupção condicional.

Endereço
Especifica o primeiro byte da instrução em que o ponto de interrupção está definido. Se você omitir Address, o ponteiro de instrução atual será usado. Para obter mais informações sobre a sintaxe, consulte Sintaxe de intervalo de endereços e endereços.

Passa
Especifica o número da passagem de execução na qual o ponto de interrupção está 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 2 ativa o ponto de interrupção na segunda vez em 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 Passes , use bl (Lista de Pontos de Interrupção).

O contador Passes é decrementado somente quando o aplicativo é executado após o ponto de interrupção em resposta a um comando g (Go). O contador não será reduzido se você estiver percorrendo o código ou rastreando-o. Quando o contador Passes atinge 1, você pode redefini-lo apenas limpando e redefinindo o ponto de interrupção.

CommandString
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írgula contidos nas aspas de segundo nível (\") são interpretados como parte da cadeia de caracteres entre aspas inseridas.

Os comandos CommandString serão executados somente se o ponto de interrupção for atingido enquanto o aplicativo estiver em execução 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.

SymbolPattern
Especifica um padrão. O depurador tenta corresponder esse padrão a 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 aos 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 dinâmica
Plataformas all

Informações adicionais

Para obter mais informações sobre 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 Configurando 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 resolve 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 (pontos de interrupção bu).

  • O comando bm (Definir Ponto de Interrupção de 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 acompanha 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 (Comandos de Ponto de Interrupção de Exibiçã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 pontos de interrupção bp e pontos de interrupção 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 permanece associado ao valor simbólico (normalmente um símbolo mais um deslocamento) que foi usado e rastreia esse local simbólico mesmo que seu endereço seja alterado.

  • 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 persistem após carregamentos e descarregamentos repetidos.

  • Os pontos de interrupção definidos com bp não são salvos em workspaces do WinDbg. Os pontos de interrupção definidos com bu são salvos em workspaces.

O comando bm é útil quando você deseja usar caracteres curinga no padrão de símbolo para um ponto de interrupção. A sintaxe bmSymbolPattern é 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 em dados do programa em vez de código executável, isso poderá levar à corrupção de dados. Portanto, você deverá 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ê deverá usar o comando ba (Interromper no Access ). 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) causará 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 de 12 bytes após o início da função MyTest. Esse ponto de interrupção é ignorado para as seis primeiras 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 os pontos de interrupção criados com a opção /d e aqueles criados sem ele. Os .bpcmds (Comandos de Ponto de Interrupção de Exibição) podem ser usados para distinguir entre esses dois tipos. Se o ponto de interrupção foi criado por bm sem o comutador /d , a exibição .bpcmds indica o tipo de ponto de interrupção como bu, seguido pelo símbolo avaliado colocado no token @!"" (que indica que é um símbolo literal e não uma expressão numérica ou registro). Se o ponto de interrupção tiver sido criado pelo 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 ;