From a509f4ec4b404f3eb8edb8640f5a94fe9def89fe Mon Sep 17 00:00:00 2001 From: mmentovai Date: Tue, 16 Sep 2008 18:50:02 +0000 Subject: [PATCH] Generate Windows full memory dumps as a separate file. Patch by Huan Ren . r=me git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@285 4c0a9323-5329-0410-9bdc-e9ce6186880e --- .../crash_generation/minidump_generator.cc | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/client/windows/crash_generation/minidump_generator.cc b/src/client/windows/crash_generation/minidump_generator.cc index 72736ffa..cb5e52a2 100644 --- a/src/client/windows/crash_generation/minidump_generator.cc +++ b/src/client/windows/crash_generation/minidump_generator.cc @@ -78,6 +78,17 @@ bool MinidumpGenerator::WriteMinidump(HANDLE process_handle, return false; } + // If the client requests a full memory dump, we will write a normal mini + // dump and a full memory dump. Both dump files use the same uuid as file + // name prefix. + bool full_memory_dump = dump_type & MiniDumpWithFullMemory; + wstring full_dump_file_path; + if (full_memory_dump) { + full_dump_file_path.assign(dump_file_path); + full_dump_file_path.resize(full_dump_file_path.size() - 4); // strip .dmp + full_dump_file_path.append(TEXT("-full.dmp")); + } + HANDLE dump_file = CreateFile(dump_file_path.c_str(), GENERIC_WRITE, 0, @@ -90,6 +101,22 @@ bool MinidumpGenerator::WriteMinidump(HANDLE process_handle, return false; } + HANDLE full_dump_file = INVALID_HANDLE_VALUE; + if (full_memory_dump) { + full_dump_file = CreateFile(full_dump_file_path.c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (full_dump_file == INVALID_HANDLE_VALUE) { + CloseHandle(dump_file); + return false; + } + } + MINIDUMP_EXCEPTION_INFORMATION* dump_exception_pointers = NULL; MINIDUMP_EXCEPTION_INFORMATION dump_exception_info; @@ -142,11 +169,15 @@ bool MinidumpGenerator::WriteMinidump(HANDLE process_handle, sizeof(client_assert_info), &bytes_read)) { CloseHandle(dump_file); + if (full_dump_file != INVALID_HANDLE_VALUE) + CloseHandle(full_dump_file); return false; } if (bytes_read != sizeof(client_assert_info)) { CloseHandle(dump_file); + if (full_dump_file != INVALID_HANDLE_VALUE) + CloseHandle(full_dump_file); return false; } @@ -159,15 +190,33 @@ bool MinidumpGenerator::WriteMinidump(HANDLE process_handle, ++user_streams.UserStreamCount; } - bool result = write_dump(process_handle, - process_id, - dump_file, - dump_type, - exception_pointers ? &dump_exception_info : NULL, - &user_streams, - NULL) != FALSE; + bool result_minidump = write_dump( + process_handle, + process_id, + dump_file, + static_cast((dump_type & (~MiniDumpWithFullMemory)) + | MiniDumpNormal), + exception_pointers ? &dump_exception_info : NULL, + &user_streams, + NULL) != FALSE; + + bool result_full_memory = true; + if (full_memory_dump) { + result_full_memory = write_dump( + process_handle, + process_id, + full_dump_file, + static_cast(dump_type & (~MiniDumpNormal)), + exception_pointers ? &dump_exception_info : NULL, + &user_streams, + NULL) != FALSE; + } + + bool result = result_minidump && result_full_memory; CloseHandle(dump_file); + if (full_dump_file != INVALID_HANDLE_VALUE) + CloseHandle(full_dump_file); // Store the path of the dump file in the out parameter if dump generation // succeeded.