Jakie są powody, dla których Kompilacja wersji działa inaczej niż Kompilacja debugowania

Mam program Visual Studio 2005 C++, który działa inaczej w trybie wydania niż w trybie debugowania. W trybie release występuje (pozorna) przerywana awaria. W trybie debugowania nie ulega awarii. Jakie są powody, dla których Kompilacja Wydania będzie działać inaczej niż kompilacja debugowania?

Warto również wspomnieć, że mój program jest dość złożony i wykorzystuje kilka bibliotek stron trzecich do przetwarzania XML, pośrednictwa w komunikatach itp...

Z góry dzięki!

Author: BeachRunnerFred, 2008-11-23

10 answers

Surviving the Release Version daje dobry przegląd.

Rzeczy, które napotkałem - większość jest już wymieniona

Inicjalizacja zmiennej zdecydowanie najbardziej powszechne. W Visual Studio debug buduje explicitely initialize allocated memory to given values, see e.g. Memory Values here. Wartości te są zwykle łatwe do wykrycia, powodują błąd przekroczenia granic, gdy są używane jako indeks lub naruszenie dostępu, gdy są używane jako wskaźnik. Niewtajemniczona wartość logiczna jest jednak prawdziwa i może powodować niezainicjowane błędy pamięci niezauważone przez lata.

W Release buildach, w których pamięć nie jest jednoznacznie zainicjalizowana, zachowuje tylko zawartość, którą miała wcześniej. Prowadzi to do" śmiesznych wartości "i" losowych " awarii, ale równie często do deterministycznych awarii, które wymagają pozornie niepowiązanych poleceń do wykonania przed poleceniem, które faktycznie się zawiesza. Jest to spowodowane pierwszym poleceniem "ustawiania" miejsca pamięci o określonych wartościach, a gdy lokalizacje pamięci zostaną poddane recyklingowi, drugie polecenie widzi je jako inicjalizację. Jest to bardziej powszechne w przypadku niezainicjowanych zmiennych stosu niż sterty, ale ta ostatnia też mi się przydarzyła.

Inicjalizacja pamięci surowej może być również różna w kompilacji release, niezależnie od tego, czy zaczynasz od visual studio (dołączony debugger), czy od Explorera. To sprawia ,że jest to" najładniejszy " rodzaj błędów budowania wersji, które nigdy nie pojawiają się pod debuggerem.

Poprawne optymalizacje come drugi w moim exeprience. Standard C++ pozwala na wiele optymalizacji, które mogą być zaskakujące, ale są w pełni poprawne, np. gdy dwa wskaźniki alias tej samej lokalizacji pamięci, kolejność inicjalizacji nie jest brana pod uwagę, lub wiele wątków modyfikuje te same lokalizacje pamięci, i można oczekiwać pewnej kolejności, w której wątek B widzi zmiany dokonane przez wątek A. często winą za te zmiany jest kompilator. Nie tak szybko, Młody yedi! - patrz poniżej

Timing Release builds don ' t po prostu "uruchom szybciej", z różnych powodów (optymalizacje, funkcje logowania zapewniające punkt synchronizacji wątku, debugowanie kodu, jak twierdzenia nie wykonane itp.) również względny czas między operacjami zmienia się dramatycznie. Najczęściej spotykanym problemem są warunki rasowe, ale także impasy i PROSTE" INNE " wykonanie kodu opartego na wiadomości / timerze / zdarzeniu. Mimo, że są to problemy z czasem, mogą być zaskakująco stabilne w różnych wersjach i platformach, z reprodukcje, które "działają zawsze, z wyjątkiem PC 23".

Guard Bytes . Kompilacje debugowania często umieszczają (więcej) bajtów zabezpieczających wokół wybranych instancji i alokacji, aby chronić przed przepełnieniem indeksu, a czasem jego zaniżeniem. W rzadkich przypadkach, gdy kod opiera się na offsetach lub rozmiarach, np. serializując surowe struktury, są one różne.

Inne różnice w kodzie niektóre instrukcje-np. asserts-oceniają do zera w release builds. Czasami mają inną stronę efekty. Jest to powszechne w makro trickery, jak w klasycznym (warning: multiple errors)

#ifdef DEBUG
#define Log(x) cout << #x << x << "\n";
#else 
#define Log(x)
#endif

if (foo)
  Log(x)
if (bar)
  Run();

, który w kompilacji release ocenia do if (foo & & bar) Ten typ błędu jest bardzo rzadki przy normalnym kodzie C / C++ i poprawnie napisanych makrach.

Błędy kompilatora to naprawdę nigdy się nie zdarza. Cóż-tak , ale przez większą część swojej kariery lepiej Ci będzie, zakładając, że tak nie jest. W ciągu dekady pracy z VC6, znalazłem jeden, gdzie jestem wciąż przekonany, że jest to błąd kompilatora, w porównaniu z dziesiątkami wzorców (może nawet setkami instancji)z niewystarczającym zrozumieniem pisma (a. k. a. standard).

 120
Author: peterchen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-18 04:22:11

W wersji debugowania często włączane są asercje i / lub symbole debugowania. Może to prowadzić do różnych układów pamięci. W przypadku błędnego wskaźnika, przepełnienia tablicy lub podobnego dostępu do pamięci, do której uzyskujesz dostęp w jednym przypadku critical bad memory (np. function pointer), a w innym przypadku może tylko niektóre niekrytyczne pamięci (np. tylko ciąg doc jest trashed)

 6
