Jaka jest różnica między debugowaniem a wydaniem w programie Visual Studio?

Odpowiedzi:

114

Najważniejsze jest to, że w trybie debugowania nie ma optymalizacji, podczas gdy w trybie wydania są optymalizacje. Jest to ważne, ponieważ kompilator jest bardzo zaawansowany i może wykonać dość skomplikowane ulepszenie kodu na niskim poziomie. W rezultacie niektóre wiersze kodu mogą zostać pozostawione bez żadnych instrukcji lub niektóre mogą zostać pomieszane. Debugowanie krok po kroku byłoby niemożliwe. Ponadto zmienne lokalne są często optymalizowane w tajemniczy sposób, więc zegarki i zegarki QuickWatches często nie działają, ponieważ zmienna jest „zoptymalizowana”. Jest też mnóstwo innych optymalizacji. Spróbuj kiedyś debugować zoptymalizowany kod .NET, a zobaczysz.

Inną kluczową różnicą jest to, że z tego powodu domyślne ustawienia wydania nie zawracają sobie głowy generowaniem obszernych informacji o symbolach debugowania. To jest plik .PDB, który mogłeś zauważyć i pozwala debugerowi dowiedzieć się, które instrukcje asemblera odpowiadają której linii kodu itp.

Vilx-
źródło
1
„W rezultacie niektóre wiersze kodu mogą zostać pozostawione bez żadnych instrukcji, a niektóre mogą zostać pomieszane”. YUP, popełniliśmy błąd, używając ramek stosu, aby uzyskać nazwę bieżącej metody / właściwości - i wiele właściwości zostało wstawionych w wydaniu ...
kpollock
4
„Najważniejsze jest to, że w trybie debugowania nie ma optymalizacji” - to dyskusyjne. Najważniejsze jest to, że istnieją informacje o debugowaniu, które umożliwiają debugowanie. chociaż może to również istnieć w wydaniu.
shoosh
Nie wiem, który tryb jest domyślny (debugowanie / wydanie). Z mojego doświadczenia wynika, że ​​wszystkie projekty są w trybie debugowania, a zespół instalatorów zajmie się tym wydaniem, aby uniknąć pliku pdb i wprowadzić optymalizację. Ale dzisiaj natknąłem się na sytuację, że zmieniono tryb na release i nie jestem w stanie złamać kodu za pomocą break pointa. Próbowałem przez długą godzinę robić wiele rzeczy i wreszcie zauważyłem, że jest to spowodowane problemem z obecnym trybem kompilacji. @ Vlix- Dzięki za odpowiedź.
kbvishnu
1
To faktycznie pomogło mi rozwiązać problem „Nazwa„ zmienna ”nie istnieje w bieżącym kontekście”, który napotkałem podczas próby przeanalizowania symbolu w bezpośrednim oknie podczas debugowania aplikacji zgodnej z domyślną konfiguracją wydania. Wielkie dzięki!
M463
1) A co z następującymi kwestiami? W projekcie ASP.NET MVC istnieją 3 konfiguracje: base (web), debug (web.debug), release (web.release). Załóżmy, że ustawiamy parametry połączenia debugowania i zwalniania przez transformację do odpowiedniej konfiguracji (debugowanie i wydanie). Podczas publikacji możemy publikować zgodnie z naszym wyborem w oknie dialogowym publikowania. Ale kiedy uruchamiam aplikację, pomimo wybrania opcji Debuguj, używa ona konfiguracji wydania (ponieważ ustawiam konfigurację debugowania w konfiguracji podstawowej i konfiguracji debugowania), czy to normalne?
Jason
52

„Debugowanie” i „Wydanie” to w rzeczywistości tylko dwie etykiety dla całej masy ustawień, które mogą wpływać na twoją kompilację i debugowanie.

W trybie „debugowania” zazwyczaj dostępne są:

  • Pliki bazy danych debugowania programów, które pozwalają na dokładne śledzenie wykonywania programu w źródle w czasie wykonywania.
  • Wszystkie optymalizacje są wyłączone, co pozwala na sprawdzanie wartości zmiennych i śledzenie funkcji, które w innym przypadku mogłyby zostać zoptymalizowane na zewnątrz lub wbudowane
  • Definicja preprocesora _DEBUG, która umożliwia pisanie kodu działającego inaczej w trybie debugowania w porównaniu z wersją, na przykład do narzędzi ASSERTs, które powinny być używane tylko podczas debugowania
  • Łączenie z bibliotekami, które również zostały skompilowane z włączonymi opcjami debugowania, które zwykle nie są wdrażane na rzeczywistych klientach (ze względu na rozmiar i bezpieczeństwo)

W trybie „Release” optymalizacje są włączone (chociaż dostępnych jest wiele opcji), a definicja preprocesora _DEBUG nie jest zdefiniowana. Zwykle jednak nadal będziesz chciał generować pliki PDB, ponieważ bardzo przydatna jest możliwość „debugowania” w trybie wydania, gdy rzeczy działają szybciej.

