Index: source/Commands/CommandObjectPlatform.cpp =================================================================== --- source/Commands/CommandObjectPlatform.cpp +++ source/Commands/CommandObjectPlatform.cpp @@ -249,6 +249,8 @@ PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch)); if (platform_sp) { + m_interpreter.GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp); + platform_sp->GetStatus (result.GetOutputStream()); result.SetStatus (eReturnStatusSuccessFinishResult); } Index: source/Commands/CommandObjectTarget.cpp =================================================================== --- source/Commands/CommandObjectTarget.cpp +++ source/Commands/CommandObjectTarget.cpp @@ -160,7 +160,6 @@ NULL), m_option_group (interpreter), m_arch_option (), - m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."), m_platform_path (LLDB_OPT_SET_1, false, "platform-path", 'P', 0, eArgTypePath, "Path to the remote file to use for this target."), m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable."), @@ -181,7 +180,6 @@ m_arguments.push_back (arg); m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); - m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); @@ -336,13 +334,13 @@ TargetSP target_sp; const char *arch_cstr = m_arch_option.GetArchitectureName(); + ArchSpec arch_spec(arch_cstr); const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue(); Error error (debugger.GetTargetList().CreateTarget (debugger, -// remote_file ? remote_file : file_spec, file_path, - arch_cstr, + arch_spec, get_dependent_files, - &m_platform_options, + platform_sp, target_sp)); if (target_sp) @@ -436,7 +434,6 @@ private: OptionGroupOptions m_option_group; OptionGroupArchitecture m_arch_option; - OptionGroupPlatform m_platform_options; OptionGroupFile m_core_file; OptionGroupFile m_platform_path; OptionGroupFile m_symbol_file; Index: source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -288,82 +288,6 @@ } // 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); } Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -212,6 +212,7 @@ 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); Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ 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 @@ 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 @@ 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 @@ { 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) { @@ -483,7 +569,7 @@ 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,7 +662,7 @@ 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); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -282,9 +282,8 @@ ListenThread (lldb::thread_arg_t arg); private: - lldb_private::HostThread m_listen_thread; + lldb_private::HostThread m_listen_thread; std::string m_listen_url; - //------------------------------------------------------------------ // For GDBRemoteCommunication only Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2850,7 +2850,11 @@ const char *packet = stream.GetData(); int packet_len = stream.GetSize(); - if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) + // give the process a few seconds to startup + const uint32_t old_packet_timeout = SetPacketTimeout (10); + auto result = SendPacketAndWaitForResponse(packet, packet_len, response, false); + SetPacketTimeout (old_packet_timeout); + if (result == PacketResult::Success) { std::string name; std::string value; Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -45,6 +45,7 @@ // Project includes #include "Utility/StringExtractorGDBRemote.h" +#include "Utility/UriParser.h" #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" @@ -1910,6 +1911,9 @@ // Spawn a new thread to accept the port that gets bound after // binding to port 0 (zero). + // ignore the hostname send from the remote end, just use the ip address + // that we're currently communicating with as the hostname + // Spawn a debugserver and try to get the port it listens to. ProcessLaunchInfo debugserver_launch_info; if (hostname.empty()) @@ -1919,7 +1923,14 @@ debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); - Error error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), + std::string platform_scheme; + std::string platform_ip; + int platform_port; + std::string platform_path; + bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path); + assert(ok); + Error error = StartDebugserverProcess ( + platform_ip.c_str(), port, debugserver_launch_info, port); Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -973,9 +973,12 @@ { Error error; // Only connect if we have a valid connect URL + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); if (connect_url && connect_url[0]) { + if (log) + log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url); std::unique_ptr conn_ap(new ConnectionFileDescriptor()); if (conn_ap.get()) { Index: source/Target/Platform.cpp =================================================================== --- source/Target/Platform.cpp +++ source/Target/Platform.cpp @@ -1233,7 +1233,64 @@ uint32_t uid, uint32_t gid) { - Error error("unimplemented"); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); + 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("PutFile: 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; + for (;;) + { + size_t bytes_read = buffer_sp->GetByteSize(); + error = source_file.Read(buffer_sp->GetBytes(), bytes_read); + if (error.Fail() || bytes_read == 0) + break; + + const uint64_t bytes_written = WriteFile(dest_file, offset, + buffer_sp->GetBytes(), bytes_read, error); + if (error.Fail()) + break; + + offset += bytes_written; + if (bytes_written != bytes_read) + { + // We didn't write the correct number of bytes, so adjust + // the file position in the source file we are reading from... + source_file.SeekFromStart(offset); + } + } + CloseFile(dest_file, error); + + if (uid == UINT32_MAX && gid == UINT32_MAX) + return error; + + // TODO: ChownFile? + return error; } Index: source/Target/TargetList.cpp =================================================================== --- source/Target/TargetList.cpp +++ source/Target/TargetList.cpp @@ -126,7 +126,11 @@ bool prefer_platform_arch = false; CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); - if (platform_options && platform_options->PlatformWasSpecified ()) + + // let's see if there is already an existing plaform before we go creating another... + platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + + if (!platform_sp && platform_options && platform_options->PlatformWasSpecified ()) { const bool select_platform = true; platform_sp = platform_options->CreatePlatformWithOptions (interpreter, Index: tools/lldb-gdbserver/lldb-gdbserver.cpp =================================================================== --- tools/lldb-gdbserver/lldb-gdbserver.cpp +++ tools/lldb-gdbserver/lldb-gdbserver.cpp @@ -428,7 +428,7 @@ // Ensure we connected. if (s_listen_connection_up) { - printf ("Connection established.\n"); + printf ("Connection established '%s'\n", s_listen_connection_up->GetURI().c_str()); gdb_server.SetConnection (s_listen_connection_up.release()); } else @@ -640,6 +640,15 @@ log_args.AppendArgument("default"); ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get()); } + Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_VERBOSE)); + if (log) + { + log->Printf ("lldb-gdbserver launch"); + for (int i = 0; i < argc; i++) + { + log->Printf ("argv[%i] = '%s'", i, argv[i]); + } + } // Skip any options we consumed with getopt_long_only. argc -= optind;