如果添加 fmod Visual C++ 后某个测试中的某一行代码,所有测试都会失败、无法获取类型和 FileNotFoundException 测试

发布于 2024-07-16 06:09:54 字数 4184 浏览 5 评论 0原文

我已经找出导致问题的原因,但我仍然不知道为什么 - 它发生在我开始使用 fmod 时,并且它一定与链接器决定如何引入和执行有关静态库和.dll。 我的测试代码是静态库; 它引用了另一个静态库 fmodex_vc,它在某个时刻(尽管我不知道何时)决定加载其 fmodex.dll。 (它与其他所有内容位于同一目录中,所以我不知道为什么它找不到它。)据我所知,被测试的代码绝对不会调用 fmod 初始化函数,但也许 fmod 有一些初始化自身并加载到 dll 中的静态全局初始值设定项? 只有当使用它的模块中的代码被...使用时,该代码才会被拉入?

我正在使用 Visual Studio 测试框架测试非托管 C++ 代码,当我开始使用 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 /code>s 为其字段。

  • 无论我如何运行测试(从测试视图、运行选定的、运行全部、从命令行运行、从测试菜单运行),我都会收到错误。
  • 尝试使用调试器进入测试失败 - 在调试器进入之前测试失败。将调试器设置为在系统异常时中断也没有执行任何操作。
  • 被测试的代码是静态.lib。 CLR 支持是 /clr
  • 哦,这只是:如果我调用静态实体成员函数,同样的处理。 如果我将所述静态函数移到类之外,则同样的情况。 但是,如果我将该功能移至另一个模块,那就没问题了。

如果我将调试器设置为在出现任何异常时中断,我确实会得到一些有趣的结果:

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 为什么要这样做?

I've figured out what caused the problem but I still don't know why - it happened when I started using fmod, and it must have something to do with how the linker decides to bring in and execute static libraries and .dll's. My code under test is a static lib; it refers to fmodex_vc, another static lib, which at some point (though I know not when) decides to load in its fmodex.dll. (Which is in the same directory as everything else, so I don't know why it wouldn't find it.) As far as I know, the code under test absolutely does not call the fmod initialization functions, but maybe fmod has some static global initializers that initialize themselves and load in the dll? And that code only gets pulled in if code in a module that uses it gets...used?

I'm testing unmanaged C++ code using the Visual Studio test framework and when I started using fmod it stopped working: Every test, even "test" tests that do nothing, would report (wrapped for readability):

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

After a lot of trial and error, excluding .cpp files and re-adding them, I discovered that only one of the test files elicits the problem; and it only does if this line is called:

EntityMgr::Init();

Interestingly, all the tests start failing with that message if that line is in the code. EntityMgr::Init() is a function that does very little:

EntityMgr* EntityMgr::instG = null;

and

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

and

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, is a pretty vanilla class with no pointers, just various floats for its fields.

  • No matter how I run the tests (from test view, run selected, run all, run from the command line, from the test menu) I get the error.
  • Attempting to step into the test with the debugger fails - the test fails before the debugger gets to step in. Setting the debugger to break on System exceptions did nothing as well.
  • The code under test is a static .lib. CLR support is /clr.
  • Oh, and this just in: if I call a static Entity member function, same deal. If I move said static function outside of the class, same deal. But, if I move that function to another module, it's fine.

If I set the debugger to break on any exception, I do get something interesting:

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

There's no source code at that location, of course. Here's the call stack:

     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()     

And here's the stack trace that mstest reports - I don't get anything useful out of it.

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().

Why is fmod doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

青萝楚歌 2024-07-23 06:09:54

