Razões comuns para bugs na versão de lançamento não está presente no modo de depuração

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

  •  21-09-2019
  •  | 
  •  

Pergunta

Quais são as razões para bugs e anormal do programa de comportamento que se manifestam apenas na versão o modo de compilação, mas que não ocorrem quando no modo de depuração?

Foi útil?

Solução

Muitas vezes, no modo de depuração em C++, todas as variáveis são nulos inicializado, enquanto o mesmo não acontece no modo de versão, a menos que explicitamente indicado.

Verifique se há qualquer depurar macros e variáveis não inicializadas

O seu programa usa threading, em seguida, a otimização pode também causar alguns problemas no modo de edição.

Verifique, também, para todas as exceções, por exemplo, que não estão diretamente relacionados ao modo de edição, mas em algum momento nós simplesmente ignorar algumas exceções crítica, como mem de violação de acesso no VC++, mas o mesmo pode ser um problema, pelo menos em outro sistema operacional, como o Linux, o Solaris.Idealmente, o programa não deve pegar tais exceções crítica como acessar um ponteiro NULO.

Outras dicas

Uma armadilha comum está usando uma expressão com efeito colateral dentro de uma afirmação.

Outras diferenças podem ser:

  • Em uma linguagem coletada por lixo, o coletor é geralmente mais agressivo no modo de liberação;
  • O layout da memória pode ser diferente;
  • A memória pode ser inicializada de maneira diferente (por exemplo, pode ser zerado no modo de depuração ou reutilizado de maneira mais agressiva);
  • Os habitantes locais podem ser promovidos para registrar valores na liberação, o que pode causar problemas com os valores de ponto flutuante.

Eu fui mordido por um número de erros no passado que tem sido muito bem em compilações de Depuração, mas falha em compilações.Existem muitas causas subjacentes (incluindo, claro, aqueles que já foram resumidos neste segmento) e eu fui pego de surpresa por todos os seguintes:

  • Membro variáveis ou funções de membro em uma #ifdef _DEBUG, para que uma classe é um tamanho diferente em uma compilação de depuração.Às vezes #ifndef NDEBUG é usado em uma versão de compilação
  • Da mesma forma, existe um diferente #ifdef o que acontece de estar presente apenas em uma das duas versões
  • A versão de depuração usa as versões de depuração do sistema de bibliotecas, especialmente a pilha e funções de alocação de memória
  • Antes de funções em uma versão de compilação
  • Pedido de inclusão de arquivos de cabeçalho.Isso não deve causar problemas, mas se você tiver algo como um #pragma pack que não tenha sido reposto em seguida, isso pode levar a problemas desagradáveis.Problemas semelhantes também pode ocorrer usando cabeçalhos pré-compilados e forçado inclui
  • Caches:poderá ter de código, tais como caches, que só é usado em versões de lançamento, ou o tamanho do cache de limites que são diferentes
  • Configurações de projeto:as configurações de depuração e liberação podem ter diferentes configurações de compilação (isto é provável de acontecer quando usando um IDE)
  • Condições de corrida, problemas de timing e miscellanous efeitos colaterais que ocorrem como resultado de depuração apenas o código

Algumas dicas que eu acumulei ao longo dos anos para chegar ao fundo de debug/release bugs:

  • Tente reproduzir o comportamento anômalo em uma compilação de depuração se você pode, e melhor ainda, escrever um teste de unidade para capturá-lo
  • Pense sobre o que difere entre os dois:configurações de compilador, caches, somente para depuração de código.Tente minimizar essas diferenças temporariamente
  • Criar uma versão de compilação com otimizações de desligado (então, você é mais provável para obter dados úteis no depurador), ou a optimização da compilação de depuração.Minimizando as alterações entre debug e release, você é mais provável ser capaz de isolar qual a diferença está causando o erro.

Sim!, Se você tiver compilação condicional, pode haver bugs de tempo (Código de liberação otimizado, código de depuração não otimizado), reutilização de memória vs. heap de depuração.

Pode, especialmente se você estiver no reino C.

Uma causa pode ser que a versão de depuração possa adicionar código para verificar os ponteiros perdidos e, de alguma forma, proteger seu código de travar (ou se comportar incorretamente). Se for esse o caso, você deve verificar cuidadosamente os avisos e outras mensagens que recebe do seu compilador.

Outra causa pode ser a otimização (que normalmente está ligada para versões de liberação e desativada para depuração). O código e o layout de dados podem ter sido otimizados e, embora seu programa de depuração tenha sido, por exemplo, acessar a memória não utilizada, a versão de liberação agora está tentando acessar a memória reservada ou até apontar para o código!

EDIT: Vejo outras mencionadas: é claro que você pode ter seções de código inteiras que são excluídas condicionalmente se não forem compilando no modo de depuração. Se for esse o caso, espero que seja realmente depurando o código e não algo vital para a correção do próprio programa!

As funções da biblioteca do CRT se comportam de maneira diferente na liberação de depuração vs ( /md vs /mdd).