Author: flolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-23 12:51:45

Zmienne, które nie zostały zainicjowane jawnie, zostaną wyzerowane lub nie mogą być zerowane w Release build.

 5
Author: Burkhard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-23 09:07:39

Release build (miejmy nadzieję) będzie działał szybciej niż twój debug build. Jeśli używasz więcej niż jednego wątku, możesz zobaczyć więcej przeplatania lub po prostu jeden wątek działa szybciej niż inne, czego możesz nie zauważyć w kompilacji debugowania.

 2
Author: Eugene Yokota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-23 09:15:05

Miałem podobny problem nie tak dawno temu, który zakończył się tym, że stos był traktowany inaczej w Release buildach. Inne rzeczy, które mogą się różnić:

  • alokacja pamięci jest traktowana inaczej z kompilacją debugowania w kompilatorze VS (np. zapisanie 0xcc nad wyczyszczoną pamięcią, itd.)
  • rozwijanie pętli i inne optymalizacje kompilatora
  • / Align = "left" / ]}
 2
Author: Nik Reiman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:07

To zależy zarówno od producenta kompilatora, jak i bibliotek kompilowanych z flagami debugowania. Chociaż kod debugowania nigdy nie powinien wpływać na działający kod (nie powinien mieć skutków ubocznych), czasami tak jest.

W szczególności, zmienne mogą być inicjowane tylko w trybie debugowania i pozostawione niezainicjalizowane w trybie RELEASE. STL w kompilatorach Visual Studio różnią się w trybach debugowania i Wydania. Chodzi o to, że Iteratory są w pełni sprawdzane w debugowaniu, aby wykryć ewentualne błędy (używając unieważnionych iteratorów, na przykład iterator do wektora jest unieważniony, jeśli wstawianie nastąpi po pobraniu iteratora).

To samo dzieje się z bibliotekami innych firm, pierwsze o czym myślę to QT4, który zakończy program z assert, jeśli wątek inny niż ten, który stworzył obiekt graficzny wykonuje operacje malowania.

Ze wszystkimi zmianami, Twój kod i ślad pamięci będą się różnić w obu trybach. Wskaźnik (odczytując pozycję, mijamy koniec array) problem może przejść niezauważony, jeśli ta pozycja jest czytelna.

Asercje mają na celu zabicie aplikacji podczas debugowania i zniknięcie z kompilacji RELEASE, więc nie uważałbym twierdzeń za twój problem. / Align = "left" /

Jakiś czas temu pojawiły się problemy z niektórymi optymalizacjami kompilatorów łamiącymi kod, ale ostatnio nie czytałem reklamacji. Może być problem z optymalizacją, ale to nie bądź moim pierwszym podejrzanym.

 2
Author: David Rodríguez - dribeas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-23 09:47:57

Wersje kompilacji są zwykle kompilowane z włączoną optymalizacją w kompilatorze, podczas gdy wersje debugowania zwykle nie są.

W niektórych językach lub przy użyciu wielu różnych bibliotek może to powodować przerywane awarie - szczególnie, gdy wybrany poziom optymalizacji jest bardzo wysoki.

Wiem, że tak jest w przypadku kompilatora gcc C++, ale nie jestem pewien co do kompilatora Microsoftu.

 2
Author: fluffels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-01 08:01:14

Http://www.debuginfo.com/tips/userbpntdll.html

Ze względu na fakt, że bajty strażnika są dodawane w kompilacjach debugowania, możesz być w stanie "bezpiecznie" uzyskać dostęp do pamięci, która jest poza granicami dla tablicy (szczególnie dynamicznych tablic), ale spowoduje to naruszenie dostępu w kompilacji release. Ten błąd może pozostać niezauważony, powodując uszkodzoną stertę i ewentualnie naruszenie dostępu w miejscu niezwiązanym z pierwotnym błędem.

Użyj PageHeap (lub, jeśli masz narzędzia do debugowania zainstalowane możesz użyć gflags), aby odkryć błędy związane z uszkodzonymi stertami.

Http://support.microsoft.com/?id=286470

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-11 22:56:15

Z mojego doświadczenia wynika, że najczęstszym powodem wydaje się być to, że konfiguracje różnią się na więcej sposobów niż ustawienia release/build. Np. dołączone są różne biblioteki lub kompilator debugowania ma inny rozmiar stosu niż kompilator wydania.

Aby tego uniknąć w naszych projektach Visual Studio 2005 używamy arkuszy właściwości szeroko. W ten sposób konfiguracje wydania i debugowania mogą współdzielić wspólne ustawienia.

 0
Author: Tobias Furuholm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-09 21:21:22

Ten post wraz z linkami jest bardzo pomocny w naprawianiu związanego z nim błędu. dodając do powyższej listy, różnice w wywołaniu konwencji mogą również prowadzić do tego zachowania - zawiodło to w release build tylko z optymalizacją dla mnie. zadeklarowałem jako _ _ stdcall i zdefiniowałem jako _ _ cdecl (domyślnie). [o dziwo to Ostrzeżenie nie jest wybierane nawet w warn level 4 MSVC?]

 0
Author: FL4SOF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-17 08:49:16