Sollte ich Release-Builds mit Debug-Informationen als "voll" oder "nur pdb" kompilieren?

113

Wenn Sie in Visual Studio 2010 für ein C # -Projekt zu Projekteigenschaften> Erstellen> Erweitert> Debug-Informationen gehen, haben Sie drei Optionen: Keine, Vollständig oder Nur PDF. Aufgrund der Antwort auf diese Frage glaube ich, einige der Unterschiede zwischen Voll- und Nur-PDF-Dateien zu verstehen. Was ist jedoch für einen Release-Build besser geeignet? Wenn ich "voll" verwende, gibt es Leistungseinbußen? Wenn ich "nur pdb" verwende, ist es dann schwieriger, Produktionsprobleme zu beheben?

Was ist der Unterschied zwischen "voll" und "pdbonly"? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option

RationalGeek
quelle
Die pdb-only oder keine, immer für Release-Builds.
Leppie
13
@leppie Danke, aber ich suche nach einer Rechtfertigung für diese Position.
RationalGeek
Verwandte Frage: stackoverflow.com/questions/1270986/…
janv8000
Das ist großartig, wenn es keine Auswirkungen auf die Leistung gibt. Was ist mit der Auswirkung auf das Gedächtnis? Wenn ich eine Instanz von StackTrace erstelle und Dateiinformationen anfordere, müssen diese aus den PDF-Symboldaten stammen. Werden beim Start der Anwendung alle Symbole in den Speicher geladen? Was ist die ungefähre Speichernutzung davon? (zB prozentualer Overhead im Verhältnis zur Codegröße.)
Jojo

Antworten:

90

Ich würde mit bauen pdb-only. Sie können dem freigegebenen Produkt keinen Debugger hinzufügen. Wenn Sie jedoch einen Absturzspeicherauszug erhalten, können Sie mit Visual Studio oder WinDBG die Stapelspuren und Speicherabbilder zum Zeitpunkt des Absturzes untersuchen.

Wenn Sie sich für fullanstatt entscheiden pdb-only, erhalten Sie dieselben Vorteile, außer dass die ausführbare Datei direkt an einen Debugger angehängt werden kann. Sie müssen feststellen, ob dies angesichts Ihres Produkts und Ihrer Kunden angemessen ist.

Stellen Sie sicher, dass Sie die PDB-Dateien irgendwo speichern, damit Sie sie beim Eingang eines Absturzberichts referenzieren können. Wenn Sie einen Symbolserver zum Speichern dieser Debugging-Symbole einrichten können, umso besser.

Wenn Sie sich für das Bauen entscheiden none, haben Sie bei einem Absturz auf dem Feld keinen Rückgriff. Sie können den Absturz nicht nachträglich untersuchen, was Ihre Fähigkeit, das Problem aufzuspüren, erheblich beeinträchtigen könnte.

Ein Hinweis zur Leistung:

Sowohl John Robbins als auch Eric Lippert haben Blog-Posts über die /debugFlagge geschrieben, und beide weisen darauf hin, dass diese Einstellung keine Auswirkungen auf die Leistung hat . Es gibt ein separates /optimizeFlag, das vorschreibt, ob der Compiler Optimierungen durchführen soll.

Matt Dillard
quelle
7
@Matt, der MSDN-Artikel über den Schalter / debug warnt ausdrücklich vor einer Auswirkung der Verwendung der Einstellung "Voll" auf die Leistung: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: Wenn 'voll' keine Nachteile im Vergleich zu 'nur pdb' hat, sondern nur Vorteile, warum gibt es 'nur pdb' überhaupt? Gibt es einen Grund, es über "voll" zu verwenden? Außerdem sollten Sie die Korrektur zum MSDN-Artikel im Abschnitt "Community-Inhalt" hinzufügen.
Allon Guralnek
9
@ AllGuralnek Zitat aus dem verlinkten John Robbins Artikel: Der wahre Grund: Geschichte. Zurück in .NET 1.0 gab es Unterschiede, in .NET 2.0 jedoch nicht. Es sieht so aus, als würde .NET 4.0 dem gleichen Muster folgen. Nach einer Überprüfung mit dem CLR-Debugging-Team gibt es überhaupt keinen Unterschied.
Bentayloruk
5
Das ist nicht wahr. Sie können nur mit pdb erstellen und trotzdem einen Debugger anhängen. Ich habe es nur getan, um sicherzugehen.
Mark
2
"Ich würde nur mit pdb erstellen. Sie können dem veröffentlichten Produkt keinen Debugger hinzufügen." Was ist Ihre Informationsquelle hier? Wie sowohl @Mark als auch ich festgestellt haben, scheint dies nicht korrekt zu sein.
MEMark
65

WARNUNG Die MSDN- Dokumentation für / debug switch (in Visual Studio ist Debug Info) scheint veraltet zu sein! Dies ist, was es hat, was falsch ist

Wenn Sie / debug: full verwenden , beachten Sie, dass sich dies auf die Geschwindigkeit und Größe des JIT-optimierten Codes sowie auf die Codequalität mit / debug: full auswirkt . Wir empfehlen / debuggen: pdbonly oder kein PDB zum Generieren von Release-Code.

Ein Unterschied zwischen / debug: pdbonly und / debug: full besteht darin, dass der Compiler mit / debug: full ein a ausgibt , mit DebuggableAttributedem dem JIT-Compiler mitgeteilt wird, dass Debug-Informationen verfügbar sind.

