/ MT e / MD constrói deixar de funcionar, mas apenas quando depurador não está anexado: como depurar? [duplicado]

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

Pergunta

I tem um único pequeno roscados aplicação C ++, compilado e ligado utilizando o Visual Studio 2005, que utiliza o impulso (CRC, program_options, e tokenizer), uma dose significativa de STL, e diversos outros sistemas de cabeçalhos.

(É objetivo principal é lido em um arquivo .csv e gerar um binário .dat e uma emparelhado .h declarando estruturas que "explicar" o formato do .dat. Personalizado)

A ferramenta está falhando (violação de acesso em NULL) quando executado fora do depurador, apenas no lançamento. Por exemplo. pressionando F5 não causa a ferramenta para acidente, Ctrl-F5 faz. Quando eu re-anexar o depurador, eu recebo esta pilha:

ntdll.dll!_RtlAllocateHeap@12()  + 0x26916 bytes    
csv2bin.exe!malloc(unsigned int size=0x00000014)  Line 163 + 0x63 bytes C
csv2bin.exe!operator new(unsigned int size=0x00000014)  Line 59 + 0x8 bytes C++
>csv2bin.exe!Record::addField(const char * string=0x0034aac8)  Line 62 + 0x7 bytes  C++
csv2bin.exe!main(int argc=0x00000007, char * * argv=0x00343998)  Line 253   C++
csv2bin.exe!__tmainCRTStartup()  Line 327 + 0x12 bytes  C

A linha está falhando em uma repartição pouco inócuo aparência:

pField = new NumberField(this, static_cast<NumberFieldInfo*>(pFieldInfo));

... Eu não acredito que tenha alcançado o construtor ainda, é apenas a alocação de memória antes de saltar para o construtor. Ele também tem executado este dezenas de código de vezes no momento em que deixa de funcionar, geralmente em um local consistente (mas de outra forma não-suspeito).

O problema desaparece quando compilação com / MTd ou / MDd (depuração de tempo de execução), e volta ao usar / MT ou / MD.

O NULL é carregado a partir da pilha, e eu posso vê-lo em vista da memória. _RtlAllocateHeap @ 12 + 0x26916 bytes parece ser um enorme offset, como um salto incorreta foi feita.

Eu tentei _HAS_ITERATOR_DEBUGGING em uma compilação de depuração e que não tenha trazido qualquer coisa suspeita.

Soltando um HeapValidate no início e no final do registro mostra :: AddField num montão OK até quando ele trava.

Este utilizado para o trabalho - eu não estou inteiramente certo o que mudou entre agora e a última vez que compilou a ferramenta (provavelmente anos atrás, talvez sob uma VS mais velho). Nós tentamos uma versão mais antiga de aumento (1,36 vs 1,38).

Antes de cair de volta à investigação Manual do código ou alimentando isso para PC-Lint e pentear através da sua saída, alguma sugestão sobre como depurar efetivamente isso?

[Eu vou ser feliz para atualizar a questão com mais informações, se você pedir informação nos comentários.]

Foi útil?

Solução

Uma pequena diferença conhecimentos entre correr com depurador anexado ou não é o OS Debug Heap (ver também Por que meu código executado lentamente quando tenho depurador anexado ?). Você pode virar a pilha de depuração off usando _NO_DEBUG_HEAP ambiente variável. Você pode especificar essa seja em suas propriedades do computador, ou nas configurações do projeto no Visual Studio.

Uma vez que você virar a pilha de depuração off, você deve ver o mesmo acidente, mesmo com depurador anexado.

Dito isso, ser corrupções de memória consciente pode ser difícil de debug, como muitas vezes a causa real da corrupção (como alguns saturação de buffer) pode ser muito longe de onde você vê os sintomas (o acidente).

Outras dicas

Application Verifier foi super-útil para resolver isso de uma vez eu tive _NO_DEBUG_HEAP = 1 no ambiente, consulte a resposta aceita aqui: Finding onde a memória a última libertou?

É provavelmente também vale a pena mencionar pageheap , que eu achei enquanto olha para Application Verifier. Parece que cobre algum terreno similar.

(FYI, foi um estouro de buffer de um caractere:

m_pEnumName = (char*)malloc(strlen(data) /* missing +1 here */);
strcpy(m_pEnumName, data);

... mais um ridiculamente bom argumento para não usar strcpy diretamente.)

Crashing dentro novo ou malloc geralmente é um indício de que a estrutura (interna) da implementação malloc foi corrompido. Esta é a maior parte do tempo feito por escrito passado uma alocação anterior (buffer overflow). Em seguida, na próxima chamada para novos ou malloc as falhas de aplicativos como a estrutura interna agora contém dados inválidos.

Verifique se você pode substituir qualquer espaço alocado anterior.

Se o seu aplicativo é portátil você pode tentar construí-lo no Linux e executá-lo sob Valgrind .

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