什么时候使用MiniTumpWriteDomainp设置\u使用\u转换器无法写入转储? 我们在Windows上的32位C++可执行文件中有一个罕见的崩溃,它不会产生内存转储。我们没有重新编程的案例,当崩溃发生时,游戏几秒钟后就消失了,所以我们需要内存转储来找到原因。其他崩溃确实会产生内存转储,所以我们知道我们的内存转储功能有时会工作,只是在这个特定的崩溃上不起作用
在什么情况下,什么时候使用MiniTumpWriteDomainp设置\u使用\u转换器无法写入转储? 我们在Windows上的32位C++可执行文件中有一个罕见的崩溃,它不会产生内存转储。我们没有重新编程的案例,当崩溃发生时,游戏几秒钟后就消失了,所以我们需要内存转储来找到原因。其他崩溃确实会产生内存转储,所以我们知道我们的内存转储功能有时会工作,只是在这个特定的崩溃上不起作用,c++,crash-dumps,C++,Crash Dumps,在什么情况下,\u set\u se\u translator和MiniDumpWriteDump的组合不能产生内存转储?我们是否在内存转储处理中出错,导致它有时无法生成转储 以下是我们目前的工作: 在主线程中主函数的开始处,我们调用SetUnhandledExceptionFilter(CrashDumpManager::unhandledExceptionHandler) 在每个线程中,我们调用\u set\u se\u translator(CrashDumpManager::MiniDu
\u set\u se\u translator
和MiniDumpWriteDump
的组合不能产生内存转储?我们是否在内存转储处理中出错,导致它有时无法生成转储
以下是我们目前的工作:
在主线程中主函数的开始处,我们调用SetUnhandledExceptionFilter(CrashDumpManager::unhandledExceptionHandler)代码>
在每个线程中,我们调用\u set\u se\u translator(CrashDumpManager::MiniDumpFunction)代码>
这就是CrashDumpManager.h的外观:
#include <Windows.h>
#include <Dbghelp.h>
class CrashDumpManager
{
public:
static void MiniDumpFunction(unsigned int nExceptionCode, EXCEPTION_POINTERS *pException);
static LONG CALLBACK unhandledExceptionHandler(EXCEPTION_POINTERS* e);
//If the game crashes because of a memory leak then there won't be enough memory free to generate a memory dump
//Therefore 10MB is allocated here and deleted before the crashdump is written.
static unsigned char* crashdumpMemory;
};
#include "CrashDumpManager.h"
void CrashDumpManager::MiniDumpFunction(unsigned int nExceptionCode, EXCEPTION_POINTERS *pException)
{
delete crashdumpMemory;
crashdumpMemory = nullptr;
// prevent stack overflow when crashing in this function
static bool calledFunctionOnce = false;
if (!calledFunctionOnce)
{
calledFunctionOnce = true;
HMODULE dbgHelpModule = LoadLibraryA("dbghelp");
if (dbgHelpModule == nullptr)
return;
auto writeMiniDumpFunction = (decltype(&MiniDumpWriteDump))GetProcAddress(dbgHelpModule, "MiniDumpWriteDump");
if (writeMiniDumpFunction == nullptr)
return;
char name[MAX_PATH];
{
char* nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
SYSTEMTIME t;
GetSystemTime(&t);
wsprintfA(nameEnd - strlen(".exe"), "_%4d%02d%02d_%02d%02d%02d.mdmp",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
}
HANDLE dumpFileHandle = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (dumpFileHandle == INVALID_HANDLE_VALUE)
return;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = pException;
exceptionInfo.ClientPointers = FALSE;
auto dumped = writeMiniDumpFunction(GetCurrentProcess(), GetCurrentProcessId(), dumpFileHandle,
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
pException ? &exceptionInfo : nullptr, nullptr, nullptr);
CloseHandle(dumpFileHandle);
}
}
LONG CALLBACK CrashDumpManager::unhandledExceptionHandler(EXCEPTION_POINTERS* e)
{
CrashDumpManager::MiniDumpFunction(0, e);
return EXCEPTION_CONTINUE_SEARCH;
}
unsigned char* CrashDumpManager::crashdumpMemory = new unsigned char[10*1024*1024];
这很正常,您希望像MiniDumpWriteDump()这样相当复杂的函数仍能在损坏的进程中正确运行。唯一真正安全的方法是使用单独的进程外监视程序进程。值得一提的一个极端情况是,您必须小心存储该文件的位置。正如发布的那样,在正确安装的程序上,它注定会失败。无法对c:\program文件进行写访问。请尝试以下几点:1)不要使用动态内存分配(如果使用,请记住对数组使用delete[]
)-堆可能会混乱。2) 确保只有一个线程可以在MiniDumpFunction
(使用适当的同步原语)3)确保所有线程调用\u set\u se\u translator
(是否检查了创建线程的库?)禁用您自己的崩溃转储机制,并将系统设置为为所有崩溃创建完全内存转储忘记添加2):到达MiniDumpFunction
的其他线程如果不是第一个到达那里,则应该挂起-绝对不是异常\u CONTINUE\u SEARCH
。并且写入微型转储的线程应该在之后尽快退出应用程序。