xref: /llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp (revision 4f297566b3150097de26c6a23a987d2bd5fc19c5)
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 = Status::FromErrorStringWithFormat(
85         "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__, "Invalid target");
86     return;
87   }
88 
89   ScriptInterpreter *interpreter =
90       target_sp->GetDebugger().GetScriptInterpreter();
91 
92   if (!interpreter) {
93     error = Status::FromErrorStringWithFormat(
94         "ScriptedProcess::%s () - ERROR: %s", __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 = Status::FromErrorStringWithFormat(
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   auto obj_or_err = GetInterface().CreatePluginObject(
112       m_scripted_metadata.GetClassName(), exe_ctx,
113       m_scripted_metadata.GetArgsSP());
114 
115   if (!obj_or_err) {
116     llvm::consumeError(obj_or_err.takeError());
117     error = Status::FromErrorString("Failed to create script object.");
118     return;
119   }
120 
121   StructuredData::GenericSP object_sp = *obj_or_err;
122 
123   if (!object_sp || !object_sp->IsValid()) {
124     error = Status::FromErrorStringWithFormat(
125         "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
126         "Failed to create valid script object");
127     return;
128   }
129 }
130 
131 ScriptedProcess::~ScriptedProcess() {
132   Clear();
133   // If the interface is not valid, we can't call Finalize(). When that happens
134   // it means that the Scripted Process instanciation failed and the
135   // CreateProcess function returns a nullptr, so no one besides this class
136   // should have access to that bogus process object.
137   if (!m_interface_up)
138     return;
139   // We need to call finalize on the process before destroying ourselves to
140   // make sure all of the broadcaster cleanup goes as planned. If we destruct
141   // this class, then Process::~Process() might have problems trying to fully
142   // destroy the broadcaster.
143   Finalize(true /* destructing */);
144 }
145 
146 void ScriptedProcess::Initialize() {
147   static llvm::once_flag g_once_flag;
148 
149   llvm::call_once(g_once_flag, []() {
150     PluginManager::RegisterPlugin(GetPluginNameStatic(),
151                                   GetPluginDescriptionStatic(), CreateInstance);
152   });
153 }
154 
155 void ScriptedProcess::Terminate() {
156   PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance);
157 }
158 
159 Status ScriptedProcess::DoLoadCore() {
160   ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();
161 
162   return DoLaunch(nullptr, launch_info);
163 }
164 
165 Status ScriptedProcess::DoLaunch(Module *exe_module,
166                                  ProcessLaunchInfo &launch_info) {
167   LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__);
168 
169   /* MARK: This doesn't reflect how lldb actually launches a process.
170            In reality, it attaches to debugserver, then resume the process.
171            That's not true in all cases.  If debugserver is remote, lldb
172            asks debugserver to launch the process for it. */
173   Status error = GetInterface().Launch();
174   SetPrivateState(eStateStopped);
175   return error;
176 }
177 
178 void ScriptedProcess::DidLaunch() { m_pid = GetInterface().GetProcessID(); }
179 
180 void ScriptedProcess::DidResume() {
181   // Update the PID again, in case the user provided a placeholder pid at launch
182   m_pid = GetInterface().GetProcessID();
183 }
184 
185 Status ScriptedProcess::DoResume(RunDirection direction) {
186   LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s resuming process", __FUNCTION__);
187 
188   if (direction == RunDirection::eRunForward) {
189     return GetInterface().Resume();
190   } else {
191     return Status::FromErrorStringWithFormatv(
192         "error: {0} does not support reverse execution of processes", GetPluginName());
193   }
194 }
195 
196 Status ScriptedProcess::DoAttach(const ProcessAttachInfo &attach_info) {
197   Status error = GetInterface().Attach(attach_info);
198   SetPrivateState(eStateRunning);
199   SetPrivateState(eStateStopped);
200   if (error.Fail())
201     return error;
202   // NOTE: We need to set the PID before finishing to attach otherwise we will
203   // hit an assert when calling the attach completion handler.
204   DidLaunch();
205 
206   return {};
207 }
208 
209 Status
210 ScriptedProcess::DoAttachToProcessWithID(lldb::pid_t pid,
211                                          const ProcessAttachInfo &attach_info) {
212   return DoAttach(attach_info);
213 }
214 
215 Status ScriptedProcess::DoAttachToProcessWithName(
216     const char *process_name, const ProcessAttachInfo &attach_info) {
217   return DoAttach(attach_info);
218 }
219 
220 void ScriptedProcess::DidAttach(ArchSpec &process_arch) {
221   process_arch = GetArchitecture();
222 }
223 
224 Status ScriptedProcess::DoDestroy() { return Status(); }
225 
226 bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); }
227 
228 size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
229                                      Status &error) {
230   lldb::DataExtractorSP data_extractor_sp =
231       GetInterface().ReadMemoryAtAddress(addr, size, error);
232 
233   if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
234     return 0;
235 
236   offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
237       0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
238 
239   if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
240     return ScriptedInterface::ErrorWithMessage<size_t>(
241         LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error);
242 
243   // FIXME: We should use the diagnostic system to report a warning if the
244   // `bytes_copied` is different from `size`.
245 
246   return bytes_copied;
247 }
248 
249 size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
250                                       size_t size, Status &error) {
251   lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>(
252       buf, size, GetByteOrder(), GetAddressByteSize());
253 
254   if (!data_extractor_sp || !data_extractor_sp->GetByteSize())
255     return 0;
256 
257   lldb::offset_t bytes_written =
258       GetInterface().WriteMemoryAtAddress(vm_addr, data_extractor_sp, error);
259 
260   if (!bytes_written || bytes_written == LLDB_INVALID_OFFSET)
261     return ScriptedInterface::ErrorWithMessage<size_t>(
262         LLVM_PRETTY_FUNCTION, "Failed to copy write buffer to memory.", error);
263 
264   // FIXME: We should use the diagnostic system to report a warning if the
265   // `bytes_written` is different from `size`.
266 
267   return bytes_written;
268 }
269 
270 Status ScriptedProcess::EnableBreakpointSite(BreakpointSite *bp_site) {
271   assert(bp_site != nullptr);
272 
273   if (bp_site->IsEnabled()) {
274     return {};
275   }
276 
277   if (bp_site->HardwareRequired()) {
278     return Status::FromErrorString(
279         "Scripted Processes don't support hardware breakpoints");
280   }
281 
282   Status error;
283   GetInterface().CreateBreakpoint(bp_site->GetLoadAddress(), error);
284 
285   return error;
286 }
287 
288 ArchSpec ScriptedProcess::GetArchitecture() {
289   return GetTarget().GetArchitecture();
290 }
291 
292 Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
293                                               MemoryRegionInfo &region) {
294   Status error;
295   if (auto region_or_err =
296           GetInterface().GetMemoryRegionContainingAddress(load_addr, error))
297     region = *region_or_err;
298 
299   return error;
300 }
301 
302 Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos &region_list) {
303   Status error;
304   lldb::addr_t address = 0;
305 
306   while (auto region_or_err =
307              GetInterface().GetMemoryRegionContainingAddress(address, error)) {
308     if (error.Fail())
309       break;
310 
311     MemoryRegionInfo &mem_region = *region_or_err;
312     auto range = mem_region.GetRange();
313     address += range.GetRangeBase() + range.GetByteSize();
314     region_list.push_back(mem_region);
315   }
316 
317   return error;
318 }
319 
320 void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }
321 
322 bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
323                                          ThreadList &new_thread_list) {
324   // TODO: Implement
325   // This is supposed to get the current set of threads, if any of them are in
326   // old_thread_list then they get copied to new_thread_list, and then any
327   // actually new threads will get added to new_thread_list.
328   m_thread_plans.ClearThreadCache();
329 
330   Status error;
331   StructuredData::DictionarySP thread_info_sp = GetInterface().GetThreadsInfo();
332 
333   if (!thread_info_sp)
334     return ScriptedInterface::ErrorWithMessage<bool>(
335         LLVM_PRETTY_FUNCTION,
336         "Couldn't fetch thread list from Scripted Process.", error);
337 
338   // Because `StructuredData::Dictionary` uses a `std::map<ConstString,
339   // ObjectSP>` for storage, each item is sorted based on the key alphabetical
340   // order. Since `GetThreadsInfo` provides thread indices as the key element,
341   // thread info comes ordered alphabetically, instead of numerically, so we
342   // need to sort the thread indices before creating thread.
343 
344   StructuredData::ArraySP keys = thread_info_sp->GetKeys();
345 
346   std::map<size_t, StructuredData::ObjectSP> sorted_threads;
347   auto sort_keys = [&sorted_threads,
348                     &thread_info_sp](StructuredData::Object *item) -> bool {
349     if (!item)
350       return false;
351 
352     llvm::StringRef key = item->GetStringValue();
353     size_t idx = 0;
354 
355     // Make sure the provided index is actually an integer
356     if (!llvm::to_integer(key, idx))
357       return false;
358 
359     sorted_threads[idx] = thread_info_sp->GetValueForKey(key);
360     return true;
361   };
362 
363   size_t thread_count = thread_info_sp->GetSize();
364 
365   if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count)
366     // Might be worth showing the unsorted thread list instead of return early.
367     return ScriptedInterface::ErrorWithMessage<bool>(
368         LLVM_PRETTY_FUNCTION, "Couldn't sort thread list.", error);
369 
370   auto create_scripted_thread =
371       [this, &error, &new_thread_list](
372           const std::pair<size_t, StructuredData::ObjectSP> pair) -> bool {
373     size_t idx = pair.first;
374     StructuredData::ObjectSP object_sp = pair.second;
375 
376     if (!object_sp)
377       return ScriptedInterface::ErrorWithMessage<bool>(
378           LLVM_PRETTY_FUNCTION, "Invalid thread info object", error);
379 
380     auto thread_or_error =
381         ScriptedThread::Create(*this, object_sp->GetAsGeneric());
382 
383     if (!thread_or_error)
384       return ScriptedInterface::ErrorWithMessage<bool>(
385           LLVM_PRETTY_FUNCTION, toString(thread_or_error.takeError()), error);
386 
387     ThreadSP thread_sp = thread_or_error.get();
388     lldbassert(thread_sp && "Couldn't initialize scripted thread.");
389 
390     RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
391     if (!reg_ctx_sp)
392       return ScriptedInterface::ErrorWithMessage<bool>(
393           LLVM_PRETTY_FUNCTION,
394           llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx))
395               .str(),
396           error);
397 
398     new_thread_list.AddThread(thread_sp);
399 
400     return true;
401   };
402 
403   llvm::for_each(sorted_threads, create_scripted_thread);
404 
405   return new_thread_list.GetSize(false) > 0;
406 }
407 
408 void ScriptedProcess::RefreshStateAfterStop() {
409   // Let all threads recover from stopping and do any clean up based on the
410   // previous thread state (if any).
411   m_thread_list.RefreshStateAfterStop();
412 }
413 
414 bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
415   info.Clear();
416   info.SetProcessID(GetID());
417   info.SetArchitecture(GetArchitecture());
418   lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
419   if (module_sp) {
420     const bool add_exe_file_as_first_arg = false;
421     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
422                            add_exe_file_as_first_arg);
423   }
424   return true;
425 }
426 
427 lldb_private::StructuredData::ObjectSP
428 ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
429   Status error;
430   auto error_with_message = [&error](llvm::StringRef message) {
431     return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
432                                                      message.data(), error);
433   };
434 
435   StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages();
436 
437   if (!loaded_images_sp || !loaded_images_sp->GetSize())
438     return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
439         LLVM_PRETTY_FUNCTION, "No loaded images.", error);
440 
441   ModuleList module_list;
442   Target &target = GetTarget();
443 
444   auto reload_image = [&target, &module_list, &error_with_message](
445                           StructuredData::Object *obj) -> bool {
446     StructuredData::Dictionary *dict = obj->GetAsDictionary();
447 
448     if (!dict)
449       return error_with_message("Couldn't cast image object into dictionary.");
450 
451     ModuleSpec module_spec;
452     llvm::StringRef value;
453 
454     bool has_path = dict->HasKey("path");
455     bool has_uuid = dict->HasKey("uuid");
456     if (!has_path && !has_uuid)
457       return error_with_message("Dictionary should have key 'path' or 'uuid'");
458     if (!dict->HasKey("load_addr"))
459       return error_with_message("Dictionary is missing key 'load_addr'");
460 
461     if (has_path) {
462       dict->GetValueForKeyAsString("path", value);
463       module_spec.GetFileSpec().SetPath(value);
464     }
465 
466     if (has_uuid) {
467       dict->GetValueForKeyAsString("uuid", value);
468       module_spec.GetUUID().SetFromStringRef(value);
469     }
470     module_spec.GetArchitecture() = target.GetArchitecture();
471 
472     ModuleSP module_sp =
473         target.GetOrCreateModule(module_spec, true /* notify */);
474 
475     if (!module_sp)
476       return error_with_message("Couldn't create or get module.");
477 
478     lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
479     lldb::offset_t slide = LLDB_INVALID_OFFSET;
480     dict->GetValueForKeyAsInteger("load_addr", load_addr);
481     dict->GetValueForKeyAsInteger("slide", slide);
482     if (load_addr == LLDB_INVALID_ADDRESS)
483       return error_with_message(
484           "Couldn't get valid load address or slide offset.");
485 
486     if (slide != LLDB_INVALID_OFFSET)
487       load_addr += slide;
488 
489     bool changed = false;
490     module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/,
491                               changed);
492 
493     if (!changed && !module_sp->GetObjectFile())
494       return error_with_message("Couldn't set the load address for module.");
495 
496     dict->GetValueForKeyAsString("path", value);
497     FileSpec objfile(value);
498     module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename());
499 
500     return module_list.AppendIfNeeded(module_sp);
501   };
502 
503   if (!loaded_images_sp->ForEach(reload_image))
504     return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
505         LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error);
506 
507   target.ModulesDidLoad(module_list);
508 
509   return loaded_images_sp;
510 }
511 
512 lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() {
513   StructuredData::DictionarySP metadata_sp = GetInterface().GetMetadata();
514 
515   Status error;
516   if (!metadata_sp || !metadata_sp->GetSize())
517     return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>(
518         LLVM_PRETTY_FUNCTION, "No metadata.", error);
519 
520   return metadata_sp;
521 }
522 
523 void ScriptedProcess::UpdateQueueListIfNeeded() {
524   CheckScriptedInterface();
525   for (ThreadSP thread_sp : Threads()) {
526     if (const char *queue_name = thread_sp->GetQueueName()) {
527       QueueSP queue_sp = std::make_shared<Queue>(
528           m_process->shared_from_this(), thread_sp->GetQueueID(), queue_name);
529       m_queue_list.AddQueue(queue_sp);
530     }
531   }
532 }
533 
534 ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
535   CheckScriptedInterface();
536   return *m_interface_up;
537 }
538 
539 void *ScriptedProcess::GetImplementation() {
540   StructuredData::GenericSP object_instance_sp =
541       GetInterface().GetScriptObjectInstance();
542   if (object_instance_sp &&
543       object_instance_sp->GetType() == eStructuredDataTypeGeneric)
544     return object_instance_sp->GetAsGeneric()->GetValue();
545   return nullptr;
546 }
547