30#include "llvm/Support/Error.h"
40 return "Scripted Process plug-in.";
48 llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
51 return llvm::is_contained(supported_languages, language);
64 if (!scripted_metadata)
68 auto process_sp = std::shared_ptr<ScriptedProcess>(
71 if (
error.Fail() || !process_sp || !process_sp->m_interface_up) {
77 llvm::formatv(
"failed to create ScriptedProcess: {0}",
80 target_sp->GetDebugger().GetID());
90 bool plugin_specified_by_name) {
102 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
"Invalid target");
107 target_sp->GetDebugger().GetScriptInterpreter();
111 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
112 "Debugger has no Script Interpreter");
120 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
121 "Script interpreter couldn't create Scripted Process Interface");
132 std::string error_msg = llvm::toString(obj_or_err.takeError());
134 "failed to create script object: {0}", error_msg);
140 if (!object_sp || !object_sp->IsValid()) {
142 "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__,
143 "Failed to create valid script object");
175 return DoLaunch(
nullptr, launch_info);
205 "{0} does not support reverse execution of processes",
GetPluginName());
212 "failed to attach to scripted process: {0}",
error.AsCString());
248 if (!data_extractor_sp || !data_extractor_sp->HasData() ||
error.Fail()) {
251 "Failed to read memory from scripted process at 0x{0:x-}: {1}", addr,
257 offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
258 0, data_extractor_sp->GetByteSize(), buf, size,
GetByteOrder());
262 LLVM_PRETTY_FUNCTION,
"Failed to copy read memory to buffer.",
error);
275 if (!data_extractor_sp || !data_extractor_sp->HasData())
284 "failed to write memory to scripted process at 0x{0:x-}: {1}",
285 vm_addr,
error.AsCString());
288 LLVM_PRETTY_FUNCTION,
"Failed to copy write buffer to memory.",
error);
294 return bytes_written;
298 assert(bp_site !=
nullptr);
306 "Scripted Processes don't support hardware breakpoints");
322 if (
auto region_or_err =
324 region = *region_or_err;
333 while (
auto region_or_err =
340 address += range.GetRangeBase() + range.GetByteSize();
341 region_list.push_back(mem_region);
362 LLVM_PRETTY_FUNCTION,
363 "Couldn't fetch thread list from Scripted Process.",
error);
373 std::map<size_t, StructuredData::ObjectSP> sorted_threads;
374 auto sort_keys = [&sorted_threads,
379 llvm::StringRef key = item->GetStringValue();
383 if (!llvm::to_integer(key, idx))
386 sorted_threads[idx] = thread_info_sp->GetValueForKey(key);
390 size_t thread_count = thread_info_sp->GetSize();
392 if (!keys->ForEach(sort_keys) || sorted_threads.size() != thread_count)
395 LLVM_PRETTY_FUNCTION,
"Couldn't sort thread list.",
error);
397 auto create_scripted_thread =
398 [
this, &
error, &new_thread_list](
399 const std::pair<size_t, StructuredData::ObjectSP> pair) ->
bool {
400 size_t idx = pair.first;
405 LLVM_PRETTY_FUNCTION,
"Invalid thread info object",
error);
407 auto thread_or_error =
410 if (!thread_or_error) {
412 llvm::formatv(
"failed to create scripted thread ({0}): {1}", idx,
413 llvm::toString(thread_or_error.takeError()))
419 ThreadSP thread_sp = thread_or_error.get();
420 lldbassert(thread_sp &&
"Couldn't initialize scripted thread.");
425 LLVM_PRETTY_FUNCTION,
426 llvm::Twine(
"Invalid Register Context for thread " + llvm::Twine(idx))
435 llvm::for_each(sorted_threads, create_scripted_thread);
437 return new_thread_list.
GetSize(
false) > 0;
452 const bool add_exe_file_as_first_arg =
false;
454 add_exe_file_as_first_arg);
463 auto error_with_message = [&
error](llvm::StringRef message) {
465 message.data(),
error);
470 if (!loaded_images_sp || !loaded_images_sp->GetSize())
472 LLVM_PRETTY_FUNCTION,
"No loaded images.",
error);
477 auto reload_image = [&target, &module_list, &error_with_message](
482 return error_with_message(
"Couldn't cast image object into dictionary.");
486 bool has_path = dict->
HasKey(
"path");
487 bool has_uuid = dict->
HasKey(
"uuid");
488 if (!has_path && !has_uuid)
489 return error_with_message(
"Dictionary should have key 'path' or 'uuid'");
490 if (!dict->
HasKey(
"load_addr"))
491 return error_with_message(
"Dictionary is missing key 'load_addr'");
493 llvm::StringRef path =
"";
499 llvm::StringRef uuid =
"";
510 return error_with_message(
511 "Couldn't get valid load address or slide offset.");
521 bool is_placeholder_module =
false;
527 "ScriptedProcess::%s unable to locate the matching "
528 "object file path %s, creating a placeholder module at 0x%" PRIx64,
529 __FUNCTION__, path.str().c_str(), load_addr);
534 is_placeholder_module =
true;
537 bool changed =
false;
538 module_sp->SetLoadAddress(target, load_addr,
false ,
541 if (!changed && !module_sp->GetObjectFile())
542 return error_with_message(
"Couldn't set the load address for module.");
545 module_sp->SetFileSpecAndObjectName(objfile,
548 if (is_placeholder_module) {
556 size_t loaded_images_size = loaded_images_sp->GetSize();
557 bool print_error =
true;
558 for (
size_t idx = 0; idx < loaded_images_size; idx++) {
559 const auto &loaded_image = loaded_images_sp->GetItemAtIndex(idx);
560 if (!reload_image(loaded_image.get()) && print_error) {
563 LLVM_PRETTY_FUNCTION,
"Couldn't reload all images.",
error);
569 return loaded_images_sp;
576 if (!metadata_sp || !metadata_sp->GetSize())
578 LLVM_PRETTY_FUNCTION,
"No metadata.",
error);
586 if (
const char *queue_name = thread_sp->GetQueueName()) {
587 QueueSP queue_sp = std::make_shared<Queue>(
588 m_process->shared_from_this(), thread_sp->GetQueueID(), queue_name);
602 if (object_instance_sp &&
604 return object_instance_sp->GetAsGeneric()->GetValue();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
static constexpr lldb::ScriptLanguage g_supported_script_languages[]
An architecture specification class.
Class that manages the actual breakpoint that will be inserted into the running program.
A uniqued constant string class.
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetPath(llvm::StringRef p)
Temporary helper for FileSystem change.
llvm::StringRef GetFilename() const
Filename string const get accessor.
size_t MemorySize() const
Get the memory cost of this object.
A collection class for Module objects.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
ArchSpec & GetArchitecture()
A class that describes an executable image and its associated object and symbol files.
static lldb::ModuleSP CreateModuleFromObjectFile(Args &&...args)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
void SetArchitecture(const ArchSpec &arch)
void SetProcessID(lldb::pid_t pid)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
QueueList m_queue_list
The list of libdispatch queues at a given stop point.
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
lldb::ByteOrder GetByteOrder() const
ThreadList::ThreadIterable Threads()
ThreadPlanStackMap m_thread_plans
This is the list of thread plans for threads in m_thread_list, as well as threads we knew existed,...
uint32_t GetAddressByteSize() const
void SetPrivateState(lldb::StateType state)
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
ThreadList m_thread_list
The threads for this process as the user will see them.
Target & GetTarget()
Get the target object pointer for this module.
virtual lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface()
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef user_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
StructuredData::GenericSP GetScriptObjectInstance()
virtual lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error)
virtual StructuredData::DictionarySP GetThreadsInfo()
virtual Status Attach(const ProcessAttachInfo &attach_info)
virtual lldb::pid_t GetProcessID()
virtual bool CreateBreakpoint(lldb::addr_t addr, Status &error)
virtual StructuredData::DictionarySP GetMetadata()
virtual StructuredData::ArraySP GetLoadedImages()
virtual lldb::offset_t WriteMemoryAtAddress(lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error)
virtual llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, ExecutionContext &exe_ctx, StructuredData::Generic *script_obj=nullptr)=0
Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
void * GetImplementation() override
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
const ScriptedMetadata m_scripted_metadata
void DidAttach(ArchSpec &process_arch) override
Called after attaching a process.
Status DoDestroy() override
static llvm::StringRef GetPluginNameStatic()
Status GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override
Obtain all the mapped memory regions within this process.
static bool IsScriptLanguageSupported(lldb::ScriptLanguage language)
ArchSpec GetArchitecture()
bool IsAlive() override
Check if a process is still alive.
Status DoAttach(const ProcessAttachInfo &attach_info)
Status DoLoadCore() override
bool GetProcessInfo(ProcessInstanceInfo &info) override
lldb_private::StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(lldb::BinaryInformationLevel info_level) override
Retrieve a StructuredData dictionary about all of the binaries loaded in the process at this time.
void DidResume() override
Called after resuming a process.
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
void CheckScriptedInterface() const
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const ScriptedMetadata &scripted_metadata, Status &error)
lldb::ScriptedProcessInterfaceUP m_interface_up
llvm::StringRef GetPluginName() override
Status EnableBreakpointSite(BreakpointSite *bp_site) override
lldb_private::StructuredData::DictionarySP GetMetadata() override
Fetch process defined metadata.
Status DoAttachToProcessWithName(const char *process_name, const ProcessAttachInfo &attach_info) override
Attach to an existing process using a partial process name.
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
~ScriptedProcess() override
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path, bool can_connect)
static llvm::StringRef GetPluginDescriptionStatic()
void UpdateQueueListIfNeeded() override
ScriptedProcessInterface & GetInterface() const
void DidLaunch() override
Called after launching a process.
Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
static llvm::Expected< std::shared_ptr< ScriptedThread > > Create(ScriptedProcess &process, StructuredData::Generic *script_object=nullptr)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
virtual lldb::addr_t GetLoadAddress() const
bool HardwareRequired() const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool HasKey(llvm::StringRef key) const
Dictionary * GetAsDictionary()
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
const ProcessLaunchInfo & GetProcessLaunchInfo() const
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
bool SetFromStringRef(llvm::StringRef str)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_OFFSET
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
ScriptLanguage
Script interpreter types.
std::shared_ptr< lldb_private::Queue > QueueSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateRunning
Process or thread is running and can't be examined.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
BinaryInformationLevel
When the Process plugin can retrieve information about all binaries loaded in the target process,...
std::shared_ptr< lldb_private::Target > TargetSP
@ eStructuredDataTypeGeneric
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP