【问题标题】:Declaring a HMODULE throws an exception at runtime声明 HMODULE 会在运行时引发异常
【发布时间】:2012-01-05 23:20:35
【问题描述】:

我正在编写一个 C++ DLL,它会在它的一个函数中加载另一个 DLL。但是,当我尝试运行它时,它会在我第一次声明我的 HMODULE 变量时崩溃,甚至在我尝试调用 LoadLibrary 之前。

具体来说,我的代码是:

HMODULE my_hmod;
my_hmod = LoadLibrary("C:\\path_to_dll");

它在这两行之间崩溃(我已经通过它并注意到它在“ostream”中崩溃,如果这有帮助的话)。

例外情况如下:

PixelMotionBlur.exe 中 0x00a7392d (d3d9.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000000。

任何帮助将不胜感激!如果需要,我会发布更多代码/调试信息。

编辑:这是实际的功能代码:

    D3D9Wrapper::IDirect3D9* WINAPI Direct3DCreate9(UINT Version)
{
    InitializeDLL();
    HMODULE hD3D;
    if(IsWow64())
    {
        hD3D = LoadLibrary("C:\\Windows\\SysWOW64\\d3d9.dll");
    }
    else
    {
        hD3D = LoadLibrary(g_Globals.RealD3D9DLL.CString());
    }

    if( hD3D == NULL )
    {
        g_Globals.ErrorFile() << "LoadLibrary on d3d9.dll failed\n";
        return NULL;
    }

    D3D9Wrapper::D3DCREATE pCreate = (D3D9Wrapper::D3DCREATE)GetProcAddress(hD3D, _T("Direct3DCreate9"));
    if( pCreate == NULL )
    {
        g_Globals.ErrorFile() << "coud not find Direct3DCreate9 in d3d9.dll\n";
        return NULL;
    }

    D3D9Base::LPDIRECT3D9 pD3D = pCreate(D3D_SDK_VERSION);
    if( pD3D == NULL )
    {
        return NULL;
    }

    //return (D3D9Wrapper::IDirect3D9*)pD3D;
    return D3D9Wrapper::IDirect3D9::GetDirect3D(pD3D);
}

如果有帮助,这个 DLL 的功能(大部分实际上不是我的代码,而是在获得许可的情况下使用)是通过在目标 .exe 的文件夹中放置一个也名为 d3d9 的新 dll 来挂钩对 d3d9.dll 的所有调用(现在我正在使用 Direct X 9 sdk 中的示例 .exe 对其进行测试)。

编辑 2:这是函数的完整反汇编:

    D3D9Wrapper::IDirect3D9* WINAPI Direct3DCreate9(UINT Version)
{
008B6960  push        ebp  
008B6961  mov         ebp,esp  
008B6963  and         esp,0FFFFFFF8h  
008B6966  sub         esp,8  
    InitializeDLL();
008B6969  cmp         byte ptr [g_Globals (8CAC40h)],0  
008B6970  push        esi  
008B6971  push        edi  
008B6972  jne         Direct3DCreate9+48h (8B69A8h)  
008B6974  mov         edi,offset g_Globals (8CAC40h)  
008B6979  call        Globals::Init (8B6A80h)  
008B697E  mov         eax,dword ptr [g_Globals+34h (8CAC74h)]  
008B6983  push        8C0D98h  
008B6988  push        eax  
008B6989  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B698E  call        dword ptr [__imp_D3D9CallbackInitialize (8B81A4h)]  
008B6994  mov         ecx,dword ptr [g_Globals+34h (8CAC74h)]  
008B699A  push        8C0DB0h  
008B699F  push        ecx  
008B69A0  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B69A5  add         esp,10h  
    HMODULE hD3D;
    if(IsWow64())
008B69A8  push        8C0E60h  
008B69AD  push        8C0E70h  
008B69B2  mov         dword ptr [esp+14h],0  
008B69BA  call        dword ptr [__imp__GetModuleHandleA@4 (8B80D0h)]  
008B69C0  mov         edi,dword ptr [__imp__GetProcAddress@8 (8B80C4h)]  
008B69C6  push        eax  
008B69C7  call        edi  
008B69C9  mov         esi,eax  
008B69CB  test        esi,esi  
008B69CD  je          Direct3DCreate9+94h (8B69F4h)  
008B69CF  lea         edx,[esp+0Ch]  
008B69D3  push        edx  
008B69D4  call        dword ptr [__imp__GetCurrentProcess@0 (8B80B8h)]  
008B69DA  push        eax  
008B69DB  call        esi  
008B69DD  test        eax,eax  
008B69DF  jne         Direct3DCreate9+94h (8B69F4h)  
008B69E1  mov         eax,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B69E6  push        8C0E7Ch  
008B69EB  push        eax  
008B69EC  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B69F1  add         esp,8  
008B69F4  cmp         dword ptr [esp+0Ch],0  
008B69F9  je          Direct3DCreate9+0A2h (8B6A02h)  
    {
        hD3D = LoadLibrary("C:\\Windows\\SysWOW64\\d3d9.dll");
008B69FB  push        8C0E98h  
    }
    else
008B6A00  jmp         Direct3DCreate9+0B1h (8B6A11h)  
    {
        hD3D = LoadLibrary(g_Globals.RealD3D9DLL.CString());
008B6A02  mov         eax,dword ptr [g_Globals+1Ch (8CAC5Ch)]  
008B6A07  test        eax,eax  
008B6A09  jne         Direct3DCreate9+0B0h (8B6A10h)  
008B6A0B  mov         eax,offset g_Globals+1Ch (8CAC5Ch)  
008B6A10  push        eax  
008B6A11  call        dword ptr [__imp__LoadLibraryA@4 (8B80CCh)]  
    }

    if( hD3D == NULL )
008B6A17  test        eax,eax  
008B6A19  jne         Direct3DCreate9+0D9h (8B6A39h)  
    {
        g_Globals.ErrorFile() << "LoadLibrary on d3d9.dll failed\n";
008B6A1B  mov         ecx,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B6A21  push        8C0EB8h  
008B6A26  push        ecx  
008B6A27  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B6A2C  add         esp,8  
        return NULL;
008B6A2F  xor         eax,eax  
}
008B6A31  pop         edi  
008B6A32  pop         esi  
008B6A33  mov         esp,ebp  
008B6A35  pop         ebp  
008B6A36  ret         4  
    }
    D3D9Wrapper::D3DCREATE pCreate = (D3D9Wrapper::D3DCREATE)GetProcAddress(hD3D, _T("Direct3DCreate9"));
008B6A39  push        8C0ED8h  
008B6A3E  push        eax  
008B6A3F  call        edi  
    if( pCreate == NULL )
008B6A41  test        eax,eax  
008B6A43  jne         Direct3DCreate9+103h (8B6A63h)  
    {
        g_Globals.ErrorFile() << "coud not find Direct3DCreate9 in d3d9.dll\n";
008B6A45  mov         edx,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B6A4B  push        8C0EE8h  
008B6A50  push        edx  
008B6A51  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B6A56  add         esp,8  
        return NULL;
008B6A59  xor         eax,eax  
}
008B6A5B  pop         edi  
008B6A5C  pop         esi  
008B6A5D  mov         esp,ebp  
008B6A5F  pop         ebp  
008B6A60  ret         4  
    }

