380 if (target ==
nullptr) {
385>
386 LLDB_LOGF(log,
"PlatformPOSIX::%s created new target", __FUNCTION__);
389 LLDB_LOGF(log,
"PlatformPOSIX::%s target already existed, setting target",
393 if (target &&
error.Success()) {
396 LLDB_LOGF(log,
"PlatformPOSIX::%s set selected target to %p %s",
397 __FUNCTION__, (
void *)target,
398 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
404 "gdb-remote",
nullptr,
true);
408 if (listener_sp ==
nullptr) {
413 process_sp->HijackProcessEvents(listener_sp);
415 error = process_sp->Attach(attach_info);
433 LLDB_LOG(log,
"target {0}", &target);
461 LLDB_LOG(log,
"having target create process with gdb-remote plugin");
467 "CreateProcess() failed for gdb-remote process");
472 LLDB_LOG(log,
"successfully created process");
479 LLDB_LOG(log,
"launching process with the following file actions:");
484 file_action->
Dump(stream);
491 error = process_sp->Launch(launch_info);
492 if (
error.Success()) {
498 process_sp->SetSTDIOPseudoTerminal(launch_info.
GetPTY());
499 LLDB_LOG(log,
"hooked up STDIO pty to process");
501 LLDB_LOG(log,
"not using process STDIO pty");
530 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
535 frame_sp->CalculateExecutionContext(exe_ctx);
546 exe_ctx, expr_options, expr_cstr, expr_prefix, result_valobj_sp);
548 return result_valobj_sp ? result_valobj_sp->GetError().Clone()
549 :
Status(
"unknown error");
551 if (result_valobj_sp->GetError().Fail())
552 return result_valobj_sp->GetError().Clone();
556llvm::Expected<std::unique_ptr<UtilityFunction>>
573 static const char *dlopen_wrapper_code = R
"(
574 const int RTLD_LAZY = 1;
576 struct __lldb_dlopen_result {
578 const char *error_str;
581 extern "C" void *memcpy(void *, const void *, size_t size);
582 extern "C" size_t strlen(const char *);
585 void * __lldb_dlopen_wrapper (const char *name,
586 const char *path_strings,
588 __lldb_dlopen_result *result_ptr)
590 // This is the case where the name is the full path:
592 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
593 if (result_ptr->image_ptr)
594 result_ptr->error_str = nullptr;
596 result_ptr->error_str = dlerror();
600 // This is the case where we have a list of paths:
601 size_t name_len = strlen(name);
602 while (path_strings && path_strings[0] != '\0') {
603 size_t path_len = strlen(path_strings);
604 memcpy((void *) buffer, (void *) path_strings, path_len);
605 buffer[path_len] = '/';
606 char *target_ptr = buffer+path_len+1;
607 memcpy((void *) target_ptr, (void *) name, name_len + 1);
608 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
609 if (result_ptr->image_ptr) {
610 result_ptr->error_str = nullptr;
613 result_ptr->error_str = dlerror();
614 path_strings = path_strings + path_len + 1;
620 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
624 expr.append(dlopen_wrapper_code);
630 if (!utility_fn_or_error) {
631 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
632 return llvm::createStringError(
633 "dlopen error: could not create utility function: %s",
636 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
637 std::move(*utility_fn_or_error);
646 return llvm::createStringError(
"dlopen error: no scratch type system");
664 dlopen_utility_func_up->MakeFunctionCaller(
665 clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error);
666 if (utility_error.Fail())
667 return llvm::createStringError(
668 "dlopen error: could not make function caller: %s",
669 utility_error.AsCString());
671 if (!dlopen_utility_func_up->GetFunctionCaller())
672 return llvm::createStringError(
673 "dlopen error: could not get function caller.");
675 return dlopen_utility_func_up;
680 const std::vector<std::string> *paths,
684 loaded_image->
Clear();
687 path = remote_file.
GetPath(
false);
691 error = Status::FromErrorString(
692 "dlopen error: no thread available to call dlopen.");
696 DiagnosticManager diagnostics;
698 ExecutionContext exe_ctx;
699 thread_sp->CalculateExecutionContext(exe_ctx);
706 llvm::Expected<UtilityFunction &> dlopen_utility_func_or_err =
709 if (!dlopen_utility_func_or_err) {
710 error = Status::FromError(dlopen_utility_func_or_err.takeError());
714 FunctionCaller *do_dlopen_function =
715 dlopen_utility_func_or_err->GetFunctionCaller();
716 if (!do_dlopen_function) {
718 Status::FromErrorString(
"dlopen error: could not get function caller.");
725 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
726 size_t path_len = path.size() + 1;
731 error = Status::FromErrorStringWithFormat(
732 "dlopen error: could not allocate memory for path: %s",
738 llvm::scope_exit path_cleanup([process, path_addr] {
743 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
744 if (utility_error.
Fail()) {
745 error = Status::FromErrorStringWithFormat(
746 "dlopen error: could not write path string: %s",
757 if (utility_error.
Fail()) {
758 error = Status::FromErrorStringWithFormat(
759 "dlopen error: could not allocate memory for path: %s",
765 llvm::scope_exit return_cleanup([process, return_addr] {
773 std::optional<llvm::scope_exit<std::function<void()>>> path_array_cleanup;
779 std::optional<llvm::scope_exit<std::function<void()>>> buffer_cleanup;
782 if (paths !=
nullptr) {
787 size_t buffer_size = 0;
788 std::string path_array;
789 for (
auto path : *paths) {
794 size_t path_size = path.size();
795 path_array.append(path);
796 path_array.push_back(
'\0');
797 if (path_size > buffer_size)
798 buffer_size = path_size;
800 path_array.push_back(
'\0');
806 error = Status::FromErrorStringWithFormat(
807 "dlopen error: could not allocate memory for path array: %s",
813 path_array_cleanup.emplace([process, path_array_addr]() {
818 process->
WriteMemory(path_array_addr, path_array.data(),
819 path_array.size(), utility_error);
821 if (utility_error.
Fail()) {
822 error = Status::FromErrorStringWithFormat(
823 "dlopen error: could not write path array: %s",
829 buffer_size += path.size() + 2;
835 error = Status::FromErrorStringWithFormat(
836 "dlopen error: could not allocate memory for buffer: %s",
842 buffer_cleanup.emplace([process, buffer_addr]() {
862 "dlopen error: could not write function arguments:"));
869 llvm::scope_exit args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
874 EvaluateExpressionOptions options;
877 options.SetIgnoreBreakpoints(
true);
878 options.SetUnwindOnError(
true);
879 options.SetTrapExceptions(
false);
882 options.SetIsForUtilityExpr(
true);
888 if (!scratch_ts_sp) {
890 Status::FromErrorString(
"dlopen error: Unable to get TypeSystemClang");
894 CompilerType clang_void_pointer_type =
900 exe_ctx, &func_args_addr, options, diagnostics, return_value);
904 "dlopen error: failed executing dlopen wrapper function:"));
909 llvm::Expected<lldb::addr_t> token =
913 "dlopen error: could not read the return struct: {0}",
914 llvm::fmt_consume(token.takeError()));
920 if (loaded_image && buffer_addr != 0x0)
924 std::string name_string;
927 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
933 std::string dlopen_error_str;
934 llvm::Expected<lldb::addr_t> error_addr =
937 error = Status::FromErrorStringWithFormatv(
938 "dlopen error: could not read error string: {0}",
939 llvm::fmt_consume(error_addr.takeError()));
944 *error_addr + addr_size, dlopen_error_str, utility_error);
945 if (utility_error.
Success() && num_chars > 0)
947 dlopen_error_str.c_str());
956 uint32_t image_token) {
962 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
970 if (result_valobj_sp->GetError().Fail())
971 return result_valobj_sp->GetError().Clone();
974 if (result_valobj_sp->ResolveValue(scalar)) {
986 extern "C" void* dlopen(const char*, int);
987 extern "C" void* dlsym(void*, const char*);
988 extern "C" int dlclose(void*);
989 extern "C" char* dlerror(void);
994 if (basename.empty())
995 return basename.str();
997 return llvm::formatv(
"lib{0}.so", basename).str();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A command line argument class.
Generic representation of a type in a programming language.
A subclass of DataBuffer that stores a data buffer on the heap.
A class to manage flag bits.
TargetList & GetTargetList()
Get accessor for the target list.
llvm::Error GetAsError(lldb::ExpressionResults result, llvm::Twine message={}) const
Returns an ExpressionError with arg as error code.
A plug-in interface definition class for dynamic loaders.
virtual Status CanLoadImage()=0
Ask if it is ok to try and load or unload an shared library (image).
void SetUnwindOnError(bool unwind=false)
void SetExecutionPolicy(ExecutionPolicy policy=eExecutionPolicyAlways)
void SetLanguage(lldb::LanguageType language_type)
void SetTrapExceptions(bool b)
void SetTimeout(const Timeout< std::micro > &timeout)
void SetIgnoreBreakpoints(bool ignore=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
Represents a file descriptor action to be performed during process launch.
void Dump(Stream &stream) const
static FileCache & GetInstance()
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
ValueList GetArgumentValues() const
void DeallocateFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Deallocate the arguments structure.
lldb::ExpressionResults ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager, Value &results)
Run the function this FunctionCaller was created with.
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, std::string *error_output, const Timeout< std::micro > &timeout, bool run_in_shell=true)
Run a shell command.
static lldb::ListenerSP MakeListener(llvm::StringRef name)
virtual llvm::StringRef GetPluginName()=0
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
void SetHijackListener(const lldb::ListenerSP &listener_sp)
lldb::ListenerSP GetHijackListener() const
lldb::ListenerSP GetListener() const
lldb::ListenerSP GetShadowListener() const
const FileAction * GetFileActionAtIndex(size_t idx) const
void SetLaunchInSeparateProcessGroup(bool separate)
std::chrono::seconds GetUtilityExpressionTimeout() const
A plug-in interface definition class for debugging a process.
void ResetImageToken(size_t token)
lldb::addr_t CallocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process, this also clears the allocated memory.
ThreadList & GetThreadList()
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a null-terminated C string from memory.
size_t AddImageToken(lldb::addr_t image_ptr)
llvm::Expected< lldb::addr_t > ReadPointerFromMemory(lldb::addr_t vm_addr)
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
lldb::addr_t GetImagePtrFromToken(size_t token) const
uint32_t GetAddressByteSize() const
size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error)
Write memory to a process.
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
llvm::Expected< UtilityFunction & > GetLoadImageUtilityFunction(Platform *platform, llvm::function_ref< llvm::Expected< std::unique_ptr< UtilityFunction > >()> factory)
Get the cached UtilityFunction that assists in loading binary images into the process.
Target & GetTarget()
Get the target object pointer for this module.
@ invalid_fd
Invalid file descriptor value.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
unsigned int UInt(unsigned int fail_value=0) const
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
bool Success() const
Test for success condition.
const char * GetData() const
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file, bool can_connect)
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateUtilityFunction(std::string expression, std::string name, lldb::LanguageType language, ExecutionContext &exe_ctx)
Creates and installs a UtilityFunction for the given language.
lldb::ThreadSP GetExpressionExecutionThread()
static lldb::ExpressionResults Evaluate(ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Evaluate one expression in the scratch context of the target passed in the exe_ctx and return its res...
void PushValue(const Value &value)
Value * GetValueAtIndex(size_t idx)
const Scalar & GetScalar() const
See comment on m_scalar to understand what GetScalar returns.
@ Scalar
A raw scalar value.
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
#define LLDB_INVALID_IMAGE_TOKEN
#define LLDB_INVALID_ADDRESS
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.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
@ eLanguageTypeC_plus_plus
ISO C++:1998.
ExpressionResults
The results of expression evaluation.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::Module > ModuleSP