annotate foosdk/sdk/foobar2000/shared/minidump.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "shared.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include <imagehlp.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #ifdef _M_ARM64EC
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 typedef ARM64EC_NT_CONTEXT myCONTEXT;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 typedef CONTEXT myCONTEXT;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 struct DumpState {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 int state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 myCONTEXT*context;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 __declspec(noinline) static bool safeRead(volatile const void* addr, size_t& dest)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 __try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 dest = *(const volatile size_t*)addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 __except (1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 __declspec(noinline) static bool safeTestReadAccess(volatile const void* addr)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 size_t dummy;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 return safeRead(addr, dummy);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 #if defined(_M_ARM64) || defined(_M_ARM64EC)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 BOOL WINAPI MiniDumpCallback(PVOID CallbackParam,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 const PMINIDUMP_CALLBACK_INPUT CallbackInput,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 PMINIDUMP_CALLBACK_OUTPUT CallbackOutput)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 static const unsigned STACK_SEARCH_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 static const unsigned MEM_BLOCK_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 if (CallbackInput->CallbackType == MemoryCallback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 // Called to get user defined blocks of memory to write until
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 // callback returns FALSE or CallbackOutput->MemorySize == 0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 DumpState* ds = (DumpState*)CallbackParam;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 switch (ds->state) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 // Save memory referenced by registers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 case 0: CallbackOutput->MemoryBase = ds->context->X0; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 case 1: CallbackOutput->MemoryBase = ds->context->X1; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 case 2: CallbackOutput->MemoryBase = ds->context->X2; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 case 3: CallbackOutput->MemoryBase = ds->context->X3; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 case 4: CallbackOutput->MemoryBase = ds->context->X4; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 case 5: CallbackOutput->MemoryBase = ds->context->X5; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 case 6: CallbackOutput->MemoryBase = ds->context->X6; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 case 7: CallbackOutput->MemoryBase = ds->context->X7; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 case 8: CallbackOutput->MemoryBase = ds->context->X8; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 case 9: CallbackOutput->MemoryBase = ds->context->X9; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 case 10: CallbackOutput->MemoryBase = ds->context->X10; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 case 11: CallbackOutput->MemoryBase = ds->context->X11; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 case 12: CallbackOutput->MemoryBase = ds->context->X12; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 #ifndef _M_ARM64EC
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 case 13: CallbackOutput->MemoryBase = ds->context->X13; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 case 14: CallbackOutput->MemoryBase = ds->context->X14; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 case 15: CallbackOutput->MemoryBase = ds->context->X15; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 case 16: CallbackOutput->MemoryBase = ds->context->X16; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 case 17: CallbackOutput->MemoryBase = ds->context->X17; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 case 18: CallbackOutput->MemoryBase = ds->context->X18; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 case 19: CallbackOutput->MemoryBase = ds->context->X19; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 case 20: CallbackOutput->MemoryBase = ds->context->X20; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 case 21: CallbackOutput->MemoryBase = ds->context->X21; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 case 22: CallbackOutput->MemoryBase = ds->context->X22; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 case 23: CallbackOutput->MemoryBase = ds->context->X23; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 case 24: CallbackOutput->MemoryBase = ds->context->X24; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 case 25: CallbackOutput->MemoryBase = ds->context->X25; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 case 26: CallbackOutput->MemoryBase = ds->context->X26; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 case 27: CallbackOutput->MemoryBase = ds->context->X27; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 case 28: CallbackOutput->MemoryBase = ds->context->X28; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 // Save memory referenced by values in stack.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 if (ds->state < 0x1000)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 ds->state = 0x1000;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 size_t addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 do {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 if (ds->state > 0x1000 + STACK_SEARCH_SIZE)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 if (!safeRead((void*)((ds->context->Sp & ~7) + ds->state - 0x1000), addr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 ds->state += 4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 } while (addr < 0x1000 || !safeTestReadAccess((void*)addr));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 CallbackOutput->MemoryBase = addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 if (CallbackOutput->MemoryBase >= MEM_BLOCK_SIZE / 2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 CallbackOutput->MemoryBase -= MEM_BLOCK_SIZE / 2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 CallbackOutput->MemorySize = MEM_BLOCK_SIZE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 // No need to perform additional checks here, the minidump engine
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 // safely clips the addresses to valid memory pages only.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 // Also seems to apply for overlapped areas etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 #elif defined(_M_IX86)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 BOOL WINAPI MiniDumpCallback(PVOID CallbackParam,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 const PMINIDUMP_CALLBACK_INPUT CallbackInput,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 PMINIDUMP_CALLBACK_OUTPUT CallbackOutput)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 static const unsigned STACK_SEARCH_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 static const unsigned MEM_BLOCK_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 if (CallbackInput->CallbackType == MemoryCallback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 // Called to get user defined blocks of memory to write until
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 // callback returns FALSE or CallbackOutput->MemorySize == 0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 DumpState* ds = (DumpState*)CallbackParam;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 switch (ds->state) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 // Save memory referenced by registers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 case 0: CallbackOutput->MemoryBase = ds->context->Eax; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 case 1: CallbackOutput->MemoryBase = ds->context->Ebx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 case 2: CallbackOutput->MemoryBase = ds->context->Ecx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 case 3: CallbackOutput->MemoryBase = ds->context->Edx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 case 4: CallbackOutput->MemoryBase = ds->context->Esi; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 case 5: CallbackOutput->MemoryBase = ds->context->Edi; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 case 6: CallbackOutput->MemoryBase = ds->context->Ebp; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 case 7: CallbackOutput->MemoryBase = ds->context->Esp; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 case 8: CallbackOutput->MemoryBase = ds->context->Eip; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 // Save memory referenced by values in stack.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 if (ds->state < 0x1000)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 ds->state = 0x1000;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 size_t addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 do {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 if (ds->state > 0x1000 + STACK_SEARCH_SIZE)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 if (!safeRead((void*)((ds->context->Esp & ~3) + ds->state - 0x1000), addr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 ds->state += 4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 } while (addr < 0x1000 || !safeTestReadAccess((void*)addr));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 CallbackOutput->MemoryBase = addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (CallbackOutput->MemoryBase >= MEM_BLOCK_SIZE / 2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 CallbackOutput->MemoryBase -= MEM_BLOCK_SIZE / 2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 CallbackOutput->MemorySize = MEM_BLOCK_SIZE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 // No need to perform additional checks here, the minidump engine
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 // safely clips the addresses to valid memory pages only.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 // Also seems to apply for overlapped areas etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 #elif defined(_M_X64)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 BOOL WINAPI MiniDumpCallback(PVOID CallbackParam,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 const PMINIDUMP_CALLBACK_INPUT CallbackInput,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 PMINIDUMP_CALLBACK_OUTPUT CallbackOutput)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 static const unsigned STACK_SEARCH_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 static const unsigned MEM_BLOCK_SIZE = 0x400;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 if (CallbackInput->CallbackType == MemoryCallback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 // Called to get user defined blocks of memory to write until
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 // callback returns FALSE or CallbackOutput->MemorySize == 0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 DumpState* ds = (DumpState*)CallbackParam;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 switch (ds->state) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 // Save memory referenced by registers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 case 0: CallbackOutput->MemoryBase = ds->context->Rax; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 case 1: CallbackOutput->MemoryBase = ds->context->Rbx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 case 2: CallbackOutput->MemoryBase = ds->context->Rcx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 case 3: CallbackOutput->MemoryBase = ds->context->Rdx; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 case 4: CallbackOutput->MemoryBase = ds->context->Rsi; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 case 5: CallbackOutput->MemoryBase = ds->context->Rdi; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 case 6: CallbackOutput->MemoryBase = ds->context->Rsp; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 case 7: CallbackOutput->MemoryBase = ds->context->Rbp; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 case 8: CallbackOutput->MemoryBase = ds->context->R8; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 case 9: CallbackOutput->MemoryBase = ds->context->R9; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 case 10: CallbackOutput->MemoryBase = ds->context->R10; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 case 11: CallbackOutput->MemoryBase = ds->context->R11; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 case 12: CallbackOutput->MemoryBase = ds->context->R12; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 case 13: CallbackOutput->MemoryBase = ds->context->R13; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 case 14: CallbackOutput->MemoryBase = ds->context->R14; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 case 15: CallbackOutput->MemoryBase = ds->context->R15; ds->state++; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 // Save memory referenced by values in stack.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 if (ds->state < 0x1000)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 ds->state = 0x1000;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 size_t addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 do {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 if (ds->state > 0x1000 + STACK_SEARCH_SIZE)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 if (!safeRead((void*)((ds->context->Rsp & ~7) + ds->state - 0x1000), addr))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 return FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 ds->state += 4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 } while (addr < 0x1000 || !safeTestReadAccess((void*)addr));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 CallbackOutput->MemoryBase = addr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 if (CallbackOutput->MemoryBase >= MEM_BLOCK_SIZE / 2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 CallbackOutput->MemoryBase -= MEM_BLOCK_SIZE / 2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 CallbackOutput->MemorySize = MEM_BLOCK_SIZE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 // No need to perform additional checks here, the minidump engine
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 // safely clips the addresses to valid memory pages only.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 // Also seems to apply for overlapped areas etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 return TRUE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 #endif // _M_X64
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 BOOL WriteMiniDumpHelper(HANDLE hDump, LPEXCEPTION_POINTERS param) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 MINIDUMP_EXCEPTION_INFORMATION exception = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 exception.ThreadId = GetCurrentThreadId();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 exception.ExceptionPointers = param;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 exception.ClientPointers = FALSE;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 DumpState ds;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 ds.state = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 ds.context = reinterpret_cast<myCONTEXT*>(param->ContextRecord);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 MINIDUMP_CALLBACK_INFORMATION mci;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 mci.CallbackRoutine = &MiniDumpCallback;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 mci.CallbackParam = (void*)&ds;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 return MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDump, (MINIDUMP_TYPE)(MiniDumpWithUnloadedModules), &exception, NULL, &mci);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 }