首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕获dll异常后发生访问冲突

捕获dll异常后发生访问冲突
EN

Stack Overflow用户
提问于 2009-06-09 03:19:58
回答 7查看 8.8K关注 0票数 3

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

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

如果我启用了对异常进行中断,则对第二个异常进行中断会将位置显示为

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

但是看起来帧堆栈可能已经损坏了。我搞不懂为什么会抛出这个异常。

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

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

代码语言:javascript
复制
//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;
}
EN

回答 7

Stack Overflow用户

发布于 2009-06-09 05:25:49

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

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

然而,一般来说,跨DLL边界抛出异常是自找麻烦。如果你抛出非POD对象,你可能会遇到由不同堆中的不同C运行时库分配的内存问题,不同的编译器设置,STL version...you得到了重点。

更改您的代码,这样您就不会抛出DLL边界。有一天,你的团队中有人改变了编译器的设置,或者第三方的头文件#define改变了,你的程序开始崩溃,你将很难找到根本原因。

无论如何,在没有看到真正的代码的情况下,我只是在尝试猜测可能会出错的地方。希望能有所帮助。

票数 4
EN

Stack Overflow用户

发布于 2009-06-09 16:39:28

当DLL引发异常时,需要调用的堆栈展开代码的大部分都在DLL中。如果卸载DLL,如何调用该代码?

不要在动态链接的模块边界上抛出异常。

票数 3
EN

Stack Overflow用户

发布于 2009-06-09 03:38:16

您是否在实际代码中通过值调用异常?在这种情况下,在catch块末尾复制的异常对象的析构函数中可能存在异常。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/967982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档