summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
diff options
context:
space:
mode:
authorAdrian McCarthy <amccarth@google.com>2015-09-01 16:59:31 +0000
committerAdrian McCarthy <amccarth@google.com>2015-09-01 16:59:31 +0000
commit6c3d03c4680ec3262d1c45708bfa831b71b6c6a4 (patch)
tree7f1e577ba2ed2d1d9a0403073cbdfd55447fd921 /lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
parentc963a222f1b8e01a158c4a7e8b3af7c30dc197f7 (diff)
downloadbcm5719-llvm-6c3d03c4680ec3262d1c45708bfa831b71b6c6a4.tar.gz
bcm5719-llvm-6c3d03c4680ec3262d1c45708bfa831b71b6c6a4.zip
Implement DoReadMemory for Windows mini dumps.
Differential Revision: http://reviews.llvm.org/D12507 llvm-svn: 246558
Diffstat (limited to 'lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp')
-rw-r--r--lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp80
1 files changed, 76 insertions, 4 deletions
diff --git a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
index c643f26551c..d8c70fd99a5 100644
--- a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
+++ b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
@@ -227,19 +227,42 @@ ProcessWinMiniDump::IsAlive()
return true;
}
+bool
+ProcessWinMiniDump::WarnBeforeDetach () const
+{
+ // Since this is post-mortem debugging, there's no need to warn the user
+ // that quitting the debugger will terminate the process.
+ return false;
+}
+
size_t
ProcessWinMiniDump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
{
// Don't allow the caching that lldb_private::Process::ReadMemory does
- // since in core files we have it all cached our our core file anyway.
+ // since we have it all cached our our dump file anyway.
return DoReadMemory(addr, buf, size, error);
}
size_t
ProcessWinMiniDump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Error &error)
{
- // TODO
- return 0;
+ // I don't have a sense of how frequently this is called or how many memory
+ // ranges a mini dump typically has, so I'm not sure if searching for the
+ // appropriate range linearly each time is stupid. Perhaps we should build
+ // an index for faster lookups.
+ Range range = {0};
+ if (!FindMemoryRange(addr, &range))
+ {
+ return 0;
+ }
+
+ // There's at least some overlap between the beginning of the desired range
+ // (addr) and the current range. Figure out where the overlap begins and
+ // how much overlap there is, then copy it to the destination buffer.
+ const size_t offset = range.start - addr;
+ const size_t overlap = std::min(size, range.size - offset);
+ std::memcpy(buf, range.ptr + offset, overlap);
+ return overlap;
}
void
@@ -307,6 +330,54 @@ ProcessWinMiniDump::Data::~Data()
}
}
+bool
+ProcessWinMiniDump::FindMemoryRange(lldb::addr_t addr, Range *range_out) const
+{
+ size_t stream_size = 0;
+ auto mem_list_stream = static_cast<const MINIDUMP_MEMORY_LIST *>(FindDumpStream(MemoryListStream, &stream_size));
+ if (mem_list_stream)
+ {
+ for (ULONG32 i = 0; i < mem_list_stream->NumberOfMemoryRanges; ++i) {
+ const MINIDUMP_MEMORY_DESCRIPTOR &mem_desc = mem_list_stream->MemoryRanges[i];
+ const MINIDUMP_LOCATION_DESCRIPTOR &loc_desc = mem_desc.Memory;
+ const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
+ const size_t range_size = loc_desc.DataSize;
+ if (range_start <= addr && addr < range_start + range_size)
+ {
+ range_out->start = range_start;
+ range_out->size = range_size;
+ range_out->ptr = reinterpret_cast<const uint8_t *>(m_data_up->m_base_addr) + loc_desc.Rva;
+ return true;
+ }
+ }
+ }
+
+ // Some mini dumps have a Memory64ListStream that captures all the heap
+ // memory. We can't exactly use the same loop as above, because the mini
+ // dump uses slightly different data structures to describe those.
+ auto mem_list64_stream = static_cast<const MINIDUMP_MEMORY64_LIST *>(FindDumpStream(Memory64ListStream, &stream_size));
+ if (mem_list64_stream)
+ {
+ size_t base_rva = mem_list64_stream->BaseRva;
+ for (ULONG32 i = 0; i < mem_list64_stream->NumberOfMemoryRanges; ++i) {
+ const MINIDUMP_MEMORY_DESCRIPTOR64 &mem_desc = mem_list64_stream->MemoryRanges[i];
+ const lldb::addr_t range_start = mem_desc.StartOfMemoryRange;
+ const size_t range_size = mem_desc.DataSize;
+ if (range_start <= addr && addr < range_start + range_size)
+ {
+ range_out->start = range_start;
+ range_out->size = range_size;
+ range_out->ptr = reinterpret_cast<const uint8_t *>(m_data_up->m_base_addr) + base_rva;
+ return true;
+ }
+ base_rva += range_size;
+ }
+ }
+
+ return false;
+}
+
+
Error
ProcessWinMiniDump::MapMiniDumpIntoMemory(const char *file)
{
@@ -397,7 +468,8 @@ ProcessWinMiniDump::ReadModuleList() {
}
void *
-ProcessWinMiniDump::FindDumpStream(unsigned stream_number, size_t *size_out) {
+ProcessWinMiniDump::FindDumpStream(unsigned stream_number, size_t *size_out) const
+{
void *stream = nullptr;
*size_out = 0;
OpenPOWER on IntegriCloud