Должен ли я компилировать сборки выпуска с отладочной информацией как «полная» или «только pdb»?

114

В Visual Studio 2010 для проекта C #, если вы перейдете в Свойства проекта> Сборка> Дополнительно> Информация об отладке, у вас будет три варианта: нет, полный или только pdb. Основываясь на ответе на этот вопрос , я считаю, что понимаю некоторые различия между full и pdb-only. Однако что больше подходит для сборки выпуска? Если я использую «полный», будет ли производительность снижена? Если я использую "pdb-only", будет ли труднее отлаживать производственные проблемы?

В чем разница между "full" и "pdbonly"? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/debug-compiler-option

RationalGeek
источник
Только pdb или none, всегда для сборок выпуска.
leppie
13
@leppie Спасибо, но я ищу какое-то оправдание своей позиции.
RationalGeek
Связанный вопрос: stackoverflow.com/questions/1270986/…
janv8000
Это здорово, если не влияет на производительность. А как насчет воздействия на память? Если я создаю экземпляр StackTrace и запрашиваю информацию о файле, она должна поступать из данных символа pdb. Все ли символы загружаются в память при запуске приложения? Какое примерное использование памяти этим? (например, накладные расходы в процентах относительно размера кода.)
yoyo

Ответы:

90

Я бы построил с помощью pdb-only. Вы не сможете подключить отладчик к выпущенному продукту, но если вы получите аварийный дамп, вы можете использовать Visual Studio или WinDBG для проверки трассировки стека и дампа памяти во время сбоя.

Если вы выберете fullвместо pdb-only, вы получите те же преимущества, за исключением того, что исполняемый файл может быть прикреплен непосредственно к отладчику. Вам нужно будет определить, разумно ли это для вашего продукта и клиентов.

Обязательно сохраните файлы PDB где-нибудь, чтобы вы могли ссылаться на них при поступлении отчета о сбое. Если вы можете настроить сервер символов для хранения этих отладочных символов, тем лучше.

Если вы решите строить с none, у вас не будет выхода, когда в поле произойдет сбой. Вы не сможете провести какое-либо постфактумное исследование аварии, что может серьезно затруднить вашу способность отследить проблему.

Примечание о производительности:

И Джон Роббинс, и Эрик Липперт написали в блогах сообщения о /debugфлаге, и оба они указывают, что этот параметр не оказывает никакого влияния на производительность . Есть отдельный /optimizeфлаг, который указывает, должен ли компилятор выполнять оптимизацию.

Мэтт Диллард
источник
7
@Matt, статья MSDN о переключателе / ​​debug явно предупреждает о влиянии на производительность использования параметра «full»: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.
Аллон Гуралнек,
3
@Matt: Если «full» не имеет недостатков по сравнению с «pdb-only», но имеет только преимущества, почему вообще существует «pdb-only»? Есть ли причина использовать его сверх "полного"? Кроме того, вам следует внести исправление в статью MSDN в разделе «Содержимое сообщества».
Аллон Гуралнек
9
Цитата @AllonGuralnek из связанной статьи Джона Роббинса: Настоящая причина: история. Еще в .NET 1.0 были различия, но в .NET 2.0 их нет. Похоже, что .NET 4.0 будет следовать той же схеме. После двойной проверки с группой отладки CLR никакой разницы нет.
bentayloruk
5
Это неправда. Вы можете собрать только pdb и по-прежнему подключить отладчик. Я просто сделал это на всякий случай.
Марк
2
«Я бы собирал только pdb. Вы не сможете прикрепить отладчик к выпущенному продукту». Какой у вас здесь источник информации? Как отметили и @Mark, и я, это не кажется правильным.
MEMark
66

ПРЕДУПРЕЖДЕНИЕ. Документация MSDN для параметра / debug (в Visual Studio это Debug Info) кажется устаревшей! Это то, что у него неверно

Если вы используете / debug: full , имейте в виду, что есть некоторое влияние на скорость и размер JIT-оптимизированного кода и небольшое влияние на качество кода с / debug: full . Мы рекомендуем / debug: pdbonly или no PDB для генерации кода выпуска.

Одно различие между / debug: pdbonly и / debug: full заключается в том, что с / debug: full компилятор выдает a DebuggableAttribute, который используется, чтобы сообщить компилятору JIT о доступности отладочной информации.

