Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h =================================================================== --- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h +++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h @@ -100,6 +100,9 @@ void ReadExceptionRecord(); + void + ReadModuleList(); + // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant // checks. If there's a failure (e.g., if the requested stream doesn't exist), // the function returns nullptr and sets *size_out to 0. Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp =================================================================== --- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp +++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp @@ -37,6 +37,36 @@ using namespace lldb_private; +namespace +{ + +// Getting a string out of a mini dump is a chore. You're usually given a +// relative virtual address (RVA), which points to a counted string that's in +// Windows Unicode (UTF-16). This wrapper handles all the redirection and +// returns a UTF-8 copy of the string. +std::string +GetMiniDumpString(const void *base_addr, const RVA rva) +{ + std::string result; + if (!base_addr) + { + return result; + } + auto md_string = reinterpret_cast(static_cast(base_addr) + rva); + const auto length_required = + ::WideCharToMultiByte(CP_UTF8, 0, md_string->Buffer, md_string->Length, + nullptr, 0, nullptr, nullptr); + result.resize(length_required); + const auto actual_length = + ::WideCharToMultiByte(CP_UTF8, 0, md_string->Buffer, md_string->Length, + &result[0], static_cast(result.size()), + nullptr, nullptr); + result.resize(actual_length); + return result; +} + +} // anonymous namespace + // Encapsulates the private data for ProcessWinMiniDump. // TODO(amccarth): Determine if we need a mutex for access. class ProcessWinMiniDump::Data @@ -133,8 +163,7 @@ } m_target.SetArchitecture(DetermineArchitecture()); - // TODO(amccarth): Build the module list. - + ReadModuleList(); ReadExceptionRecord(); return error; @@ -341,6 +370,31 @@ } } +void +ProcessWinMiniDump::ReadModuleList() { + size_t size = 0; + auto module_list_ptr = static_cast(FindDumpStream(ModuleListStream, &size)); + if (!module_list_ptr || module_list_ptr->NumberOfModules == 0) + { + return; + } + + for (ULONG32 i = 0; i < module_list_ptr->NumberOfModules; ++i) + { + const auto &module = module_list_ptr->Modules[i]; + const auto file_name = GetMiniDumpString(m_data_up->m_base_addr, module.ModuleNameRva); + ModuleSpec module_spec = FileSpec(file_name, true); + + lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec); + if (!module_sp) + { + continue; + } + bool load_addr_changed = false; + module_sp->SetLoadAddress(GetTarget(), module.BaseOfImage, false, load_addr_changed); + } +} + void * ProcessWinMiniDump::FindDumpStream(unsigned stream_number, size_t *size_out) { void *stream = nullptr;