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/RegisterContext.h" 23 #include "lldb/Utility/State.h" 24 25 #include <mutex> 26 27 LLDB_PLUGIN_DEFINE(ScriptedProcess) 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 llvm::StringRef ScriptedProcess::GetPluginDescriptionStatic() { 33 return "Scripted Process plug-in."; 34 } 35 36 static constexpr lldb::ScriptLanguage g_supported_script_languages[] = { 37 ScriptLanguage::eScriptLanguagePython, 38 }; 39 40 bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) { 41 llvm::ArrayRef<lldb::ScriptLanguage> supported_languages = 42 llvm::makeArrayRef(g_supported_script_languages); 43 44 return llvm::is_contained(supported_languages, language); 45 } 46 47 void ScriptedProcess::CheckInterpreterAndScriptObject() const { 48 lldbassert(m_interpreter && "Invalid Script Interpreter."); 49 lldbassert(m_script_object_sp && "Invalid Script Object."); 50 } 51 52 lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, 53 lldb::ListenerSP listener_sp, 54 const FileSpec *file, 55 bool can_connect) { 56 if (!target_sp || 57 !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage())) 58 return nullptr; 59 60 Status error; 61 ScriptedProcess::ScriptedProcessInfo scripted_process_info( 62 target_sp->GetProcessLaunchInfo()); 63 64 auto process_sp = std::make_shared<ScriptedProcess>( 65 target_sp, listener_sp, scripted_process_info, error); 66 67 if (error.Fail() || !process_sp || !process_sp->m_script_object_sp || 68 !process_sp->m_script_object_sp->IsValid()) { 69 LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s", 70 error.AsCString()); 71 return nullptr; 72 } 73 74 return process_sp; 75 } 76 77 bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp, 78 bool plugin_specified_by_name) { 79 return true; 80 } 81 82 ScriptedProcess::ScriptedProcess( 83 lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, 84 const ScriptedProcess::ScriptedProcessInfo &scripted_process_info, 85 Status &error) 86 : Process(target_sp, listener_sp), 87 m_scripted_process_info(scripted_process_info) { 88 89 if (!target_sp) { 90 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 91 __FUNCTION__, "Invalid target"); 92 return; 93 } 94 95 m_interpreter = target_sp->GetDebugger().GetScriptInterpreter(); 96 97 if (!m_interpreter) { 98 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 99 __FUNCTION__, 100 "Debugger has no Script Interpreter"); 101 return; 102 } 103 104 ExecutionContext exe_ctx(target_sp, /*get_process=*/false); 105 106 StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject( 107 m_scripted_process_info.GetClassName().c_str(), exe_ctx, 108 m_scripted_process_info.GetArgsSP()); 109 110 if (!object_sp || !object_sp->IsValid()) { 111 error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", 112 __FUNCTION__, 113 "Failed to create valid script object"); 114 return; 115 } 116 117 m_script_object_sp = object_sp; 118 } 119 120 ScriptedProcess::~ScriptedProcess() { 121 Clear(); 122 // We need to call finalize on the process before destroying ourselves to 123 // make sure all of the broadcaster cleanup goes as planned. If we destruct 124 // this class, then Process::~Process() might have problems trying to fully 125 // destroy the broadcaster. 126 Finalize(); 127 } 128 129 void ScriptedProcess::Initialize() { 130 static llvm::once_flag g_once_flag; 131 132 llvm::call_once(g_once_flag, []() { 133 PluginManager::RegisterPlugin(GetPluginNameStatic(), 134 GetPluginDescriptionStatic(), CreateInstance); 135 }); 136 } 137 138 void ScriptedProcess::Terminate() { 139 PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance); 140 } 141 142 Status ScriptedProcess::DoLoadCore() { 143 ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo(); 144 145 return DoLaunch(nullptr, launch_info); 146 } 147 148 Status ScriptedProcess::DoLaunch(Module *exe_module, 149 ProcessLaunchInfo &launch_info) { 150 CheckInterpreterAndScriptObject(); 151 152 /* FIXME: This doesn't reflect how lldb actually launches a process. 153 In reality, it attaches to debugserver, then resume the process. */ 154 Status error = GetInterface().Launch(); 155 SetPrivateState(eStateRunning); 156 157 if (error.Fail()) 158 return error; 159 160 // TODO: Fetch next state from stopped event queue then send stop event 161 // const StateType state = SetThreadStopInfo(response); 162 // if (state != eStateInvalid) { 163 // SetPrivateState(state); 164 165 SetPrivateState(eStateStopped); 166 167 UpdateThreadListIfNeeded(); 168 GetThreadList(); 169 170 return {}; 171 } 172 173 void ScriptedProcess::DidLaunch() { 174 CheckInterpreterAndScriptObject(); 175 m_pid = GetInterface().GetProcessID(); 176 } 177 178 Status ScriptedProcess::DoResume() { 179 CheckInterpreterAndScriptObject(); 180 181 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 182 // FIXME: Fetch data from thread. 183 const StateType thread_resume_state = eStateRunning; 184 LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__, 185 StateAsCString(thread_resume_state)); 186 187 bool resume = (thread_resume_state == eStateRunning); 188 assert(thread_resume_state == eStateRunning && "invalid thread resume state"); 189 190 Status error; 191 if (resume) { 192 LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__); 193 194 SetPrivateState(eStateRunning); 195 SetPrivateState(eStateStopped); 196 error = GetInterface().Resume(); 197 } 198 199 return error; 200 } 201 202 Status ScriptedProcess::DoStop() { 203 CheckInterpreterAndScriptObject(); 204 205 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 206 207 if (GetInterface().ShouldStop()) { 208 SetPrivateState(eStateStopped); 209 LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__); 210 return {}; 211 } 212 213 LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__); 214 return GetInterface().Stop(); 215 } 216 217 Status ScriptedProcess::DoDestroy() { return Status(); } 218 219 bool ScriptedProcess::IsAlive() { 220 if (m_interpreter && m_script_object_sp) 221 return GetInterface().IsAlive(); 222 return false; 223 } 224 225 size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 226 Status &error) { 227 if (!m_interpreter) 228 return GetInterface().ErrorWithMessage<size_t>(LLVM_PRETTY_FUNCTION, 229 "No interpreter.", error); 230 231 lldb::DataExtractorSP data_extractor_sp = 232 GetInterface().ReadMemoryAtAddress(addr, size, error); 233 234 if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail()) 235 return 0; 236 237 offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData( 238 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder()); 239 240 if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) 241 return GetInterface().ErrorWithMessage<size_t>( 242 LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error); 243 244 return size; 245 } 246 247 ArchSpec ScriptedProcess::GetArchitecture() { 248 return GetTarget().GetArchitecture(); 249 } 250 251 Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, 252 MemoryRegionInfo ®ion) { 253 CheckInterpreterAndScriptObject(); 254 255 Status error; 256 if (auto region_or_err = 257 GetInterface().GetMemoryRegionContainingAddress(load_addr, error)) 258 region = *region_or_err; 259 260 return error; 261 } 262 263 Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { 264 CheckInterpreterAndScriptObject(); 265 266 Status error; 267 lldb::addr_t address = 0; 268 269 while (auto region_or_err = 270 GetInterface().GetMemoryRegionContainingAddress(address, error)) { 271 if (error.Fail()) 272 break; 273 274 MemoryRegionInfo &mem_region = *region_or_err; 275 auto range = mem_region.GetRange(); 276 address += range.GetRangeBase() + range.GetByteSize(); 277 region_list.push_back(mem_region); 278 } 279 280 return error; 281 } 282 283 void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); } 284 285 bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, 286 ThreadList &new_thread_list) { 287 // TODO: Implement 288 // This is supposed to get the current set of threads, if any of them are in 289 // old_thread_list then they get copied to new_thread_list, and then any 290 // actually new threads will get added to new_thread_list. 291 292 CheckInterpreterAndScriptObject(); 293 m_thread_plans.ClearThreadCache(); 294 295 Status error; 296 ScriptLanguage language = m_interpreter->GetLanguage(); 297 298 if (language != eScriptLanguagePython) 299 return GetInterface().ErrorWithMessage<bool>( 300 LLVM_PRETTY_FUNCTION, 301 llvm::Twine("ScriptInterpreter language (" + 302 llvm::Twine(m_interpreter->LanguageToString(language)) + 303 llvm::Twine(") not supported.")) 304 .str(), 305 error); 306 307 lldb::ThreadSP thread_sp; 308 thread_sp = std::make_shared<ScriptedThread>(*this, error); 309 310 if (!thread_sp || error.Fail()) 311 return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, 312 error.AsCString(), error); 313 314 new_thread_list.AddThread(thread_sp); 315 316 return new_thread_list.GetSize(false) > 0; 317 } 318 319 void ScriptedProcess::RefreshStateAfterStop() { 320 // Let all threads recover from stopping and do any clean up based on the 321 // previous thread state (if any). 322 m_thread_list.RefreshStateAfterStop(); 323 } 324 325 bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { 326 info.Clear(); 327 info.SetProcessID(GetID()); 328 info.SetArchitecture(GetArchitecture()); 329 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); 330 if (module_sp) { 331 const bool add_exe_file_as_first_arg = false; 332 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 333 add_exe_file_as_first_arg); 334 } 335 return true; 336 } 337 338 ScriptedProcessInterface &ScriptedProcess::GetInterface() const { 339 return m_interpreter->GetScriptedProcessInterface(); 340 } 341