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,
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 nullptr, 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,
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 nullptr, std::chrono::seconds(10));
194 src_path.c_str(), dst_path.c_str());
202 nullptr,
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,
280 stream.
Printf(
", options: ");
283 stream.
Printf(
", prefix: ");
287 stream.
Printf(
"ignore remote-hostname ");
313 "can't connect to the host platform '{0}', always connected",
325 "failed to create a 'remote-gdb-server' platform");
359 "can't disconnect from the host platform '{0}', always connected",
378 if (target ==
nullptr) {
383 target = new_target_sp.get();
384 LLDB_LOGF(log,
"PlatformPOSIX::%s created new target", __FUNCTION__);
387 LLDB_LOGF(log,
"PlatformPOSIX::%s target already existed, setting target",
391 if (target &&
error.Success()) {
394 LLDB_LOGF(log,
"PlatformPOSIX::%s set selected target to %p %s",
395 __FUNCTION__, (
void *)target,
396 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
402 "gdb-remote",
nullptr,
true);
406 if (listener_sp ==
nullptr) {
411 process_sp->HijackProcessEvents(listener_sp);
413 error = process_sp->Attach(attach_info);
431 LLDB_LOG(log,
"target {0}", &target);
459 LLDB_LOG(log,
"having target create process with gdb-remote plugin");
465 "CreateProcess() failed for gdb-remote process");
470 LLDB_LOG(log,
"successfully created process");
477 LLDB_LOG(log,
"launching process with the following file actions:");
482 file_action->
Dump(stream);
489 error = process_sp->Launch(launch_info);
490 if (
error.Success()) {
496 process_sp->SetSTDIOFileDescriptor(pty_fd);
497 LLDB_LOG(log,
"hooked up STDIO pty to process");
499 LLDB_LOG(log,
"not using process STDIO pty");
528 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
533 frame_sp->CalculateExecutionContext(exe_ctx);
544 exe_ctx, expr_options, expr_cstr, expr_prefix, result_valobj_sp);
546 return result_valobj_sp ? result_valobj_sp->GetError().Clone()
547 :
Status(
"unknown error");
549 if (result_valobj_sp->GetError().Fail())
550 return result_valobj_sp->GetError().Clone();
554std::unique_ptr<UtilityFunction>
572 static const char *dlopen_wrapper_code = R
"(
573 const int RTLD_LAZY = 1;
575 struct __lldb_dlopen_result {
577 const char *error_str;
580 extern "C" void *memcpy(void *, const void *, size_t size);
581 extern "C" size_t strlen(const char *);
584 void * __lldb_dlopen_wrapper (const char *name,
585 const char *path_strings,
587 __lldb_dlopen_result *result_ptr)
589 // This is the case where the name is the full path:
591 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
592 if (result_ptr->image_ptr)
593 result_ptr->error_str = nullptr;
595 result_ptr->error_str = dlerror();
599 // This is the case where we have a list of paths:
600 size_t name_len = strlen(name);
601 while (path_strings && path_strings[0] != '\0') {
602 size_t path_len = strlen(path_strings);
603 memcpy((void *) buffer, (void *) path_strings, path_len);
604 buffer[path_len] = '/';
605 char *target_ptr = buffer+path_len+1;
606 memcpy((void *) target_ptr, (void *) name, name_len + 1);
607 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
608 if (result_ptr->image_ptr) {
609 result_ptr->error_str = nullptr;
612 result_ptr->error_str = dlerror();
613 path_strings = path_strings + path_len + 1;
619 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
623 expr.append(dlopen_wrapper_code);
629 if (!utility_fn_or_error) {
630 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
632 "dlopen error: could not create utility function: %s",
636 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
637 std::move(*utility_fn_or_error);
665 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
666 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
667 if (utility_error.
Fail()) {
669 "dlopen error: could not make function caller: %s",
674 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
675 if (!do_dlopen_function) {
682 return dlopen_utility_func_up;
687 const std::vector<std::string> *paths,
691 loaded_image->
Clear();
694 path = remote_file.
GetPath(
false);
698 error = Status::FromErrorString(
699 "dlopen error: no thread available to call dlopen.");
703 DiagnosticManager diagnostics;
705 ExecutionContext exe_ctx;
706 thread_sp->CalculateExecutionContext(exe_ctx);
709 UtilityFunction *dlopen_utility_func;
711 FunctionCaller *do_dlopen_function =
nullptr;
716 this, [&]() -> std::unique_ptr<UtilityFunction> {
720 if (!dlopen_utility_func)
724 if (!do_dlopen_function) {
726 Status::FromErrorString(
"dlopen error: could not get function caller.");
733 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
734 size_t path_len = path.size() + 1;
739 error = Status::FromErrorStringWithFormat(
740 "dlopen error: could not allocate memory for path: %s",
746 llvm::scope_exit path_cleanup([process, path_addr] {
751 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
752 if (utility_error.
Fail()) {
753 error = Status::FromErrorStringWithFormat(
754 "dlopen error: could not write path string: %s",
765 if (utility_error.
Fail()) {
766 error = Status::FromErrorStringWithFormat(
767 "dlopen error: could not allocate memory for path: %s",
773 llvm::scope_exit return_cleanup([process, return_addr] {
781 std::optional<llvm::scope_exit<std::function<void()>>> path_array_cleanup;
787 std::optional<llvm::scope_exit<std::function<void()>>> buffer_cleanup;
790 if (paths !=
nullptr) {
795 size_t buffer_size = 0;
796 std::string path_array;
797 for (
auto path : *paths) {
802 size_t path_size = path.size();
803 path_array.append(path);
804 path_array.push_back(
'\0');
805 if (path_size > buffer_size)
806 buffer_size = path_size;
808 path_array.push_back(
'\0');
814 error = Status::FromErrorStringWithFormat(
815 "dlopen error: could not allocate memory for path array: %s",
821 path_array_cleanup.emplace([process, path_array_addr]() {
826 process->
WriteMemory(path_array_addr, path_array.data(),
827 path_array.size(), utility_error);
829 if (utility_error.
Fail()) {
830 error = Status::FromErrorStringWithFormat(
831 "dlopen error: could not write path array: %s",
837 buffer_size += path.size() + 2;
843 error = Status::FromErrorStringWithFormat(
844 "dlopen error: could not allocate memory for buffer: %s",
850 buffer_cleanup.emplace([process, buffer_addr]() {
870 "dlopen error: could not write function arguments:"));
877 llvm::scope_exit args_cleanup([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.
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.
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, std::string *error_output, const Timeout< std::micro > &timeout, bool run_in_shell=true)
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