编辑 3: 引发异常时的调用堆栈:

>   d3d9.dll!std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr, const char * _Val)  Line 773 + 0x3 bytes    C++
    d3d9.dll!InitializeDLL()  Line 70 + 0x15 bytes  C++
    d3d9.dll!Direct3DCreate9(unsigned int Version)  Line 141    C++
    PixelMotionBlur.exe!DXUT_Dynamic_Direct3DCreate9(unsigned int SDKVersion)  Line 714 + 0xc bytes C++
    PixelMotionBlur.exe!DXUTDelayLoadD3D9()  Line 2706 + 0xa bytes  C++
    PixelMotionBlur.exe!DXUTGetD3D9Object()  Line 712 + 0x23 bytes  C++
    PixelMotionBlur.exe!CD3D9Enumeration::Enumerate(bool (_D3DCAPS9 *, _D3DFORMAT, _D3DFORMAT, bool, void *)* IsD3D9DeviceAcceptableFunc, void * pIsD3D9DeviceAcceptableFuncUserContext)  Line 309 + 0x5 bytes  C++
    PixelMotionBlur.exe!DXUTGetD3D9Enumeration(bool bForceEnumerate)  Line 255  C++
    PixelMotionBlur.exe!DXUTFindValidDeviceSettings(DXUTDeviceSettings * pOut, DXUTDeviceSettings * pIn, DXUTMatchOptions * pMatchOptions)  Line 174    C++
    PixelMotionBlur.exe!DXUTCreateDevice(bool bWindowed, int nSuggestedWidth, int nSuggestedHeight)  Line 2010 + 0x17 bytes C++
    PixelMotionBlur.exe!wWinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal)  Line 207  C++
    PixelMotionBlur.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes  C
    PixelMotionBlur.exe!wWinMainCRTStartup()  Line 371  C
    kernel32.dll!75e1339a()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!77829ed2()    
    ntdll.dll!77829ea5()    

