我目前正在尝试用C ++创建一个编译器,它在运行时生成机器代码。但是,我目前正在尝试启用安全异常处理(使用/ SAFESEH进行编译)。我的自定义异常处理程序在调试模式下工作,但是当我在发布模式下运行相同的代码时,我的进程才被终止。
我很确定问题是我无法注册我的自定义异常处理程序,因为当我使用/ SAFESEH编译我的代码时:NO,即使在发布模式下一切正常。
我的自定义异常处理程序是用我的其他C ++代码编写的,我试图通过将.asm文件添加到包含内容的项目中来将其注册为异常处理程序:
.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end
如here所述。然后使用/ safeseh选项(以及其他)组装asm文件。
我的处理函数目前有以下声明:
extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct
_CONTEXT *ContextRecord, void * DispatcherContext);
将此函数注册为异常处理程序的正确方法是什么?
感谢您的任何建议!
答案 0 :(得分: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的参数数量不匹配。
答案 1 :(得分:1)
从MSDN文档看起来您的ASM是正确的。您是否已将/safeseh
选项添加到ml.exe
?
答案 2 :(得分:0)
ExceptionHandler函数的签名实际上是:
typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
__in struct _EXCEPTION_RECORD *ExceptionRecord,
__in PVOID EstablisherFrame,
__inout struct _CONTEXT *ContextRecord,
__inout PVOID DispatcherContext
);
见this MSDN page。 32位窗口使用相同的异常例程,因此请忽略doc提及x64的事实。