Все тесты не пройдены, невозможно получить тип и FileNotFoundException, если определенная строка кода в одном тесте после добавления теста fmod Visual C ++ - PullRequest
3 голосов
/ 09 апреля 2009

Я выяснил, что вызвало проблему, но я до сих пор не знаю, почему - это произошло, когда я начал использовать fmod, и это должно иметь какое-то отношение к тому, как компоновщик решает ввести и выполнить статические библиотеки и .dll х. Мой тестируемый код - статическая библиотека; он ссылается на fmodex_vc, другую статическую библиотеку, которая в какой-то момент (хотя я не знаю, когда) решает загрузить в нее fmodex.dll. (Он находится в том же каталоге, что и все остальные, поэтому я не знаю, почему он его не найдет.) Насколько я знаю, тестируемый код абсолютно не вызывает функции инициализации fmod, но, возможно, fmod имеет некоторые статические глобальные инициализаторы, которые сами инициализируются и загружаются в dll? И этот код включается только в том случае, если код в модуле, который его использует, ... используется?

Я тестирую неуправляемый код C ++, используя тестовую среду Visual Studio, и когда я начал использовать fmod, он перестал работать: каждый тест, даже "тестовые" тесты, которые ничего не делают, сообщал (упакован для удобства чтения):

Unable to get type SlidersTest.UnitTest1, SlidersTest.
    Error: System.IO.FileNotFoundException: 
    The specified module could not be found.
    (Exception from HRESULT: 0x8007007E)

После большого количества проб и ошибок, за исключением файлов .cpp и их повторного добавления, я обнаружил, что только один из тестовых файлов выявляет проблему; и это только если эта строка называется:

EntityMgr::Init();

Интересно, что все тесты начинают проваливаться с этим сообщением, если эта строка находится в коде. EntityMgr::Init() - это функция, которая выполняет очень мало:

EntityMgr* EntityMgr::instG = null;

и

void EntityMgr::Init()
{
   instG = new EntityMgr;
}

и

class EntityMgr
{
private:
   static EntityMgr* instG;
public:
   EntityMgr()   // does nothing beyond the default 
   {
   }

   static void Init();
   static EntityMgr* Inst() { return instG; }

   ...

   vector<Entity> entitiesG;
};

Entity, FWIW, довольно ванильный класс без указателей, просто различные float s для его полей.

  • Независимо от того, как я запускаю тесты (из вида теста, запустить выбранный, запустить все, запустить из командной строки, из меню теста), я получаю ошибку.
  • Попытка войти в тест с помощью отладчика не удалась - тест не прошел до того, как отладчик вошел в систему. Установка прерывания отладчика на системные исключения также ничего не делала.
  • Тестируемый код является статическим .lib. Поддержка CLR /clr.
  • Да, и это просто: если я вызываю статическую функцию-член Entity, то же самое. Если я переместу указанную статическую функцию за пределы класса, сделаю то же самое. Но если я перенесу эту функцию в другой модуль, это нормально.

Если я установлю отладчик так, чтобы он прерывался на любое исключение, я получаю кое-что интересное:

First-chance exception at 0x7c812aeb in vstesthost.exe: Microsoft C++ exception: HRException at memory location 0x05129890..

Конечно, в этом месте нет исходного кода. Вот стек вызовов:

     kernel32.dll!7c812aeb()    
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    kernel32.dll!7c812aeb()     
    [External Code] 
    msvcr80.dll!78158ed7()  
    msvcr80.dll!78158e34()  
    msvcr80.dll!78158047()  
    msvcr80.dll!7815850e()  
    msvcr80.dll!78158872()  
    msvcr80.dll!78158a57()  
    msvcr80.dll!78158b11()  
    ntdll.dll!7c9032a8()    
    ntdll.dll!7c90327a()    
    ntdll.dll!7c92a9ef()    
    ntdll.dll!7c90e46a()    
    kernel32.dll!7c812aeb()     
    kernel32.dll!7c812aeb()     
    kernel32.dll!7c812aeb()     
    msvcr80.dll!78139c4d()  
    msvcr80.dll!781323ff()  
    msctf.dll!74755764()    
    msctf.dll!74721557()    
    ws2_32.dll!71ab12bb()   
    ntdll.dll!7c90118a()    
    ntdll.dll!7c91b084()    
    ntdll.dll!7c90de7c()    
    ntdll.dll!7c90d04c()    
    ntdll.dll!7c90e43f()    
    kernel32.dll!7c80b713()     

А вот и трассировка стека, которую сообщает mstest - из этого я ничего полезного не получаю.

Unable to get type SlidersTest.game_EntityMgr_test, SlidersTest. Error: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)
   at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.GetType(UnitTestElement unitTest, String type)
   at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.ResolveMethods().

Почему fmod делает это?

Ответы [ 7 ]

1 голос
/ 14 мая 2009

Я предлагаю запустить ваше приложение в режиме профиля Dependency Walker (http://www.dependencywalker.com/).. Оно может записывать все попытки загрузки DLL и EXE вместе с полученными кодами ошибок - похоже, что ошибка File not Found происходит косвенная зависимость - возможно, вырвана из ссылки FMod.

В этом случае при профилировании вашего приложения с помощью Dependency Walker будет показана одна или несколько неудачных попыток загрузить библиотеку. Один из них будет ответственным за ошибку.

0 голосов
/ 20 мая 2009

Я бы запустил его в отладчике и проверил выходные данные запуска, в частности строку «путь загрузки \ fmodex.dll», чтобы увидеть, загружает ли он правильную DLL.

Я видел похожие ошибки при смешивании библиотек из разных конфигураций.

0 голосов
/ 14 апреля 2009

Как FMod .dll попадает в ваш тестовый каталог? Есть ли у вас его настроить, чтобы скопировать его туда, где mstest хочет провести тест? Обратите внимание, что «Копировать в выходной каталог» фактически не выполняет этого. Есть какой-то другой метод, хотя я не могу вспомнить, что это такое.

0 голосов
/ 10 апреля 2009

Можно ли настроить Visual Studio на разрыв всех исключений, независимо от того, откуда они берутся во время отладки?

Звучит так, как будто космические лучи или неисправный жесткий диск привели к повреждению тестового .dll или повреждению созданной вами библиотеки DLL (последовательно). Перед повторной установкой всей Visual Studio вы можете попросить ее выполнить ремонт, который должен проверить наличие несоответствий между вашей текущей установкой и тем, что находится на вашем установочном носителе.

0 голосов
/ 10 апреля 2009

Поскольку вы говорите, что это начало происходить внезапно, я предполагаю, что тесты с этой строкой кода ранее работали просто отлично. Это может быть радикальным выбором, но в отсутствие другого решения, возможно, вы бы рассмотрели переустановку Visual Studio (длительная процедура, чтобы убедиться)

0 голосов
/ 10 апреля 2009

Моя лучшая догадка из того, что вы уже опубликовали, заключается в том, что исключение выдается где-то внутри загрузчика типа CLR - похоже, что сборка, от которой вы косвенно зависите, отсутствует в GAC, или не копируется в тестовый каталог.

Есть ли фактическая трассировка стека в результатах теста? Это может помочь определить, какой тип (ы) он пытается загрузить.

0 голосов
/ 09 апреля 2009

Может быть, какое-то свойство было изменено для этого файла? Вероятно, уже смотрел на это, но убедитесь, что все настройки от "Наследовать от родителя" в Visual Studio.

Jay

...