2017-01-06 5 views
0

Ich verwende VS2015.Führt nicht korrekt gleiche Operationen im Freigabemodus aus

Im Debug-Modus hervorgehoben while-Schleife funktioniert korrekt - wenn !P_Object->first_request wahr ist, bricht es.
Aber dieselben Bedingungen funktionieren nicht im Freigabemodus. Außerdem kann man in der Quickwatch sehen, dass die Visual Studio Quickwatch !P_Object->first_request als falsch erkennt, aber die Schleife wiederholt sich.

BTW: P_Object->first_request Variable als falsch in der Klasse initialisiert und auf True in Thread (vielleicht ist diese Information hilfreich - idk).

enter image description here

Wie um diesen Fehler zu beheben?

DEBUG Command line - "/GS /analyze- /W3 /Zc:wchar_t /I"C:\boost_1_62_0" /ZI /Gm /Od /Fd"Debug\vc140.pdb" /Zc:inline /fp:precise /D "WIN32" /D "WIN32_LEAN_AND_MEAN_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MTd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\ExpenditureAndReceipts.pch""; 

RELEASE Command line - "/GS /analyze- /W3 /Gy /Zc:wchar_t /I"C:\boost_1_62_0" /Zi /Gm- /O2 /Fd"Release\vc140.pdb" /Zc:inline /fp:precise /D "WIN32" /D "WIN32_LEAN_AND_MEANNDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MT /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\ExpenditureAndReceipts.pch""; 
+3

Ich denke, dass es optimiert wurde, da die Schleife nichts tut – pm100

+1

Sie könnten die Variable "volatile" markieren, um den Compiler zu sagen, seine Verwendung nicht zu optimieren. –

+1

Sie müssen korrekte Inter-Thread-Synchronisation verwenden (* nicht * nur Slapping 'volatile' auf die Variable). Verwenden Sie einen atomaren Datentyp, einen kritischen Abschnitt, Mutex oder was auch immer geeignet ist. –

Antwort

-1

Im Wesentlichen ein Release-Bug muss genau wie jeder andere Fehler behandelt werden, außer Sie haben keine Maschinerie, um Ihnen zu helfen. Reduzieren Sie die Anwendung auf "Hello World" - etwas, das ein wenig Leistung gibt und ohne Fehler herunterfährt. Dann setzen Sie die gesamte Anwendung wieder ein und fügen Sie einen Schalter hinzu, so dass Sie zwischen der fehlerfreien "Hallo Welt" Version und der abgemagerten Version mit ein paar Tastenkombinationen wechseln können.

Fügen Sie jetzt die Funktionalität zur Hello World Version hinzu und nehmen Sie es aus der vollständigen Version heraus (natürlich behalten eine komplette Version). Versuchen Sie, den Punkt zu lokalisieren, in dem der Fehler erscheint, also können Sie mit ein paar Tastenanschlägen zwischen einer fehlerfreien, ein wenig verkrüppelten und einer abgenutzten Version wechseln

Wenn dies nicht der Fall ist, beginnen Sie mit der Verwendung dieser Informationen, um diagnostic printf zu aktivieren (eine Debug-Konsole wird gestartet, damit Sie stdout sehen können)

Freigabe Null initialisiert Speicher allocated with malloc(), ist anders, und es gibt viele andere kleine Änderungen. Es ist nicht ungewöhnlich, einen Release-only-Bug zu haben, obwohl dies natürlich den Debug-Modus überflüssig macht.

+0

Es gibt keine Nur-Version-Fehler, nur Fehler, die im Freigabemodus anders (und strenger) auftreten. –

3

Sie können ein Bool nicht in einem Thread lesen und in einem anderen schreiben. Der Compiler kann den Lesevorgang im ersten Thread zwischenspeichern und die Speicheränderung nie lesen.

Wenn Sie Multi-Thread-Programmierung schreiben, kommunizieren Sie über Atomics und Mutexes und dergleichen.

Ersetzen Sie first_request durch eine std::atomic<bool>. Dies kann erfordern, anderen Code zu ändern. Wenn das erledigt ist, sollten die Dinge gut sein.

Was Sie getan haben (in einem Thread lesen, in einem anderen schreiben, keine Synchronisation) ist undefiniertes Verhalten. Undefiniertes Verhalten stürzt nicht immer ab, manchmal führt dies nur dazu, dass Release-Builds keinen Sinn ergeben.

+0

Können Sie eine Quelle für weitere Informationen zu Ihrer ersten Aussage empfehlen? Anscheinend schreibe ich seit Jahren falschen multithreaded Code und würde gerne darüber nachlesen ... –

+1

@JackWhite [Dieser tolle SO Post] (http://Stackoverflow.com/a/6319356/1774667) beschreibt das C + +11 Gewindemodell. Grundsätzlich definiert C++ 03 nicht, wie Threading funktioniert. C++ 11 definiert ein Modell, und darin ein Lesen und Schreiben ohne irgendeine Art von Synchronisation (es gibt viele Arten, wie es synchronisiert werden kann, nicht nur ein Mutex) ist einfach undefiniertes Verhalten. Punkt. Der Fall, in dem der Wert in einem Thread zwischengespeichert und nie wieder aus dem Speicher gelesen wird, nun, ich habe es gesehen und gesehen, dass es in SO-Fragen enthalten ist, aber nicht sicher, was zu nennen ist. – Yakk

Verwandte Themen