Joris Timmermans
źródło
5
„tylko dwie etykiety” - w rzeczywistości program Visual Studio umożliwia tworzenie większej liczby! Może to być wyjątkowo przydatne podczas testowania programu. Na przykład niedawno napisałem program do mojej pracy, który akceptował nazwy plików z wiersza poleceń. Przetestowałem parsowanie w wierszu poleceń, ale kiedy już to zrobiłem, nie chciałem codziennie bawić się CMD i listami nazw plików; Stworzyłem konfigurację, za pomocą której mogłem użyć kompilacji warunkowej, aby podać fikcyjne wartości wiersza poleceń i przetestować logikę biznesową programu, co dało mi znacznie szybszy cykl iteracji w rozwoju programu.
Brian S
9

Przeważnie debugowanie zawiera wiele dodatkowych informacji przydatnych podczas debugowania. W trybie wydania wszystko to jest wycinane i wymieniane na wydajność.

Rik
źródło
1) A co z następującymi kwestiami? W projekcie ASP.NET MVC istnieją 3 konfiguracje: base (web), debug (web.debug), release (web.release). Załóżmy, że ustawiamy parametry połączenia debugowania i zwalniania przez transformację do odpowiedniej konfiguracji (debugowanie i wydanie). Podczas publikacji możemy publikować zgodnie z naszym wyborem w oknie dialogowym publikowania. Ale kiedy uruchamiam aplikację, pomimo wybrania opcji Debuguj, używa ona konfiguracji wydania (ponieważ ustawiam konfigurację debugowania w konfiguracji podstawowej i konfiguracji debugowania), czy to normalne?
Jason
2) Czy podczas uruchamiania aplikacji w trybie debugowania lub wydania VS używa podstawowej konfiguracji internetowej lub odpowiedniej konfiguracji internetowej (web.debug.confg lub web.release.config)?
Jason
7

Jeśli przejrzysz opcje kompilacji projektu i porównasz je, zobaczysz, jakie są różnice.

Zakładając, że pytanie dotyczy kodu natywnego / C ++ (nie jest to do końca jasne ze sformułowania):

Zasadniczo w debugowaniu wszystkie optymalizacje generowania kodu są wyłączone. Niektóre biblioteki (np. STL ) domyślnie używają dokładniejszego sprawdzania błędów (np. Iteratory debugowania). Generowanych jest więcej informacji debugowania (np. Dla „Edytuj i kontynuuj”). Więcej rzeczy jest generowanych w kodzie w celu wychwytywania błędów (lokalne wartości zmiennych są ustawiane na niezainicjowany wzorzec i używana jest sterta debugowania).

NeARAZ
źródło
2
@Vilx: kiedy odpowiedziałem, nie było jeszcze tagu .net, tylko visualstudio. Więc założyłem, że to C ++.
NeARAZ
6

Najwyraźniej tryb debugowania tworzy wiele dodatkowych wątków, które pomagają w debugowaniu. Pozostają one aktywne przez cały czas trwania procesu, niezależnie od tego, czy dołączysz debugger, czy nie. Zobacz moje powiązane pytanie tutaj .

Matt Jacobsen
źródło
Ale tylko dla .NET (nie C ++)?
Peter Mortensen
6

Prawdopodobnie warto wspomnieć o bardzo oczywistym, że flagi kompilacji pozwalają na inną logikę, która powinna być używana tylko do zmiany rejestrowania i komunikatów "konsoli", ale może to być nadużywane i radykalnie zmienić nie tylko niskie poziomy, ale rzeczywistą logikę biznesową.

annakata
źródło
„… radykalna zmiana… rzeczywista logika biznesowa” - brzmi dla mnie jak błąd! Mamy dużo kodu warunkowego i naprawdę trudno go zrozumieć. Ponadto każda kombinacja warunkowych flag kodu jest zasadniczo inną wersją oprogramowania, które należy przetestować, aby zapewnić poprawność i podstawową integralność. Według „Code Complete”, mojej Biblii o budowie oprogramowania, nasza „Podstawowa Dyrektywa” dotyczy zarządzania złożonością. (To nasz problem nr 1 do rozwiązania). Pomyśl długo i intensywnie, zanim bezkrytycznie dodasz więcej flag warunkowych!
MikrousługiOnDDD
Mój powyższy komentarz nie miał na celu tej odpowiedzi, szczególnie w ostatnim zdaniu ... to była tylko dodatkowa rzecz, o której pomyślałem, że czytelnicy, którzy tu przyjeżdżają, powinni przeczytać.
MicroservicesOnDDD
6

