Frage

Was sind die typischen Gründe für Fehler und abnormale Programmverhalten sind, dass manifestieren sich nur in Release Kompilierungsmodus die aber nicht auftreten, wenn im Debug-Modus?

War es hilfreich?

Lösung

Viele Male, in der Debug-Modus in C ++ alle Variablen null initialisiert, während das gleiche im Release-Modus geschieht nicht, sofern nicht ausdrücklich angegeben ist.

Überprüfen Sie für alle Debug-Makros und nicht initialisierten Variablen

Gibt es in Ihrem Programm verwendet Einfädeln, dann Optimierung kann auch einige Probleme im Release-Modus führen.

überprüfen Sie auch für alle Ausnahmen, zum Beispiel nicht direkt mit Release-Modus verwendet, aber irgendwann wir einfach ignorieren einige kritischen Ausnahmen, wie mem Zugriffsverletzung in VC ++, aber das gleiche ein Problem zumindest in anderem Betriebssystem wie Linux, Solaris sein kann. Im Idealfall fängt Ihr Programm sollte nicht so kritisch Ausnahmen wie einen NULL-Zeiger zugreifen.

Andere Tipps

Eine gemeinsame pitfall unter Verwendung eines Ausdrucks mit Nebenwirkung im Inneren eines zusetzen.

Weitere Unterschiede könnten sein:

  • In einer Garbage Collection Sprache, die Kollektor ist in der Regel aggressiver im Release-Modus;
  • Layout des Speichers kann oft unterschiedlich sein;
  • Speicher kann anders initialisiert (zum Beispiel könnte sein, im Debug-Modus auf Null gesetzt oder wiederverwendet mehr aggressiv in Release);
  • Die Einheimischen können gefördert werden Werte in der Freisetzung zu registrieren, wo zu Problemen mit Gleitkomma- Werte.

Ich habe durch eine Reihe von Fehlern in der Vergangenheit gebissen, die fein waren in Debug baut aber Absturz in Release baut. Es gibt viele Ursachen (darunter natürlich auch diejenigen, die bereits in diesem Thread zusammengefasst wurden), und ich habe von allen folgenden ertappt:

  • Mitgliedsvariablen oder Member-Funktionen in einem #ifdef _DEBUG, so dass eine Klasse eine andere Größe in einem Debug-Build ist. Manchmal ist #ifndef NDEBUG in einem Release-Build verwendet
  • In ähnlicher Weise ist es eine andere #ifdef, die nur in einer der beiden sein geschieht Builds
  • Die Debug-Version verwendet Debug-Versionen der Systembibliotheken, vor allem der Heap und Speicherzuordnungsfunktionen
  • inlined Funktionen in einem Release-Build
  • Reihenfolge der Aufnahme von Header-Dateien. Dies sollte keine Probleme verursachen, aber wenn Sie so etwas wie ein #pragma pack haben, die zurückgesetzt wurde nicht dann kann dies zu bösen Problemen führen. Ähnliche Probleme können auch vorkompilierte Header und gezwungen enthält
  • auftreten mit
  • Caches: Sie können Code wie Caches haben, die verwendet wird nur in Release-Builds, oder Cache-Größenbeschränkungen, die anders sind
  • Projektkonfigurationen: die Debug-und Release-Konfigurationen unterschiedliche Build-Einstellungen haben können (dies ist wahrscheinlich passieren, wenn eine IDE)
  • Race Conditions, Timing-Probleme und miscellanous Nebenwirkungen als Folge des Debug auftretenden nur Code

Einige Tipps, dass ich im Laufe der Jahre angesammelt haben für an der Unterseite des Debug / Release Bugs bekommen:

  • Versuchen anomale Verhalten in einem Debug-Build zu reproduzieren, wenn Sie können, und noch besser, schreiben einen Komponententest, es zu erfassen
  • Denken Sie darüber nach, was unterscheidet sich zwischen den beiden: Compiler-Einstellungen, Caches, Debug-only-Code. Versuchen Sie, diese Unterschiede temporär
  • zu minimieren
  • Erstellen Sie ein Release-Build mit Optimierungen ausgeschaltet (so dass Sie mehr sind wahrscheinlich nützliche Daten im Debugger zu bekommen), oder ein optimierte Debug-Build. Durch die Minimierung der Änderungen zwischen Debug und Release sind Sie eher in der Lage sein, zu isolieren, die Differenz der Fehler verursacht.