我建议在 Dependency Walker 的配置文件模式 (http://www.dependencywalker.com/) 下运行您的应用程序。 它可以记录所有加载 DLL 和 EXE 的尝试,以及生成的错误代码 - 听起来“找不到文件”错误可能来自间接依赖项 - 可能是从链接 FMod 中引入的。

如果是这种情况,使用 Dependency Walker 分析应用程序将显示一次或多次加载库的失败尝试。 其中之一将是对错误负责的人。

I suggest running your application under Dependency Walker's Profile mode (http://www.dependencywalker.com/). It can record all attempts to load DLLs and EXEs, along with the resulting error codes - it sounds likely that the File not Found error is coming from an indirect dependency - perhaps being pulled in from linking FMod.

If this is the case, profiling your application with Dependency Walker will show one or more failed attempts to load a library. One of them will be the one responsible for the error.

南薇 2024-07-23 06:09:54

也许该文件的某些属性已被修改? 可能已经看过这个,但请确保所有设置都来自 Visual Studio 中的“从父级继承”。

杰伊

Maybe some property was modified for that file? Probably already looked at this, but make sure that all the settings are from "Inherit from parent" in Visual Studio.

Jay

独留℉清风醉 2024-07-23 06:09:54

我最好的猜测是,从您到目前为止发布的内容来看,异常是在 CLR 类型加载器内部的某处引发的 - 它看起来像是您间接依赖的程序集,要么不在 GAC 中,要么不在 GAC 中t 被复制到测试目录。

测试结果中是否有实际的堆栈跟踪? 这可能有助于缩小其尝试加载的类型的范围。

My best guess, from what you've posted so-far is that the exception is being thrown somewhere inside the CLR type loader — it looks like an assembly that you're indirectly dependent on either isn't in the GAC, or isn't being copied to the test directory.

Is there an actual stack trace in the test results? That might help narrow down what type(s) its trying to load.

时光无声 2024-07-23 06:09:54

既然你说这种情况突然开始发生,我认为使用这行代码的测试之前工作得很好。 这可能是一个激进的选择,但在没有其他解决方案的情况下,也许您会考虑重新安装 Visual Studio(这肯定是一个漫长的过程)

Since you say that this started happening all of a sudden, I assume that tests with this line of code were working just fine previously. This may be a radical choice, but in the absence of another solution, perhaps you would consider reinstalling visual studio (a long procedure to be sure)

执着的年纪 2024-07-23 06:09:54

您能否将 Visual Studio 设置为在所有异常发生时中断,无论它们在调试期间来自何处?

听起来好像宇宙射线或有故障的硬盘驱动器导致测试 .dll 损坏,或者您正在构建的 dll 损坏(始终)。 在重新安装所有 Visual Studio 之前,您可能需要要求它进行修复,这应该检查当前安装与安装介质上的内容之间是否存在不一致。

Can you set Visual Studio to break on all exceptions, regardless of where they come from during debugging?

It sounds as if cosmic rays or a faulty hard drive have caused a test .dll to become corrupt, or the dll you're building is corrupt (consistently). Before re-installing all of Visual Studio, you may want to ask it to do a repair, which should check for inconsistencies between your current install and what's on your installation medium.

不回头走下去 2024-07-23 06:09:54

FMod .dll 如何进入您的测试目录? 您是否已将其设置为将其复制到 mstest 希望进行测试的任何位置? 请注意,“复制到输出目录”实际上并没有完成此任务。 还有其他方法,虽然我不太记得是什么了。

How is the FMod .dll getting into your test directory? Do you have it set up to copy it to wherever mstest wants the test to occur? Note that "Copy to Output Directory" doesn't actually accomplish this. There's some other method, though I can't remember quite what it is.

枕花眠 2024-07-23 06:09:54

我会在调试器中运行它并检查运行输出 - 特别是“loading path\fmodex.dll”行以查看它是否加载了正确的 dll。

当混合来自不同配置的 dll 时,我看到过类似的错误。

I'd run it in a debugger and check the run output - in particular the "loading path\fmodex.dll" line to see if it's loading the right dll.

I've seen similar errors when mixing dlls from different configurations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文