Когда выпуск 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 и все работало правильно.