Ja !, wenn Sie die bedingte Kompilierung haben, kann es zu Timing Bugs (optimierte Freigabecode Vers, nicht optimierte Debug-Code), Speicherwiederverwendung vs. Debug-Heap.

Es kann, besonders wenn man in dem C-Bereich ist.

Eine Ursache könnte sein, dass die Debug-Version Code hinzufügen kann für Streu Zeiger zu überprüfen und irgendwie Code schützen vor einem Absturz (oder verhalten sich falsch). Wenn dies der Fall ist, sollten Sie sorgfältig überprüfen Warnungen und andere Nachrichten, die Sie von Ihrem Compiler erhalten.

könnte eine weitere Ursache sein Optimierung (die in der Regel ist für die Release-Versionen und weg für debug). Der Code und die Daten-Layout optimiert worden sein und während Debugging-Programm nur war zum Beispiel nicht genutzte Speicher zugreift, wird die Release-Version nun für den Zugriff reservierten Speicher versuchen oder sogar Code zeigen!

EDIT: Ich sehe andere erwähnt: Natürlich können Sie ganze Codeabschnitte, die bedingt sind ausgeschlossen, wenn nicht im Debug-Modus kompilieren. Wenn das der Fall ist, hoffe ich, dass wirklich Code debuggen und nicht etwas, von entscheidenden Bedeutung für die Richtigkeit des Programms selbst!

Die CRT-Bibliothek Funktionen verhalten sich anders in Debug-vs-Release (/ MD vs / MDD).

Zum Beispiel können die Debug-Versionen oft prefill puffert Sie an die angegebene Länge passieren Ihren Anspruch zu überprüfen. Beispiele hierfür sind strcpy_s, StringCchCopy usw. Auch wenn die Saiten früher beenden, Ihre szDest besser n Bytes lang!

Sicher, zum Beispiel, wenn Sie verwenden Konstruktionen wie

#if DEBUG

//some code

#endif

In .NET, auch wenn Sie die bedingte Kompilierung nicht wie #if DEBUG verwenden, ist der Compiler noch viel mehr liberal mit Optimierungen im Release-Modus, als es im Debug-Modus ist, die auch nur Bugs zu lösen führen können.

Sie müßten viel mehr Informationen geben, aber ja, es ist möglich. Es hängt davon ab, was Ihre Debug-Version der Fall ist. Sie haben auch die Protokollierung oder zusätzliche Kontrollen, dass die nicht in eine Release-Version kompiliert bekommen. Diese Debug nur Codepfade können unbeabsichtigte Nebenwirkungen, die ihren Zustand ändern oder beeinflussen Variablen auf seltsame Weise. Debug-Builds in der Regel langsamer laufen, so dass diese Threading und verstecken Rennbedingungen beeinflussen können. Das gleiche gilt für straight forward Optimierungen von einem Release der Kompilierung, ist es möglich (wenn auch unwahrscheinlich diese Tage), dass eine Freigabe der Kompilierung kann Kurzschluss etwas wie eine Optimierung.

Ohne weitere Einzelheiten, ich, dass „nicht in Ordnung“ bedeutet davon ausgehen, dass es entweder nicht nicht kompiliert oder wirft eine Art von Fehlern zur Laufzeit. Überprüfen Sie, ob Sie Code haben, der auf der Compilation Version beruht, entweder über #if DEBUG Aussagen oder über Methoden gekennzeichnet mit dem Conditional Attribut.

Das ist möglich, wenn Sie die bedingte Kompilierung, so dass der Debug-Code und Freigabecode ist unterschiedlich, und es ist ein Fehler in dem Code, der nur in dem Release-Modus verwendet wird.

Anders als das, es ist nicht möglich. Es gibt Unterschied, wie Debug-Code und Freigabecode kompiliert werden, und Unterschiede, wie Code ausgeführt wird, wenn unter einem Debugger oder nicht ausgeführt, aber wenn eine dieses Unterschied Ursache etwas anderes als ein Unterschied in der Leistung, das Problem war es die ganze Zeit.

