1 //===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "ProcessMinidump.h" 11 #include "ThreadMinidump.h" 12 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/ModuleSpec.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/Section.h" 17 #include "lldb/Target/JITLoaderList.h" 18 #include "lldb/Target/MemoryRegionInfo.h" 19 #include "lldb/Target/SectionLoadList.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/UnixSignals.h" 22 #include "lldb/Utility/LLDBAssert.h" 23 #include "lldb/Utility/Log.h" 24 #include "lldb/Utility/State.h" 25 26 #include "llvm/Support/MemoryBuffer.h" 27 #include "llvm/Support/Threading.h" 28 29 #include "Plugins/Process/Utility/StopInfoMachException.h" 30 // C includes 31 // C++ includes 32 33 using namespace lldb; 34 using namespace lldb_private; 35 using namespace minidump; 36 37 //------------------------------------------------------------------ 38 /// A placeholder module used for minidumps, where the original 39 /// object files may not be available (so we can't parse the object 40 /// files to extract the set of sections/segments) 41 /// 42 /// This placeholder module has a single synthetic section (.module_image) 43 /// which represents the module memory range covering the whole module. 44 //------------------------------------------------------------------ 45 class PlaceholderModule : public Module { 46 public: 47 PlaceholderModule(const ModuleSpec &module_spec) : 48 Module(module_spec.GetFileSpec(), module_spec.GetArchitecture()) { 49 if (module_spec.GetUUID().IsValid()) 50 SetUUID(module_spec.GetUUID()); 51 } 52 53 // Creates a synthetic module section covering the whole module image (and 54 // sets the section load address as well) 55 void CreateImageSection(const MinidumpModule *module, Target& target) { 56 const ConstString section_name(".module_image"); 57 lldb::SectionSP section_sp(new Section( 58 shared_from_this(), // Module to which this section belongs. 59 nullptr, // ObjectFile 60 0, // Section ID. 61 section_name, // Section name. 62 eSectionTypeContainer, // Section type. 63 module->base_of_image, // VM address. 64 module->size_of_image, // VM size in bytes of this section. 65 0, // Offset of this section in the file. 66 module->size_of_image, // Size of the section as found in the file. 67 12, // Alignment of the section (log2) 68 0, // Flags for this section. 69 1)); // Number of host bytes per target byte 70 section_sp->SetPermissions(ePermissionsExecutable | ePermissionsReadable); 71 GetSectionList()->AddSection(section_sp); 72 target.GetSectionLoadList().SetSectionLoadAddress( 73 section_sp, module->base_of_image); 74 } 75 76 ObjectFile *GetObjectFile() override { return nullptr; } 77 78 SectionList *GetSectionList() override { 79 return Module::GetUnifiedSectionList(); 80 } 81 }; 82 83 ConstString ProcessMinidump::GetPluginNameStatic() { 84 static ConstString g_name("minidump"); 85 return g_name; 86 } 87 88 const char *ProcessMinidump::GetPluginDescriptionStatic() { 89 return "Minidump plug-in."; 90 } 91 92 lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, 93 lldb::ListenerSP listener_sp, 94 const FileSpec *crash_file) { 95 if (!crash_file) 96 return nullptr; 97 98 lldb::ProcessSP process_sp; 99 // Read enough data for the Minidump header 100 constexpr size_t header_size = sizeof(MinidumpHeader); 101 auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), 102 header_size, 0); 103 if (!DataPtr) 104 return nullptr; 105 106 lldbassert(DataPtr->GetByteSize() == header_size); 107 108 // first, only try to parse the header, beacuse we need to be fast 109 llvm::ArrayRef<uint8_t> HeaderBytes = DataPtr->GetData(); 110 const MinidumpHeader *header = MinidumpHeader::Parse(HeaderBytes); 111 if (header == nullptr) 112 return nullptr; 113 114 auto AllData = 115 FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0); 116 if (!AllData) 117 return nullptr; 118 119 auto minidump_parser = MinidumpParser::Create(AllData); 120 // check if the parser object is valid 121 if (!minidump_parser) 122 return nullptr; 123 124 return std::make_shared<ProcessMinidump>(target_sp, listener_sp, *crash_file, 125 minidump_parser.getValue()); 126 } 127 128 bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp, 129 bool plugin_specified_by_name) { 130 return true; 131 } 132 133 ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp, 134 lldb::ListenerSP listener_sp, 135 const FileSpec &core_file, 136 MinidumpParser minidump_parser) 137 : Process(target_sp, listener_sp), m_minidump_parser(minidump_parser), 138 m_core_file(core_file), m_is_wow64(false) {} 139 140 ProcessMinidump::~ProcessMinidump() { 141 Clear(); 142 // We need to call finalize on the process before destroying ourselves to 143 // make sure all of the broadcaster cleanup goes as planned. If we destruct 144 // this class, then Process::~Process() might have problems trying to fully 145 // destroy the broadcaster. 146 Finalize(); 147 } 148 149 void ProcessMinidump::Initialize() { 150 static llvm::once_flag g_once_flag; 151 152 llvm::call_once(g_once_flag, []() { 153 PluginManager::RegisterPlugin(GetPluginNameStatic(), 154 GetPluginDescriptionStatic(), 155 ProcessMinidump::CreateInstance); 156 }); 157 } 158 159 void ProcessMinidump::Terminate() { 160 PluginManager::UnregisterPlugin(ProcessMinidump::CreateInstance); 161 } 162 163 Status ProcessMinidump::DoLoadCore() { 164 Status error; 165 166 // Minidump parser initialization & consistency checks 167 error = m_minidump_parser.Initialize(); 168 if (error.Fail()) 169 return error; 170 171 // Do we support the minidump's architecture? 172 ArchSpec arch = GetArchitecture(); 173 switch (arch.GetMachine()) { 174 case llvm::Triple::x86: 175 case llvm::Triple::x86_64: 176 case llvm::Triple::arm: 177 case llvm::Triple::aarch64: 178 // Any supported architectures must be listed here and also supported in 179 // ThreadMinidump::CreateRegisterContextForFrame(). 180 break; 181 default: 182 error.SetErrorStringWithFormat("unsupported minidump architecture: %s", 183 arch.GetArchitectureName()); 184 return error; 185 } 186 GetTarget().SetArchitecture(arch, true /*set_platform*/); 187 188 m_thread_list = m_minidump_parser.GetThreads(); 189 m_active_exception = m_minidump_parser.GetExceptionStream(); 190 ReadModuleList(); 191 192 llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid(); 193 if (!pid) { 194 error.SetErrorString("failed to parse PID"); 195 return error; 196 } 197 SetID(pid.getValue()); 198 199 return error; 200 } 201 202 ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); } 203 204 uint32_t ProcessMinidump::GetPluginVersion() { return 1; } 205 206 Status ProcessMinidump::DoDestroy() { return Status(); } 207 208 void ProcessMinidump::RefreshStateAfterStop() { 209 if (!m_active_exception) 210 return; 211 212 if (m_active_exception->exception_record.exception_code == 213 MinidumpException::DumpRequested) { 214 return; 215 } 216 217 lldb::StopInfoSP stop_info; 218 lldb::ThreadSP stop_thread; 219 220 Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id); 221 stop_thread = Process::m_thread_list.GetSelectedThread(); 222 ArchSpec arch = GetArchitecture(); 223 224 if (arch.GetTriple().getOS() == llvm::Triple::Linux) { 225 stop_info = StopInfo::CreateStopReasonWithSignal( 226 *stop_thread, m_active_exception->exception_record.exception_code); 227 } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { 228 stop_info = StopInfoMachException::CreateStopReasonWithMachException( 229 *stop_thread, m_active_exception->exception_record.exception_code, 2, 230 m_active_exception->exception_record.exception_flags, 231 m_active_exception->exception_record.exception_address, 0); 232 } else { 233 std::string desc; 234 llvm::raw_string_ostream desc_stream(desc); 235 desc_stream << "Exception " 236 << llvm::format_hex( 237 m_active_exception->exception_record.exception_code, 8) 238 << " encountered at address " 239 << llvm::format_hex( 240 m_active_exception->exception_record.exception_address, 241 8); 242 stop_info = StopInfo::CreateStopReasonWithException( 243 *stop_thread, desc_stream.str().c_str()); 244 } 245 246 stop_thread->SetStopInfo(stop_info); 247 } 248 249 bool ProcessMinidump::IsAlive() { return true; } 250 251 bool ProcessMinidump::WarnBeforeDetach() const { return false; } 252 253 size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size, 254 Status &error) { 255 // Don't allow the caching that lldb_private::Process::ReadMemory does since 256 // we have it all cached in our dump file anyway. 257 return DoReadMemory(addr, buf, size, error); 258 } 259 260 size_t ProcessMinidump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 261 Status &error) { 262 263 llvm::ArrayRef<uint8_t> mem = m_minidump_parser.GetMemory(addr, size); 264 if (mem.empty()) { 265 error.SetErrorString("could not parse memory info"); 266 return 0; 267 } 268 269 std::memcpy(buf, mem.data(), mem.size()); 270 return mem.size(); 271 } 272 273 ArchSpec ProcessMinidump::GetArchitecture() { 274 if (!m_is_wow64) { 275 return m_minidump_parser.GetArchitecture(); 276 } 277 278 llvm::Triple triple; 279 triple.setVendor(llvm::Triple::VendorType::UnknownVendor); 280 triple.setArch(llvm::Triple::ArchType::x86); 281 triple.setOS(llvm::Triple::OSType::Win32); 282 return ArchSpec(triple); 283 } 284 285 Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr, 286 MemoryRegionInfo &range_info) { 287 Status error; 288 auto info = m_minidump_parser.GetMemoryRegionInfo(load_addr); 289 if (!info) { 290 error.SetErrorString("No valid MemoryRegionInfo found!"); 291 return error; 292 } 293 range_info = info.getValue(); 294 return error; 295 } 296 297 void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); } 298 299 bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, 300 ThreadList &new_thread_list) { 301 uint32_t num_threads = 0; 302 if (m_thread_list.size() > 0) 303 num_threads = m_thread_list.size(); 304 305 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { 306 llvm::ArrayRef<uint8_t> context; 307 if (!m_is_wow64) 308 context = m_minidump_parser.GetThreadContext(m_thread_list[tid]); 309 else 310 context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]); 311 312 lldb::ThreadSP thread_sp( 313 new ThreadMinidump(*this, m_thread_list[tid], context)); 314 new_thread_list.AddThread(thread_sp); 315 } 316 return new_thread_list.GetSize(false) > 0; 317 } 318 319 void ProcessMinidump::ReadModuleList() { 320 std::vector<const MinidumpModule *> filtered_modules = 321 m_minidump_parser.GetFilteredModuleList(); 322 323 for (auto module : filtered_modules) { 324 llvm::Optional<std::string> name = 325 m_minidump_parser.GetMinidumpString(module->module_name_rva); 326 327 if (!name) 328 continue; 329 330 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); 331 if (log) { 332 log->Printf("ProcessMinidump::%s found module: name: %s %#010" PRIx64 333 "-%#010" PRIx64 " size: %" PRIu32, 334 __FUNCTION__, name.getValue().c_str(), 335 uint64_t(module->base_of_image), 336 module->base_of_image + module->size_of_image, 337 uint32_t(module->size_of_image)); 338 } 339 340 // check if the process is wow64 - a 32 bit windows process running on a 341 // 64 bit windows 342 if (llvm::StringRef(name.getValue()).endswith_lower("wow64.dll")) { 343 m_is_wow64 = true; 344 } 345 346 const auto uuid = m_minidump_parser.GetModuleUUID(module); 347 auto file_spec = FileSpec(name.getValue(), GetArchitecture().GetTriple()); 348 FileSystem::Instance().Resolve(file_spec); 349 ModuleSpec module_spec(file_spec, uuid); 350 Status error; 351 lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error); 352 if (!module_sp || error.Fail()) { 353 // We failed to locate a matching local object file. Fortunately, the 354 // minidump format encodes enough information about each module's memory 355 // range to allow us to create placeholder modules. 356 // 357 // This enables most LLDB functionality involving address-to-module 358 // translations (ex. identifing the module for a stack frame PC) and 359 // modules/sections commands (ex. target modules list, ...) 360 if (log) { 361 log->Printf("Unable to locate the matching object file, creating a " 362 "placeholder module for: %s", 363 name.getValue().c_str()); 364 } 365 366 auto placeholder_module = 367 std::make_shared<PlaceholderModule>(module_spec); 368 placeholder_module->CreateImageSection(module, GetTarget()); 369 module_sp = placeholder_module; 370 GetTarget().GetImages().Append(module_sp); 371 } 372 373 if (log) { 374 log->Printf("ProcessMinidump::%s load module: name: %s", __FUNCTION__, 375 name.getValue().c_str()); 376 } 377 378 bool load_addr_changed = false; 379 module_sp->SetLoadAddress(GetTarget(), module->base_of_image, false, 380 load_addr_changed); 381 } 382 } 383 384 bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) { 385 info.Clear(); 386 info.SetProcessID(GetID()); 387 info.SetArchitecture(GetArchitecture()); 388 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); 389 if (module_sp) { 390 const bool add_exe_file_as_first_arg = false; 391 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 392 add_exe_file_as_first_arg); 393 } 394 return true; 395 } 396 397 // For minidumps there's no runtime generated code so we don't need JITLoader(s) 398 // Avoiding them will also speed up minidump loading since JITLoaders normally 399 // try to set up symbolic breakpoints, which in turn may force loading more 400 // debug information than needed. 401 JITLoaderList &ProcessMinidump::GetJITLoaders() { 402 if (!m_jit_loaders_ap) { 403 m_jit_loaders_ap = llvm::make_unique<JITLoaderList>(); 404 } 405 return *m_jit_loaders_ap; 406 } 407