https://git.reactos.org/?p=reactos.git;a=commitdiff;h=34d40a5f3d90373e40fb5…
commit 34d40a5f3d90373e40fb5418f99046dce3ff9528
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Fri Sep 11 15:55:33 2020 +0200
Commit: Jérôme Gardou <jerome.gardou(a)reactos.org>
CommitDate: Wed Sep 16 10:35:40 2020 +0200
[WINESYNC] dbghelp: Support full memory dumps.
Add support of flag MinidumpWithFullMemory in function
MinidumpWriteDump. A Memory64ListStream is added to the minidump
streams and all memory regions of the process with MEM_COMMIT state
are written to the last part of the minidump file.
Signed-off-by: Eric Bissonnette <ebisso.dev(a)gmail.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id b90bbcbe750f6af0ce13f2577984f4818e05a013 by Eric Bissonnette
<ebisso.dev(a)gmail.com>
---
dll/win32/dbghelp/dbghelp_private.h | 9 +++
dll/win32/dbghelp/minidump.c | 129 ++++++++++++++++++++++++++++++++++--
sdk/include/psdk/dbghelp.h | 13 ++++
sdk/tools/winesync/dbghelp.cfg | 2 +-
4 files changed, 145 insertions(+), 8 deletions(-)
diff --git a/dll/win32/dbghelp/dbghelp_private.h b/dll/win32/dbghelp/dbghelp_private.h
index 2138bd65154..565399ebcc1 100644
--- a/dll/win32/dbghelp/dbghelp_private.h
+++ b/dll/win32/dbghelp/dbghelp_private.h
@@ -500,6 +500,12 @@ struct dump_memory
ULONG rva;
};
+struct dump_memory64
+{
+ ULONG64 base;
+ ULONG64 size;
+};
+
struct dump_module
{
unsigned is_elf;
@@ -538,6 +544,9 @@ struct dump_context
struct dump_memory* mem;
unsigned num_mem;
unsigned alloc_mem;
+ struct dump_memory64* mem64;
+ unsigned num_mem64;
+ unsigned alloc_mem64;
/* callback information */
MINIDUMP_CALLBACK_INFORMATION* cb;
};
diff --git a/dll/win32/dbghelp/minidump.c b/dll/win32/dbghelp/minidump.c
index f72177e6d2d..4e2c7641c9d 100644
--- a/dll/win32/dbghelp/minidump.c
+++ b/dll/win32/dbghelp/minidump.c
@@ -294,6 +294,49 @@ static BOOL fetch_macho_module_info_cb(const WCHAR* name, unsigned
long base,
return TRUE;
}
+void minidump_add_memory64_block(struct dump_context* dc, ULONG64 base, ULONG64 size)
+{
+ if (!dc->mem64)
+ {
+ dc->alloc_mem64 = 32;
+ dc->mem64 = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem64 *
sizeof(*dc->mem64));
+ }
+ else if (dc->num_mem64 >= dc->alloc_mem64)
+ {
+ dc->alloc_mem64 *= 2;
+ dc->mem64 = HeapReAlloc(GetProcessHeap(), 0, dc->mem64,
+ dc->alloc_mem64 * sizeof(*dc->mem64));
+ }
+ if (dc->mem64)
+ {
+ dc->mem64[dc->num_mem64].base = base;
+ dc->mem64[dc->num_mem64].size = size;
+ dc->num_mem64++;
+ }
+ else dc->num_mem64 = dc->alloc_mem64 = 0;
+}
+
+static void fetch_memory64_info(struct dump_context* dc)
+{
+ ULONG_PTR addr;
+ MEMORY_BASIC_INFORMATION mbi;
+
+ addr = 0;
+ while (VirtualQueryEx(dc->hProcess, (LPCVOID)addr, &mbi, sizeof(mbi)) != 0)
+ {
+ /* Memory regions with state MEM_COMMIT will be added to the dump */
+ if (mbi.State == MEM_COMMIT)
+ {
+ minidump_add_memory64_block(dc, (ULONG_PTR)mbi.BaseAddress, mbi.RegionSize);
+ }
+
+ if ((addr + mbi.RegionSize) < addr)
+ break;
+
+ addr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
+ }
+}
+
static void fetch_modules_info(struct dump_context* dc)
{
EnumerateLoadedModulesW64(dc->hProcess, fetch_pe_module_info_cb, dc);
@@ -853,6 +896,60 @@ static unsigned dump_memory_info(struct dump_context* dc)
return sz;
}
+/******************************************************************
+ * dump_memory64_info
+ *
+ * dumps information about the memory of the process (virtual memory)
+ */
+static unsigned dump_memory64_info(struct dump_context* dc)
+{
+ MINIDUMP_MEMORY64_LIST mdMem64List;
+ MINIDUMP_MEMORY_DESCRIPTOR64 mdMem64;
+ DWORD written;
+ unsigned i, len, sz;
+ RVA rva_base;
+ char tmp[1024];
+ ULONG64 pos;
+ LARGE_INTEGER filepos;
+
+ sz = sizeof(mdMem64List.NumberOfMemoryRanges) +
+ sizeof(mdMem64List.BaseRva) +
+ dc->num_mem64 * sizeof(mdMem64);
+
+ mdMem64List.NumberOfMemoryRanges = dc->num_mem64;
+ mdMem64List.BaseRva = dc->rva + sz;
+
+ append(dc, &mdMem64List.NumberOfMemoryRanges,
+ sizeof(mdMem64List.NumberOfMemoryRanges));
+ append(dc, &mdMem64List.BaseRva,
+ sizeof(mdMem64List.BaseRva));
+
+ rva_base = dc->rva;
+ dc->rva += dc->num_mem64 * sizeof(mdMem64);
+
+ /* dc->rva is not updated past this point. The end of the dump
+ * is just the full memory data. */
+ filepos.QuadPart = dc->rva;
+ for (i = 0; i < dc->num_mem64; i++)
+ {
+ mdMem64.StartOfMemoryRange = dc->mem64[i].base;
+ mdMem64.DataSize = dc->mem64[i].size;
+ SetFilePointerEx(dc->hFile, filepos, NULL, FILE_BEGIN);
+ for (pos = 0; pos < dc->mem64[i].size; pos += sizeof(tmp))
+ {
+ len = min(dc->mem64[i].size - pos, sizeof(tmp));
+ if (ReadProcessMemory(dc->hProcess,
+ (void*)(ULONG_PTR)(dc->mem64[i].base + pos),
+ tmp, len, NULL))
+ WriteFile(dc->hFile, tmp, len, &written, NULL);
+ }
+ filepos.QuadPart += mdMem64.DataSize;
+ writeat(dc, rva_base + i * sizeof(mdMem64), &mdMem64, sizeof(mdMem64));
+ }
+
+ return sz;
+}
+
static unsigned dump_misc_info(struct dump_context* dc)
{
MINIDUMP_MISC_INFO mmi;
@@ -898,6 +995,9 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE
hFile,
dc.mem = NULL;
dc.num_mem = 0;
dc.alloc_mem = 0;
+ dc.mem64 = NULL;
+ dc.num_mem64 = 0;
+ dc.alloc_mem64 = 0;
dc.rva = 0;
if (!fetch_process_info(&dc)) return FALSE;
@@ -912,8 +1012,6 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE
hFile,
if (DumpType & MiniDumpWithDataSegs)
FIXME("NIY MiniDumpWithDataSegs\n");
- if (DumpType & MiniDumpWithFullMemory)
- FIXME("NIY MiniDumpWithFullMemory\n");
if (DumpType & MiniDumpWithHandleData)
FIXME("NIY MiniDumpWithHandleData\n");
if (DumpType & MiniDumpFilterMemory)
@@ -962,11 +1060,15 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE
hFile,
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
&mdDir, sizeof(mdDir));
- mdDir.StreamType = MemoryListStream;
- mdDir.Location.Rva = dc.rva;
- mdDir.Location.DataSize = dump_memory_info(&dc);
- writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
- &mdDir, sizeof(mdDir));
+
+ if (!(DumpType & MiniDumpWithFullMemory))
+ {
+ mdDir.StreamType = MemoryListStream;
+ mdDir.Location.Rva = dc.rva;
+ mdDir.Location.DataSize = dump_memory_info(&dc);
+ writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
+ &mdDir, sizeof(mdDir));
+ }
mdDir.StreamType = MiscInfoStream;
mdDir.Location.Rva = dc.rva;
@@ -999,12 +1101,25 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE
hFile,
}
}
+ /* 3.4) write full memory (if requested) */
+ if (DumpType & MiniDumpWithFullMemory)
+ {
+ fetch_memory64_info(&dc);
+
+ mdDir.StreamType = Memory64ListStream;
+ mdDir.Location.Rva = dc.rva;
+ mdDir.Location.DataSize = dump_memory64_info(&dc);
+ writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
+ &mdDir, sizeof(mdDir));
+ }
+
/* fill the remaining directory entries with 0's (unused stream types) */
/* NOTE: this should always come last in the dump! */
for (i = idx_stream; i < nStreams; i++)
writeat(&dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir,
sizeof(emptyDir));
HeapFree(GetProcessHeap(), 0, dc.mem);
+ HeapFree(GetProcessHeap(), 0, dc.mem64);
HeapFree(GetProcessHeap(), 0, dc.modules);
HeapFree(GetProcessHeap(), 0, dc.threads);
diff --git a/sdk/include/psdk/dbghelp.h b/sdk/include/psdk/dbghelp.h
index aa0cdff1c69..5da7c94e574 100644
--- a/sdk/include/psdk/dbghelp.h
+++ b/sdk/include/psdk/dbghelp.h
@@ -807,6 +807,19 @@ typedef struct _MINIDUMP_MEMORY_LIST
MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges[1]; /* FIXME: 0-sized array not supported
*/
} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST;
+typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64
+{
+ ULONG64 StartOfMemoryRange;
+ ULONG64 DataSize;
+} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64;
+
+typedef struct _MINIDUMP_MEMORY64_LIST
+{
+ ULONG64 NumberOfMemoryRanges;
+ RVA64 BaseRva;
+ MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges[1]; /* FIXME: 0-sized array not supported
*/
+} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST;
+
#define MINIDUMP_MISC1_PROCESS_ID 0x00000001
#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002
diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg
index 5b1c15a7d2a..97e98a51f55 100644
--- a/sdk/tools/winesync/dbghelp.cfg
+++ b/sdk/tools/winesync/dbghelp.cfg
@@ -4,4 +4,4 @@ files:
include/dbghelp.h: sdk/include/psdk/dbghelp.h
include/wine/mscvpdb.h: sdk/include/reactos/wine/mscvpdb.h
tags:
- wine: edcff4046c5aa70c047c1a523a93a5cc5782fb44
+ wine: b90bbcbe750f6af0ce13f2577984f4818e05a013