In der Debug-Version kann der Fehler nicht auftreten werden (weil das Timing oder Speicherzuweisung unterschiedlich ist), aber das bedeutet nicht, dass der Fehler ist nicht da. Es kann auch andere Faktoren sein, die nicht auf den Debug-Modus verwendet, die den Zeitpunkt des Codes ändert, wodurch den Fehler auftritt oder nicht, aber es läuft alles auf die Tatsache, dass, wenn der Code korrekt wäre, würde der Fehler nicht auf in einer Situation befindet.

Also, nein, die Debug-Version ist nicht in Ordnung, nur weil Sie es, ohne sie einen Fehler ausführen können. Tritt ein Fehler auf, wenn Sie es im Release-Modus laufen, es ist nicht wegen des Release-Modus, es ist, weil der Fehler von Anfang an da war.

Es gibt Compiler-Optimierungen, dass kann gültigen Code brechen , weil sie zu aggressiv.

Versuchen Sie Ihren Code mit weniger Optimierung Kompilieren aktiviert.

In einer Nicht-Leer Funktion, alle Ausführungspfade sollten mit einer return-Anweisung beenden.

Im Debug-Modus, wenn Sie vergessen, einen solchen Weg mit einer return-Anweisung beenden dann in der Regel liefert die Funktion standardmäßig 0.

Doch im Release-Modus Ihre Funktion kann Müll Werte zurückgeben, die beeinflussen können, wie Ihr Programm ausgeführt wird.

Es ist möglich. Wenn es passiert, und keine bedingte Kompilierung beteiligt ist, als man ziemlich sicher sein, dass Ihr Programm falsch ist, und wird im Debug-Modus arbeitet nur wegen zufälligen Speicher Initialisierungen oder sogar das Layouts im Speicher!

ich gerade erlebt, dass wenn ich eine Montagefunktion rief, die nicht die Register der vorherigen Werte wiederhergestellt hat.

In der "Release" Konfiguration VS wurde mit / O2 kompilieren, die den Code für Geschwindigkeit optimiert. So einige lokalen Variablen, bei denen lediglich der Abbildung auf CPU-Register (zur Optimierung), die mit der oben erwähnten Funktion geteilt wurde zu ernsthafter Speicherbeschädigung führt.

Wie auch immer sehen, wenn Sie nicht indirekt mit CPU-Registern überall in Ihrem Code durcheinander.

Ich erinnere mich vor einiger Zeit, als wir dll und PDB in C / C ++ zu bauen.

Ich erinnere mich an diese:

  • Logdaten Hinzufügen irgendwann den Fehler Schritt machen würde oder verschwinden oder einen völlig anderen Fehler angezeigt zu machen (so ist es nicht wirklich eine Option war).
  • Viele dieser Fehler, bei denen aufgrund char Zuordnung in strcpy und strcat und Arrays von char [] etc ...
  • Wir gejätet etwas heraus durch Grenzprüfeinrichtung laufen und einfach Festsetzung der Speicher alloc / dealloc Fragen.
  • Viele Male gingen wir systematisch durch den Code und fixiert eine char Zuweisung (wie durch alle Dateien).
  • Auf jeden Fall ist es etwas im Zusammenhang mit Speicherzuweisung und die Verwaltung und Einschränkungen und Unterschieden zwischen dem Debug-Modus und Release-Modus.

Und dann hoffte das Beste.

ich manchmal vorübergehend geliefert Debug-Versionen von DLLs zu Kunden, um die Produktion nicht zu halten ab, während auf diesem Fehler zu arbeiten.

Weitere Gründe könnten DB Anrufe sein. Sind Sie speichern und denselben Datensatz mehrfach in demselben Thread zu aktualisieren, manchmal für die Aktualisierung. Es ist möglich, das Update fehlgeschlagen ist oder nicht funktioniert hat, wie erwartet, weil die vorherigen Befehl erstellen wurde noch verarbeitet und für die Aktualisierung scheiterte der db Anruf auf einen Eintrag zu finden. dies würde nicht in Debug passiert als Debugger stellt sicher, dass alle anstehenden Aufgaben vor der Landung zu beenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top