5

我目前正在尝试用 C++ 创建一个编译器,它在运行时生成机器代码。但是,我目前正在尝试启用安全异常处理(使用 /SAFESEH 编译)。我的自定义异常处理程序在调试模式下工作,但是当我在发布模式下运行相同的代码时,我的进程刚刚终止。

我很确定问题是我无法注册我的自定义异常处理程序,因为当我使用 /SAFESEH:NO 编译我的代码时,即使在发布模式下也一切正常。

我的自定义异常处理程序是用我的其他 C++ 代码编写的,我尝试通过将 .asm 文件添加到我的项目中,将其注册为异常处理程序,其内容如下:

.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end

如此处所述。然后使用 /safeseh 选项(以及其他选项)组装 asm 文件。

我的处理函数目前有以下声明:

extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct 
_CONTEXT *ContextRecord, void * DispatcherContext);

将此函数注册为异常处理程序的正确方法是什么?

感谢您的任何建议!

4

3 回答 3

4

我终于找到了一个描述问题的页面:here。但是,页面中的代码示例未经修改就无法工作。

问题似乎是将外部过程注册为异常处理程序无法按预期工作,因此您必须将本地程序集过程注册为异常处理程序。

根据前面提到的页面上给出的示例,这就是我最终得到的:

.386
.model flat, stdcall
option casemap :none

extern MyExceptionHandler@16:near

MyExceptionHandlerAsm proto
.SAFESEH MyExceptionHandlerAsm

.code
MyExceptionHandlerAsm proc
    jmp MyExceptionHandler@16
MyExceptionHandlerAsm endp
end

这似乎可行,但它很可能不是最优雅的解决方案。例如:为了避免从 C/C++ 引用 MyExceptionHandlerAsm 时出现链接错误,我必须将其声明为:

extern "C" int __stdcall MyExceptionHandlerAsm();

如果有人试图从 C/C++ 调用 MyExceptionHandlerAsm,这会崩溃,因为参数的数量与 MyExceptionHandler 的数量不匹配。

于 2012-08-19T10:24:37.613 回答
1

MSDN文档看来,您的 ASM 是正确的。您是否添加了/safeseh选项ml.exe

于 2012-08-18T19:56:18.580 回答
0

ExceptionHandler函数的签名其实是:

typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
    __in struct _EXCEPTION_RECORD *ExceptionRecord,
    __in PVOID EstablisherFrame,
    __inout struct _CONTEXT *ContextRecord,
    __inout PVOID DispatcherContext
    );

请参阅此 MSDN 页面。相同的异常例程用于 32 位窗口,因此请忽略文档提到 x64 的事实。

于 2012-08-20T02:50:26.253 回答