Czy powinienem kompilować kompilacje wydań z informacjami o debugowaniu jako „pełne” czy „tylko pdb”?

114

W programie Visual Studio 2010 dla projektu C #, jeśli przejdziesz do właściwości projektu> kompilacja> zaawansowane> informacje o debugowaniu, masz trzy opcje: brak, pełne lub tylko pdb. Opierając się na odpowiedzi na to pytanie , uważam, że rozumiem niektóre różnice między pełnym a tylko PDB. Które jednak jest bardziej odpowiednie w przypadku kompilacji wydania? Jeśli użyję opcji „full”, czy będzie to miało wpływ na wydajność? Jeśli użyję „tylko pdb”, czy trudniej będzie debugować problemy produkcyjne?

Jaka jest różnica między „full” a „pdbonly”? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option

RationalGeek
źródło
Pdb-only lub none, zawsze dla kompilacji wydania.
leppie
13
@leppie Dzięki, ale szukam uzasadnienia dla tego stanowiska.
RationalGeek
Powiązane pytanie: stackoverflow.com/questions/1270986/…
janv8000
To świetnie, jeśli nie ma to wpływu na wydajność. A co z wpływem na pamięć? Jeśli utworzę wystąpienie StackTrace i zażądam informacji o pliku, musi to pochodzić z danych symbolu pdb. Czy wszystkie symbole są ładowane do pamięci podczas uruchamiania aplikacji? Jakie jest przybliżone użycie pamięci? (np. procent narzutu w stosunku do rozmiaru kodu).
yoyo

Odpowiedzi:

90

Budowałbym z pdb-only. Nie będzie można dołączyć debugera do wydanego produktu, ale jeśli pojawi się zrzut awaryjny , możesz użyć programu Visual Studio lub WinDBG do zbadania śladów stosu i zrzutów pamięci w czasie awarii.

Jeśli wybierzesz fullzamiast pdb-only, uzyskasz te same korzyści, z wyjątkiem tego, że plik wykonywalny można dołączyć bezpośrednio do debugera. Musisz ustalić, czy jest to uzasadnione, biorąc pod uwagę Twój produkt i klientów.

Pamiętaj, aby zapisać gdzieś pliki PDB, aby móc się do nich odwoływać, gdy nadejdzie raport o awarii. Jeśli możesz skonfigurować serwer symboli do przechowywania tych symboli debugowania, tym lepiej.

Jeśli zdecydujesz się budować z none, nie będziesz mieć możliwości odwołania się w przypadku awarii w terenie. Nie będzie można przeprowadzić żadnego badania po fakcie, co może poważnie utrudnić śledzenie problemu.

Uwaga dotycząca wydajności:

Zarówno John Robbins, jak i Eric Lippert napisali na blogu posty dotyczące /debugflagi i obaj wskazują, że to ustawienie ma zerowy wpływ na wydajność . Istnieje osobna /optimizeflaga, która określa, czy kompilator powinien przeprowadzać optymalizacje.

Matt Dillard
źródło
7
@Matt, artykuł MSDN na temat przełącznika / debug wyraźnie ostrzega o wpływie na wydajność korzystania z ustawienia „pełne”: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: Jeśli „pełny” nie ma wad w porównaniu z „tylko pdb”, ale ma tylko zalety, dlaczego w ogóle istnieje „tylko pdb”? Czy jest jakiś powód, aby używać go „w pełni”? Należy również dodać poprawkę do artykułu MSDN w sekcji „Treści społeczności”.
Allon Guralnek
9
Cytat @AllonGuralnek z połączonego artykułu Johna Robbinsa: Prawdziwy powód: historia. W .NET 1.0 były różnice, ale w .NET 2.0 ich nie ma. Wygląda na to, że .NET 4.0 będzie działać według tego samego wzorca. Po dwukrotnym sprawdzeniu z zespołem ds. Debugowania CLR nie ma żadnej różnicy.
bentayloruk
5
To nieprawda. Możesz budować tylko z pdb i nadal dołączać debugger. Zrobiłem to tylko dla pewności.
Mark
2
„Budowałbym tylko z pdb. Nie będzie można dołączyć debuggera do wydanego produktu” Jakie jest twoje źródło informacji? Jak zauważyliśmy zarówno @Mark, jak i ja, nie wydaje się to być poprawne.
MEMark
66

OSTRZEŻENIE Dokumentacja MSDN dla przełącznika / debug (w programie Visual Studio jest to informacja o debugowaniu) wydaje się być nieaktualna! To jest to, co jest nieprawidłowe

Jeśli używasz / debug: full , pamiętaj, że ma to pewien wpływ na szybkość i rozmiar kodu zoptymalizowanego pod kątem JIT oraz niewielki wpływ na jakość kodu z / debug: full . Zalecamy / debug: pdbonly lub brak PDB do generowania kodu wydania.

Jedna różnica między / debug: pdbonly i / debug: full polega na tym, że z / debug: full kompilator emituje znak DebuggableAttribute, który jest używany do poinformowania kompilatora JIT, że informacje debugowania są dostępne.