Por exemplo, as versões de depuração geralmente preenchem os buffers que você passa para o comprimento indicado para verificar sua reivindicação. Exemplos incluem strcpy_s, StringCchCopy, etc. mesmo que as cordas terminam anteriormente, seu Szdest melhor ser n bytes de longa duração!

Claro, por exemplo, se você usar construções como

#if DEBUG

//some code

#endif

No .net, mesmo que você não use compilação condicional como #if DEBUG, o compilador ainda é muito mais liberal com otimizações no modo de liberação do que no modo de depuração, o que também pode levar a liberação apenas de bugs.

Você precisa dar muito mais informações, mas sim, é possível.Depende do que a sua versão de depuração não.Você pode muito bem ter registo ou extra verifica no que que não é compilado em uma versão de lançamento.Estes depuração apenas caminhos de código pode ter efeitos colaterais indesejados que mudar de estado ou afetam as variáveis de formas estranhas.Compilações de depuração normalmente são executados mais lentamente, de modo que este pode afectar threading e ocultar condições de corrida.O mesmo para a frente otimizações de uma versão de compilação, é possível (embora improvável nos dias de hoje) que uma versão de compilação de maio de curto-circuito, algo como uma otimização.

Sem mais detalhes, assumirei que "não ok" significa que ele não compila ou lança algum tipo de erro no tempo de execução. Verifique se você tem código que depende da versão de compilação, seja via #if DEBUG declarações ou via métodos marcados com o Conditional atributo.

Isso é possível, se você tiver compilação condicional, para que o código de depuração e o código de liberação sejam diferentes, e há um bug no código que é usado apenas no modo de liberação.

Fora isso, não é possível. Há diferença na forma como o código de depuração e o código de liberação são compilados e as diferenças na forma como o código é executado se executado sob um depurador ou não, mas se alguma dessas diferenças causar algo além de uma diferença de desempenho, o problema estava lá o tempo todo.

Na versão Debug, o erro pode não estar ocorrendo (porque a alocação de tempo ou memória é diferente), mas isso não significa que o erro não esteja lá. Também pode haver outros fatores que não estão relacionados ao modo de depuração que altera o momento do código, fazendo com que o erro ocorra ou não, mas tudo se resume ao fato de que, se o código estivesse correto, o erro não ocorreria em qualquer uma das situações.

Portanto, não, a versão de depuração não está bem apenas porque você pode executá -la sem receber um erro. Se ocorrer um erro quando você o executa no modo de liberação, não é por causa do modo de liberação, é porque o erro estava lá desde o início.

Existem otimizações do compilador que pode quebrar o código válido Porque eles são muito agressivos.

Tente compilar seu código com menos otimização ativada.

Em uma função não void, todos os caminhos de execução devem terminar com uma instrução RETURN.

No modo de depuração, se você esquecer de encerrar esse caminho com uma declaração de retorno, a função geralmente retorna 0 por padrão.

No entanto, no modo de liberação, sua função pode retornar valores de lixo, o que pode afetar a forma como seu programa é executado.

É possível. Se isso acontecer e nenhuma compilação condicional estiver envolvida, você pode ter certeza de que seu programa está errado e está trabalhando no modo de depuração apenas por causa das inicializações fortuitas de memória ou mesmo layout na memória!

Eu só a experiência de que quando eu estava chamando uma função de assembly que não restaurou o dos registradores valores anteriores.

No "Lançamento" de configuração, VS estava compilando com /O2 que otimiza o código de velocidade.Assim, algumas variáveis locais onde apenas o mapeamento para registradores de CPU (para optimization), que foram partilhados com a referida função, levando a graves de corrupção de memória.

De qualquer forma, veja se você não está indiretamente mexer com registradores de CPU em qualquer lugar no seu código.

Lembro -me de que atrás, quando estávamos construindo DLL e PDB em C/C ++.

Eu me lembro disso:

  • A adição de dados de log em algum momento faria o bug mover ou desaparecer ou fazer um erro totalmente outro erro (para que não fosse realmente uma opção).
  • Muitos desses erros, devido à alocação de char em strcpy e strcat e matrizes de char [] etc ...
  • Nós eliminamos algumas elaboradas com o verificador de limites e simplesmente corrigindo os problemas de alocação/reá à memória.
  • Muitas vezes, passamos sistematicamente pelo código e corrigimos uma alocação de char (como através de todos os arquivos).
  • Definitivamente, é algo relacionado à alocação de memória, gerenciamento e restrições e diferenças entre o modo de depuração e o modo de liberação.

E então esperou o melhor.

Às vezes, entreguei temporariamente as versões de depuração das DLLs para os clientes, para não adiar a produção, enquanto trabalhava nesses bugs.

Outras razões podem ser chamadas de banco de dados. Você está salvando e atualizando o mesmo registro várias vezes no mesmo thread, às vezes para atualizar. É possível que a atualização falhasse ou não funcionou conforme o esperado, porque o comando Create anterior ainda estava processando e, para a atualização, a chamada do banco de dados não conseguiu encontrar nenhum registro. Isso não acontecerá na depuração, pois o depurador pretende concluir todas as tarefas pendentes antes do pouso.

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