c++ - 捕获dll异常后访问冲突

标签 c++ exception dll virtual access-violation

我必须在运行时将模块作为 dll 动态加载,因为它们事先不知道,只是它们符合类接口(interface)。我注意到的是,在我捕获到 dll 抛出的异常(在主线程的主程序中)之后,调用了正确的析构函数并销毁了模块并卸载了 dll,但是随后作为 } 在 catch block 的末尾当逐行执行时,Visual Studio C++ 调试器会到达,我得到另一个异常,它使程序崩溃

xxxxx.exe 中 0x68ad2377 (msvcr90d.dll) 处的第一次异常:0xC0000005:访问冲突读取位置 0x02958f14。

如果我启用异常中断,则在第二个异常上中断显示位置为

msvcr90d.dll!__DestructExceptionObject(EHExceptionRecord * pExcept=0x0017ee4c, unsigned char fThrowNotAllowed=0) 第 1803 行 + 0xf 字节

但看起来帧堆栈可能已损坏。我不明白为什么会抛出这个异常。

我的代码结构的简化版本如下:

一个非常简化的程序结构:

//shared header:
class Module
{
public:
    virtual void Foo(void) = 0;
};


//dll:
class SomeSpecificModule : public Module
{
public:
    virtual void Foo(void);
};

void SomeSpecificModule::Foo(void)
{
    throw 1;
}

extern "C" __declspec(dllexport) Module* GetModule()
{
    return new SomeSpecificModule;
}


//program:
typedef ptrGetModule* (*GetModule)();

int main(void)
{
    HANDLE hMod = LoadLibrary("SomeSpecificModule.dll");
    ptrGetModule GetModule = (ptrGetModule)GetProcAddress(hMod, "GetModule");
    try
    {
        Module *d = GetModule();
        d->Foo();
    }
    catch (...)
    {
        cout << '!' << endl;
    }
    return 0;
}

最佳答案

要记住的是,C 运行时库的每个拷贝都有自己的状态。如果 SomeSpecificModule.dll 静态链接到 C 运行时库,则可能会发生此类问题。如果是这种情况,请尝试链接 C 运行时库的 DLL 版本。您还必须确保 SomeSpecificModule.dll 的编译和链接方式与您的主模块完全相同。

您提到 DLL 被卸载并调用了正确的析构函数,听起来您的真实程序比您发布的示例要多得多。如果您在 try block 中卸载了 SomeSpecificModule.dll,那么您已经卸载了 SomeSpecificModule::Foo() 的异常记录,我想这就是您在 msvcr90d.dll!__DestructExceptionObject(EHExceptionRecord * .. .

但是,一般来说,跨 DLL 边界抛出异常是自找麻烦。如果您抛出非 POD 对象,您可能会遇到由不同堆、不同编译器设置、STL 版本中的不同 C 运行时库分配的内存问题……您明白了。

更改您的代码,以免超出 DLL 边界。有一天,您团队中的某个人更改了编译器设置或更改了第三方 header #define,您的程序开始崩溃,您将很难追查根本原因。

无论如何,在没有看到真正的代码的情况下,我只是想猜测可能出了什么问题。希望对您有所帮助。

关于c++ - 捕获dll异常后访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/967982/

相关文章:

c++ - Emscripten + Visual Studio + 静态库

c++ - 在应用程序运行时禁用 WER

multithreading - java.lang.IllegalStateException : Not on FX application thread Calling Function

windows - Windows 中供应商的 OpenGL 驱动程序在哪里?

windows - 如何从调用导入地址表中找出函数名?

c++ - 如何使用 Cmake 编译 Zlib 源代码

c++ - 仅在具有零参数模板的头文件中定义 C++ 全局函数?

ios - 如何在 Swift 中获取堆栈跟踪错误?

c++ - 自定义异常并不总是执行 what()

.net - 程序集加载版本不匹配 : Why is it loading?