【问题讨论】:

  • 它并没有在你认为它崩溃的地方崩溃。
  • 这不是崩溃。您是否在启用优化的情况下进行编译?如果是这样,调试器就在向您撒谎崩溃的位置。发布更多代码,并在该地址周围发布反汇编。
  • 其他 dll 是否在其 DllMain 中执行任何操作?
  • 我正在使用 VS 2010 编译器,我对它很陌生——我认为它没有优化,因为我在项目配置属性中关闭了“整个程序优化”。 VS 是否还有其他地方可以偷偷进行编译优化?
  • @Zac 另一个 dll(即我要加载的那个)肯定没有调用它的 main,因为即使没有 loadlibrary 调用,错误仍然存​​在:-/

标签: c++ dll handle loadlibrary


【解决方案1】:

根据调用堆栈,错误在 InitializeDLL 函数中。在没有看到该函数的源代码的情况下真的不能肯定地说,但由于它是通过 std::ostream 的 NULL 指针异常,我敢打赌你正试图向 std::cout 或类似的发送一个 NULL 字符串.

检查 InitializeDLL 所在源文件的第 70 行。如果您没有发现问题,请发布 InintializeDLL 中的代码。

【讨论】:

  • 你先生,真的很神奇。这正是问题所在,尽管我完全误导了你,但你仍然设法找到了它。太棒了,我向大家道歉,我没有正确定位我的问题。
  • 另外,我应该删除这个问题,因为问题根本与 HMODULE 无关?
  • 留下这个问题,因为解决问题的道路可能对其他人有用。
【解决方案2】:

确保您正在运行和构建程序的调试版本。在 VS2010 中,确保您选择了“调试”构建配置并在调试器菜单中确保您在抛出任何 C++ 异常时中断。

你是对的 - 我能够很好地做到以下几点。

HMODULE hD3D = LoadLibrary(L"C:\\Windows\\SysWOW64\\d3d9.dll");

【讨论】:

  • 我刚刚尝试将配置更改为调试,但问题仍然存在。除了与其关联的配置属性预设之外,不同的配置名称真的很重要吗?
  • 另外,我试着把 "HMODULE hD3D = LoadLibrary(L"C:\\Windows\\SysWOW64\\d3d9.dll");"在我的 dll 的另一部分,它加载得很好——然后不管怎样都会在同一个地方崩溃:(
  • 当然,属性是重要的部分,调试配置应该希望关闭所有优化并打开调试检查。崩溃时的调用堆栈是什么?
  • 它“在 ostream 中崩溃”这一事实是一个重要线索。
猜你喜欢
  • 2012-02-07
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2018-04-14
  • 1970-01-01
  • 2020-07-27
相关资源
最近更新 更多