Ошибка LoaderLock was detected при отладке в Civil 3d.

Автор Тема: Ошибка LoaderLock was detected при отладке в Civil 3d.  (Прочитано 8428 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
В последнее время, при завершении отладки приложения, стала выскакивать эта ошибка:
LoaderLock was detected
Message: Попытка выполнения управляемого кода под блокировкой OS Loader. Запуск управляемого кода в пределах функции DllMain или функции инициализации образа может вызвать зависание приложения.
Что интересно, при отладке в Civil 3d 2014 такого нет (подгружаю ту же самую DLL, те же самые действия при отладке). Проявляется в версиях 2015-2017. Отладку завершаю закрытием Civil 3D. Visual Studio 2013.
Поискал в интернете, многие рекомендуют просто не обращать внимания. В принципе, на работе приложения это никак не сказывается. В настройках отладки можно отключить вывод этого сообщения. Но прежде, чем это сделать, хочу попробовать понять, в чем может быть причина. У кого-нибудь еще такое предупреждение выскакивает?

Отмечено как Решение Дмитрий Загорулькин 30-09-2016, 15:04:22

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Что интересно, при отладке в Civil 3d 2014 такого нет. Проявляется в версиях 2015-2017.
Вероятнее всего это связано с отсутствием Fiber в последних версиях. Согласен, что на это можно не обращать внимание и отключить сообщение. В действительности это не исключение. Просто "умный" отладчик анализирует код в функции DllMain, которая есть у любого exe/dll/arx/dbx/crx...-файла и которая обычно вызывается дважды - один раз при загрузке и один раз при выгрузке. Так вот если этот "умный" отладчик обнаруживает там управляемый код, то это он считает ошибкой и ругается по этому поводу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Кстати, в древних версиях тоже встречалось: http://forums.autodesk.com/t5/net/quot-loaderlock-has-detected-a-problem-quot-when-debugging-with/td-p/1913103
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Ну VLIDE-то я не запускаю.
Сейчас потестировал немного. Это сообщение появляется при отладке только одного из моих проектов, и раньше его не было. Интересно, чем он отличается от остальных? Что же я такого мог добавить за последнее время, что вызвало такое поведение? Я грешу на обработчики событий приложения, коллекции документов и самих документов. Попробую разобраться.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ты самостоятельно не мог изменить код DllMain. И метод Terminate вызывается до кода DllMain. Но ты мог загрузить (использовать) одну из сборок, в DllMain которой используется управляемый код. Вот сюда можешь "копать" в первую очередь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Нашел то место в коде, которое влияет на появление этого сообщения. Это происходит, если внутри методов Overrule для метки трубы или колодца получить связанный с меткой объект через COM и затем получить его ObjectId. Вот примерно так:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.GraphicsInterface;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.Civil.DatabaseServices;
  6. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  7.  
  8. namespace CivilTest
  9. {
  10.     class PViewStructLabelDrawOverrule : DrawableOverrule
  11.     {
  12.         public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
  13.         {
  14.             StructureProfileLabel label = drawable as StructureProfileLabel;
  15.  
  16.             if (!ReferenceEquals(label, null))
  17.             {
  18.                 // Получаем COM объект метки колодца на виде профиля
  19.                 dynamic labelCOM = label.AcadObject;
  20.                 // Из свойства COM объекта метки получаем COM объект колодца на виде
  21.                 // профиля, к которому относится эта метка (через .NET не получить)
  22.                 dynamic pViewPartCOM = labelCOM.ProfileNetworkPart;
  23.                 // Получаем Id колодца на виде профиля
  24.                 ObjectId pViewPartId = AcDb.DBObject.FromAcadObject(pViewPartCOM);
  25.             }
  26.  
  27.             base.ViewportDraw(drawable, vd);
  28.         }
  29.     }
  30.  
  31.     public class PViewStructLabelDrawOverruleCmd
  32.     {
  33.         static PViewStructLabelDrawOverrule m_overrule = null;
  34.  
  35.         [CommandMethod("PViewStructLabelDrawOverruleOnOff")]
  36.         public static void CmdRun()
  37.         {
  38.             if (ReferenceEquals(m_overrule, null))
  39.             {
  40.                 m_overrule = new PViewStructLabelDrawOverrule();
  41.                 Overrule.AddOverrule
  42.                     (RXClass.GetClass(typeof(StructureProfileLabel)),
  43.                     m_overrule, false);
  44.                 Overrule.Overruling = true;
  45.             }
  46.             else
  47.             {
  48.                 Overrule.RemoveOverrule
  49.                     (RXClass.GetClass(typeof(StructureProfileLabel)),
  50.                     m_overrule);
  51.                 m_overrule = null;
  52.             }
  53.             Application.DocumentManager.
  54.                 MdiActiveDocument.Editor.Regen();
  55.         }
  56.     }
  57. }
  58.  
Строки 19, 22 и 24. Если убрать хотя бы строку 24, то сообщение уже не появляется.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Похоже, что добавление COM/ActiveX приводит к тому, что в DllMain при выгрузке выполняется какой-то дополнительный код. Например, освобождаются ресурсы, связанные с COM-моделью AutoCAD. Возможно если их освободить раньше, такого сообщения не будет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Попробовал их освободить таким образом:
Код - C# [Выбрать]
  1.                 int lblRefCount = Marshal.ReleaseComObject(labelCOM);
  2.                 int pvPartRefCount = Marshal.ReleaseComObject(pViewPartCOM);
  3.  
  4.                 labelCOM = null;
  5.                 pViewPartCOM = null;
Но ничего не изменилось. Честно говоря, что-то иссякает мой энтузиазм по поиску и устранению причины этого поведения. Наверное, сниму я эту галочку в настройках отладки и успокоюсь :)