Когда релиз DLL не работает, но отладка DLL - PullRequest
16 голосов
/ 15 декабря 2008

После развертывания нашей огромной распределенной системы на одном из наших клиентов мы столкнулись с неожиданной ошибкой. В ходе расследования мы заменяем сборку, вызвавшую ошибку, на ту, в которую мы добавили некоторый диагностический код. Используемая нами dll встроена в режим отладки. И вдруг все работает!

Замена dll отладки на версию выпуска (с диагностическим кодом) снова приводит к сбою.

В нашем коде нет директив прекомпилятора, атрибутов условной отладки и т. Д. Проблема была обнаружена в двух разных местах установки, а в нескольких других она работает нормально.

(В проекте есть смесь C # и VB.NET, проблемная сборка VB.NET .., если это имеет какое-то значение)

Итак, вопрос: Что вы делаете в подобных ситуациях? И в чем может быть причина - в целом? Любые советы по устранению этой проблемы приветствуются.

Ответы [ 15 ]

12 голосов
/ 15 декабря 2008

По причинам ... ну, некоторый намек на симптом поможет. Одна возможность состоит в том, что у вас есть код для метода, такого как 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);

Теперь он вызывается в любом режиме.

5 голосов
/ 15 декабря 2008

Вы можете попробовать отключить Оптимизировать код в настройках сборки. Какая реальная ошибка вы получаете.

Еще одна вещь, которую вы можете сделать, это скомпилировать в режиме выпуска, но включить условную #Debug Это будет обрабатывать случай, если использование вами Diagnostics.Debug и кода в нем влияет на ваше приложение.

4 голосов
/ 15 декабря 2008

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

4 голосов
/ 15 декабря 2008

Вы пробовали включить файлы отладки? (pdbs)

Если вы перейдете к настройкам своего проекта, а затем на вкладке компиляции выберите сборку релиза в раскрывающемся меню в верхней части, затем выберите дополнительные параметры компиляции в нижней части, убедитесь, что она настроена для создания полной информации отладки, затем повторно разверните ее Теперь вы должны получить более подробную информацию о причине сбоя.

4 голосов
/ 15 декабря 2008
Debug.Assert(ImportantMethod());
3 голосов
/ 25 июля 2018

Была такая же проблема с C # DLL, содержащей клиент WCF, предоставленный для нескольких клиентских приложений.

Обнаружено, что в клиентской библиотеке C # существует метод доступа к StackTrace для целей ведения журнала, который при компиляции в отладке оказывается другим.

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(2).GetMethod();

GetFrame(2) не существовало в выпуске. Более подробную информацию об этом можно найти здесь: Методы класса StackTrace, не работающие в режиме выпуска

Забавно, что на VB.NET-клиенте повлияли, а в другом C # .NET-клиенте он работал нормально.

Надеюсь, это поможет.

3 голосов
/ 15 декабря 2008

Это может быть своего рода состояние гонки, если вы не работаете с однопоточным кодом. Например, если какая-то часть вашей программы должна выполнить некоторые действия, прежде чем другие части смогут получить к ней доступ, она может выйти из строя в режиме выпуска просто потому, что к коду обращаются слишком рано. Когда-то у нас была похожая проблема с кодом для мобильных телефонов, который нормально работал в эмуляторе, но на телефоне, который работал медленнее, ситуация была совсем не такой.

1 голос
/ 31 июля 2014

Прежде всего извините за мой английский. Я знаю, что этот пост старый, но у меня точно такая же проблема, и я понимаю, что в режиме отладки сборка сделана для 32-битной ОС , а режим выпуска - для 64-бит по умолчанию. Это делает DLL, созданную для 32-битных не работает в релизе. Если вы идете в Свойства проекта -> построить, вы можете выбрать архитектуру, которую вы хотите. Это работает для меня. До свидания.

1 голос
/ 12 июня 2014

Убедитесь, что приложение создается под правильной целевой платформой. Это может быть проблемой, особенно когда речь идет о предоставлении или использовании DLL. Посмотрите в «Project-> Properties» и выберите вкладку «Build». Опция Цель платформы позволит вам выбрать между любым процессором (по умолчанию), x86 или x64.

1 голос
/ 15 июля 2009

В какой-то момент у меня возникла проблема с тем, что финализаторы ушли раньше, чем ожидалось, потому что я не до конца понимал взаимодействие между финализаторами, сборщиком мусора и когда локальный объект считается коллекционируемым (подсказка: это не на закрытии фигурная скобка блока). Если ваш код использует финализаторы, вы можете заглянуть в GC.KeepAlive (). В следующем блоке:

void MyFunction() 
{ 
  Foo f = new Foo();
  SomeFunction(f.SomeProp);
}

f получает право на финализацию до того, как SomeFunction() даже запустится! Если финализатор делает что-то вроде утилизации того, что SomeProp раздает, у вас могут возникнуть проблемы. Добавление вызова к GC.KeepAlive(f) после вызова к SomeFunction гарантирует, что f не будет иметь права на финализацию, пока после вызова к KeepAlive().

Редактировать: После всего этого я забыл указать, что эта проблема была гораздо более выраженной при работе в режиме выпуска. Я не знаю, помещает ли сборка Debug неявные KeepAlives для локальных пользователей в конце функции для выгоды отладчика, или если сборка мусора просто менее агрессивна, или что, но режим Release значительно усугубил эту проблему в моем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...