Devo compilar versões de lançamento com informações de depuração como “completo” ou “somente PDB”?

114

No Visual Studio 2010 para um projeto C #, se você for para Propriedades do projeto> Compilar> Avançado> Informações de depuração, terá três opções: nenhum, completo ou somente pdb. Com base na resposta a esta pergunta , acredito que entendo algumas das diferenças entre full e PDB somente. No entanto, o que é mais apropriado para uma versão de lançamento? Se eu usar "full", haverá ramificações de desempenho? Se eu usar "somente PDB", será mais difícil depurar problemas de produção?

Qual é a diferença entre "full" e "pdbonly"? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option

RationalGeek
fonte
O pdb somente ou nenhum, sempre para compilações de lançamento.
leppie,
13
@leppie Obrigado, mas estou procurando alguma justificativa para essa posição.
RationalGeek,
Pergunta relacionada: stackoverflow.com/questions/1270986/…
janv8000
Isso é ótimo se não houver impacto no desempenho. E o impacto na memória? Se eu criar uma instância de StackTrace e solicitar informações do arquivo, ela terá que vir dos dados do símbolo PDB. Todos os símbolos são carregados na memória no início do aplicativo? Qual é o uso de memória aproximado disso? (por exemplo, porcentagem de sobrecarga em relação ao tamanho do código.)
yoyo

Respostas:

90

Eu construiria com pdb-only. Você não poderá anexar um depurador ao produto lançado, mas se obtiver um despejo de memória , você pode usar o Visual Studio ou WinDBG para examinar os rastreamentos de pilha e despejos de memória no momento da falha.

Se você escolher com, em fullvez de pdb-only, obterá os mesmos benefícios, exceto que o executável pode ser anexado diretamente a um depurador. Você precisará determinar se isso é razoável, dados seus produtos e clientes.

Certifique-se de salvar os arquivos PDB em algum lugar para que possa referenciá-los quando um relatório de travamento chegar. Se você puder configurar um servidor de símbolos para armazenar esses símbolos de depuração, tanto melhor.

Se você optar por construir com none, você não terá nenhum recurso quando houver uma falha no campo. Você não poderá fazer nenhum tipo de exame após o fato do acidente, o que pode prejudicar seriamente sua capacidade de rastrear o problema.

Uma nota sobre o desempenho:

Tanto John Robbins quanto Eric Lippert escreveram postagens de blog sobre a /debugbandeira e ambos indicam que essa configuração tem impacto zero no desempenho . Há um /optimizesinalizador separado que determina se o compilador deve realizar otimizações.

Matt Dillard
fonte
7
@Matt, o artigo do MSDN sobre a opção / debug avisa explicitamente sobre o impacto no desempenho do uso da configuração 'completa':If you use /debug:full, be aware that there is some impact on the speed and size of JIT optimized code and a small impact on code quality with /debug:full. We recommend /debug:pdbonly or no PDB for generating release code.
Allon Guralnek
3
@Matt: Se 'full' não tem desvantagens em comparação com 'somente pdb', mas tem apenas vantagens, por que existe 'somente pdb'? Existe alguma razão para usá-lo 'cheio'? Além disso, você deve adicionar a correção ao artigo do MSDN na seção 'Conteúdo da Comunidade'.
Allon Guralnek de
9
Citação de @AllonGuralnek do artigo vinculado de John Robbins: O verdadeiro motivo: história. No .NET 1.0 havia diferenças, mas no .NET 2.0 não. Parece que o .NET 4.0 seguirá o mesmo padrão. Depois de verificar duas vezes com a Equipe de depuração CLR, não há diferença alguma.
bentayloruk
5
Isso não é verdade. Você pode construir somente com PDB e ainda anexar um depurador. Só fiz isso para ter certeza.
Marcos
2
"Gostaria de construir apenas com PDB. Você não conseguirá anexar um depurador ao produto lançado" Qual é a sua fonte de informação aqui? Como @Mark e eu observamos, isso não parece estar correto.
MEMark
66

AVISO A documentação do MSDN para a opção / debug (no Visual Studio é Debug Info) parece estar desatualizada! Isto é o que está incorreto

Se você usar / debug: full , esteja ciente de que há algum impacto na velocidade e no tamanho do código JIT otimizado e um pequeno impacto na qualidade do código com / debug: full . Recomendamos / debug: pdbonly ou nenhum PDB para gerar o código de lançamento.

Uma diferença entre / debug: pdbonly e / debug: full é que com / debug: full o compilador emite um DebuggableAttribute, que é usado para informar ao compilador JIT que as informações de depuração estão disponíveis.