Was ist dann jetzt wahr?

  1. Nur Pdb - Vor .NET 2.0 war es hilfreich, die Absturzabbilder von freigegebenen Produkten ( Kundencomputern) zu untersuchen. Der Debugger konnte jedoch nicht angehängt werden. Dies ist in .NET 2.0 nicht der Fall. Es ist genau das gleiche wie Full .
  2. Vollständig - Dies hilft uns bei der Untersuchung von Absturzabbildern und ermöglicht es uns, den Debugger an den Release-Build anzuhängen. Im Gegensatz zu MSDN-Erwähnungen wirkt sich dies jedoch nicht auf die Leistung aus (seit .NET 2.0). Es funktioniert genauso wie Pdb-only .

Wenn sie genau gleich sind, warum haben wir diese Optionen? John Robbins (Windows Debugging God) fand heraus, dass diese aus historischen Gründen vorhanden sind.

Zurück in .NET 1.0 gab es Unterschiede, in .NET 2.0 jedoch nicht. Es sieht so aus, als würde .NET 4.0 dem gleichen Muster folgen. Nach einer Überprüfung mit dem CLR-Debugging-Team gibt es überhaupt keinen Unterschied.

Was steuert, ob der JITter einen Debug-Build ausführt, ist der Schalter / optimize. <…>

Unter dem Strich möchten Sie Ihre Release-Builds mit / optimize + und einem der Schalter / debug erstellen, damit Sie mit dem Quellcode debuggen können.

dann beweist er es weiter.

Jetzt ist die Optimierung Teil eines separaten Schalters /optimize(im Visual Studio heißt sie Optimize code).

Kurz gesagt, unabhängig davon, ob DebugInfo pdb-only oder full einstellt, werden wir die gleichen Ergebnisse erzielen. Es wird empfohlen, None zu vermeiden, da Sie dadurch nicht in der Lage sind, die Crash-Dumps des freigegebenen Produkts zu analysieren oder den Debugger anzuhängen.

rpattabi
quelle
3
Fantastische Antwort! Meine eigenen Untersuchungen (Vergleich generierter Dateien) zeigen die gleichen Ergebnisse.
MEMark
@rpattabi Können Sie die Referenz angeben, dass pdbonly und full identisch sind? Es ist 2019 und die Dokumentation zeigt immer noch, dass sie unterschiedlich sind und bei voller Leistung Leistungseinbußen auftreten. Und VS2019 erstellt ein Projekt mit Releasedem Debugtyp der Konfiguration, der standardmäßig auf eingestellt ist pdbonly.
Joe
@joe Es gibt eine Diskussion am Ende der MSDN-Dokumentation msdn.microsoft.com/en-us/library/8cw0bt21.aspx . Schau es dir an. Ein Mitwirkender verwies auf github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/…, um aktuelle Informationen zu erhalten, bei denen pdbonly und full als gleich erwähnt werden. (Zu Ihrer Information. Ich verwende kein Windows oder VS mehr. Ich habe also nicht verfolgt, was dort passiert. Aber wie ich überprüft habe, sind die Informationen in meiner Antwort immer noch relevant und das MSDN-Dokument ist immer noch falsch.)
rpattabi
16

Sie möchten nur PDB, aber Sie möchten die PDB-Dateien nicht an Benutzer weitergeben. Wenn Sie sie jedoch neben Ihren Binärdateien für sich haben, können Sie Crash-Dumps in einen Debugger wie WinDbg laden und sehen, wo Ihr Programm tatsächlich fehlgeschlagen ist. Dies kann sehr nützlich sein, wenn Ihr Code auf einem Computer abstürzt, auf den Sie keinen Zugriff haben.

Beim vollständigen Debuggen wird Ihrem Code das Attribut [Debuggable] hinzugefügt. Dies hat einen großen Einfluss auf die Geschwindigkeit. Beispielsweise können einige Schleifenoptimierungen deaktiviert werden, um das Einzelschreiten zu vereinfachen. Darüber hinaus hat dies einen geringen Einfluss auf den JIT-Prozess, da das Tracking aktiviert wird.

Blasrohrpfeil
quelle
Macht Sinn. Ich verteile DLLs sowieso nicht wirklich an die Benutzer - es ist eine ASP.NET-App. Aber können Sie Ihre Antwort verbessern und begründen, warum Sie "pdb-only" vs. "full" wählen sollten? Ist es ein Leistungsproblem?
RationalGeek
@jkohlhepp: Ich möchte hinzufügen, dass das Debuggen von Release-Builds etwas schwierig ist, da Sie einige Informationen verlieren (aufgrund von JIT). Fast immer können Sie die Werte von Methodenargumenten nicht sehen. Zur Umgehung dieses, können Sie vorübergehend deaktivieren JIT - Optimierung mit dieser .
Ilian Pinzon
Danke Blowdart und danke Ilian Pinzon für die zusätzlichen Infos. Ich weiß, dass Sie mit dem Release-Code kein perfektes Debugging erzielen können, aber die PDBs sind besser als nichts.
RationalGeek
Die Verwendung der Einstellung "Voll" hat keine Auswirkungen auf die Leistung. Es ermöglicht einfach das Anhängen eines Debuggers an einen laufenden Prozess.
Matt Dillard
1
Gute Frage zu MSDN Matt, msdn.microsoft.com/en-us/library/8cw0bt21 , und ich warte auf die Antwort.
Luke Hutton
4

Ich bin gerade dabei, einen nicht behandelten Ausnahmebehandler zu schreiben, und der Stack-Trace enthält die Zeilennummer, wenn nur pdb verwendet wird. Andernfalls erhalte ich nur den Namen des Sub / der Funktion, wenn ich Keine auswähle.

Wenn ich die .pdb nicht verteile, erhalte ich die Zeilennummer im Stack-Trace auch mit dem Build nur für pdb nicht.

Also verteile ich die PDF-Datei zusammen mit der Exe aus meiner VB-App (XCOPY-Bereitstellung in einem LAN).

rheitzman
quelle