1 //===-- ScriptedProcess.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ScriptedProcess.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/PluginManager.h"
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"
30 LLDB_PLUGIN_DEFINE(ScriptedProcess
)
33 using namespace lldb_private
;
35 llvm::StringRef
ScriptedProcess::GetPluginDescriptionStatic() {
36 return "Scripted Process plug-in.";
39 static constexpr lldb::ScriptLanguage g_supported_script_languages
[] = {
40 ScriptLanguage::eScriptLanguagePython
,
43 bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language
) {
44 llvm::ArrayRef
<lldb::ScriptLanguage
> supported_languages
=
45 llvm::ArrayRef(g_supported_script_languages
);
47 return llvm::is_contained(supported_languages
, language
);
50 lldb::ProcessSP
ScriptedProcess::CreateInstance(lldb::TargetSP target_sp
,
51 lldb::ListenerSP listener_sp
,
55 !IsScriptLanguageSupported(target_sp
->GetDebugger().GetScriptLanguage()))
58 ScriptedMetadata
scripted_metadata(target_sp
->GetProcessLaunchInfo());
61 auto process_sp
= std::shared_ptr
<ScriptedProcess
>(
62 new ScriptedProcess(target_sp
, listener_sp
, scripted_metadata
, error
));
64 if (error
.Fail() || !process_sp
|| !process_sp
->m_interface_up
) {
65 LLDB_LOGF(GetLog(LLDBLog::Process
), "%s", error
.AsCString());
72 bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp
,
73 bool plugin_specified_by_name
) {
77 ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp
,
78 lldb::ListenerSP listener_sp
,
79 const ScriptedMetadata
&scripted_metadata
,
81 : Process(target_sp
, listener_sp
), m_scripted_metadata(scripted_metadata
) {
84 error
.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
85 __FUNCTION__
, "Invalid target");
89 ScriptInterpreter
*interpreter
=
90 target_sp
->GetDebugger().GetScriptInterpreter();
93 error
.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
95 "Debugger has no Script Interpreter");
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");
108 ExecutionContext
exe_ctx(target_sp
, /*get_process=*/false);
110 // Create process script object
111 auto obj_or_err
= GetInterface().CreatePluginObject(
112 m_scripted_metadata
.GetClassName(), exe_ctx
,
113 m_scripted_metadata
.GetArgsSP());
116 llvm::consumeError(obj_or_err
.takeError());
117 error
.SetErrorString("Failed to create script object.");
121 StructuredData::GenericSP object_sp
= *obj_or_err
;
123 if (!object_sp
|| !object_sp
->IsValid()) {
124 error
.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
126 "Failed to create valid script object");
131 ScriptedProcess::~ScriptedProcess() {
133 // We need to call finalize on the process before destroying ourselves to
134 // make sure all of the broadcaster cleanup goes as planned. If we destruct
135 // this class, then Process::~Process() might have problems trying to fully
136 // destroy the broadcaster.
140 void ScriptedProcess::Initialize() {
141 static llvm::once_flag g_once_flag
;
143 llvm::call_once(g_once_flag
, []() {
144 PluginManager::RegisterPlugin(GetPluginNameStatic(),
145 GetPluginDescriptionStatic(), CreateInstance
);
149 void ScriptedProcess::Terminate() {
150 PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance
);
153 Status
ScriptedProcess::DoLoadCore() {
154 ProcessLaunchInfo launch_info
= GetTarget().GetProcessLaunchInfo();
156 return DoLaunch(nullptr, launch_info
);
159 Status
ScriptedProcess::DoLaunch(Module
*exe_module
,
160 ProcessLaunchInfo
&launch_info
) {
161 LLDB_LOGF(GetLog(LLDBLog::Process
), "ScriptedProcess::%s launching process", __FUNCTION__
);
163 /* MARK: This doesn't reflect how lldb actually launches a process.
164 In reality, it attaches to debugserver, then resume the process.
165 That's not true in all cases. If debugserver is remote, lldb
166 asks debugserver to launch the process for it. */
167 Status error
= GetInterface().Launch();
168 SetPrivateState(eStateStopped
);
172 void ScriptedProcess::DidLaunch() { m_pid
= GetInterface().GetProcessID(); }
174 void ScriptedProcess::DidResume() {
175 // Update the PID again, in case the user provided a placeholder pid at launch
176 m_pid
= GetInterface().GetProcessID();
179 Status
ScriptedProcess::DoResume() {
180 LLDB_LOGF(GetLog(LLDBLog::Process
), "ScriptedProcess::%s resuming process", __FUNCTION__
);
182 return GetInterface().Resume();
185 Status
ScriptedProcess::DoAttach(const ProcessAttachInfo
&attach_info
) {
186 Status error
= GetInterface().Attach(attach_info
);
187 SetPrivateState(eStateRunning
);
188 SetPrivateState(eStateStopped
);
191 // NOTE: We need to set the PID before finishing to attach otherwise we will
192 // hit an assert when calling the attach completion handler.
199 ScriptedProcess::DoAttachToProcessWithID(lldb::pid_t pid
,
200 const ProcessAttachInfo
&attach_info
) {
201 return DoAttach(attach_info
);
204 Status
ScriptedProcess::DoAttachToProcessWithName(
205 const char *process_name
, const ProcessAttachInfo
&attach_info
) {
206 return DoAttach(attach_info
);
209 void ScriptedProcess::DidAttach(ArchSpec
&process_arch
) {
210 process_arch
= GetArchitecture();
213 Status
ScriptedProcess::DoDestroy() { return Status(); }
215 bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); }
217 size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr
, void *buf
, size_t size
,
219 lldb::DataExtractorSP data_extractor_sp
=
220 GetInterface().ReadMemoryAtAddress(addr
, size
, error
);
222 if (!data_extractor_sp
|| !data_extractor_sp
->GetByteSize() || error
.Fail())
225 offset_t bytes_copied
= data_extractor_sp
->CopyByteOrderedData(
226 0, data_extractor_sp
->GetByteSize(), buf
, size
, GetByteOrder());
228 if (!bytes_copied
|| bytes_copied
== LLDB_INVALID_OFFSET
)
229 return ScriptedInterface::ErrorWithMessage
<size_t>(
230 LLVM_PRETTY_FUNCTION
, "Failed to copy read memory to buffer.", error
);
232 // FIXME: We should use the diagnostic system to report a warning if the
233 // `bytes_copied` is different from `size`.
238 size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr
, const void *buf
,
239 size_t size
, Status
&error
) {
240 lldb::DataExtractorSP data_extractor_sp
= std::make_shared
<DataExtractor
>(
241 buf
, size
, GetByteOrder(), GetAddressByteSize());
243 if (!data_extractor_sp
|| !data_extractor_sp
->GetByteSize())
246 lldb::offset_t bytes_written
=
247 GetInterface().WriteMemoryAtAddress(vm_addr
, data_extractor_sp
, error
);
249 if (!bytes_written
|| bytes_written
== LLDB_INVALID_OFFSET
)
250 return ScriptedInterface::ErrorWithMessage
<size_t>(
251 LLVM_PRETTY_FUNCTION
, "Failed to copy write buffer to memory.", error
);
253 // FIXME: We should use the diagnostic system to report a warning if the
254 // `bytes_written` is different from `size`.
256 return bytes_written
;
259 Status
ScriptedProcess::EnableBreakpointSite(BreakpointSite
*bp_site
) {
260 assert(bp_site
!= nullptr);
262 if (bp_site
->IsEnabled()) {
266 if (bp_site
->HardwareRequired()) {
267 return Status("Scripted Processes don't support hardware breakpoints");
271 GetInterface().CreateBreakpoint(bp_site
->GetLoadAddress(), error
);
276 ArchSpec
ScriptedProcess::GetArchitecture() {
277 return GetTarget().GetArchitecture();
280 Status
ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr
,
281 MemoryRegionInfo
®ion
) {
283 if (auto region_or_err
=
284 GetInterface().GetMemoryRegionContainingAddress(load_addr
, error
))
285 region
= *region_or_err
;
290 Status
ScriptedProcess::GetMemoryRegions(MemoryRegionInfos
®ion_list
) {
292 lldb::addr_t address
= 0;
294 while (auto region_or_err
=
295 GetInterface().GetMemoryRegionContainingAddress(address
, error
)) {
299 MemoryRegionInfo
&mem_region
= *region_or_err
;
300 auto range
= mem_region
.GetRange();
301 address
+= range
.GetRangeBase() + range
.GetByteSize();
302 region_list
.push_back(mem_region
);
308 void ScriptedProcess::Clear() { Process::m_thread_list
.Clear(); }
310 bool ScriptedProcess::DoUpdateThreadList(ThreadList
&old_thread_list
,
311 ThreadList
&new_thread_list
) {
313 // This is supposed to get the current set of threads, if any of them are in
314 // old_thread_list then they get copied to new_thread_list, and then any
315 // actually new threads will get added to new_thread_list.
316 m_thread_plans
.ClearThreadCache();
319 StructuredData::DictionarySP thread_info_sp
= GetInterface().GetThreadsInfo();
322 return ScriptedInterface::ErrorWithMessage
<bool>(
323 LLVM_PRETTY_FUNCTION
,
324 "Couldn't fetch thread list from Scripted Process.", error
);
326 // Because `StructuredData::Dictionary` uses a `std::map<ConstString,
327 // ObjectSP>` for storage, each item is sorted based on the key alphabetical
328 // order. Since `GetThreadsInfo` provides thread indices as the key element,
329 // thread info comes ordered alphabetically, instead of numerically, so we
330 // need to sort the thread indices before creating thread.
332 StructuredData::ArraySP keys
= thread_info_sp
->GetKeys();
334 std::map
<size_t, StructuredData::ObjectSP
> sorted_threads
;
335 auto sort_keys
= [&sorted_threads
,
336 &thread_info_sp
](StructuredData::Object
*item
) -> bool {
340 llvm::StringRef key
= item
->GetStringValue();
343 // Make sure the provided index is actually an integer
344 if (!llvm::to_integer(key
, idx
))
347 sorted_threads
[idx
] = thread_info_sp
->GetValueForKey(key
);
351 size_t thread_count
= thread_info_sp
->GetSize();
353 if (!keys
->ForEach(sort_keys
) || sorted_threads
.size() != thread_count
)
354 // Might be worth showing the unsorted thread list instead of return early.
355 return ScriptedInterface::ErrorWithMessage
<bool>(
356 LLVM_PRETTY_FUNCTION
, "Couldn't sort thread list.", error
);
358 auto create_scripted_thread
=
359 [this, &error
, &new_thread_list
](
360 const std::pair
<size_t, StructuredData::ObjectSP
> pair
) -> bool {
361 size_t idx
= pair
.first
;
362 StructuredData::ObjectSP object_sp
= pair
.second
;
365 return ScriptedInterface::ErrorWithMessage
<bool>(
366 LLVM_PRETTY_FUNCTION
, "Invalid thread info object", error
);
368 auto thread_or_error
=
369 ScriptedThread::Create(*this, object_sp
->GetAsGeneric());
371 if (!thread_or_error
)
372 return ScriptedInterface::ErrorWithMessage
<bool>(
373 LLVM_PRETTY_FUNCTION
, toString(thread_or_error
.takeError()), error
);
375 ThreadSP thread_sp
= thread_or_error
.get();
376 lldbassert(thread_sp
&& "Couldn't initialize scripted thread.");
378 RegisterContextSP reg_ctx_sp
= thread_sp
->GetRegisterContext();
380 return ScriptedInterface::ErrorWithMessage
<bool>(
381 LLVM_PRETTY_FUNCTION
,
382 llvm::Twine("Invalid Register Context for thread " + llvm::Twine(idx
))
386 new_thread_list
.AddThread(thread_sp
);
391 llvm::for_each(sorted_threads
, create_scripted_thread
);
393 return new_thread_list
.GetSize(false) > 0;
396 void ScriptedProcess::RefreshStateAfterStop() {
397 // Let all threads recover from stopping and do any clean up based on the
398 // previous thread state (if any).
399 m_thread_list
.RefreshStateAfterStop();
402 bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo
&info
) {
404 info
.SetProcessID(GetID());
405 info
.SetArchitecture(GetArchitecture());
406 lldb::ModuleSP module_sp
= GetTarget().GetExecutableModule();
408 const bool add_exe_file_as_first_arg
= false;
409 info
.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
410 add_exe_file_as_first_arg
);
415 lldb_private::StructuredData::ObjectSP
416 ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
418 auto error_with_message
= [&error
](llvm::StringRef message
) {
419 return ScriptedInterface::ErrorWithMessage
<bool>(LLVM_PRETTY_FUNCTION
,
420 message
.data(), error
);
423 StructuredData::ArraySP loaded_images_sp
= GetInterface().GetLoadedImages();
425 if (!loaded_images_sp
|| !loaded_images_sp
->GetSize())
426 return ScriptedInterface::ErrorWithMessage
<StructuredData::ObjectSP
>(
427 LLVM_PRETTY_FUNCTION
, "No loaded images.", error
);
429 ModuleList module_list
;
430 Target
&target
= GetTarget();
432 auto reload_image
= [&target
, &module_list
, &error_with_message
](
433 StructuredData::Object
*obj
) -> bool {
434 StructuredData::Dictionary
*dict
= obj
->GetAsDictionary();
437 return error_with_message("Couldn't cast image object into dictionary.");
439 ModuleSpec module_spec
;
440 llvm::StringRef value
;
442 bool has_path
= dict
->HasKey("path");
443 bool has_uuid
= dict
->HasKey("uuid");
444 if (!has_path
&& !has_uuid
)
445 return error_with_message("Dictionary should have key 'path' or 'uuid'");
446 if (!dict
->HasKey("load_addr"))
447 return error_with_message("Dictionary is missing key 'load_addr'");
450 dict
->GetValueForKeyAsString("path", value
);
451 module_spec
.GetFileSpec().SetPath(value
);
455 dict
->GetValueForKeyAsString("uuid", value
);
456 module_spec
.GetUUID().SetFromStringRef(value
);
458 module_spec
.GetArchitecture() = target
.GetArchitecture();
461 target
.GetOrCreateModule(module_spec
, true /* notify */);
464 return error_with_message("Couldn't create or get module.");
466 lldb::addr_t load_addr
= LLDB_INVALID_ADDRESS
;
467 lldb::offset_t slide
= LLDB_INVALID_OFFSET
;
468 dict
->GetValueForKeyAsInteger("load_addr", load_addr
);
469 dict
->GetValueForKeyAsInteger("slide", slide
);
470 if (load_addr
== LLDB_INVALID_ADDRESS
)
471 return error_with_message(
472 "Couldn't get valid load address or slide offset.");
474 if (slide
!= LLDB_INVALID_OFFSET
)
477 bool changed
= false;
478 module_sp
->SetLoadAddress(target
, load_addr
, false /*=value_is_offset*/,
481 if (!changed
&& !module_sp
->GetObjectFile())
482 return error_with_message("Couldn't set the load address for module.");
484 dict
->GetValueForKeyAsString("path", value
);
485 FileSpec
objfile(value
);
486 module_sp
->SetFileSpecAndObjectName(objfile
, objfile
.GetFilename());
488 return module_list
.AppendIfNeeded(module_sp
);
491 if (!loaded_images_sp
->ForEach(reload_image
))
492 return ScriptedInterface::ErrorWithMessage
<StructuredData::ObjectSP
>(
493 LLVM_PRETTY_FUNCTION
, "Couldn't reload all images.", error
);
495 target
.ModulesDidLoad(module_list
);
497 return loaded_images_sp
;
500 lldb_private::StructuredData::DictionarySP
ScriptedProcess::GetMetadata() {
501 StructuredData::DictionarySP metadata_sp
= GetInterface().GetMetadata();
504 if (!metadata_sp
|| !metadata_sp
->GetSize())
505 return ScriptedInterface::ErrorWithMessage
<StructuredData::DictionarySP
>(
506 LLVM_PRETTY_FUNCTION
, "No metadata.", error
);
511 void ScriptedProcess::UpdateQueueListIfNeeded() {
512 CheckScriptedInterface();
513 for (ThreadSP thread_sp
: Threads()) {
514 if (const char *queue_name
= thread_sp
->GetQueueName()) {
515 QueueSP queue_sp
= std::make_shared
<Queue
>(
516 m_process
->shared_from_this(), thread_sp
->GetQueueID(), queue_name
);
517 m_queue_list
.AddQueue(queue_sp
);
522 ScriptedProcessInterface
&ScriptedProcess::GetInterface() const {
523 CheckScriptedInterface();
524 return *m_interface_up
;
527 void *ScriptedProcess::GetImplementation() {
528 StructuredData::GenericSP object_instance_sp
=
529 GetInterface().GetScriptObjectInstance();
530 if (object_instance_sp
&&
531 object_instance_sp
->GetType() == eStructuredDataTypeGeneric
)
532 return object_instance_sp
->GetAsGeneric()->GetValue();