Qual é a melhor maneira de anexar um depurador a um processo em VC ++ apenas no ponto certo no tempo?

StackOverflow https://stackoverflow.com/questions/663449

Pergunta

Quando a depuração, às vezes você precisa anexar um processo já em execução em vez de apenas iniciar o aplicativo em um depurador.

comum é para me colocar em um Sleep () ou chamada MessageBox, de modo que é mais fácil para anexar um depurador. Preocupa-me que alguns destes podem ser comprometidos, eventualmente, para controle de origem.

O que é a melhor coisa a fazer para evitar essa situação enquanto ainda atrasar o tempo suficiente para que você pode anexar o depurador a um processo em execução?

Guardando a suspensão ou caixa de mensagem com um #ifdef _DEBUG é uma forma, mas eu estou querendo saber se existe uma maneira melhor.

Com um sono você também tem o problema que você não pode anexar no tempo. Com um MessageBox você tem o problema que você pode ser remotamente depuração, ou depurar um processo que não tem GUI visível (exemplo de execução como um serviço no Vista)

Outras dicas

Para anexar um depurador em um determinado ponto, você tem várias opções:

O mais simples é apenas para DebugBreak chamada, que é praticamente equivalente a __asm int 3, mas também trabalha em outras arquiteturas (MSVC para x64 não permite linha de montagem, se bem me lembro). Isso vai abrir a janela depurador just-in-time, e você será capaz de selecionar a partir de depuradores registrados (ou seja, Visual Studio) para anexar ao processo.

Como alternativa, você pode introduzir uma chamada para Sleep, dando-lhe uma oportunidade para anexar o depurador. Você deve usar #ifdef _DEBUG em torno deste, para garantir que você realmente não enviar com este código incluído.

Uma pergunta: por que você não pode executar o código a partir do IDE? É um serviço ou um DLL IIS-carregado ou similar?

Neste caso, você pode conferir a chave de registro ImageFileExecutionOptions, que lhe permite anexar um depurador no momento em que o processo é iniciado.

Se você usar cdb para isso, você pode configurá-lo como servidor ou cliente para uma instância WinDbg, e depurar dessa forma. Eu fiz isso no passado usando WinDbg como um depurador de kernel, e usando ImageFileExecutionOptions para começar ntsd -d com o processo de chamada. Isso faz com que WinDbg para quebrar em modo de usuário. Isso às vezes é uma técnica útil.

outra variante, que às vezes eu uso é

while( !::IsDebuggerPresent() )
    ::Sleep( 100 ); // to avoid 100% CPU load

deve apenas silenciosamente esperar até que você anexar o depurador ao processo.

Freddy e Reoa tem as soluções corretas. Mas eu queria acrescentar uma razão para não usar um MessageBox.

Exibindo um MessageBox pára apenas parcialmente sua aplicação. Porque você está mostrando UI, uma bomba de mensagem ainda está em execução em pelo menos um segmento em seu programa. Portanto, se seu código faz qualquer um dos seguintes.

  1. comunica através de mensagens do Windows
  2. Tem UI não-trivial
  3. é multi-threaded

Você vai ser essencialmente solicitando um depurador em estado de um, mas anexando ao seu programa em um estado completamente diferente. Isso pode levar a desconcertante situações e bugs.

Recentemente, fizemos uma mudança na nossa base de código para nunca mostrar um MessageBox, a fim de facilitar a ruptura por este motivo. Ela produz muito mau comportamento para um aplicativo não-trivial.

Tendo anexar em 'apenas o ponto certo' é uma dor ... uma opção é mas DebugBreak explícita () declarações no código para forçar a questão, e protegendo-os com #ifdef _DEBUG seria uma boa ideia. Nós usamos uma macro ASSERT que pode chamar DebugBreak (), para que se pode afirmar apenas escrever (false)

Outra opção a considerar está usando 'opções de execução de arquivo de imagem' para iniciar o depurador automaticamente. Veja este blogue MSDN documentação.

Olhe-se:

DebugBreak, __debugbreak e amigos

ou

timeToChase static void () {__asm ??{int 3; }; }

__asm int 3 

Este ponto de interrupção duro vai abrir o diálogo de depuração, que vai deixar você anexar ao processo. Envoltório que em _DEBUG #ifdef e você só vai bater-lo em compilações de depuração.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top