llvm-svn: 246302
This commit is contained in:
Adrian McCarthy 2015-08-28 14:42:03 +00:00
parent 85d58684da
commit 23d14b6ade
2 changed files with 60 additions and 2 deletions

View File

@ -30,6 +30,7 @@
#include "lldb/Target/UnixSignals.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ConvertUTF.h"
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "ExceptionRecord.h"
@ -37,6 +38,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<const MINIDUMP_STRING *>(static_cast<const char *>(base_addr) + rva);
auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
const auto source_length = ::wcslen(md_string->Buffer);
const auto source_end = source_start + source_length;
result.resize(4*source_length); // worst case length
auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
const auto result_end = result_start + result.size();
ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
result.resize(result_size); // shrink to 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 +164,7 @@ ProcessWinMiniDump::DoLoadCore()
}
m_target.SetArchitecture(DetermineArchitecture());
// TODO(amccarth): Build the module list.
ReadModuleList();
ReadExceptionRecord();
return error;
@ -341,6 +371,31 @@ ProcessWinMiniDump::ReadExceptionRecord() {
}
}
void
ProcessWinMiniDump::ReadModuleList() {
size_t size = 0;
auto module_list_ptr = static_cast<MINIDUMP_MODULE_LIST*>(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;

View File

@ -100,6 +100,9 @@ private:
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.