Когда выпуск dll не работает, но debug dlls do
После развертывания нашей огромной распределенной системы одному из наших клиентов возникает непредвиденная ошибка. Во время расследования мы заменяем сборку, вызывая ошибку, с тем, где мы добавили некоторый диагностический код. Используемая DLL встроена в режим отладки. И вдруг все работает!
Замена debug dll версией выпуска (с диагностическим кодом) заставляет его снова сбой.
В нашем коде отсутствуют директивы прекомпилятора, условные атрибуты отладки и т.д. Проблема была обнаружена в двух разных местах установки, в то время как она отлично работает еще в нескольких.
(В проекте есть сочетание С# и VB.NET, сборка troublesom - VB.NET.., если это имеет значение)
Итак, вопрос: Что вы делаете в таких ситуациях? И что может быть причиной - вообще? Любые советы по отладке этой проблемы приветствуются.
Ответы
Ответ 1
По причинам... ну, какой-то намек на симптом поможет. Одна из возможностей заключается в том, что у вас есть код для метода типа Debug.WriteLine
, который имеет побочные эффекты (т.е. Заставляет его работать). Вызовы методам, отмеченные [Conditional(...)]
, не компилируются, если у вас нет правильных символов, поэтому ничего, помеченное как [Conditional("DEBUG")]
, будет отключено.
Он также может быть ошибкой компилятора, но это немного маловероятно (но не невозможно).
Что такое симптом? Как это ломается?
В качестве примера вышесказанного:
static string Bar { get; set; }
static void Main()
{
Bar = "I'm broken";
Debug.WriteLine(Foo());
Console.WriteLine(Bar);
}
// note Foo only called in DEBUG builds
static string Foo()
{
Bar = "I'm working";
return "mwahahah";
}
Скомпилированный в режиме DEBUG он печатает "Я работаю"; скомпилированный в режиме RELEASE, он печатает "Я сломан". Звучит ли это похоже? Убедитесь, что вы не вызываете какие-либо методы отладки напрямую с вещами, которые имеют побочные эффекты. В большинстве случаев вы можете исправить по косвенности:
string foo = Foo();
Debug.WriteLine(foo);
Теперь он вызывается в любом режиме.
Ответ 2
Вы можете попробовать и отключить Оптимизировать код в настройках сборки. Какова фактическая ошибка, которую вы получаете.
Еще одна вещь, которую вы можете сделать, - скомпилировать в режиме выпуска, но разрешить #Debug условно. Это будет обрабатывать случай, если ваше использование Diagnostics.Debug и код там влияют на ваше приложение.
Ответ 3
Debug.Assert(ImportantMethod());
Ответ 4
Вы пытались включить файлы отладки? (pdbs)
Если вы соедините настройки своего проекта, а затем на вкладке компиляции выберите свою версию выпуска в раскрывающемся списке вверху, а затем выберите расширенные параметры компиляции в нижней части страницы, убедитесь, что она задает FULL отладочную информацию, а затем передислоцирует, теперь вы должны получить более подробную информацию о причине сбоя.
Ответ 5
Я видел время, которое вызывает проблемы между сборкой Debug и Release. Как правило, сборка Debug выполняется медленнее, чем Release build. Возможно, вы захотите проверить временную критическую часть вашего кода.
Ответ 6
Это может быть какое-то состояние гонки, если вы не работаете в однопоточном коде. Например, если какая-то часть вашей программы должна выполнить некоторые действия, прежде чем другие части смогут ее получить, она может выйти из режима освобождения просто потому, что к коду обращаются слишком рано. У нас когда-то была аналогичная проблема с некоторым кодом для мобильных телефонов, который работал нормально в эмуляторе, но на телефоне, который был медленнее, сатура была совсем не такой.
Ответ 7
У меня была проблема в один момент, когда финализаторы уходили раньше, чем ожидалось, потому что я не полностью понял взаимодействие между финализаторами, сборщиком мусора и когда локальный объект считается коллекционным (намек: он не при закрытии фигурная скобка блока). Если ваш код использует финализаторы, вы можете посмотреть в GC.KeepAlive(). В следующем блоке:
void MyFunction()
{
Foo f = new Foo();
SomeFunction(f.SomeProp);
}
f
становится доступным для завершения до того, как SomeFunction()
даже работает! Если финализатор делает что-то вроде удаления любых SomeProp
рук, вы можете попасть в беду. Добавление вызова к GC.KeepAlive(f)
после вызова SomeFunction
гарантирует, что f
не подходит для завершения до тех пор, пока не будет вызван вызов KeepAlive()
.
Изменить: после всего этого я забыл указать, что эта проблема была гораздо более выраженной при работе в режиме Release. Я не знаю, добавляет ли сборка Debug неявные KeepAlives для локальных пользователей в конце функции для преимущества отладчика или если сборка мусора просто менее агрессивна или что-то, но режим Release значительно усугубил эту проблему в моем случае.
Ответ 8
Убедитесь, что приложение построено под правильной платформой. Это может быть проблемой, особенно когда речь идет о предоставлении или потреблении DLL. Посмотрите в разделе "Project- > Properties" и выберите вкладку "Build". Опция целевой платформы позволяет вам выбирать между любыми CPU (по умолчанию), x86 или x64.
Ответ 9
Прежде всего, извините за мой английский. Я знаю, что этот пост старый, но у меня есть одна и та же проблема, и я понимаю, что в режиме отладки сборка выполнена для 32-разрядной ОС, а режим выпуска - 64 бит по умолчанию. Это делает dll, сделанный для 32 бит, не работает в выпуске. Если вы перейдете к свойствам проекта → сборка, вы можете выбрать нужную архитектуру. Это работает для меня.
До свидания.
Ответ 10
Вы, наверное, знаете это, но,
переменные иногда инициализируются по-разному в сборках отладки и выпуска.
Например.
Я думаю, что переменные автоматически инициализируются в сборках отладки VC6, это может скрыть проблемы, если вы не инициализировали что-то. Я также думаю, что массивы отладки могут использовать часовые байт в попытке указать перерасход. Это также может привести к поведению.
Ответ 11
У меня была аналогичная проблема. Мое положение:
Я определил некоторые функции отражения в библиотеке классов A. Затем я определил библиотеку пользовательских элементов управления WPF B, которая использует функции из библиотеки A. Затем я закодировал приложение, которое использует пользовательский элемент управления из библиотеки B и функции в библиотеке A. Когда я использовал отладочную версию библиотеки B, она отлично работает. Но когда я использовал версию библиотеки B, функции отражения не работали. Я также определил другие функции в библиотеке А. Кажется, что только функции отражения вызывают проблемы. Я не могу понять причину. Наконец, я сдался и перевел функции отражения из библиотеки A в библиотеку B. И это сработало.
Ответ 12
Вы решили свою проблему?
У меня такая же проблема, как и вы.
Если я скомпилирую dll в debug, все отлично работает.
Если я компилирую в выпуске, я получаю исключение с нулевой ссылкой.
Но если я включу некоторые строки, подобные описанным выше в некоторых методах, исключение исчезнет даже в режиме деблокирования:
System.Diagnostics.EventLog.WriteEntry( "blablabla", "blablabla" )
Надеюсь, что это поможет вам.
Ответ 13
В моем случае это было то, что мой DLL-потребительский проект (в VS) имел конфигурацию x64, но решение было в любом процессоре.
По какой-то причине при запуске приложения это не связано с моей x64 DLL.
Я настроил приложение на явную платформу x64 и все работало правильно.