DbgHelp教程4——Minidump自定义信息
发布于 2016-05-14
MiniDumpWriteDump的MINIDUMP_TYPE可以控制往dump里面写入什么信息。不过MINIDUMP_TYPE只是一些固定的类型信息,比如内存、句柄、进程、线程信息,有时候为了定位问题,我们想收集一些其他的数据,然后写入到dump里面。恰好PMINIDUMP_USER_STREAM_INFORMATION参数可以做这个事情。
long WINAPI WriteDump(EXCEPTION_POINTERS *info) {
HANDLE hDumpFile =
CreateFile(L"mini.dmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile != INVALID_HANDLE_VALUE) {
int minidump_type =
MiniDumpNormal | MiniDumpWithDataSegs | MiniDumpWithHandleData;
MINIDUMP_EXCEPTION_INFORMATION dump_exception_info;
dump_exception_info.ExceptionPointers = info;
dump_exception_info.ThreadId = GetCurrentThreadId();
dump_exception_info.ClientPointers = TRUE;
MINIDUMP_USER_STREAM_INFORMATION user_stream_infomation;
const ULONG array_size = 10;
user_stream_infomation.UserStreamCount = array_size;
user_stream_infomation.UserStreamArray =
new MINIDUMP_USER_STREAM[array_size];
for (int i = 0; i < array_size; i++) {
std::string s("test mimidump user stream infomation");
char* buffer = new char[s.size() +1];
memset(buffer, 0 , s.size() + 1);
memcpy(buffer, s.c_str(), s.size() + 1);
user_stream_infomation.UserStreamArray[i].Type = 0xfffff+i;
user_stream_infomation.UserStreamArray[i].BufferSize = s.size() + 1;
user_stream_infomation.UserStreamArray[i].Buffer = buffer;
}
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile,
static_cast<MINIDUMP_TYPE>(minidump_type),
&dump_exception_info, &user_stream_infomation, NULL);
}
return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR *argv[]) {
SetUnhandledExceptionFilter(WriteDump);
DbgHelpWrapper* p = nullptr;
p->EnumAllLines();
return 0;
}
MINIDUMP_USER_STREAM的Type值必须大于MINIDUMP_STREAM_TYPE::LastReservedStream,因为之前这些值都是保留的标准类型。
可惜的是Windbg不能直接读取MINIDUMP_USER_STREAM_INFORMATION的信息,我们只好通过MiniDumpReadDumpStream接口去读取dump里面的数据。
void ReadDump() {
HANDLE hFile = CreateFile(L"mini.dmp", GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if ((NULL == hFile) || (INVALID_HANDLE_VALUE == hFile))
return;
HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (NULL == hMapFile)
return;
PVOID pViewOfFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
if (NULL == pViewOfFile)
return;
PMINIDUMP_DIRECTORY minidump_directory = NULL;
PVOID stream_pointer = NULL;
ULONG stream_size = 0;
if (!MiniDumpReadDumpStream(pViewOfFile, 0xfffff+1, &minidump_directory,
&stream_pointer, &stream_size))
return;
std::string s((char*)stream_pointer);
cout << s << endl;
}
根据MINIDUMP_STREAM_TYPE的描述,我们还可以从dump文件里面读取一些预置的信息,比如线程列表、模块列表、内存列表、异常信息、系统信息、句柄信息、函数表信息、等等。