35#include "llvm/ADT/ScopeExit.h"
58 std::unique_ptr<lldb_private::OptionGroupOptions> options(
63 m_options[&interpreter] = std::move(options);
72 if (!platform || !path || *path == 0)
83 command.
Printf(
":%d", gid);
84 command.
Printf(
"%s", path);
87 nullptr, std::chrono::seconds(10));
98 if (source == destination)
102 std::string src_path(source.
GetPath());
103 if (src_path.empty())
105 std::string dst_path(destination.
GetPath());
106 if (dst_path.empty())
109 command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
112 std::chrono::seconds(10));
117 if (
chown_file(
this, dst_path.c_str(), uid, gid) != 0)
122 std::string src_path(source.
GetPath());
123 if (src_path.empty())
125 std::string dst_path(destination.
GetPath());
126 if (dst_path.empty())
128 "unable to get file path for destination");
143 nullptr, std::chrono::minutes(1));
165 std::string src_path(source.
GetPath());
166 if (src_path.empty())
168 std::string dst_path(destination.
GetPath());
169 if (dst_path.empty())
172 if (source == destination)
174 "local scenario->source and destination are the same file "
175 "path: no operation performed");
178 cp_command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
181 std::chrono::seconds(10));
194 src_path.c_str(), dst_path.c_str());
202 nullptr, std::chrono::minutes(1));
212 LLDB_LOGF(log,
"[GetFile] Using block by block transfer....\n");
215 lldb::eFilePermissionsFileDefault,
error);
220 uint32_t permissions = 0;
223 if (permissions == 0)
224 permissions = lldb::eFilePermissionsFileDefault;
236 if (
error.Success()) {
240 while (
error.Success()) {
241 const uint64_t n_read =
ReadFile(fd_src, offset, buffer_sp->GetBytes(),
242 buffer_sp->GetByteSize(),
error);
248 buffer_sp->GetBytes(), n_read,
278 stream.
Printf(
", options: ");
281 stream.
Printf(
", prefix: ");
285 stream.
Printf(
"ignore remote-hostname ");
311 "can't connect to the host platform '{0}', always connected",
323 "failed to create a 'remote-gdb-server' platform");
357 "can't disconnect from the host platform '{0}', always connected",
376 if (target ==
nullptr) {
381 target = new_target_sp.get();
382 LLDB_LOGF(log,
"PlatformPOSIX::%s created new target", __FUNCTION__);
385 LLDB_LOGF(log,
"PlatformPOSIX::%s target already existed, setting target",
389 if (target &&
error.Success()) {
392 LLDB_LOGF(log,
"PlatformPOSIX::%s set selected target to %p %s",
393 __FUNCTION__, (
void *)target,
394 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
400 "gdb-remote",
nullptr,
true);
404 if (listener_sp ==
nullptr) {
409 process_sp->HijackProcessEvents(listener_sp);
411 error = process_sp->Attach(attach_info);
429 LLDB_LOG(log,
"target {0}", &target);
457 LLDB_LOG(log,
"having target create process with gdb-remote plugin");
463 "CreateProcess() failed for gdb-remote process");
468 LLDB_LOG(log,
"successfully created process");
475 LLDB_LOG(log,
"launching process with the following file actions:");
480 file_action->
Dump(stream);
487 error = process_sp->Launch(launch_info);
488 if (
error.Success()) {
494 process_sp->SetSTDIOFileDescriptor(pty_fd);
495 LLDB_LOG(log,
"hooked up STDIO pty to process");
497 LLDB_LOG(log,
"not using process STDIO pty");
526 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
531 frame_sp->CalculateExecutionContext(exe_ctx);
542 exe_ctx, expr_options, expr_cstr, expr_prefix, result_valobj_sp);
544 return result_valobj_sp ? result_valobj_sp->GetError().Clone()
545 :
Status(
"unknown error");
547 if (result_valobj_sp->GetError().Fail())
548 return result_valobj_sp->GetError().Clone();
552std::unique_ptr<UtilityFunction>
570 static const char *dlopen_wrapper_code = R
"(
571 const int RTLD_LAZY = 1;
573 struct __lldb_dlopen_result {
575 const char *error_str;
578 extern "C" void *memcpy(void *, const void *, size_t size);
579 extern "C" size_t strlen(const char *);
582 void * __lldb_dlopen_wrapper (const char *name,
583 const char *path_strings,
585 __lldb_dlopen_result *result_ptr)
587 // This is the case where the name is the full path:
589 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
590 if (result_ptr->image_ptr)
591 result_ptr->error_str = nullptr;
593 result_ptr->error_str = dlerror();
597 // This is the case where we have a list of paths:
598 size_t name_len = strlen(name);
599 while (path_strings && path_strings[0] != '\0') {
600 size_t path_len = strlen(path_strings);
601 memcpy((void *) buffer, (void *) path_strings, path_len);
602 buffer[path_len] = '/';
603 char *target_ptr = buffer+path_len+1;
604 memcpy((void *) target_ptr, (void *) name, name_len + 1);
605 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
606 if (result_ptr->image_ptr) {
607 result_ptr->error_str = nullptr;
610 result_ptr->error_str = dlerror();
611 path_strings = path_strings + path_len + 1;
617 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
621 expr.append(dlopen_wrapper_code);
627 if (!utility_fn_or_error) {
628 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
630 "dlopen error: could not create utility function: %s",
634 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
635 std::move(*utility_fn_or_error);
663 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
664 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
665 if (utility_error.
Fail()) {
667 "dlopen error: could not make function caller: %s",
672 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
673 if (!do_dlopen_function) {
680 return dlopen_utility_func_up;
685 const std::vector<std::string> *paths,
689 loaded_image->
Clear();
692 path = remote_file.
GetPath(
false);
696 error = Status::FromErrorString(
697 "dlopen error: no thread available to call dlopen.");
701 DiagnosticManager diagnostics;
703 ExecutionContext exe_ctx;
704 thread_sp->CalculateExecutionContext(exe_ctx);
707 UtilityFunction *dlopen_utility_func;
709 FunctionCaller *do_dlopen_function =
nullptr;
714 this, [&]() -> std::unique_ptr<UtilityFunction> {
718 if (!dlopen_utility_func)
722 if (!do_dlopen_function) {
724 Status::FromErrorString(
"dlopen error: could not get function caller.");
731 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
732 size_t path_len = path.size() + 1;
737 error = Status::FromErrorStringWithFormat(
738 "dlopen error: could not allocate memory for path: %s",
744 auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
749 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
750 if (utility_error.
Fail()) {
751 error = Status::FromErrorStringWithFormat(
752 "dlopen error: could not write path string: %s",
763 if (utility_error.
Fail()) {
764 error = Status::FromErrorStringWithFormat(
765 "dlopen error: could not allocate memory for path: %s",
771 auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
779 std::optional<llvm::detail::scope_exit<std::function<void()>>>
786 std::optional<llvm::detail::scope_exit<std::function<void()>>> buffer_cleanup;
789 if (paths !=
nullptr) {
794 size_t buffer_size = 0;
795 std::string path_array;
796 for (
auto path : *paths) {
801 size_t path_size = path.size();
802 path_array.append(path);
803 path_array.push_back(
'\0');
804 if (path_size > buffer_size)
805 buffer_size = path_size;
807 path_array.push_back(
'\0');
813 error = Status::FromErrorStringWithFormat(
814 "dlopen error: could not allocate memory for path array: %s",
820 path_array_cleanup.emplace([process, path_array_addr]() {
825 process->
WriteMemory(path_array_addr, path_array.data(),
826 path_array.size(), utility_error);
828 if (utility_error.
Fail()) {
829 error = Status::FromErrorStringWithFormat(
830 "dlopen error: could not write path array: %s",
836 buffer_size += path.size() + 2;
842 error = Status::FromErrorStringWithFormat(
843 "dlopen error: could not allocate memory for buffer: %s",
849 buffer_cleanup.emplace([process, buffer_addr]() {
869 "dlopen error: could not write function arguments:"));
877 llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
882 EvaluateExpressionOptions options;
885 options.SetIgnoreBreakpoints(
true);
886 options.SetUnwindOnError(
true);
887 options.SetTrapExceptions(
false);
890 options.SetIsForUtilityExpr(
true);
896 if (!scratch_ts_sp) {
898 Status::FromErrorString(
"dlopen error: Unable to get TypeSystemClang");
902 CompilerType clang_void_pointer_type =
908 exe_ctx, &func_args_addr, options, diagnostics, return_value);
912 "dlopen error: failed executing dlopen wrapper function:"));
921 "dlopen error: could not read the return struct: %s",
928 if (loaded_image && buffer_addr != 0x0)
932 std::string name_string;
935 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
941 std::string dlopen_error_str;
944 if (utility_error.
Fail()) {
945 error = Status::FromErrorStringWithFormat(
946 "dlopen error: could not read error string: %s",
954 if (utility_error.
Success() && num_chars > 0)
956 dlopen_error_str.c_str());
965 uint32_t image_token) {
971 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
979 if (result_valobj_sp->GetError().Fail())
980 return result_valobj_sp->GetError().Clone();
983 if (result_valobj_sp->ResolveValue(scalar)) {
995 extern "C" void* dlopen(const char*, int);
996 extern "C" void* dlsym(void*, const char*);
997 extern "C" int dlclose(void*);
998 extern "C" char* dlerror(void);
1006 StreamString stream;
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 uniqued constant string class.
bool IsEmpty() const
Test for empty string.
const char * GetCString() const
Get the string value as a C string.
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.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
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.
Encapsulates a function that can be called.
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, const Timeout< std::micro > &timeout, bool run_in_shell=true, bool hide_stderr=false)
Run a shell command.
static lldb::ListenerSP MakeListener(const char *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.
UtilityFunction * GetLoadImageUtilityFunction(Platform *platform, llvm::function_ref< std::unique_ptr< UtilityFunction >()> factory)
Get the cached UtilityFunction that assists in loading binary images into the 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)
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
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.
Target & GetTarget()
Get the target object pointer for this module.
@ invalid_fd
Invalid file descriptor value.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
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...
FunctionCaller * GetFunctionCaller()
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