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()) {
493 process_sp->SetSTDIOFileDescriptor(pty_fd);
494 LLDB_LOG(log,
"hooked up STDIO pty to process");
496 LLDB_LOG(log,
"not using process STDIO pty");
524 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
529 frame_sp->CalculateExecutionContext(exe_ctx);
540 exe_ctx, expr_options, expr_cstr, expr_prefix, result_valobj_sp);
542 return result_valobj_sp ? result_valobj_sp->GetError().Clone()
543 :
Status(
"unknown error");
545 if (result_valobj_sp->GetError().Fail())
546 return result_valobj_sp->GetError().Clone();
550std::unique_ptr<UtilityFunction>
568 static const char *dlopen_wrapper_code = R
"(
569 const int RTLD_LAZY = 1;
571 struct __lldb_dlopen_result {
573 const char *error_str;
576 extern "C" void *memcpy(void *, const void *, size_t size);
577 extern "C" size_t strlen(const char *);
580 void * __lldb_dlopen_wrapper (const char *name,
581 const char *path_strings,
583 __lldb_dlopen_result *result_ptr)
585 // This is the case where the name is the full path:
587 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
588 if (result_ptr->image_ptr)
589 result_ptr->error_str = nullptr;
591 result_ptr->error_str = dlerror();
595 // This is the case where we have a list of paths:
596 size_t name_len = strlen(name);
597 while (path_strings && path_strings[0] != '\0') {
598 size_t path_len = strlen(path_strings);
599 memcpy((void *) buffer, (void *) path_strings, path_len);
600 buffer[path_len] = '/';
601 char *target_ptr = buffer+path_len+1;
602 memcpy((void *) target_ptr, (void *) name, name_len + 1);
603 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
604 if (result_ptr->image_ptr) {
605 result_ptr->error_str = nullptr;
608 result_ptr->error_str = dlerror();
609 path_strings = path_strings + path_len + 1;
615 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
619 expr.append(dlopen_wrapper_code);
625 if (!utility_fn_or_error) {
626 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
628 "dlopen error: could not create utility function: %s",
632 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
633 std::move(*utility_fn_or_error);
661 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
662 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
663 if (utility_error.
Fail()) {
665 "dlopen error: could not make function caller: %s",
670 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
671 if (!do_dlopen_function) {
678 return dlopen_utility_func_up;
683 const std::vector<std::string> *paths,
687 loaded_image->
Clear();
690 path = remote_file.
GetPath(
false);
695 "dlopen error: no thread available to call dlopen.");
702 thread_sp->CalculateExecutionContext(exe_ctx);
712 this, [&]() -> std::unique_ptr<UtilityFunction> {
716 if (!dlopen_utility_func)
720 if (!do_dlopen_function) {
729 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
730 size_t path_len = path.size() + 1;
736 "dlopen error: could not allocate memory for path: %s",
742 auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
747 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
748 if (utility_error.
Fail()) {
750 "dlopen error: could not write path string: %s",
761 if (utility_error.
Fail()) {
763 "dlopen error: could not allocate memory for path: %s",
769 auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
777 std::optional<llvm::detail::scope_exit<std::function<void()>>>
784 std::optional<llvm::detail::scope_exit<std::function<void()>>> buffer_cleanup;
787 if (paths !=
nullptr) {
792 size_t buffer_size = 0;
793 std::string path_array;
794 for (
auto path : *paths) {
799 size_t path_size = path.size();
800 path_array.append(path);
801 path_array.push_back(
'\0');
802 if (path_size > buffer_size)
803 buffer_size = path_size;
805 path_array.push_back(
'\0');
812 "dlopen error: could not allocate memory for path array: %s",
818 path_array_cleanup.emplace([process, path_array_addr]() {
823 process->
WriteMemory(path_array_addr, path_array.data(),
824 path_array.size(), utility_error);
826 if (utility_error.
Fail()) {
828 "dlopen error: could not write path array: %s",
834 buffer_size += path.size() + 2;
841 "dlopen error: could not allocate memory for buffer: %s",
847 buffer_cleanup.emplace([process, buffer_addr]() {
867 "dlopen error: could not write function arguments:"));
875 llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
883 options.SetIgnoreBreakpoints(
true);
884 options.SetUnwindOnError(
true);
885 options.SetTrapExceptions(
false);
888 options.SetIsForUtilityExpr(
true);
894 if (!scratch_ts_sp) {
906 exe_ctx, &func_args_addr, options, diagnostics, return_value);
910 "dlopen error: failed executing dlopen wrapper function:"));
917 if (utility_error.
Fail()) {
919 "dlopen error: could not read the return struct: %s",
926 if (loaded_image && buffer_addr != 0x0)
930 std::string name_string;
933 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
939 std::string dlopen_error_str;
942 if (utility_error.
Fail()) {
944 "dlopen error: could not read error string: %s",
952 if (utility_error.
Success() && num_chars > 0)
954 dlopen_error_str.c_str());
963 uint32_t image_token) {
969 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
977 if (result_valobj_sp->GetError().Fail())
978 return result_valobj_sp->GetError().Clone();
981 if (result_valobj_sp->ResolveValue(scalar)) {
993 extern "C" void* dlopen(const char*, int);
994 extern "C" void* dlsym(void*, const char*);
995 extern "C" int dlclose(void*);
996 extern "C" char* dlerror(void);
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.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
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
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error)
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
PseudoTerminal & GetPTY()
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.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
@ invalid_fd
Invalid file descriptor value.
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)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
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...
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
FunctionCaller * GetFunctionCaller()
void PushValue(const Value &value)
Value * GetValueAtIndex(size_t idx)
const Scalar & GetScalar() const
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