Então, o que é verdade agora?

  1. Somente PDB - antes do .NET 2.0, ajudava a investigar os despejos de memória do produto lançado (máquinas do cliente). Mas não deixou anexar o depurador. Este não é o caso do .NET 2.0. É exatamente igual a Full .
  2. Completo - Isso nos ajuda a investigar despejos de memória e também nos permite anexar o depurador ao lançamento do build. Mas, ao contrário das menções do MSDN, não afeta o desempenho (desde o .NET 2.0). Ele faz exatamente o mesmo que somente Pdb .

Se eles são exatamente iguais, por que temos essas opções? John Robbins (deus da depuração do Windows) descobriu que eles existem por razões históricas.

No .NET 1.0 havia diferenças, mas no .NET 2.0 não. Parece que o .NET 4.0 seguirá o mesmo padrão. Depois de verificar duas vezes com a Equipe de depuração CLR, não há diferença alguma.

O que controla se o JITter faz uma compilação de depuração é a opção / Optimize. <…>

O resultado final é que você deseja construir suas versões de lançamento com / optimize + e qualquer uma das opções / debug para que possa depurar com o código-fonte.

então ele passa a provar isso.

Agora, a otimização faz parte de um switch separado /optimize(no Visual Studio é chamado Optimize code).

Em suma, independentemente de DebugInfo definir somente pdb ou full, teremos os mesmos resultados. A recomendação é evitar Nenhum, pois isso privaria você de ser capaz de analisar os despejos de memória do produto lançado ou anexar o depurador.

rpattabi
fonte
3
Resposta fantástica! Minhas próprias investigações (comparando arquivos gerados) mostram os mesmos resultados.
MEMark
@rpattabi Você pode especificar a referência que pdbonly e full são a mesma coisa? É 2019 e a documentação ainda indica que eles são diferentes e completos terão degradação de desempenho. E o VS2019 cria projeto com Releaseo tipo de depuração da configuração definido como padrão pdbonly.
joe
@joe Há uma discussão na parte inferior da documentação do MSDN msdn.microsoft.com/en-us/library/8cw0bt21.aspx . Dê uma olhada nisto. Um contribuidor apontou para github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/… para informações atualizadas, onde pdbonly e full são mencionados como o mesmo. (Para sua informação. Não uso mais o Windows ou o VS. Portanto, não tenho acompanhado o que está acontecendo lá. Mas, conforme
analisei
16

Você vai querer apenas PDB, mas não vai querer dar os arquivos PDB aos usuários. Tê-los para você, no entanto, junto com seus binários, lhe dá a capacidade de carregar despejos de memória em um depurador como o WinDbg e ver onde seu programa realmente falhou. Isso pode ser bastante útil quando seu código está travando em uma máquina à qual você não tem acesso.

A depuração completa adiciona o atributo [Debuggable] ao seu código. Isso tem um grande impacto na velocidade. Por exemplo, algumas otimizações de loop podem ser desabilitadas para tornar a etapa única mais fácil. Além disso, tem um pequeno efeito no processo JIT, pois ativa o rastreamento.

dardo
fonte
Faz sentido. Eu realmente não distribuo DLLs para os usuários de qualquer maneira - é um aplicativo ASP.NET. Mas você pode melhorar sua resposta e justificar por que deve escolher "somente PDB" em vez de "completo"? É um problema de desempenho?
RationalGeek,
@jkohlhepp: Eu gostaria de acrescentar que a depuração de compilações de lançamento é um pouco complicada, pois você perderá algumas informações (devido ao JIT). Quase sempre, você não poderá ver os valores dos argumentos do método. Para contornar isso, você pode desabilitar temporariamente a otimização JIT usando isso .
Ilian Pinzon,
Obrigado blowdart e obrigado Ilian Pinzon pelas informações adicionais. Eu sei que você não pode obter uma depuração perfeita com o código de lançamento, mas ter os PDBs é melhor do que nada.
RationalGeek de
Usar a configuração "total" não tem impacto no desempenho. Ele simplesmente permite que um depurador seja anexado a um processo em execução.
Matt Dillard de
1
Boa pergunta no MSDN Matt, msdn.microsoft.com/en-us/library/8cw0bt21 , esperando pela resposta eu mesmo.
Luke Hutton
4

Estou no processo de escrever um manipulador de exceção não tratada e o rastreamento de pilha inclui o número da linha quando pdb-only é usado, caso contrário, recebo apenas o nome da Sub / Function quando escolho Nenhum.

Se eu não distribuir o .pdb, não obtenho o número da linha no rastreamento da pilha, mesmo com a compilação somente PDB.

Então, estou distribuindo (XCOPY implanta em uma LAN) o pdb junto com o exe do meu aplicativo VB.

Rheitzman
fonte