diff options
Diffstat (limited to 'source/Plugins/Process/minidump/ProcessMinidump.cpp')
-rw-r--r-- | source/Plugins/Process/minidump/ProcessMinidump.cpp | 94 |
1 files changed, 66 insertions, 28 deletions
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index a7fc42cad16c9..e30a3c82a8873 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -49,16 +49,19 @@ namespace { class PlaceholderObjectFile : public ObjectFile { public: PlaceholderObjectFile(const lldb::ModuleSP &module_sp, - const ModuleSpec &module_spec, lldb::offset_t base, - lldb::offset_t size) + const ModuleSpec &module_spec, lldb::addr_t base, + lldb::addr_t size) : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), m_base(base), m_size(size) { - m_symtab_up = llvm::make_unique<Symtab>(this); + m_symtab_up = std::make_unique<Symtab>(this); } - ConstString GetPluginName() override { return ConstString("placeholder"); } + static ConstString GetStaticPluginName() { + return ConstString("placeholder"); + } + ConstString GetPluginName() override { return GetStaticPluginName(); } uint32_t GetPluginVersion() override { return 1; } bool ParseHeader() override { return true; } Type CalculateType() override { return eTypeUnknown; } @@ -80,7 +83,7 @@ public: } void CreateSections(SectionList &unified_section_list) override { - m_sections_up = llvm::make_unique<SectionList>(); + m_sections_up = std::make_unique<SectionList>(); auto section_sp = std::make_shared<Section>( GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"), eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0, @@ -109,11 +112,12 @@ public: GetFileSpec(), m_base, m_base + m_size); } + lldb::addr_t GetBaseImageAddress() const { return m_base; } private: ArchSpec m_arch; UUID m_uuid; - lldb::offset_t m_base; - lldb::offset_t m_size; + lldb::addr_t m_base; + lldb::addr_t m_size; }; } // namespace @@ -215,6 +219,9 @@ Status ProcessMinidump::DoLoadCore() { m_thread_list = m_minidump_parser->GetThreads(); m_active_exception = m_minidump_parser->GetExceptionStream(); + + SetUnixSignals(UnixSignals::Create(GetArchitecture())); + ReadModuleList(); llvm::Optional<lldb::pid_t> pid = m_minidump_parser->GetPid(); @@ -234,39 +241,56 @@ uint32_t ProcessMinidump::GetPluginVersion() { return 1; } Status ProcessMinidump::DoDestroy() { return Status(); } void ProcessMinidump::RefreshStateAfterStop() { + if (!m_active_exception) return; - if (m_active_exception->exception_record.exception_code == - MinidumpException::DumpRequested) { + constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF; + if (m_active_exception->ExceptionRecord.ExceptionCode == + BreakpadDumpRequested) { + // This "ExceptionCode" value is a sentinel that is sometimes used + // when generating a dump for a process that hasn't crashed. + + // TODO: The definition and use of this "dump requested" constant + // in Breakpad are actually Linux-specific, and for similar use + // cases on Mac/Windows it defines differnt constants, referring + // to them as "simulated" exceptions; consider moving this check + // down to the OS-specific paths and checking each OS for its own + // constant. return; } lldb::StopInfoSP stop_info; lldb::ThreadSP stop_thread; - Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id); + Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId); stop_thread = Process::m_thread_list.GetSelectedThread(); ArchSpec arch = GetArchitecture(); if (arch.GetTriple().getOS() == llvm::Triple::Linux) { + uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode; + + if (signo == 0) { + // No stop. + return; + } + stop_info = StopInfo::CreateStopReasonWithSignal( - *stop_thread, m_active_exception->exception_record.exception_code); + *stop_thread, signo); } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { stop_info = StopInfoMachException::CreateStopReasonWithMachException( - *stop_thread, m_active_exception->exception_record.exception_code, 2, - m_active_exception->exception_record.exception_flags, - m_active_exception->exception_record.exception_address, 0); + *stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2, + m_active_exception->ExceptionRecord.ExceptionFlags, + m_active_exception->ExceptionRecord.ExceptionAddress, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); desc_stream << "Exception " << llvm::format_hex( - m_active_exception->exception_record.exception_code, 8) + m_active_exception->ExceptionRecord.ExceptionCode, 8) << " encountered at address " << llvm::format_hex( - m_active_exception->exception_record.exception_address, - 8); + m_active_exception->ExceptionRecord.ExceptionAddress, 8); stop_info = StopInfo::CreateStopReasonWithException( *stop_thread, desc_stream.str().c_str()); } @@ -331,8 +355,8 @@ bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, // If the minidump contains an exception context, use it if (m_active_exception != nullptr && - m_active_exception->thread_id == thread.ThreadId) { - context_location = m_active_exception->thread_context; + m_active_exception->ThreadId == thread.ThreadId) { + context_location = m_active_exception->ThreadContext; } llvm::ArrayRef<uint8_t> context; @@ -351,14 +375,15 @@ void ProcessMinidump::ReadModuleList() { std::vector<const minidump::Module *> filtered_modules = m_minidump_parser->GetFilteredModuleList(); - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); for (auto module : filtered_modules) { std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString( module->ModuleNameRVA)); + const uint64_t load_addr = module->BaseOfImage; + const uint64_t load_size = module->SizeOfImage; LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name, - module->BaseOfImage, module->BaseOfImage + module->SizeOfImage, - module->SizeOfImage); + load_addr, load_addr + load_size, load_size); // check if the process is wow64 - a 32 bit windows process running on a // 64 bit windows @@ -373,7 +398,7 @@ void ProcessMinidump::ReadModuleList() { Status error; // Try and find a module with a full UUID that matches. This function will // add the module to the target if it finds one. - lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec, + lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error); if (!module_sp) { // Try and find a module without specifying the UUID and only looking for @@ -386,8 +411,8 @@ void ProcessMinidump::ReadModuleList() { ModuleSpec basename_module_spec(module_spec); basename_module_spec.GetUUID().Clear(); basename_module_spec.GetFileSpec().GetDirectory().Clear(); - module_sp = GetTarget().GetOrCreateModule(basename_module_spec, - true /* notify */, &error); + module_sp = GetTarget().GetOrCreateModule(basename_module_spec, + true /* notify */, &error); if (module_sp) { // We consider the module to be a match if the minidump UUID is a // prefix of the actual UUID, or if either of the UUIDs are empty. @@ -401,6 +426,19 @@ void ProcessMinidump::ReadModuleList() { } } } + if (module_sp) { + // Watch out for place holder modules that have different paths, but the + // same UUID. If the base address is different, create a new module. If + // we don't then we will end up setting the load address of a different + // PlaceholderObjectFile and an assertion will fire. + auto *objfile = module_sp->GetObjectFile(); + if (objfile && objfile->GetPluginName() == + PlaceholderObjectFile::GetStaticPluginName()) { + if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() != + load_addr) + module_sp.reset(); + } + } if (!module_sp) { // We failed to locate a matching local object file. Fortunately, the // minidump format encodes enough information about each module's memory @@ -415,12 +453,12 @@ void ProcessMinidump::ReadModuleList() { name); module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>( - module_spec, module->BaseOfImage, module->SizeOfImage); + module_spec, load_addr, load_size); GetTarget().GetImages().Append(module_sp, true /* notify */); } bool load_addr_changed = false; - module_sp->SetLoadAddress(GetTarget(), module->BaseOfImage, false, + module_sp->SetLoadAddress(GetTarget(), load_addr, false, load_addr_changed); } } @@ -444,7 +482,7 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) { // debug information than needed. JITLoaderList &ProcessMinidump::GetJITLoaders() { if (!m_jit_loaders_up) { - m_jit_loaders_up = llvm::make_unique<JITLoaderList>(); + m_jit_loaders_up = std::make_unique<JITLoaderList>(); } return *m_jit_loaders_up; } |