1 //===-- ScriptedProcess.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ScriptedProcess.h" 10 11 #include "lldb/Core/Debugger.h" 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/PluginManager.h" 14 15 #include "lldb/Host/OptionParser.h" 16 #include "lldb/Host/ThreadLauncher.h" 17 #include "lldb/Interpreter/CommandInterpreter.h" 18 #include "lldb/Interpreter/OptionArgParser.h" 19 #include "lldb/Interpreter/OptionGroupBoolean.h" 20 #include "lldb/Interpreter/ScriptInterpreter.h" 21 #include "lldb/Target/MemoryRegionInfo.h" 22 #include "lldb/Target/Queue.h" 23 #include "lldb/Target/RegisterContext.h" 24 #include "lldb/Utility/LLDBLog.h" 25 #include "lldb/Utility/ScriptedMetadata.h" 26 #include "lldb/Utility/State.h" 27 28 #include <mutex> 29 30 LLDB_PLUGIN_DEFINE(ScriptedProcess) 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 llvm::StringRef ScriptedProcess::GetPluginDescriptionStatic() { 36 return "Scripted Process plug-in."; 37 } 38 39 static constexpr lldb::ScriptLanguage g_supported_script_languages[] = { 40 ScriptLanguage::eScriptLanguagePython, 41 }; 42 43 bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) { 44 llvm::ArrayRef<lldb::ScriptLanguage> supported_languages = 45 llvm::ArrayRef(g_supported_script_languages); 46 47 return llvm::is_contained(supported_languages, language); 48 } 49 50 lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, 51 lldb::ListenerSP listener_sp, 52 const FileSpec *file, 53 bool can_connect) { 54 if (!target_sp || 55 !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage())) 56 return nullptr; 57 58 ScriptedMetadata scripted_metadata(target_sp->GetProcessLaunchInfo()); 59 60 Status error; 61 auto process_sp = std::shared_ptr<ScriptedProcess>( 62 new ScriptedProcess(target_sp, listener_sp, scripted_metadata, error)); 63 64 if (error.Fail() || !process_sp || !process_sp->m_interface_up) { 65 LLDB_LOGF(GetLog(LLDBLog::Process), "%s", error.AsCString()); 66 return nullptr; 67 } 68 69 return process_sp; 70 } 71 72 bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp, 73 bool plugin_specified_by_name) { 74 return true; 75 } 76 77 ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp, 78 lldb::ListenerSP listener_sp, 79 const ScriptedMetadata &scripted_metadata, 80 Status &error) 81 : Process(target_sp, listener_sp), m_scripted_metadata(scripted_metadata) { 82 83 if (!target_sp) { 84 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 85 __FUNCTION__, "Invalid target"); 86 return; 87 } 88 89 ScriptInterpreter *interpreter = 90 target_sp->GetDebugger().GetScriptInterpreter(); 91 92 if (!interpreter) { 93 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 94 __FUNCTION__, 95 "Debugger has no Script Interpreter"); 96 return; 97 } 98 99 // Create process instance interface 100 m_interface_up = interpreter->CreateScriptedProcessInterface(); 101 if (!m_interface_up) { 102 error.SetErrorStringWithFormat( 103 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__, 104 "Script interpreter couldn't create Scripted Process Interface"); 105 return; 106 } 107 108 ExecutionContext exe_ctx(target_sp, /*get_process=*/false); 109 110 // Create process script object 111 StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject( 112 m_scripted_metadata.GetClassName(), exe_ctx, 113 m_scripted_metadata.GetArgsSP()); 114 115 if (!object_sp || !object_sp->IsValid()) { 116 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 117 __FUNCTION__, 118 "Failed to create valid script object"); 119 return; 120 } 121 } 122 123 ScriptedProcess::~ScriptedProcess() { 124 Clear(); 125 // We need to call finalize on the process before destroying ourselves to 126 // make sure all of the broadcaster cleanup goes as planned. If we destruct 127 // this class, then Process::~Process() might have problems trying to fully 128 // destroy the broadcaster. 129 Finalize(); 130 } 131 132 void ScriptedProcess::Initialize() { 133 static llvm::once_flag g_once_flag; 134 135 llvm::call_once(g_once_flag, []() { 136 PluginManager::RegisterPlugin(GetPluginNameStatic(), 137 GetPluginDescriptionStatic(), CreateInstance); 138 }); 139 } 140 141 void ScriptedProcess::Terminate() { 142 PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance); 143 } 144 145 Status ScriptedProcess::DoLoadCore() { 146 ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo(); 147 148 return DoLaunch(nullptr, launch_info); 149 } 150 151 Status ScriptedProcess::DoLaunch(Module *exe_module, 152 ProcessLaunchInfo &launch_info) { 153 /* FIXME: This doesn't reflect how lldb actually launches a process. 154 In reality, it attaches to debugserver, then resume the process. */ 155 Status error = GetInterface().Launch(); 156 SetPrivateState(eStateRunning); 157 158 if (error.Fail()) 159 return error; 160 161 // TODO: Fetch next state from stopped event queue then send stop event 162 // const StateType state = SetThreadStopInfo(response); 163 // if (state != eStateInvalid) { 164 // SetPrivateState(state); 165 166 SetPrivateState(eStateStopped); 167 168 return {}; 169 } 170 171 void ScriptedProcess::DidLaunch() { 172 m_pid = GetInterface().GetProcessID(); 173 GetLoadedDynamicLibrariesInfos(); 174 } 175 176 Status ScriptedProcess::DoResume() { 177 Log *log = GetLog(LLDBLog::Process); 178 // FIXME: Fetch data from thread. 179 const StateType thread_resume_state = eStateRunning; 180 LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__, 181 StateAsCString(thread_resume_state)); 182 183 bool resume = (thread_resume_state == eStateRunning); 184 assert(thread_resume_state == eStateRunning && "invalid thread resume state"); 185 186 Status error; 187 if (resume) { 188 LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__); 189 190 SetPrivateState(eStateRunning); 191 SetPrivateState(eStateStopped); 192 error = GetInterface().Resume(); 193 } 194 195 return error; 196 } 197 198 Status ScriptedProcess::DoAttach(const ProcessAttachInfo &attach_info) { 199 Status error = GetInterface().Attach(attach_info); 200 SetPrivateState(eStateRunning); 201 SetPrivateState(eStateStopped); 202 if (error.Fail()) 203 return error; 204 // NOTE: We need to set the PID before finishing to attach otherwise we will 205 // hit an assert when calling the attach completion handler. 206 DidLaunch(); 207 208 return {}; 209 } 210 211 Status 212 ScriptedProcess::DoAttachToProcessWithID(lldb::pid_t pid, 213 const ProcessAttachInfo &attach_info) { 214 return DoAttach(attach_info); 215 } 216 217 Status ScriptedProcess::DoAttachToProcessWithName( 218 const char *process_name, const ProcessAttachInfo &attach_info) { 219 return DoAttach(attach_info); 220 } 221 222 void ScriptedProcess::DidAttach(ArchSpec &process_arch) { 223 process_arch = GetArchitecture(); 224 } 225 226 Status ScriptedProcess::DoStop() { 227 Log *log = GetLog(LLDBLog::Process); 228 229 if (GetInterface().ShouldStop()) { 230 SetPrivateState(eStateStopped); 231 LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__); 232 return {}; 233 } 234 235 LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__); 236 return GetInterface().Stop(); 237 } 238 239 Status ScriptedProcess::DoDestroy() { return Status(); } 240 241 bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); } 242 243 size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 244 Status &error) { 245 lldb::DataExtractorSP data_extractor_sp = 246 GetInterface().ReadMemoryAtAddress(addr, size, error); 247 248 if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail()) 249 return 0; 250 251 offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData( 252 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder()); 253 254 if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) 255 return ScriptedInterface::ErrorWithMessage<size_t>( 256 LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error); 257 258 // FIXME: We should use the diagnostic system to report a warning if the 259 // `bytes_copied` is different from `size`. 260 261 return bytes_copied; 262 } 263 264 size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 265 size_t size, Status &error) { 266 lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>( 267 buf, size, GetByteOrder(), GetAddressByteSize()); 268 269 if (!data_extractor_sp || !data_extractor_sp->GetByteSize()) 270 return 0; 271 272 size_t bytes_written = 273 GetInterface().WriteMemoryAtAddress(vm_addr, data_extractor_sp, error); 274 275 if (!bytes_written || bytes_written == LLDB_INVALID_OFFSET) 276 return ScriptedInterface::ErrorWithMessage<size_t>( 277 LLVM_PRETTY_FUNCTION, "Failed to copy write buffer to memory.", error); 278 279 // FIXME: We should use the diagnostic system to report a warning if the 280 // `bytes_written` is different from `size`. 281 282 return bytes_written; 283 } 284 285 Status ScriptedProcess::EnableBreakpointSite(BreakpointSite *bp_site) { 286 assert(bp_site != nullptr); 287 288 if (bp_site->IsEnabled()) { 289 return {}; 290 } 291 292 if (bp_site->HardwareRequired()) { 293 return Status("Scripted Processes don't support hardware breakpoints"); 294 } 295 296 return EnableSoftwareBreakpoint(bp_site); 297 } 298 299 ArchSpec ScriptedProcess::GetArchitecture() { 300 return GetTarget().GetArchitecture(); 301 } 302 303 Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, 304 MemoryRegionInfo ®ion) { 305 Status error; 306 if (auto region_or_err = 307 GetInterface().GetMemoryRegionContainingAddress(load_addr, error)) 308 region = *region_or_err; 309 310 return error; 311 } 312 313 Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { 314 Status error; 315 lldb::addr_t address = 0; 316 317 while (auto region_or_err = 318 GetInterface().GetMemoryRegionContainingAddress(address, error)) { 319 if (error.Fail()) 320 break; 321 322 MemoryRegionInfo &mem_region = *region_or_err; 323 auto range = mem_region.GetRange(); 324 address += range.GetRangeBase() + range.GetByteSize(); 325 region_list.push_back(mem_region); 326 } 327 328 return error; 329 } 330 331 void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); } 332 333 bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, 334 ThreadList &new_thread_list) { 335 // TODO: Implement 336 // This is supposed to get the current set of threads, if any of them are in 337 // old_thread_list then they get copied to new_thread_list, and then any 338 // actually new threads will get added to new_thread_list. 339 m_thread_plans.ClearThreadCache(); 340 341 Status error; 342 StructuredData::DictionarySP thread_info_sp = GetInterface().GetThreadsInfo(); 343 344 if (!thread_info_sp) 345 return ScriptedInterface::ErrorWithMessage<bool>( 346 LLVM_PRETTY_FUNCTION, 347 "Couldn't fetch thread list from Scripted Process.", error); 348 349 // Because `StructuredData::Dictionary` uses a `std::map<ConstString, 350 // ObjectSP>` for storage, each item is sorted based on the key alphabetical 351 // order. Since `GetThreadsInfo` provides thread indices as the key element, 352 // thread info comes ordered alphabetically, instead of numerically, so we 353 // need to sort the thread indices before creating thread. 354 355 StructuredData::ArraySP keys = thread_info_sp->GetKeys(); 356 357 std::map<size_t, StructuredData::ObjectSP> sorted_threads; 358 auto sort_keys = [&sorted_threads, 359 &thread_info_sp](StructuredData::Object *item) -> bool { 360 if (!item) 361 return false; 362 363 llvm::StringRef key = item->GetStringValue(); 364 size_t idx = 0; 365 366 // Make sure the provided index is actually an integer 367 if (!llvm::to_integer(key, idx)) 368 return false; 369 370 sorted_threads[idx] = thread_info_sp->GetValueForKey(key); 371 return true; 372 }; 373 374 size_t thread_count = thread_info_sp->GetSize(); 375 376 if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count) 377 // Might be worth showing the unsorted thread list instead of return early. 378 return ScriptedInterface::ErrorWithMessage<bool>( 379 LLVM_PRETTY_FUNCTION, "Couldn't sort thread list.", error); 380 381 auto create_scripted_thread = 382 [this, &error, &new_thread_list]( 383 const std::pair<size_t, StructuredData::ObjectSP> pair) -> bool { 384 size_t idx = pair.first; 385 StructuredData::ObjectSP object_sp = pair.second; 386 387 if (!object_sp) 388 return ScriptedInterface::ErrorWithMessage<bool>( 389 LLVM_PRETTY_FUNCTION, "Invalid thread info object", error); 390 391 auto thread_or_error = 392 ScriptedThread::Create(*this, object_sp->GetAsGeneric()); 393 394 if (!thread_or_error) 395 return ScriptedInterface::ErrorWithMessage<bool>( 396 LLVM_PRETTY_FUNCTION, toString(thread_or_error.takeError()), error); 397 398 ThreadSP thread_sp = thread_or_error.get(); 399 lldbassert(thread_sp && "Couldn't initialize scripted thread."); 400 401 RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); 402 if (!reg_ctx_sp) 403 return ScriptedInterface::ErrorWithMessage<bool>( 404 LLVM_PRETTY_FUNCTION, 405 llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx)) 406 .str(), 407 error); 408 409 new_thread_list.AddThread(thread_sp); 410 411 return true; 412 }; 413 414 llvm::for_each(sorted_threads, create_scripted_thread); 415 416 return new_thread_list.GetSize(false) > 0; 417 } 418 419 void ScriptedProcess::RefreshStateAfterStop() { 420 // Let all threads recover from stopping and do any clean up based on the 421 // previous thread state (if any). 422 m_thread_list.RefreshStateAfterStop(); 423 } 424 425 bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { 426 info.Clear(); 427 info.SetProcessID(GetID()); 428 info.SetArchitecture(GetArchitecture()); 429 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); 430 if (module_sp) { 431 const bool add_exe_file_as_first_arg = false; 432 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 433 add_exe_file_as_first_arg); 434 } 435 return true; 436 } 437 438 lldb_private::StructuredData::ObjectSP 439 ScriptedProcess::GetLoadedDynamicLibrariesInfos() { 440 Status error; 441 auto error_with_message = [&error](llvm::StringRef message) { 442 return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, 443 message.data(), error); 444 }; 445 446 StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages(); 447 448 if (!loaded_images_sp || !loaded_images_sp->GetSize()) 449 return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>( 450 LLVM_PRETTY_FUNCTION, "No loaded images.", error); 451 452 ModuleList module_list; 453 Target &target = GetTarget(); 454 455 auto reload_image = [&target, &module_list, &error_with_message]( 456 StructuredData::Object *obj) -> bool { 457 StructuredData::Dictionary *dict = obj->GetAsDictionary(); 458 459 if (!dict) 460 return error_with_message("Couldn't cast image object into dictionary."); 461 462 ModuleSpec module_spec; 463 llvm::StringRef value; 464 465 bool has_path = dict->HasKey("path"); 466 bool has_uuid = dict->HasKey("uuid"); 467 if (!has_path && !has_uuid) 468 return error_with_message("Dictionary should have key 'path' or 'uuid'"); 469 if (!dict->HasKey("load_addr")) 470 return error_with_message("Dictionary is missing key 'load_addr'"); 471 472 if (has_path) { 473 dict->GetValueForKeyAsString("path", value); 474 module_spec.GetFileSpec().SetPath(value); 475 } 476 477 if (has_uuid) { 478 dict->GetValueForKeyAsString("uuid", value); 479 module_spec.GetUUID().SetFromStringRef(value); 480 } 481 module_spec.GetArchitecture() = target.GetArchitecture(); 482 483 ModuleSP module_sp = 484 target.GetOrCreateModule(module_spec, true /* notify */); 485 486 if (!module_sp) 487 return error_with_message("Couldn't create or get module."); 488 489 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 490 lldb::addr_t slide = LLDB_INVALID_OFFSET; 491 dict->GetValueForKeyAsInteger("load_addr", load_addr); 492 dict->GetValueForKeyAsInteger("slide", slide); 493 if (load_addr == LLDB_INVALID_ADDRESS) 494 return error_with_message( 495 "Couldn't get valid load address or slide offset."); 496 497 if (slide != LLDB_INVALID_OFFSET) 498 load_addr += slide; 499 500 bool changed = false; 501 module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/, 502 changed); 503 504 if (!changed && !module_sp->GetObjectFile()) 505 return error_with_message("Couldn't set the load address for module."); 506 507 dict->GetValueForKeyAsString("path", value); 508 FileSpec objfile(value); 509 module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename()); 510 511 return module_list.AppendIfNeeded(module_sp); 512 }; 513 514 if (!loaded_images_sp->ForEach(reload_image)) 515 return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>( 516 LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error); 517 518 target.ModulesDidLoad(module_list); 519 520 return loaded_images_sp; 521 } 522 523 lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() { 524 StructuredData::DictionarySP metadata_sp = GetInterface().GetMetadata(); 525 526 Status error; 527 if (!metadata_sp || !metadata_sp->GetSize()) 528 return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>( 529 LLVM_PRETTY_FUNCTION, "No metadata.", error); 530 531 return metadata_sp; 532 } 533 534 void ScriptedProcess::UpdateQueueListIfNeeded() { 535 CheckScriptedInterface(); 536 for (ThreadSP thread_sp : Threads()) { 537 if (const char *queue_name = thread_sp->GetQueueName()) { 538 QueueSP queue_sp = std::make_shared<Queue>( 539 m_process->shared_from_this(), thread_sp->GetQueueID(), queue_name); 540 m_queue_list.AddQueue(queue_sp); 541 } 542 } 543 } 544 545 ScriptedProcessInterface &ScriptedProcess::GetInterface() const { 546 CheckScriptedInterface(); 547 return *m_interface_up; 548 } 549 550 void *ScriptedProcess::GetImplementation() { 551 StructuredData::GenericSP object_instance_sp = 552 GetInterface().GetScriptObjectInstance(); 553 if (object_instance_sp && 554 object_instance_sp->GetType() == eStructuredDataTypeGeneric) 555 return object_instance_sp->GetAsGeneric()->GetValue(); 556 return nullptr; 557 } 558