Więc co jest teraz prawdą?

  1. Tylko Pdb - przed .NET 2.0 pomogło zbadać zrzuty awaryjne z wydanego produktu (komputerów klientów). Ale to nie pozwoliło na dołączenie debuggera. Tak nie jest w przypadku .NET 2.0. To jest dokładnie to samo, co Full .
  2. Pełny - pomaga nam to badać zrzuty awaryjne, a także umożliwia dołączenie debugera do wydania kompilacji. Ale w przeciwieństwie do wzmianek MSDN, nie wpływa to na wydajność (od .NET 2.0). Robi dokładnie to samo, co tylko Pdb .

Jeśli są dokładnie takie same, dlaczego mamy te opcje? John Robbins (bóg debugowania systemu Windows) odkrył, że istnieją z powodów historycznych.

W .NET 1.0 były różnice, ale w .NET 2.0 ich nie ma. Wygląda na to, że .NET 4.0 będzie działać według tego samego wzorca. Po dwukrotnym sprawdzeniu z zespołem ds. Debugowania CLR nie ma żadnej różnicy.

To, co kontroluje, czy JITter wykonuje kompilację debugowania, to przełącznik / optimize. <…>

Najważniejsze jest to, że chcesz zbudować kompilacje wydania z / optimize + i dowolnym przełącznikiem / debug, aby móc debugować za pomocą kodu źródłowego.

następnie udowadnia to.

Teraz optymalizacja jest częścią osobnego przełącznika /optimize(w Visual Studio nazywa się to Optimize code).

Krótko mówiąc, niezależnie od ustawienia DebugInfo pdb-only lub full, uzyskamy te same wyniki. Zaleca się unikanie None, ponieważ pozbawiłoby to możliwości analizowania zrzutów awaryjnych z wydanego produktu lub dołączania debugera.

rpattabi
źródło
3
Fantastyczna odpowiedź! Moje własne badania (porównanie wygenerowanych plików) dają te same wyniki.
MEMark
@rpattabi Czy możesz określić odniesienie, że pdbonly i full są takie same? Jest rok 2019, a dokumentacja nadal wskazuje, że są one różne i pełne spowodują spadek wydajności. VS2019 tworzy projekt z Releasedomyślnym typem debugowania konfiguracji ustawionym na pdbonly.
joe
@joe Na dole dokumentacji MSDN znajduje się dyskusja msdn.microsoft.com/en-us/library/8cw0bt21.aspx . Spójrz na to. Jeden z współpracowników wskazał na github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/… , aby uzyskać aktualne informacje, gdzie pdbonly i full są wymienione jako takie same. (Do Twojej wiadomości. Nie używam już Windows ani VS. Więc nie
śledziłem
16

Będziesz chciał tylko PDB, ale nie będziesz chciał udostępniać plików PDB użytkownikom. Jednak posiadanie ich dla siebie, wraz z plikami binarnymi, daje możliwość załadowania zrzutów awaryjnych do debugera, takiego jak WinDbg, i sprawdzenia, gdzie faktycznie zawiódł program. Może to być przydatne, gdy kod ulega awarii na komputerze, do którego nie masz dostępu.

Pełne debugowanie dodaje atrybut [Debuggable] do kodu. Ma to ogromny wpływ na prędkość. Na przykład niektóre optymalizacje pętli mogą być wyłączone, aby ułatwić wykonywanie pojedynczych kroków. Ponadto ma niewielki wpływ na proces JIT, ponieważ włącza śledzenie.

strzałka do dmuchawki
źródło
Ma sens. I tak naprawdę nie rozpowszechniam bibliotek DLL dla użytkowników - jest to aplikacja ASP.NET. Ale czy możesz uściślić swoją odpowiedź i uzasadnić, dlaczego powinieneś wybrać „tylko pdb” zamiast „pełny”? Czy to problem z wydajnością?
RationalGeek
@jkohlhepp: Chciałbym dodać, że debugowanie kompilacji wydania jest trochę trudne, ponieważ stracisz część informacji (z powodu JIT). Prawie zawsze nie będziesz w stanie zobaczyć wartości argumentów metody. Aby obejść ten problem, możesz tymczasowo wyłączyć optymalizację JIT za pomocą tego .
Ilian Pinzon
Dzięki Blowdart i Ilian Pinzon za dodatkowe informacje. Wiem, że nie można uzyskać idealnego debugowania za pomocą kodu wydania, ale posiadanie plików PDB jest lepsze niż nic.
RationalGeek
Korzystanie z ustawienia „pełny” nie ma wpływu na wydajność. Po prostu umożliwia podłączenie debugera do działającego procesu.
Matt Dillard,
1
Dobre pytanie na MSDN Matt, msdn.microsoft.com/en-us/library/8cw0bt21 , sam czekam na odpowiedź.
Luke Hutton,
4

Jestem w trakcie pisania procedury obsługi nieobsługiwanego wyjątku, a ślad stosu zawiera numer wiersza, gdy używane jest tylko pdb, w przeciwnym razie po wybraniu opcji Brak po prostu otrzymuję nazwę Sub / Function.

Jeśli nie rozpowszechnię pliku .pdb, nie otrzymam numeru wiersza w śladzie stosu, nawet w przypadku kompilacji z samym pdb.

Tak więc rozpowszechniam (wdrażanie XCOPY w sieci LAN) pdb wraz z exe z mojej aplikacji VB.

rheitzman
źródło