Heisenbug inverso - o teste de unidade falha somente quando o depurador é anexado

Corrigi recentemente um defeito em nosso produto, cujo sintoma era uma violação de acesso causada pelo acesso a um ponteiro pendente.

Para boas práticas, adicionei um teste de unidade para garantir que o bug não volte. Ao escrever um teste de unidade, sempre recuperarei minha correção de defeitos e assegurarei que o teste de unidade falhe; caso contrário, sei que ele não está fazendo seu trabalho corretamente.

Depois de recuperar a correção do defeito, descobri que meu teste de unidade ainda passa (não é bom). Quando anexei um depurador ao teste de unidade para ver por que ele passou, o teste falhou (ou seja, uma exceção foi lançada) e eu pude interromper e observar que a pilha de chamadas correspondia à do defeito original que eu corrigi.

Não modifiquei as configurações "Interromper a exceção" no Visual Studio 2005, e essa é realmente uma exceção crítica do Win32 que faz com que o equipamento de teste seja finalizado (ou seja, não há um manipulador de exceção normal).

O texto da exceção é:

Unhandled exception at 0x0040fc59 in _testcase.exe: 0xC0000005:
Access violation reading location 0xcdcdcdcd.

Nota: A localização nem sempre é0xcdcdcdcd (memória heap Win32 alocada mas não escrita) Às vezes é0x00000000, e às vezes é outro endereço.

Isso parece o inverso de um Heisenbug tradicional, onde um problema desaparece ao observá-lo por meio de um depurador. No meu caso, observá-lo através do depurador faz o problema aparecer!

Meu pensamento inicial foi que essa era uma condição de corrida exposta pelas diferenças de tempo no depurador. No entanto, quando adicionei o rastreamento ao código e o executei separadamente do depurador, os dados que estou imprimindo indicam para mim que o aplicativo deve ser interrompido da mesma maneira que quando executado no depurador. Mas não é!

Alguma sugestão sobre o que poderia estar causando isso?

Atualizar: Estou estreitando a causa desse problema. Vejoessa questão para mais detalhes. Atualizarei esta pergunta com a resposta, se a encontrar.

questionAnswers(4)

yourAnswerToTheQuestion