我想做一个进程外异常处理程序,我已经创建了一个看门狗进程,当子进程引发异常时,它会进行专门的异常处理。我已经成功地通过事件调用了watchdog进程。我面临的问题是试图将异常信息指针传递给其他进程。
我在这里登陆了Passing a pointer to process spawned with exec(),并开始知道在共享内存中传递指针有这个问题:
“如果您使用共享内存,您不能传递指针。指针将包含虚拟地址,不同进程的虚拟地址不同。您必须根据共享内存区的开始交换偏移值。
如果您不使用共享内存,则无法交换任何类型的指针:其他进程将无法访问您的进程的内存。“
现在我该如何克服这个问题呢?
流程1:
struct mytest
{
_EXCEPTION_POINTERS * except ;
DWORD ThreadId ;
DWORD ProcessId ;
}
OpenFileMapping ( ) ;
void * pBuf = MapViewOfFile ( ) ;
mytest passdata ;
CopyMemory ( pBuf , &passdata , sizeof ( passdata ) ) ;
UnMapView ( ) ;
CloseHandle ( ) ;(对于ex)进程2:
cout << passdata->except->ExceptionRecord->ExceptionCode << endl ;会崩溃。我理解这是因为虚拟地址是进程特定的。但是在这种情况下,如何将异常信息传递给不同的进程并编写一个小型转储??
附言:我甚至尝试过单独传递PEXCEPTION_RECORD结构,但不起作用。
发布于 2013-04-22 22:24:16
对,你不能在另一个进程中取消引用指针,它只在崩溃的进程中有效。它只能传递给MINIDUMP_EXCEPTION_INFORMATION.ExceptionPointers字段的MiniDumpWriteDump()。从技术上讲,您可以使用ReadProcessMemory(),但是对崩溃的进程这样做是不必要的。简单的解决方案是在您的结构中添加一个额外的字段,用于存储异常代码并由您的异常过滤器编写。
mytest passdata ;
passdata.except = ExceptionInfo;
// Note: added field
passdata.ExceptionCode = ExceptionInfo->ExceptionRecord->ExceptionCode;
passdata.ThreadId = GetCurrentThreadId();
// etc..也要避免调用像OpenFileMapping和MapViewOfFile这样的winapi函数,这太冒险了。当程序由于进程堆的堆损坏而崩溃时,它们往往会死锁。崩溃和死锁的常见原因,因为堆锁仍然被持有。只需在程序初始化时执行此操作。你也不需要费心清理,当你的看门狗进程在接受小型转储后终止崩溃的进程时,Windows会处理它。
发布于 2013-04-23 20:02:13
我会把这些放在一起作为回答,虽然这真的应该是对Hans's answer的评论(以及那里的评论),但似乎有必要做一些解释:
问题中发布的代码正确地将struct mytest结构的值传递到共享内存中。
第二个代码片段:
(用于ex)进程2:
cout passdata->except->ExceptionRecord->ExceptionCode << << endl;
但是显示了一个误解:虽然您可以读取指针passdata.except的值,但在进程2中,这只是一个任意的32/64位值,它不是一个有效的指针。
你可以通过把它传递给MiniDumpWriteDump,这个函数将在目标进程的上下文中计算这个指针值(Proc1)。但是你不能在进程#2中引用它。
汉斯的例子给出了解决方案,如果你在2号进程中需要ExeptionCode的值,那么你需要在proc#1中取消对指针的引用,并将该值放入你写入共享内存的数据中。
https://stackoverflow.com/questions/16147753
复制相似问题