如何构建一个捕获所有异常的C ++ Dll包装器? [英] How to build a C++ Dll wrapper that catches all exceptions?

查看:119
本文介绍了如何构建一个捕获所有异常的C ++ Dll包装器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如标题所示,我们正在寻找一种从一块C ++代码中捕获所有异常的方法,并将其包装在一个dll中。这样我们可以屏蔽使用这个DLL的应用程序,从这个DLL中发生的任何错误。



但是,这在Windows下似乎不可能使用C ++。



示例:

  void function()
{
try
{
std :: list< int> :: iterator fd_it;
fd_it ++;
} catch(...){}
}

发生不被标准C ++ try / catch块捕获,也没有被 _set_se_translator()设置的任何SEH翻译器函数捕获。相反,DLL崩溃,使用该DLL的程序中止。我们用Visual C ++ 2005编译,选项/ SHa。有没有人知道C ++ / Win32中是否可能捕获这些问题,并制作一个rocksolid DLL包装器?

解决方案

做一个坚如磐石的DLL封装的方法是在另一个进程中加载​​buggy DLL,所以如果它崩溃了,它不会使你的主进程失败。



捕捉所有C ++异常似乎是合理的,但捕获所有结构化异常是另一个故事。 SEH可能似乎可以让你得到最多的方式,因为它可以让你捕获访问冲突,除以零异常等。



但是,如果错误的DLL碰巧从另一个线程的堆栈触摸未提交的页面怎么办?内存访问将页面错误,将调用异常处理程序,现在该页面不再是保护页面。当该线程需要增加堆栈时,它将获得访问冲突,并且进程将崩溃。 (这些 帖子更详细地描述了这种情况。)



另一个可能的问题是:持有同步对象时,错误的DLL崩溃,但是您使用SEH来捕获异常。如果您的进程尝试获取同一个同步对象,那么它会死锁而不是崩溃。共享同步对象可能是C运行时或操作系统的一部分:如果错误的DLL 1加载了错误的DLL 2,在其$ DllMain()中崩溃,而错误的DLL 1是拿着装载机锁?你的进程会在下次加载DLL时死机吗?



有关为什么这样(和函数像code> IsBadReadPtr(),具有类似的问题)是SEH的滥用:




Like the title says, we’re looking for a way to catch all exceptions from a piece of C++ code, and wrap this in a dll. This way we can shield of the application that uses this dll, from any errors occurring in this dll.

However, this does not seem possible with C++ under Windows.

Example:

void function()
{  
    try  
    {    
        std::list<int>::iterator fd_it;
        fd_it++;  
    } catch(...) {}
}

The exception that occurs is not caught by the standard C++ try/catch block, nor by any SEH translator function set by _set_se_translator(). Instead, the DLL crashes, and the program that uses the DLL is aborted. We compiled with Visual C++ 2005, with the option /SHa. Does anyone know if it’s possible in C++/Win32 to catch these kind of problems and make a rocksolid DLL wrapper?

解决方案

The only way to make a rock solid DLL wrapper is to load the buggy DLL in another process, so that if it crashes it doesn't take your primary process down with it.

Catching all C++ exceptions seems reasonable, but catching all structured exceptions is another story. SEH might seem to get you most of the way there, because it allows you to catch access violations, divide-by-zero exceptions, etc.

But what if the buggy DLL happens to touch an uncommitted page from another thread's stack? The memory access will page fault, the exception handler will be invoked, and now that page is no longer a guard page. When that thread needs to grow the stack, it will get an access violation, and the process will crash. (These posts describe this case in more detail.)

Another likely problem: the buggy DLL crashes while holding a synchronization object, but you use SEH to catch the exception. If your process attempts to acquire the same synchronization object, then it deadlocks instead of crashing. The shared synchronization object may be part of the C runtime or the OS: what if buggy DLL 1 loads buggy DLL 2, which crashes in its DllMain() while buggy DLL 1 is holding the loader lock? Will your process deadlock the next time it loads a DLL?

For more information on why this (and functions like IsBadReadPtr(), which have similar problems) is a misuse of SEH:

这篇关于如何构建一个捕获所有异常的C ++ Dll包装器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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