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


Pdb-only lub none, zawsze dla kompilacji wydania.
— leppie

13
@leppie Dzięki, ale szukam uzasadnienia dla tego stanowiska.
— RationalGeek


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.


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.


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.