捕获dll异常后访问冲突 [英] Access violation after catching dll exception

查看:40
本文介绍了捕获dll异常后访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to load modules as dlls dynamically at runtime as they are not known ahead of time, just that they conform to a class interface. What I noticed is that after I catch an exception thrown by the dll (in the main program in the main thread), the right destructors are called and the modules destroyed and dll's unloaded, but then as the } at the end of the catch block is reached by the Visual Studio C++ debugger when stepping line by line, I get another exception which crashes the program with

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

First-chance exception at 0x68ad2377 (msvcr90d.dll) in xxxxx.exe: 0xC0000005: Access violation reading location 0x02958f14.

如果我启用打破异常,打破第二个异常显示位置

If I enable breaking on exceptions, breaking on this second exception shows the location as

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

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

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

but it looks like the frame stack may be corrupt. I can't figure out why this exception is thrown.

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

A simplified version of my code structure is as follows:

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

A very simplified structure of the program:

//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 的编译和链接方式与您的主模块完全相同.

The thing to remember is that each copy of C runtime library has its own states. If SomeSpecificModule.dll is linking statically to the C runtime library, this kind of problem may happen. If that's the case, try linking with DLL version of of C runtime library. You also have to make sure SomeSpecificModule.dll is compiled and linked exactly the same way as your main module.

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

You mentioned DLL being unloaded and correct destructors were called, it sounded like your real program has a lot more going on than the sample you posted. If you unloaded SomeSpecificModule.dll in your try block, you've unloaded the exception record for SomeSpecificModule::Foo(), and I guess that's how you got the crash at msvcr90d.dll!__DestructExceptionObject(EHExceptionRecord * ...

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

However, in general throwing exception across DLL boundaries is asking for trouble. If you're throwing non POD object, you may run into issue with memory allocated by different C runtime library in different heap, different compiler setting, STL version...you get the point.

改变你的代码,这样你就不会跨越 DLL 边界.有一天,您团队中的某个人更改了编译器设置或第三方标头 #define 更改,并且您的程序开始崩溃,您将很难找到根本原因.

Change you code so you don't throw across DLL boundaries. One day someone from your team change the compiler setting or a third party header #define changed and your program start crashing you're going to have a very hard time tracing down the root cause.

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

Anyway, without seeing the real code, I'm just trying to guess what might go wrong. Hope it helps.

这篇关于捕获dll异常后访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