Go to the documentation of this file.
35 #include "llvm/ADT/ScopeExit.h"
57 std::unique_ptr<lldb_private::OptionGroupOptions> options(
62 m_options[&interpreter] = std::move(options);
71 if (!platform || !path || *path == 0)
82 command.
Printf(
":%d", gid);
83 command.
Printf(
"%s", path);
86 nullptr, std::chrono::seconds(10));
97 if (source == destination)
102 if (src_path.empty())
103 return Status(
"unable to get file path for source");
105 if (dst_path.empty())
106 return Status(
"unable to get file path for destination");
108 command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
111 std::chrono::seconds(10));
113 return Status(
"unable to perform copy");
116 if (
chown_file(
this, dst_path.c_str(), uid, gid) != 0)
117 return Status(
"unable to perform chown");
122 if (src_path.empty())
123 return Status(
"unable to get file path for source");
125 if (dst_path.empty())
126 return Status(
"unable to get file path for destination");
140 Host::RunShellCommand(command.
GetData(),
FileSpec(), &retcode,
nullptr,
141 nullptr, std::chrono::minutes(1));
152 return Platform::PutFile(source, destination, uid, gid);
163 if (src_path.empty())
164 return Status(
"unable to get file path for source");
166 if (dst_path.empty())
167 return Status(
"unable to get file path for destination");
169 if (source == destination)
170 return Status(
"local scenario->source and destination are the same file "
171 "path: no operation performed");
174 cp_command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
177 std::chrono::seconds(10));
179 return Status(
"unable to perform copy");
190 src_path.c_str(), dst_path.c_str());
197 Host::RunShellCommand(command.
GetData(),
FileSpec(), &retcode,
nullptr,
198 nullptr, std::chrono::minutes(1));
208 LLDB_LOGF(log,
"[GetFile] Using block by block transfer....\n");
211 lldb::eFilePermissionsFileDefault,
error);
214 return Status(
"unable to open source file");
219 if (permissions == 0)
220 permissions = lldb::eFilePermissionsFileDefault;
222 user_id_t fd_dst = FileCache::GetInstance().OpenFile(
223 destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly |
224 File::eOpenOptionTruncate,
229 error.SetErrorString(
"unable to open destination file");
232 if (
error.Success()) {
233 lldb::WritableDataBufferSP buffer_sp(
new DataBufferHeap(1024, 0));
236 while (
error.Success()) {
237 const uint64_t n_read =
ReadFile(fd_src, offset, buffer_sp->GetBytes(),
238 buffer_sp->GetByteSize(),
error);
243 if (FileCache::GetInstance().
WriteFile(fd_dst, offset,
244 buffer_sp->GetBytes(), n_read,
247 error.SetErrorString(
"unable to write to destination file");
260 error.SetErrorString(
"unable to close destination file");
264 return Platform::GetFile(source, destination);
273 stream.
Printf(
", options: ");
276 stream.
Printf(
", prefix: ");
280 stream.
Printf(
"ignore remote-hostname ");
299 return Platform::GetRemoteUnixSignals();
305 error.SetErrorStringWithFormatv(
306 "can't connect to the host platform '{0}', always connected",
311 platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
317 error.SetErrorString(
"failed to create a 'remote-gdb-server' platform");
350 error.SetErrorStringWithFormatv(
351 "can't disconnect from the host platform '{0}', always connected",
357 error.SetErrorString(
"the platform is not currently connected");
365 lldb::ProcessSP process_sp;
369 if (target ==
nullptr) {
370 TargetSP new_target_sp;
374 target = new_target_sp.get();
375 LLDB_LOGF(log,
"PlatformPOSIX::%s created new target", __FUNCTION__);
378 LLDB_LOGF(log,
"PlatformPOSIX::%s target already existed, setting target",
382 if (target &&
error.Success()) {
385 LLDB_LOGF(log,
"PlatformPOSIX::%s set selected target to %p %s",
386 __FUNCTION__, (
void *)target,
387 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
393 "gdb-remote",
nullptr,
true);
397 if (listener_sp ==
nullptr) {
399 Listener::MakeListener(
"lldb.PlatformPOSIX.attach.hijack");
402 process_sp->HijackProcessEvents(listener_sp);
403 error = process_sp->Attach(attach_info);
411 error.SetErrorString(
"the platform is not currently connected");
420 LLDB_LOG(log,
"target {0}", &target);
422 ProcessSP process_sp;
429 error.SetErrorString(
"the platform is not currently connected");
447 LLDB_LOG(log,
"having target create process with gdb-remote plugin");
452 error.SetErrorString(
"CreateProcess() failed for gdb-remote process");
457 LLDB_LOG(log,
"successfully created process");
463 LLDB_LOG(log,
"launching process with the following file actions:");
468 file_action->
Dump(stream);
475 error = process_sp->Launch(launch_info);
476 if (
error.Success()) {
480 if (pty_fd != PseudoTerminal::invalid_fd) {
481 process_sp->SetSTDIOFileDescriptor(pty_fd);
482 LLDB_LOG(log,
"hooked up STDIO pty to process");
484 LLDB_LOG(log,
"not using process STDIO pty");
500 llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
510 return Status(
"Selected thread isn't valid");
512 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
514 return Status(
"Frame 0 isn't valid");
517 frame_sp->CalculateExecutionContext(exe_ctx);
529 UserExpression::Evaluate(exe_ctx, expr_options, expr_cstr, expr_prefix,
530 result_valobj_sp, expr_error);
534 if (result_valobj_sp->GetError().Fail())
535 return result_valobj_sp->
GetError();
539 std::unique_ptr<UtilityFunction>
557 static const char *dlopen_wrapper_code = R
"(
558 const int RTLD_LAZY = 1;
560 struct __lldb_dlopen_result {
562 const char *error_str;
565 extern "C" void *memcpy(void *, const void *, size_t size);
566 extern "C" size_t strlen(const char *);
569 void * __lldb_dlopen_wrapper (const char *name,
570 const char *path_strings,
572 __lldb_dlopen_result *result_ptr)
574 // This is the case where the name is the full path:
576 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
577 if (result_ptr->image_ptr)
578 result_ptr->error_str = nullptr;
580 result_ptr->error_str = dlerror();
584 // This is the case where we have a list of paths:
585 size_t name_len = strlen(name);
586 while (path_strings && path_strings[0] != '\0') {
587 size_t path_len = strlen(path_strings);
588 memcpy((void *) buffer, (void *) path_strings, path_len);
589 buffer[path_len] = '/';
590 char *target_ptr = buffer+path_len+1;
591 memcpy((void *) target_ptr, (void *) name, name_len + 1);
592 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
593 if (result_ptr->image_ptr) {
594 result_ptr->error_str = nullptr;
597 result_ptr->error_str = dlerror();
598 path_strings = path_strings + path_len + 1;
604 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
608 expr.append(dlopen_wrapper_code);
614 if (!utility_fn_or_error) {
616 error.SetErrorStringWithFormat(
617 "dlopen error: could not create utility function: %s",
621 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
622 std::move(*utility_fn_or_error);
630 ScratchTypeSystemClang::GetForTarget(process->
GetTarget());
650 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
651 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
652 if (utility_error.
Fail()) {
653 error.SetErrorStringWithFormat(
654 "dlopen error: could not make function caller: %s",
659 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
660 if (!do_dlopen_function) {
661 error.SetErrorString(
"dlopen error: could not get function caller.");
666 return dlopen_utility_func_up;
671 const std::vector<std::string> *paths,
675 loaded_image->
Clear();
682 error.SetErrorString(
"dlopen error: no thread available to call dlopen.");
689 thread_sp->CalculateExecutionContext(exe_ctx);
699 this, [&]() -> std::unique_ptr<UtilityFunction> {
703 if (!dlopen_utility_func)
707 if (!do_dlopen_function) {
708 error.SetErrorString(
"dlopen error: could not get function caller.");
715 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
716 size_t path_len = path.size() + 1;
721 error.SetErrorStringWithFormat(
722 "dlopen error: could not allocate memory for path: %s",
728 auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
733 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
734 if (utility_error.
Fail()) {
735 error.SetErrorStringWithFormat(
736 "dlopen error: could not write path string: %s",
747 if (utility_error.
Fail()) {
748 error.SetErrorStringWithFormat(
749 "dlopen error: could not allocate memory for path: %s",
755 auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
763 llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
770 llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
774 if (paths !=
nullptr) {
779 size_t buffer_size = 0;
781 for (
auto path : *paths) {
786 size_t path_size = path.size();
787 path_array.append(path);
788 path_array.push_back(
'\0');
789 if (path_size > buffer_size)
790 buffer_size = path_size;
792 path_array.push_back(
'\0');
798 error.SetErrorStringWithFormat(
799 "dlopen error: could not allocate memory for path array: %s",
805 path_array_cleanup.emplace([process, path_array_addr]() {
810 process->
WriteMemory(path_array_addr, path_array.data(),
811 path_array.size(), utility_error);
813 if (utility_error.
Fail()) {
814 error.SetErrorStringWithFormat(
815 "dlopen error: could not write path array: %s",
821 buffer_size += path.size() + 2;
827 error.SetErrorStringWithFormat(
828 "dlopen error: could not allocate memory for buffer: %s",
834 buffer_cleanup.emplace([process, buffer_addr]() {
852 error.SetErrorStringWithFormat(
853 "dlopen error: could not write function arguments: %s",
862 llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
870 options.SetIgnoreBreakpoints(
true);
871 options.SetUnwindOnError(
true);
872 options.SetTrapExceptions(
false);
875 options.SetIsForUtilityExpr(
true);
880 ScratchTypeSystemClang::GetForTarget(process->
GetTarget());
882 error.SetErrorString(
"dlopen error: Unable to get TypeSystemClang");
892 exe_ctx, &func_args_addr, options, diagnostics, return_value);
894 error.SetErrorStringWithFormat(
895 "dlopen error: failed executing dlopen wrapper function: %s",
903 if (utility_error.
Fail()) {
904 error.SetErrorStringWithFormat(
905 "dlopen error: could not read the return struct: %s",
912 if (loaded_image && buffer_addr != 0
x0)
919 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
928 if (utility_error.
Fail()) {
929 error.SetErrorStringWithFormat(
930 "dlopen error: could not read error string: %s",
938 if (utility_error.
Success() && num_chars > 0)
939 error.SetErrorStringWithFormat(
"dlopen error: %s",
940 dlopen_error_str.c_str());
942 error.SetErrorStringWithFormat(
"dlopen failed for unknown reasons.");
951 return Status(
"Invalid image token");
954 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
956 lldb::ValueObjectSP result_valobj_sp;
962 if (result_valobj_sp->GetError().Fail())
963 return result_valobj_sp->GetError();
966 if (result_valobj_sp->ResolveValue(scalar)) {
977 extern "C" void* dlopen(const char*, int);
978 extern "C" void* dlsym(void*, const char*);
979 extern "C" int dlclose(void*);
980 extern "C" char* dlerror(void);
const char * toString(AppleArm64ExceptionClass EC)
FunctionCaller * GetFunctionCaller()
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
void SetTimeout(const Timeout< std::micro > &timeout)
void SetLanguage(lldb::LanguageType language)
void SetValueType(ValueType value_type)
ExpressionResults
The results of expression evaluation.
Value * GetValueAtIndex(size_t idx)
std::chrono::seconds GetUtilityExpressionTimeout() const
#define LLDB_LOGF(log,...)
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
void SetExecutionPolicy(ExecutionPolicy policy=eExecutionPolicyAlways)
virtual Status CanLoadImage()=0
Ask if it is ok to try and load or unload an shared library (image).
ThreadList & GetThreadList()
Target & GetTarget()
Get the target object pointer for this module.
void SetTrapExceptions(bool b)
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 WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error)
Write memory to a process.
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file, bool can_connect)
virtual llvm::StringRef GetPluginName()=0
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.
llvm::StringRef GetString() const
std::string GetString(char separator='\n')
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
void SetCompilerType(const CompilerType &compiler_type)
void DeallocateFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Deallocate the arguments structure.
const Scalar & GetScalar() const
static llvm::raw_ostream & error(Stream &strm)
bool Success() const
Test for success condition.
void PushValue(const Value &value)
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
bool IsEmpty() const
Test for empty string.
ValueType GetError() const
Access the error value.
bool Fail() const
Test for error condition.
const char * GetData() const
void Dump(Stream &stream) const
ValueList GetArgumentValues() const
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.
uint32_t GetAddressByteSize() const
unsigned int UInt(unsigned int fail_value=0) const
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.
const FileAction * GetFileActionAtIndex(size_t idx) const
lldb::ListenerSP GetListener() const
void SetHijackListener(const lldb::ListenerSP &listener_sp)
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
string(SUBSTRING ${p} 10 -1 pStripped) if($
void SetUnwindOnError(bool unwind=false)
void SetLaunchInSeparateProcessGroup(bool separate)
PseudoTerminal & GetPTY()
TargetList & GetTargetList()
Get accessor for the target list.
void Clear()
Clears the object state.
void SetIgnoreBreakpoints(bool ignore=false)
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
#define LLDB_INVALID_IMAGE_TOKEN
size_t AddImageToken(lldb::addr_t image_ptr)
lldb::ListenerSP GetHijackListener() const
#define LLDB_INVALID_ADDRESS
const char * GetCString() const
Get the string value as a C string.
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Generic representation of a type in a programming language.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
A class that represents a running process on the host machine.
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.
lldb::addr_t GetImagePtrFromToken(size_t token) const
CompilerType GetBasicType(lldb::BasicType type)
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
A TypeSystem implementation based on Clang.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
lldb::ListenerSP GetHijackListener() const
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.
lldb::ThreadSP GetExpressionExecutionThread()
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
void ResetImageToken(size_t token)
@ eLanguageTypeC_plus_plus
ISO C++:1998.