首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >进程外调用时MiniDumpWriteDump中的访问冲突

进程外调用时MiniDumpWriteDump中的访问冲突
EN

Stack Overflow用户
提问于 2015-09-21 09:39:34
回答 2查看 975关注 0票数 1

MiniDumpWriteDump函数的文档化

如果可能的话,应该从单独的进程中调用MiniDumpWriteDump,而不是从正在转储的目标进程中调用。

所以我编写了一个小的MFC崩溃处理程序就是这样做的。我遵循Hans在这就是答案中的建议,即将异常指针的值从崩溃程序传递给崩溃处理程序,即使异常指针在崩溃处理程序的上下文中无效。当我在调试版本中运行测试时,这很好,但是当我切换到发布版本时,崩溃处理程序就会崩溃,MiniDumpWriteDump函数内部会发生访问冲突。

我很困惑。为什么在调试版本中应该这样做,而在发布版本中却不能这样做呢?这令人恼火,因为访问冲突通常是访问无效指针的指示符,而我在崩溃处理程序中接收到的异常指针确实是无效的--但另一方面,我被告知,这不重要,因为MiniDumpWriteDump是在崩溃过程的上下文中解释指针的(从指针的起源地)。

知道我可能做错了什么吗?

在一个侧面:在他的回答中,汉斯提出了一个解决方案,其中的看门狗进程是预先启动,然后进入睡眠和醒来时,它被触发的过程。我的解决方案略有不同:我只是在崩溃发生时启动崩溃处理程序,然后通过命令行参数将必要的信息从崩溃程序传递给崩溃处理程序。我反复检查正在传递的信息是否正确,特别是异常指针.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-24 15:09:42

我改变了我的方法,这样最终的解决方案看起来就像汉斯·帕桑( Hans )建议的那样:看门狗进程是预先启动的,然后进入睡眠状态,当它被崩溃过程触发时醒来。崩溃过程对EXCEPTION_POINTERS结构进行深度复制,并将该信息传递给看门狗进程。

这是做深拷贝的代码。正如问题的注释中提到的,主要的“问题”是EXCEPTION_RECORD,它是一个潜在无限大小的链接列表。

代码语言:javascript
复制
// The maximum number of nested exception that we can handle. The value we
// use for this constant is an arbitrarily chosen number that is, hopefully,
// sufficiently high to support all realistic and surrealistic scenarios.
//
// sizeof(CrashInfo) for a maximum of 1000 = ca. 80 KB
const int MaximumNumberOfNestedExceptions = 1000;


// Structure with information about the crash that we can pass to the
// watchdog process
struct CrashInfo
{
    EXCEPTION_POINTERS exceptionPointers;
    int numberOfExceptionRecords;
    // Contiguous area of memory that can easily be processed by memcpy
    EXCEPTION_RECORD exceptionRecords[MaximumNumberOfNestedExceptions];
    CONTEXT contextRecord;
};


// The EXCEPTION_POINTERS parameter is the original exception pointer
// that we are going to deep-copy.
// The CrashInfo parameter receives the copy.
void FillCrashInfoWithExceptionPointers(CrashInfo& crashInfo, EXCEPTION_POINTERS* exceptionPointers)
{
    // De-referencing creates a copy
    crashInfo.exceptionPointers = *exceptionPointers;
    crashInfo.contextRecord = *(exceptionPointers->ContextRecord);

    int indexOfExceptionRecord = 0;
    crashInfo.numberOfExceptionRecords = 0;
    EXCEPTION_RECORD* exceptionRecord = exceptionPointers->ExceptionRecord;

    while (exceptionRecord != 0)
    {
        if (indexOfExceptionRecord >= MaximumNumberOfNestedExceptions)
        {
            // Yikes, maximum number of nested exceptions reached
            break;
        }

        // De-referencing creates a copy
        crashInfo.exceptionRecords[indexOfExceptionRecord] = *exceptionRecord;

        ++indexOfExceptionRecord;
        ++crashInfo.numberOfExceptionRecords;
        exceptionRecord = exceptionRecord->ExceptionRecord;
    }
}

当我们在看门狗进程中接收到CrashInfo结构时,我们现在遇到了一个问题:EXCEPTION_RECORD引用指向无效的内存地址,即仅在崩溃过程中有效的内存地址。下面的函数(必须在监视狗进程中运行)修复了这些引用。

代码语言:javascript
复制
// The CrashInfo parameter is both in/out
void FixExceptionPointersInCrashInfo(CrashInfo& crashInfo)
{
    crashInfo.exceptionPointers.ContextRecord = &(crashInfo.contextRecord);

    for (int indexOfExceptionRecord = 0; indexOfExceptionRecord < crashInfo.numberOfExceptionRecords; ++indexOfExceptionRecord)
    {
        if (0 == indexOfExceptionRecord)
            crashInfo.exceptionPointers.ExceptionRecord = &(crashInfo.exceptionRecords[indexOfExceptionRecord]);
        else
            crashInfo.exceptionRecords[indexOfExceptionRecord - 1].ExceptionRecord = &(crashInfo.exceptionRecords[indexOfExceptionRecord]);
    }
}

我们现在可以将&(crashInfo.exceptionPointers)传递给MiniDumpWriteDump函数了。

注意:显然这不是一个完整的解决方案。您可能希望将更多的信息从崩溃过程传递给看门狗进程。CrashInfo结构是保存此信息的候选结构。此外,这里没有显示进程如何相互通信的方式。在我的例子中,我使用Hans提出的解决方案,该解决方案在问题的开头链接:使用事件进行同步(CreateEvent + SetEvent)和使用内存映射文件(CreateFileMapping + MapViewOfFile)将信息从一个进程洗牌到下一个进程。事件和内存映射文件的(唯一)名称由主进程确定,并通过命令行参数传递给看门狗进程。

票数 0
EN

Stack Overflow用户

发布于 2016-09-22 21:34:24

我与一个类似的问题斗争,现在终于发现了什么是错误的。

信息的MSDN文档指出,如果ClientPointers地址来自目标进程而不是本地进程,则ExceptionPointers字段必须是TRUE

在正确设置这个字段之后,我可以简单地从崩溃过程中传递ThreadIdExceptionPointers,并将它们填充到转储写入过程中的MINIDUMP_EXCEPTION_INFORMATION中,并且它工作得非常完美。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32691914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档