@@ -227,19 +227,42 @@ ProcessWinMiniDump::IsAlive()
227
227
return true ;
228
228
}
229
229
230
+ bool
231
+ ProcessWinMiniDump::WarnBeforeDetach () const
232
+ {
233
+ // Since this is post-mortem debugging, there's no need to warn the user
234
+ // that quitting the debugger will terminate the process.
235
+ return false ;
236
+ }
237
+
230
238
size_t
231
239
ProcessWinMiniDump::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
232
240
{
233
241
// Don't allow the caching that lldb_private::Process::ReadMemory does
234
- // since in core files we have it all cached our our core file anyway.
242
+ // since we have it all cached our our dump file anyway.
235
243
return DoReadMemory (addr, buf, size, error);
236
244
}
237
245
238
246
size_t
239
247
ProcessWinMiniDump::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
240
248
{
241
- // TODO
242
- return 0 ;
249
+ // I don't have a sense of how frequently this is called or how many memory
250
+ // ranges a mini dump typically has, so I'm not sure if searching for the
251
+ // appropriate range linearly each time is stupid. Perhaps we should build
252
+ // an index for faster lookups.
253
+ Range range = {0 };
254
+ if (!FindMemoryRange (addr, &range))
255
+ {
256
+ return 0 ;
257
+ }
258
+
259
+ // There's at least some overlap between the beginning of the desired range
260
+ // (addr) and the current range. Figure out where the overlap begins and
261
+ // how much overlap there is, then copy it to the destination buffer.
262
+ const size_t offset = range.start - addr;
263
+ const size_t overlap = std::min (size, range.size - offset);
264
+ std::memcpy (buf, range.ptr + offset, overlap);
265
+ return overlap;
243
266
}
244
267
245
268
void
@@ -307,6 +330,54 @@ ProcessWinMiniDump::Data::~Data()
307
330
}
308
331
}
309
332
333
+ bool
334
+ ProcessWinMiniDump::FindMemoryRange (lldb::addr_t addr, Range *range_out) const
335
+ {
336
+ size_t stream_size = 0 ;
337
+ auto mem_list_stream = static_cast <const MINIDUMP_MEMORY_LIST *>(FindDumpStream (MemoryListStream, &stream_size));
338
+ if (mem_list_stream)
339
+ {
340
+ for (ULONG32 i = 0 ; i < mem_list_stream->NumberOfMemoryRanges ; ++i) {
341
+ const MINIDUMP_MEMORY_DESCRIPTOR &mem_desc = mem_list_stream->MemoryRanges [i];
342
+ const MINIDUMP_LOCATION_DESCRIPTOR &loc_desc = mem_desc.Memory ;
343
+ const lldb::addr_t range_start = mem_desc.StartOfMemoryRange ;
344
+ const size_t range_size = loc_desc.DataSize ;
345
+ if (range_start <= addr && addr < range_start + range_size)
346
+ {
347
+ range_out->start = range_start;
348
+ range_out->size = range_size;
349
+ range_out->ptr = reinterpret_cast <const uint8_t *>(m_data_up->m_base_addr ) + loc_desc.Rva ;
350
+ return true ;
351
+ }
352
+ }
353
+ }
354
+
355
+ // Some mini dumps have a Memory64ListStream that captures all the heap
356
+ // memory. We can't exactly use the same loop as above, because the mini
357
+ // dump uses slightly different data structures to describe those.
358
+ auto mem_list64_stream = static_cast <const MINIDUMP_MEMORY64_LIST *>(FindDumpStream (Memory64ListStream, &stream_size));
359
+ if (mem_list64_stream)
360
+ {
361
+ size_t base_rva = mem_list64_stream->BaseRva ;
362
+ for (ULONG32 i = 0 ; i < mem_list64_stream->NumberOfMemoryRanges ; ++i) {
363
+ const MINIDUMP_MEMORY_DESCRIPTOR64 &mem_desc = mem_list64_stream->MemoryRanges [i];
364
+ const lldb::addr_t range_start = mem_desc.StartOfMemoryRange ;
365
+ const size_t range_size = mem_desc.DataSize ;
366
+ if (range_start <= addr && addr < range_start + range_size)
367
+ {
368
+ range_out->start = range_start;
369
+ range_out->size = range_size;
370
+ range_out->ptr = reinterpret_cast <const uint8_t *>(m_data_up->m_base_addr ) + base_rva;
371
+ return true ;
372
+ }
373
+ base_rva += range_size;
374
+ }
375
+ }
376
+
377
+ return false ;
378
+ }
379
+
380
+
310
381
Error
311
382
ProcessWinMiniDump::MapMiniDumpIntoMemory (const char *file)
312
383
{
@@ -397,7 +468,8 @@ ProcessWinMiniDump::ReadModuleList() {
397
468
}
398
469
399
470
void *
400
- ProcessWinMiniDump::FindDumpStream (unsigned stream_number, size_t *size_out) {
471
+ ProcessWinMiniDump::FindDumpStream (unsigned stream_number, size_t *size_out) const
472
+ {
401
473
void *stream = nullptr ;
402
474
*size_out = 0 ;
403
475
0 commit comments