Należy również pamiętać, że podczas korzystania na przykład z MFC , debugowanie projektów łączy się z wersjami DLL nie podlegającymi redystrybucji, tak jak MFC90D.DLLpodczas gdy wydanie kompiluje łącze do wersji redystrybucyjnych, takich jakMFC90.DLL . Jest to prawdopodobnie podobne do innych frameworków.

Dlatego prawdopodobnie nie będziesz w stanie uruchamiać aplikacji do debugowania na komputerach, które nie są programistyczne.

foraidt
źródło
bardzo prawdziwe. Kiedyś wpadłem w konflikt z tym u klienta. Działa na My Machine (TM).
Matt Jacobsen,
Jesteś w stanie je rozprowadzać ... (nie wiem, czy masz prawo). Muszą znajdować się w podfolderze o odpowiednich nazwach w aplikacji.
Andreas Reiff
@Andreas Odnośnie mojego przykładu, „nieprzeznaczone do redystrybucji” oznacza, że ​​Microsoft nie zezwala na ich dystrybucję.
foraidt
4

Zaciekawiło mnie również to pytanie, kiedy opracowałem aplikację skopiowaną z istniejącej konfiguracji kompilacji wydania.

Mam programistę, który jest zainteresowany używaniem tej aplikacji w trybie debugowania, więc zastanawiałem się, co trzeba zrobić, aby ta konfiguracja kompilacji, która istnieje o nazwie ReleaseMyBuild skopiowana z konfiguracji wydania (i dlatego powinna mieć wszystkie ustawienia dostosowane do optymalizacji wydania ), aby nagle zmienić zespoły i stać się kompilacją do debugowania pomimo mylącej nazwy konfiguracji kompilacji.

Pomyślałem, że konfiguracja projektu to tylko nazwa i wygodny sposób na wybranie „całej masy ustawień”, o których wspomina Joris Timmermans. Chciałem poznać szczegóły tego, jakie mogą być te ustawienia, które powodują, że konfiguracja kompilacji o nazwie „FOO” działa jako zoptymalizowana wersja wydania .

Oto jedno spojrzenie na to. Utworzyłem nowy VCXPROJ z pustego szablonu projektu z programu Visual Studio 2010. Następnie skopiowałem go i edytowałem oba, pierwszy, aby zachować zawartość debugowania, a drugi zawartość wydania. Oto różnica skupiona na istotnych różnicach ...

Puste różnice między debugowaniem a wydaniem VCXPROJs

WYDANIE

<PropertyGroup>
    <WholeProgramOptimization>true</WholeProgramOptimization>

<ClCompile>
    <Optimization>MaxSpeed</Optimization>
    <FunctionLevelLinking>true</FunctionLevelLinking>
    <IntrinsicFunctions>true</IntrinsicFunctions>
<Link>
    <EnableCOMDATFolding>true</EnableCOMDATFolding>
    <OptimizeReferences>true</OptimizeReferences>

ODPLUSKWIĆ

<PropertyGroup>
    <UseDebugLibraries>true</UseDebugLibraries>`

<ClCompile>
    <Optimization>Disabled</Optimization>

Ciekawe, że w sekcji Link obaj mają GenerateDebugInformation ustawili wartość true.

jxramos
źródło
3

Oczywistą różnicą, jaką widzisz, jest rozmiar pliku binarnego. Kompilacja debugowania tworzy większy plik binarny niż kompilacja wydania.

Podczas kompilowania w Debug, tablica symboli jest dodawana do skompilowanego obiektu pliku kodu, co umożliwia debugowanie programów w celu uzyskania dostępu do tych plików binarnych i uzyskania dostępu do wartości obiektów i zmiennych.

Inną zauważalną różnicą jest to, że w trybie wydania plik binarny po prostu zawiesiłby się z powodu błędu krytycznego w trybie debugowania, jeśli zaczniesz debugować aplikację w programie Visual Studio, możesz sprawdzić stos wywołań, który informuje o dokładnej lokalizacji błędnej instrukcji .

fasih.rana
źródło
-15

Nie wiem, jakie są dokładne różnice, ponieważ w rzeczywistości nie ma łatwo dostępnych informacji na ten temat.

Ale główną zaobserwowaną różnicą jest to, że wersja wydania czasami uszkadza wynikowy plik DLL, a tym samym sprawia, że ​​aplikacja, aplikacja internetowa nie nadaje się do użytku.

Niestety, musisz wprowadzić kompilację debugowania do produkcji. I tak, aby opublikować, musisz użyć starego dobrego FTP.

f470071
źródło
7
Jak to odpowiada na pytanie? I proszę uważać, kiedy piszesz.
mking
Miałem podobny problem, kod działa w trybie debugowania, ale ma problem w trybie wydania. Okazuje się, że problem tkwi w moim kodzie. Jest świetny artykuł o typowych problemach w wydaniu, mam nadzieję, że może to pomóc również innym.
Weihui Guo