Тогда что верно сейчас?

  1. Pdb-only - до .NET 2.0 он помогал исследовать аварийные дампы выпущенного продукта (клиентские машины). Но это не дало возможности подключить отладчик. В .NET 2.0 это не так. Это точно так же, как и Full .
  2. Полный - это помогает нам исследовать аварийные дампы, а также позволяет нам подключить отладчик к сборке выпуска. Но в отличие от упоминаний MSDN, это не влияет на производительность (начиная с .NET 2.0). Он делает то же самое, что и Pdb-only .

Если они точно такие же, почему у нас есть эти варианты? Джон Роббинс (бог отладки Windows) обнаружил, что они существуют по историческим причинам.

Еще в .NET 1.0 были различия, но в .NET 2.0 их нет. Похоже, что .NET 4.0 будет следовать той же схеме. После двойной проверки с группой отладки CLR никакой разницы нет.

Что контролирует, выполняет ли JITter отладочную сборку, так это переключатель / optimize. <...>

Суть в том, что вы хотите создавать свои релизные сборки с / optimize + и любым из переключателей / debug, чтобы вы могли отлаживать исходный код.

затем он продолжает это доказывать.

Теперь оптимизация - это часть отдельного переключателя /optimize(в Visual Studio это называется Optimize code).

Короче говоря, независимо от настройки DebugInfo pdb-only или full, у нас будут одинаковые результаты. Рекомендуется избегать None, поскольку это лишит вас возможности анализировать аварийные дампы выпущенного продукта или подключенного отладчика.

rpattabi
источник
3
Фантастический ответ! Мои собственные исследования (сравнение сгенерированных файлов) показывают те же результаты.
MEMark
@rpattabi Вы можете указать ссылку, что pdbonly и full - это одно и то же? Сейчас 2019 год, и в документации по-прежнему указано, что они разные и полные будут иметь снижение производительности. И VS2019 создает проект с Releaseтипом отладки конфигурации по умолчанию, установленным на pdbonly.
Джо
@joe Обсуждение находится внизу документации MSDN msdn.microsoft.com/en-us/library/8cw0bt21.aspx . Взгляни на это. Один участник указал на github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/… для получения актуальной информации, где pdbonly и full упоминаются как одно и то же. (К вашему сведению. Я больше не использую окна или VS. Так что я не слежу за тем, что там происходит. Но, как я уже говорил, информация в моем ответе по-прежнему актуальна, а документ MSDN по-прежнему неверен.)
rpattabi,
16

Вам понадобится только PDB, но вы не захотите передавать файлы PDB пользователям. Однако наличие их для себя вместе с вашими двоичными файлами дает вам возможность загружать аварийные дампы в отладчик, такой как WinDbg, и видеть, где ваша программа действительно потерпела неудачу. Это может быть весьма полезно, когда ваш код дает сбой на машине, к которой у вас нет доступа.

Полная отладка добавляет в ваш код атрибут [Debuggable]. Это имеет огромное влияние на скорость. Например, некоторые оптимизации цикла могут быть отключены, чтобы упростить пошаговое выполнение. Кроме того, это оказывает небольшое влияние на процесс JIT, поскольку включает отслеживание.

blowdart
источник
Имеет смысл. Я вообще-то не раздаю DLL пользователям - это приложение ASP.NET. Но можете ли вы улучшить свой ответ и обосновать, почему вам следует выбрать вариант «только pdb» вместо «полный»? Это проблема производительности?
RationalGeek
@jkohlhepp: Хотел бы добавить, что отладка сборок релизов немного сложна, поскольку вы потеряете некоторую информацию (из-за JIT). Почти всегда вы не сможете увидеть значения аргументов метода. Чтобы обойти это, вы можете временно отключить JIT-оптимизацию с помощью этого .
Илиан Пинзон
Спасибо, blowdart, и спасибо Илиану Пинзону за дополнительную информацию. Я знаю, что вы не можете добиться идеальной отладки с кодом выпуска, но наличие PDB лучше, чем ничего.
RationalGeek
Использование «полной» настройки вовсе не имеют влияния на производительность. Он просто позволяет присоединить отладчик к запущенному процессу.
Мэтт Диллард
1
Хороший вопрос по MSDN Мэтт, msdn.microsoft.com/en-us/library/8cw0bt21 , жду ответа сам.
Люк Хаттон,
4

Я пишу обработчик необработанных исключений, и трассировка стека включает номер строки, когда используется pdb-only, в противном случае я просто получаю имя подпрограммы / функции, когда выбираю None.

Если я не распространяю .pdb, я не получаю номер строки в трассировке стека даже при сборке только для pdb.

Итак, я распространяю (развертывание XCOPY в локальной сети) pdb вместе с exe из моего приложения VB.

Rheitzman
источник