35#include "llvm/ADT/ScopeExit.h"
36#include "llvm/Support/Error.h"
37#include "llvm/Support/FormatAdapters.h"
60 std::unique_ptr<lldb_private::OptionGroupOptions> options(
65 m_options[&interpreter] = std::move(options);
74 if (!platform || !path || *path == 0)
85 command.
Printf(
":%d", gid);
86 command.
Printf(
"%s", path);
89 nullptr,
nullptr, std::chrono::seconds(10));
100 if (source == destination)
104 std::string src_path(source.
GetPath());
105 if (src_path.empty())
107 std::string dst_path(destination.
GetPath());
108 if (dst_path.empty())
111 command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
114 nullptr, std::chrono::seconds(10));
119 if (
chown_file(
this, dst_path.c_str(), uid, gid) != 0)
124 std::string src_path(source.
GetPath());
125 if (src_path.empty())
127 std::string dst_path(destination.
GetPath());
128 if (dst_path.empty())
130 "unable to get file path for destination");
145 nullptr,
nullptr, std::chrono::minutes(1));
167 std::string src_path(source.
GetPath());
168 if (src_path.empty())
170 std::string dst_path(destination.
GetPath());
171 if (dst_path.empty())
174 if (source == destination)
176 "local scenario->source and destination are the same file "
177 "path: no operation performed");
180 cp_command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
183 nullptr, std::chrono::seconds(10));
196 src_path.c_str(), dst_path.c_str());
204 nullptr,
nullptr, std::chrono::minutes(1));
214 LLDB_LOGF(log,
"[GetFile] Using block by block transfer....\n");
217 lldb::eFilePermissionsFileDefault,
error);
222 uint32_t permissions = 0;
225 if (permissions == 0)
226 permissions = lldb::eFilePermissionsFileDefault;
238 if (
error.Success()) {
242 while (
error.Success()) {
243 const uint64_t n_read =
ReadFile(fd_src, offset, buffer_sp->GetBytes(),
244 buffer_sp->GetByteSize(),
error);
250 buffer_sp->GetBytes(), n_read,
282 stream.
Printf(
", options: ");
285 stream.
Printf(
", prefix: ");
289 stream.
Printf(
"ignore remote-hostname ");
315 "can't connect to the host platform '{0}', always connected",
327 "failed to create a 'remote-gdb-server' platform");
361 "can't disconnect from the host platform '{0}', always connected",
380 if (target ==
nullptr) {
385 target = new_target_sp.get();
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->SetSTDIOFileDescriptor(pty_fd);
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();
556std::unique_ptr<UtilityFunction>
574 static const char *dlopen_wrapper_code = R
"(
575 const int RTLD_LAZY = 1;
577 struct __lldb_dlopen_result {
579 const char *error_str;
582 extern "C" void *memcpy(void *, const void *, size_t size);
583 extern "C" size_t strlen(const char *);
586 void * __lldb_dlopen_wrapper (const char *name,
587 const char *path_strings,
589 __lldb_dlopen_result *result_ptr)
591 // This is the case where the name is the full path:
593 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
594 if (result_ptr->image_ptr)
595 result_ptr->error_str = nullptr;
597 result_ptr->error_str = dlerror();
601 // This is the case where we have a list of paths:
602 size_t name_len = strlen(name);
603 while (path_strings && path_strings[0] != '\0') {
604 size_t path_len = strlen(path_strings);
605 memcpy((void *) buffer, (void *) path_strings, path_len);
606 buffer[path_len] = '/';
607 char *target_ptr = buffer+path_len+1;
608 memcpy((void *) target_ptr, (void *) name, name_len + 1);
609 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
610 if (result_ptr->image_ptr) {
611 result_ptr->error_str = nullptr;
614 result_ptr->error_str = dlerror();
615 path_strings = path_strings + path_len + 1;
621 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
625 expr.append(dlopen_wrapper_code);
631 if (!utility_fn_or_error) {
632 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
634 "dlopen error: could not create utility function: %s",
638 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
639 std::move(*utility_fn_or_error);
667 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
668 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
669 if (utility_error.
Fail()) {
671 "dlopen error: could not make function caller: %s",
676 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
677 if (!do_dlopen_function) {
684 return dlopen_utility_func_up;
689 const std::vector<std::string> *paths,
693 loaded_image->
Clear();
696 path = remote_file.
GetPath(
false);
700 error = Status::FromErrorString(
701 "dlopen error: no thread available to call dlopen.");
705 DiagnosticManager diagnostics;
707 ExecutionContext exe_ctx;
708 thread_sp->CalculateExecutionContext(exe_ctx);
711 UtilityFunction *dlopen_utility_func;
713 FunctionCaller *do_dlopen_function =
nullptr;
718 this, [&]() -> std::unique_ptr<UtilityFunction> {
722 if (!dlopen_utility_func)
726 if (!do_dlopen_function) {
728 Status::FromErrorString(
"dlopen error: could not get function caller.");
735 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
736 size_t path_len = path.size() + 1;
741 error = Status::FromErrorStringWithFormat(
742 "dlopen error: could not allocate memory for path: %s",
748 llvm::scope_exit path_cleanup([process, path_addr] {
753 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
754 if (utility_error.
Fail()) {
755 error = Status::FromErrorStringWithFormat(
756 "dlopen error: could not write path string: %s",
767 if (utility_error.
Fail()) {
768 error = Status::FromErrorStringWithFormat(
769 "dlopen error: could not allocate memory for path: %s",
775 llvm::scope_exit return_cleanup([process, return_addr] {
783 std::optional<llvm::scope_exit<std::function<void()>>> path_array_cleanup;
789 std::optional<llvm::scope_exit<std::function<void()>>> buffer_cleanup;
792 if (paths !=
nullptr) {
797 size_t buffer_size = 0;
798 std::string path_array;
799 for (
auto path : *paths) {
804 size_t path_size = path.size();
805 path_array.append(path);
806 path_array.push_back(
'\0');
807 if (path_size > buffer_size)
808 buffer_size = path_size;
810 path_array.push_back(
'\0');
816 error = Status::FromErrorStringWithFormat(
817 "dlopen error: could not allocate memory for path array: %s",
823 path_array_cleanup.emplace([process, path_array_addr]() {
828 process->
WriteMemory(path_array_addr, path_array.data(),
829 path_array.size(), utility_error);
831 if (utility_error.
Fail()) {
832 error = Status::FromErrorStringWithFormat(
833 "dlopen error: could not write path array: %s",
839 buffer_size += path.size() + 2;
845 error = Status::FromErrorStringWithFormat(
846 "dlopen error: could not allocate memory for buffer: %s",
852 buffer_cleanup.emplace([process, buffer_addr]() {
872 "dlopen error: could not write function arguments:"));
879 llvm::scope_exit args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
884 EvaluateExpressionOptions options;
887 options.SetIgnoreBreakpoints(
true);
888 options.SetUnwindOnError(
true);
889 options.SetTrapExceptions(
false);
892 options.SetIsForUtilityExpr(
true);
898 if (!scratch_ts_sp) {
900 Status::FromErrorString(
"dlopen error: Unable to get TypeSystemClang");
904 CompilerType clang_void_pointer_type =
910 exe_ctx, &func_args_addr, options, diagnostics, return_value);
914 "dlopen error: failed executing dlopen wrapper function:"));
919 llvm::Expected<lldb::addr_t> token =
923 "dlopen error: could not read the return struct: {0}",
924 llvm::fmt_consume(token.takeError()));
930 if (loaded_image && buffer_addr != 0x0)
934 std::string name_string;
937 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
943 std::string dlopen_error_str;
944 llvm::Expected<lldb::addr_t> error_addr =
947 error = Status::FromErrorStringWithFormatv(
948 "dlopen error: could not read error string: {0}",
949 llvm::fmt_consume(error_addr.takeError()));
954 *error_addr + addr_size, dlopen_error_str, utility_error);
955 if (utility_error.
Success() && num_chars > 0)
957 dlopen_error_str.c_str());
966 uint32_t image_token) {
972 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
980 if (result_valobj_sp->GetError().Fail())
981 return result_valobj_sp->GetError().Clone();
984 if (result_valobj_sp->ResolveValue(scalar)) {
996 extern "C" void* dlopen(const char*, int);
997 extern "C" void* dlsym(void*, const char*);
998 extern "C" int dlclose(void*);
999 extern "C" char* dlerror(void);
1004 if (basename.empty())
1005 return basename.str();
1007 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 uniqued constant string class.
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(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.
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)
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.
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