2013-04-22 68 views
2

我想做一个进程外的异常处理程序,我创建了一个看门狗进程,它在子进程引发异常时执行专门的异常处理。我通过事件成功地调用了看门狗进程。我面临的问题是在尝试将异常信息指针传递给其他进程时。麻烦通过_EXCEPTION_POINTERS *使用FileMapping

我在这里登陆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 () ; 

(对于离)方法2:

cout << passdata->except->ExceptionRecord->ExceptionCode << endl ; 

会崩溃。我明白这是因为虚拟地址是特定于进程的。但在这种情况下如何将异常信息传递给不同的进程并写入一个小型转储器?

P.S:我甚至尝试过单独传递PEXCEPTION_RECORD结构,但不起作用。

回答

1

对,你不能取消引用另一个进程中的指针,它只在崩溃的进程中有效。它只传递给MiniDumpWriteDump(),MINIDUMP_EXCEPTION_INFORMATION.ExceptionPointers字段。从技术上讲,你可以使用ReadProcessMemory(),但这样做对于崩溃的进程是不必要的风险。简单的解决方案是在存储异常代码并由异常过滤器编写的结构中添加一个额外的字段。

mytest passdata ; 
passdata.except = ExceptionInfo; 
// Note: added field 
passdata.ExceptionCode = ExceptionInfo->ExceptionRecord->ExceptionCode; 
passdata.ThreadId = GetCurrentThreadId(); 
// etc.. 

而且避免调用WINAPI功能,如OpenFileMapping和MapViewOfFile,实在是太冒险了。当程序因进程堆堆损坏而崩溃时,它们往往会陷入僵局。崩溃和死锁的常见原因是因为堆锁仍然存在。只需在程序初始化时执行此操作您不需要麻烦清理任何事情,当您的看门狗进程在采取小型转储后终止崩溃的进程时,Windows会照顾它。

+0

Thans @Hans Passant!我只有一个澄清。你有没有尝试传递MINIDUMP_EXCEPTION_INFORMATION.ExceptionPointers字段。它会在子进程中可读吗? – 2013-04-22 14:45:32

+0

是的,这就是为什么该领域在那里。不,它在“客户端进程”中不可读。或者我解释过的监督程序。它由MiniDumpWriteDump使用并记录在小型转储文件中。因此,当您在调试器中打开小型转储程序时,它可以向您显示发生异常的位置。调试器在使用指针时没有问题,因为它正在调试拥有指针的进程。 – 2013-04-22 14:50:33

+0

然后,如何以及如何在看门狗中调用MiniDumpWriteDump所需的步骤? – 2013-04-22 14:56:48

3

我会把这个一起作为一个答案,但它确实应该是Hans's answer(有评论)评论,但似乎一些解释是必要的:

张贴在讨论的代码正确地传递值(s)的struct mytest结构分成共享内存。

第二代码片断:

(对于离)方法2:

cout << passdata->except->ExceptionRecord->ExceptionCode << endl ; 

示出了误解虽然:虽然可以读取指针passdata.except的值,在处理2中这只是一个任意的32/64位值,它不是一个有效的指针。

可以传递给MiniDumpWriteDump,这个函数将在目标进程(proc1)的上下文中平衡这个指针值。但是你在不能在进程#2中对其进行解引用。

Hans的例子给出了解决方案,如果在进程#2中需要ExeptionCode的值,则需要对proc#1中的指针取消引用,并将该值写入您写入共享内存的数据中。

+0

很酷,谢谢@马丁巴。将按照您的指导继续操作。 – 2013-04-23 15:16:53

+0

终于完成了它。如果未来有人遇到无法写入MiniDump的问题请检查您的进程安全访问权限。 – 2013-04-25 04:41:48