diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-02-09 01:44:09 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-02-09 01:44:09 +0000 |
commit | 12bd4897ff0678fa663e09d78ebc22dd255ceb86 (patch) | |
tree | a8f4b3abea3e6937e60728991c736e6e3d322fc1 /source/Plugins/Platform | |
parent | 205afe679855a4ce8149cdaa94d3f0868ce796dc (diff) | |
download | src-test2-12bd4897ff0678fa663e09d78ebc22dd255ceb86.tar.gz src-test2-12bd4897ff0678fa663e09d78ebc22dd255ceb86.zip |
Notes
Diffstat (limited to 'source/Plugins/Platform')
3 files changed, 142 insertions, 94 deletions
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index b1be0f5b1fe1..5b72728c2b48 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -288,82 +288,6 @@ PlatformPOSIX::PutFile (const lldb_private::FileSpec& source, } // if we are still here rsync has failed - let's try the slow way before giving up } - - if (log) - log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)", - source.GetPath().c_str(), - destination.GetPath().c_str(), - uid, - gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN - // open - // read, write, read, write, ... - // close - // chown uid:gid dst - if (log) - log->Printf("[PutFile] Using block by block transfer....\n"); - - uint32_t source_open_options = File::eOpenOptionRead; - if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink) - source_open_options |= File::eOpenoptionDontFollowSymlinks; - - File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); - Error error; - uint32_t permissions = source_file.GetPermissions(error); - if (permissions == 0) - permissions = lldb::eFilePermissionsFileDefault; - - if (!source_file.IsValid()) - return Error("unable to open source file"); - lldb::user_id_t dest_file = OpenFile (destination, - File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate, - permissions, - error); - if (log) - log->Printf ("dest_file = %" PRIu64 "\n", dest_file); - if (error.Fail()) - return error; - if (dest_file == UINT64_MAX) - return Error("unable to open target file"); - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); - uint64_t offset = 0; - while (error.Success()) - { - size_t bytes_read = buffer_sp->GetByteSize(); - error = source_file.Read(buffer_sp->GetBytes(), bytes_read); - if (bytes_read) - { - const uint64_t bytes_written = WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error); - offset += bytes_written; - if (bytes_written != bytes_read) - { - // We didn't write the correct numbe of bytes, so adjust - // the file position in the source file we are reading from... - source_file.SeekFromStart(offset); - } - } - else - break; - } - CloseFile(dest_file, error); - if (uid == UINT32_MAX && gid == UINT32_MAX) - return error; - // This is remopve, don't chown a local file... -// std::string dst_path (destination.GetPath()); -// if (chown_file(this,dst_path.c_str(),uid,gid) != 0) -// return Error("unable to perform chown"); - - - uint64_t src_md5[2]; - uint64_t dst_md5[2]; - - if (FileSystem::CalculateMD5 (source, src_md5[0], src_md5[1]) && CalculateMD5 (destination, dst_md5[0], dst_md5[1])) - { - if (src_md5[0] != dst_md5[0] || src_md5[1] != dst_md5[1]) - { - error.SetErrorString("md5 checksum of installed file doesn't match, installation failed"); - } - } - return error; } return Platform::PutFile(source,destination,uid,gid); } @@ -841,8 +765,12 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info, // Set UnixSignals appropriately. process_sp->SetUnixSignals (Host::GetUnixSignals ()); - ListenerSP listener_sp (new Listener("lldb.PlatformPOSIX.attach.hijack")); - attach_info.SetHijackListener(listener_sp); + auto listener_sp = attach_info.GetHijackListener(); + if (listener_sp == nullptr) + { + listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack")); + attach_info.SetHijackListener(listener_sp); + } process_sp->HijackProcessEvents(listener_sp.get()); error = process_sp->Attach (attach_info); } diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 43eae4d906ec..ec2084aaf98c 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -30,6 +30,8 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "Utility/UriParser.h" + using namespace lldb; using namespace lldb_private; @@ -105,12 +107,76 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { + // copied from PlatformRemoteiOS + Error error; - //error.SetErrorString ("PlatformRemoteGDBServer::ResolveExecutable() is unimplemented"); - if (m_gdb_client.GetFileExists(module_spec.GetFileSpec())) - return error; - // TODO: get the remote end to somehow resolve this file - error.SetErrorString("file not found on remote end"); + // Nothing special to do here, just use the actual file and architecture + + ModuleSpec resolved_module_spec(module_spec); + + // Resolve any executable within an apk on Android? + //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); + + if (resolved_module_spec.GetFileSpec().Exists()) + { + if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact arch wasn't + // found so ask the platform for the architectures that we should be + // using (in the correct order) and see if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) + { + error = ModuleList::GetSharedModule (resolved_module_spec, + exe_module_sp, + NULL, + NULL, + NULL); + // Did we find an executable using one of the + if (error.Success()) + { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + if (idx > 0) + arch_names.PutCString (", "); + arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) + { + if (resolved_module_spec.GetFileSpec().Readable()) + { + error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), + arch_names.GetString().c_str()); + } + else + { + error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + else + { + error.SetErrorStringWithFormat ("'%s' does not exist", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + return error; } @@ -146,6 +212,15 @@ PlatformRemoteGDBServer::~PlatformRemoteGDBServer() bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) { + ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture(); + + // TODO: 64 bit systems should also advertize support for 32 bit arch + // unknown CPU, we just support the one arch + if (idx == 0) + { + arch = remote_arch; + return true; + } return false; } @@ -252,6 +327,17 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args) { const char *url = args.GetArgumentAtIndex(0); m_gdb_client.SetConnection (new ConnectionFileDescriptor()); + + // we're going to reuse the hostname when we connect to the debugserver + std::string scheme; + int port; + std::string path; + if ( !UriParser::Parse(url, scheme, m_platform_hostname, port, path) ) + { + error.SetErrorString("invalid uri"); + return error; + } + const ConnectionStatus status = m_gdb_client.Connect(url, &error); if (status == eConnectionStatusSuccess) { @@ -344,14 +430,30 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); Error error; - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; if (log) log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__); - m_gdb_client.SetSTDIN ("/dev/null"); - m_gdb_client.SetSTDOUT ("/dev/null"); - m_gdb_client.SetSTDERR ("/dev/null"); + auto num_file_actions = launch_info.GetNumFileActions (); + for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) + { + const auto file_action = launch_info.GetFileActionAtIndex (i); + if (file_action->GetAction () != FileAction::eFileActionOpen) + continue; + switch(file_action->GetFD()) + { + case STDIN_FILENO: + m_gdb_client.SetSTDIN (file_action->GetPath()); + break; + case STDOUT_FILENO: + m_gdb_client.SetSTDOUT (file_action->GetPath()); + break; + case STDERR_FILENO: + m_gdb_client.SetSTDERR (file_action->GetPath()); + break; + } + } + m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)); m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError)); @@ -389,7 +491,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) std::string error_str; if (m_gdb_client.GetLaunchSuccess (error_str)) { - pid = m_gdb_client.GetCurrentProcessID (); + const auto pid = m_gdb_client.GetCurrentProcessID (false); if (pid != LLDB_INVALID_PROCESS_ID) { launch_info.SetProcessID (pid); @@ -400,7 +502,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) { if (log) log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__); - // FIXME isn't this an error condition? Do we need to set an error here? Check with Greg. + error.SetErrorString ("failed to get PID"); } } else @@ -417,6 +519,14 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) return error; } +Error +PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid) +{ + if (!m_gdb_client.KillSpawnedProcess(pid)) + return Error("failed to kill remote spawned process"); + return Error(); +} + lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Debugger &debugger, @@ -483,7 +593,7 @@ PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_i const int connect_url_len = ::snprintf (connect_url, sizeof(connect_url), "connect://%s:%u", - override_hostname ? override_hostname : GetHostname (), + override_hostname ? override_hostname : m_platform_hostname.c_str(), port + port_offset); assert (connect_url_len < (int)sizeof(connect_url)); error = process_sp->ConnectRemote (NULL, connect_url); @@ -576,13 +686,19 @@ PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info, const int connect_url_len = ::snprintf (connect_url, sizeof(connect_url), "connect://%s:%u", - override_hostname ? override_hostname : GetHostname (), + override_hostname ? override_hostname : m_platform_hostname.c_str(), port + port_offset); assert (connect_url_len < (int)sizeof(connect_url)); - error = process_sp->ConnectRemote (NULL, connect_url); + error = process_sp->ConnectRemote(nullptr, connect_url); if (error.Success()) + { + auto listener = attach_info.GetHijackListener(); + if (listener != nullptr) + process_sp->HijackProcessEvents(listener.get()); error = process_sp->Attach(attach_info); - else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + } + + if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) { m_gdb_client.KillSpawnedProcess(debugserver_pid); } diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index 90b16b8b8fa9..a928c4695f79 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -86,7 +86,10 @@ public: virtual lldb_private::Error LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); - + + virtual lldb_private::Error + KillProcess (const lldb::pid_t pid); + virtual lldb::ProcessSP DebugProcess (lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Debugger &debugger, @@ -212,6 +215,7 @@ public: protected: GDBRemoteCommunicationClient m_gdb_client; std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to + std::string m_platform_hostname; private: DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer); |