diff options
-rw-r--r-- | include/lldb/Core/Broadcaster.h | 9 | ||||
-rw-r--r-- | include/lldb/Target/Process.h | 53 | ||||
-rw-r--r-- | source/Commands/CommandObjectPlatform.cpp | 137 | ||||
-rw-r--r-- | source/Core/Communication.cpp | 6 | ||||
-rw-r--r-- | source/Host/macosx/Host.mm | 142 | ||||
-rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 2 | ||||
-rw-r--r-- | source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 2 | ||||
-rw-r--r-- | source/Target/Process.cpp | 129 | ||||
-rw-r--r-- | tools/debugserver/source/RNBSocket.cpp | 51 | ||||
-rw-r--r-- | tools/debugserver/source/RNBSocket.h | 2 | ||||
-rw-r--r-- | tools/debugserver/source/debugserver.cpp | 3 |
11 files changed, 432 insertions, 104 deletions
diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h index a30bdd8f9..8eea00bac 100644 --- a/include/lldb/Core/Broadcaster.h +++ b/include/lldb/Core/Broadcaster.h @@ -171,6 +171,15 @@ public: m_event_names[event_mask] = name; } + const char * + GetEventName (uint32_t event_mask) const + { + event_names_map::const_iterator pos = m_event_names.find (event_mask); + if (pos != m_event_names.end()) + return pos->second.c_str(); + return NULL; + } + bool EventTypeHasListeners (uint32_t event_type); diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index 093349edd..cee05307a 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <list> +#include <vector> // Other libraries and framework includes // Project includes @@ -29,6 +30,7 @@ #include "lldb/Breakpoint/BreakpointSiteList.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/IRDynamicChecks.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" @@ -227,7 +229,8 @@ class ProcessInfo { public: ProcessInfo () : - m_name (), + m_executable (), + m_args (), m_real_uid (UINT32_MAX), m_real_gid (UINT32_MAX), m_effective_uid (UINT32_MAX), @@ -241,7 +244,8 @@ public: ProcessInfo (const char *name, const ArchSpec &arch, lldb::pid_t pid) : - m_name (), + m_executable (), + m_args (), m_real_uid (UINT32_MAX), m_real_gid (UINT32_MAX), m_effective_uid (UINT32_MAX), @@ -255,7 +259,8 @@ public: void Clear () { - m_name.clear(); + m_executable.Clear(); + m_args.Clear(); m_real_uid = UINT32_MAX; m_real_gid = UINT32_MAX; m_effective_uid = UINT32_MAX; @@ -268,30 +273,31 @@ public: const char * GetName() const { - if (m_name.empty()) - return NULL; - return m_name.c_str(); + return m_executable.GetFilename().GetCString(); } size_t GetNameLength() const { - return m_name.size(); + return m_executable.GetFilename().GetLength(); } void SetName (const char *name) { - if (name && name[0]) - m_name.assign (name); - else - m_name.clear(); + m_executable.GetFilename().SetCString (name); + } + + FileSpec & + GetExecutableFile () + { + return m_executable; } - void - SwapName (std::string &name) + const FileSpec & + GetExecutableFile () const { - m_name.swap (name); + return m_executable; } uint32_t @@ -418,13 +424,26 @@ public: Dump (Stream &s, Platform *platform) const; static void - DumpTableHeader (Stream &s, Platform *platform); + DumpTableHeader (Stream &s, Platform *platform, bool verbose = false); void - DumpAsTableRow (Stream &s, Platform *platform) const; + DumpAsTableRow (Stream &s, Platform *platform, bool verbose = false) const; + + StringList & + GetArguments() + { + return m_args; + } + + const StringList & + GetArguments() const + { + return m_args; + } protected: - std::string m_name; + FileSpec m_executable; + StringList m_args; uint32_t m_real_uid; uint32_t m_real_gid; uint32_t m_effective_uid; diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 42ede898c..12515ce3e 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -237,10 +237,10 @@ public: { Stream &ostrm = result.GetOutputStream(); - PlatformSP selected_platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); - if (selected_platform_sp) + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { - selected_platform_sp->GetStatus (ostrm); + platform_sp->GetStatus (ostrm); result.SetStatus (eReturnStatusSuccessFinishResult); } else @@ -308,13 +308,13 @@ public: { Stream &ostrm = result.GetOutputStream(); - PlatformSP selected_platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); - if (selected_platform_sp) + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { - Error error (selected_platform_sp->ConnectRemote (args)); + Error error (platform_sp->ConnectRemote (args)); if (error.Success()) { - selected_platform_sp->GetStatus (ostrm); + platform_sp->GetStatus (ostrm); result.SetStatus (eReturnStatusSuccessFinishResult); } else @@ -355,28 +355,28 @@ public: virtual bool Execute (Args& args, CommandReturnObject &result) { - PlatformSP selected_platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); - if (selected_platform_sp) + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { if (args.GetArgumentCount() == 0) { Error error; - if (selected_platform_sp->IsConnected()) + if (platform_sp->IsConnected()) { // Cache the instance name if there is one since we are // about to disconnect and the name might go with it. - const char *hostname_cstr = selected_platform_sp->GetHostname(); + const char *hostname_cstr = platform_sp->GetHostname(); std::string hostname; if (hostname_cstr) hostname.assign (hostname_cstr); - error = selected_platform_sp->DisconnectRemote (); + error = platform_sp->DisconnectRemote (); if (error.Success()) { Stream &ostrm = result.GetOutputStream(); if (hostname.empty()) - ostrm.Printf ("Disconnected from \"%s\"\n", selected_platform_sp->GetShortPluginName()); + ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetShortPluginName()); else ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str()); result.SetStatus (eReturnStatusSuccessFinishResult); @@ -390,7 +390,7 @@ public: else { // Not connected... - result.AppendErrorWithFormat ("not connected to '%s'", selected_platform_sp->GetShortPluginName()); + result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName()); result.SetStatus (eReturnStatusFailed); } } @@ -444,13 +444,16 @@ public: if (platform_sp) { + Stream &ostrm = result.GetOutputStream(); + lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID(); if (pid != LLDB_INVALID_PROCESS_ID) { ProcessInfo proc_info; if (platform_sp->GetProcessInfo (pid, proc_info)) { - proc_info.Dump (result.GetOutputStream(), platform_sp.get()); + ProcessInfo::DumpTableHeader (ostrm, platform_sp.get()); + proc_info.DumpAsTableRow(ostrm, platform_sp.get()); result.SetStatus (eReturnStatusSuccessFinishResult); } else @@ -490,7 +493,6 @@ public: } else { - Stream &ostrm = result.GetOutputStream(); ProcessInfo::DumpTableHeader (ostrm, platform_sp.get()); for (uint32_t i=0; i<matches; ++i) @@ -684,6 +686,106 @@ CommandObjectPlatformProcessList::CommandOptions::g_option_table[] = { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL } }; + +//---------------------------------------------------------------------- +// "platform process info" +//---------------------------------------------------------------------- +class CommandObjectPlatformProcessInfo : public CommandObject +{ +public: + CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "platform process info", + "Get detailed information for one or more process by process ID.", + "platform process info <pid> [<pid> <pid> ...]", + 0) + { + CommandArgumentEntry arg; + CommandArgumentData pid_args; + + // Define the first (and only) variant of this arg. + pid_args.arg_type = eArgTypePid; + pid_args.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (pid_args); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectPlatformProcessInfo () + { + } + + virtual bool + Execute (Args& args, CommandReturnObject &result) + { + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) + { + const size_t argc = args.GetArgumentCount(); + if (argc > 0) + { + Error error; + + if (platform_sp->IsConnected()) + { + Stream &ostrm = result.GetOutputStream(); + bool success; + for (size_t i=0; i<argc; ++ i) + { + const char *arg = args.GetArgumentAtIndex(i); + lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success); + if (success) + { + ProcessInfo proc_info; + if (platform_sp->GetProcessInfo (pid, proc_info)) + { + ostrm.Printf ("Process information for process %i:\n", pid); + proc_info.Dump (ostrm, platform_sp.get()); + } + else + { + ostrm.Printf ("error: no process information is available for process %i\n", pid); + } + ostrm.EOL(); + } + else + { + result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg); + result.SetStatus (eReturnStatusFailed); + break; + } + } + } + else + { + // Not connected... + result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetShortPluginName()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + // Bad args + result.AppendError ("\"platform disconnect\" doesn't take any arguments"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("no platform is currently selected"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +}; + + + + class CommandObjectPlatformProcess : public CommandObjectMultiword { public: @@ -698,6 +800,7 @@ public: { // LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter))); // LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter))); + LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter))); LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter))); } @@ -721,7 +824,7 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) : CommandObjectMultiword (interpreter, "platform", "A set of commands to manage and create platforms.", - "platform [connect|create|disconnect|list|status|select] ...") + "platform [connect|create|disconnect|info|list|status|select] ...") { LoadSubCommand ("create", CommandObjectSP (new CommandObjectPlatformCreate (interpreter))); LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter))); diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp index 789228a5b..a603d6c7b 100644 --- a/source/Core/Communication.cpp +++ b/source/Core/Communication.cpp @@ -42,6 +42,12 @@ Communication::Communication(const char *name) : lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION, "%p Communication::Communication (name = %s)", this, name); + + SetEventName (eBroadcastBitDisconnected, "disconnected"); + SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes"); + SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit"); + SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit"); + SetEventName (eBroadcastBitPacketAvailable, "packet available"); } //---------------------------------------------------------------------- diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm index adf53272b..65d60d748 100644 --- a/source/Host/macosx/Host.mm +++ b/source/Host/macosx/Host.mm @@ -24,6 +24,8 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Communication.h" #include "lldb/Core/ConnectionFileDescriptor.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Host/Endian.h" #include "lldb/Host/FileSpec.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamFile.h" @@ -968,6 +970,59 @@ GetMacOSXProcessCPUType (ProcessInfo &process_info) } static bool +GetMacOSXProcessArgs (const ProcessInfoMatch *match_info_ptr, + ProcessInfo &process_info) +{ + if (process_info.ProcessIDIsValid()) + { + int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, process_info.GetProcessID() }; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0) + { + DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *)); + uint32_t offset = 0; + uint32_t start_offset; + uint32_t argc = data.GetU32 (&offset); + const char *cstr; + + cstr = data.GetCStr (&offset); + if (cstr) + { + process_info.GetExecutableFile().SetFile(cstr, false); + + if (match_info_ptr == NULL || + NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName())) + { + // Skip NULLs + while (1) + { + const uint8_t *p = data.PeekData(offset, 1); + if ((p == NULL) || (*p != '\0')) + break; + ++offset; + } + // Now extract all arguments + StringList &proc_args = process_info.GetArguments(); + for (int i=0; i<argc; ++i) + { + start_offset = offset; + cstr = data.GetCStr(&offset); + if (cstr) + proc_args.AppendString (cstr, offset - start_offset); + } + return true; + } + } + } + } + return false; +} + +static bool GetMacOSXProcessUserAndGroup (ProcessInfo &process_info) { if (process_info.ProcessIDIsValid()) @@ -1008,46 +1063,67 @@ GetMacOSXProcessUserAndGroup (ProcessInfo &process_info) uint32_t Host::FindProcesses (const ProcessInfoMatch &match_info, ProcessInfoList &process_infos) { - int num_pids; - int size_of_pids; - std::vector<int> pid_list; + std::vector<struct kinfo_proc> kinfos; - size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); - if (size_of_pids == -1) - return 0; - - num_pids = size_of_pids/sizeof(int); + int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; - pid_list.resize (size_of_pids); - size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, &pid_list[0], size_of_pids); - if (size_of_pids == -1) + size_t pid_data_size = 0; + if (::sysctl (mib, 4, NULL, &pid_data_size, NULL, 0) != 0) return 0; - - lldb::pid_t our_pid = getpid(); - for (int i = 0; i < num_pids; i++) + // Add a few extra in case a few more show up + const size_t estimated_pid_count = (pid_data_size / sizeof(struct kinfo_proc)) + 10; + + kinfos.resize (estimated_pid_count); + pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); + + if (::sysctl (mib, 4, &kinfos[0], &pid_data_size, NULL, 0) != 0) + return 0; + + const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); + + bool all_users = match_info.GetMatchAllUsers(); + const lldb::pid_t our_pid = getpid(); + const uid_t our_uid = getuid(); + for (int i = 0; i < actual_pid_count; i++) { - struct proc_bsdinfo bsd_info; - int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE); - if (error == 0) - continue; - - // Don't offer to attach to zombie processes, already traced or exiting - // processes, and of course, ourselves... It looks like passing the second arg of - // 0 to proc_listpids will exclude zombies anyway, but that's not documented so... - if (((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT)) != 0) - || (bsd_info.pbi_status == SZOMB) - || (bsd_info.pbi_pid == our_pid)) - continue; + const struct kinfo_proc &kinfo = kinfos[i]; + bool kinfo_user_matches = false; + if (all_users) + kinfo_user_matches = true; + else + kinfo_user_matches = kinfo.kp_eproc.e_pcred.p_ruid == our_uid; + + if (kinfo_user_matches == false || // Make sure the user is acceptable + kinfo.kp_proc.p_pid == our_pid || // Skip this process + kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero) + kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... + kinfo.kp_proc.p_flag & P_TRACED || // Being debugged? + kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting? + kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta) + continue; + ProcessInfo process_info; - process_info.SetProcessID (bsd_info.pbi_pid); - if (GetMacOSXProcessName (&match_info, process_info)) + process_info.SetProcessID (kinfo.kp_proc.p_pid); + process_info.SetParentProcessID (kinfo.kp_eproc.e_ppid); + process_info.SetRealUserID (kinfo.kp_eproc.e_pcred.p_ruid); + process_info.SetRealGroupID (kinfo.kp_eproc.e_pcred.p_rgid); + process_info.SetEffectiveUserID (kinfo.kp_eproc.e_ucred.cr_uid); + if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0) + process_info.SetEffectiveGroupID (kinfo.kp_eproc.e_ucred.cr_groups[0]); + else + process_info.SetEffectiveGroupID (UINT32_MAX); + + // Make sure our info matches before we go fetch the name and cpu type + if (match_info.Matches (process_info)) { - GetMacOSXProcessCPUType (process_info); - GetMacOSXProcessUserAndGroup (process_info); - if (match_info.Matches (process_info)) - process_infos.Append (process_info); + if (GetMacOSXProcessArgs (&match_info, process_info)) + { + GetMacOSXProcessCPUType (process_info); + if (match_info.Matches (process_info)) + process_infos.Append (process_info); + } } } return process_infos.GetSize(); @@ -1057,7 +1133,7 @@ bool Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) { process_info.SetProcessID(pid); - if (GetMacOSXProcessName (NULL, process_info)) + if (GetMacOSXProcessArgs (NULL, process_info)) { GetMacOSXProcessCPUType (process_info); GetMacOSXProcessUserAndGroup (process_info); diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index d640d5b1d..39efd3599 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1169,7 +1169,7 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot extractor.GetStringRef().swap(value); extractor.SetFilePos(0); extractor.GetHexByteString (value); - process_info.SwapName (value); + process_info.SetName (value.c_str()); } } diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a2b17e568..ec07fbee0 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -134,6 +134,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_local_debugserver (true), m_thread_observation_bps() { + m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); + m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); } //---------------------------------------------------------------------- diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index 1b0a864ba..1a9bc8b45 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -42,76 +42,133 @@ void ProcessInfo::Dump (Stream &s, Platform *platform) const { const char *cstr; - if (m_pid != LLDB_INVALID_PROCESS_ID) s.Printf (" pid = %i\n", m_pid); - if (!m_name.empty()) s.Printf (" name = \"%s\"\n", m_name.c_str()); - if (m_arch.IsValid()) s.Printf (" arch = %s\n", m_arch.GetTriple().str().c_str()); - if (m_parent_pid != LLDB_INVALID_PROCESS_ID)s.Printf ("parent = %i\n", m_parent_pid); + if (m_pid != LLDB_INVALID_PROCESS_ID) + s.Printf (" pid = %i\n", m_pid); + + if (m_parent_pid != LLDB_INVALID_PROCESS_ID) + s.Printf (" parent = %i\n", m_parent_pid); + + if (m_executable) + { + s.Printf (" name = %s\n", m_executable.GetFilename().GetCString()); + s.PutCString (" file = "); + m_executable.Dump(&s); + s.EOL(); + } + const uint32_t argc = m_args.GetSize(); + if (argc > 0) + { + for (uint32_t i=0; i<argc; i++) + { + if (i < 10) + s.Printf (" arg[%u] = %s\n", i, m_args.GetStringAtIndex(i)); + else + s.Printf ("arg[%u] = %s\n", i, m_args.GetStringAtIndex(i)); + } + } + if (m_arch.IsValid()) + s.Printf (" arch = %s\n", m_arch.GetTriple().str().c_str()); + if (m_real_uid != UINT32_MAX) { cstr = platform->GetUserName (m_real_uid); - s.Printf (" uid = %u %s\n", m_real_uid, cstr ? cstr : ""); + s.Printf (" uid = %-5u (%s)\n", m_real_uid, cstr ? cstr : ""); } if (m_real_gid != UINT32_MAX) { cstr = platform->GetGroupName (m_real_gid); - s.Printf (" gid = %u %s\n", m_real_gid, cstr ? cstr : ""); + s.Printf (" gid = %-5u (%s)\n", m_real_gid, cstr ? cstr : ""); } if (m_effective_uid != UINT32_MAX) { cstr = platform->GetUserName (m_effective_uid); - s.Printf (" euid = %u %s\n", m_effective_uid, cstr ? cstr : ""); + s.Printf (" euid = %-5u (%s)\n", m_effective_uid, cstr ? cstr : ""); } if (m_effective_gid != UINT32_MAX) { cstr = platform->GetGroupName (m_effective_gid); - s.Printf (" egid = %u %s\n", m_effective_gid, cstr ? cstr : ""); + s.Printf (" egid = %-5u (%s)\n", m_effective_gid, cstr ? cstr : ""); } } void -ProcessInfo::DumpTableHeader (Stream &s, Platform *platform) +ProcessInfo::DumpTableHeader (Stream &s, Platform *platform, bool verbose) { -// s.PutCString ("PID PARENT UID GID EUID EGID TRIPLE NAME\n"); -// s.PutCString ("====== ====== ===== ===== ===== ===== ======================== ============================\n"); - s.PutCString ("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME\n"); - s.PutCString ("====== ====== ========== ========== ========== ========== ======================== ============================\n"); + if (verbose) + { + s.PutCString ("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME\n"); + s.PutCString ("====== ====== ========== ========== ========== ========== ======================== ============================\n"); + } + else + { + s.PutCString ("PID PARENT USER ARCH NAME\n"); + s.PutCString ("====== ====== ========== ======= ============================\n"); + } } void -ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform) const +ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform, bool verbose) const { if (m_pid != LLDB_INVALID_PROCESS_ID) { const char *cstr; s.Printf ("%-6u %-6u ", m_pid, m_parent_pid); - cstr = platform->GetUserName (m_real_uid); - if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed - s.Printf ("%-10s ", cstr); - else - s.Printf ("%-10u ", m_real_uid); - cstr = platform->GetGroupName (m_real_gid); - if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed - s.Printf ("%-10s ", cstr); - else - s.Printf ("%-10u ", m_real_gid); + if (verbose) + { + cstr = platform->GetUserName (m_real_uid); + if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed + s.Printf ("%-10s ", cstr); + else + s.Printf ("%-10u ", m_real_uid); - cstr = platform->GetUserName (m_effective_uid); - if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed - s.Printf ("%-10s ", cstr); + cstr = platform->GetGroupName (m_real_gid); + if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed + s.Printf ("%-10s ", cstr); + else + s.Printf ("%-10u ", m_real_gid); + + cstr = platform->GetUserName (m_effective_uid); + if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed + s.Printf ("%-10s ", cstr); + else + s.Printf ("%-10u ", m_effective_uid); + + cstr = platform->GetGroupName (m_effective_gid); + if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed + s.Printf ("%-10s ", cstr); + else + s.Printf ("%-10u ", m_effective_gid); + s.Printf ("%-24s ", m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : ""); + } else - s.Printf ("%-10u ", m_effective_uid); - - cstr = platform->GetGroupName (m_effective_gid); - if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed - s.Printf ("%-10s ", cstr); + { + s.Printf ("%-10s %.*-7s ", + platform->GetUserName (m_effective_uid), + (int)m_arch.GetTriple().getArchName().size(), + m_arch.GetTriple().getArchName().data()); + } + + if (verbose) + { + const uint32_t argc = m_args.GetSize(); + if (argc > 0) + { + for (uint32_t i=0; i<argc; i++) + { + if (i > 0) + s.PutChar (' '); + s.PutCString (m_args.GetStringAtIndex(i)); + } + } + } else - s.Printf ("%-10u ", m_effective_gid); + { + s.PutCString (GetName()); + } - s.Printf ("%-24s %s\n", - m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "", - m_name.c_str()); + s.EOL(); } } diff --git a/tools/debugserver/source/RNBSocket.cpp b/tools/debugserver/source/RNBSocket.cpp index 08fa4ac79..139a4150a 100644 --- a/tools/debugserver/source/RNBSocket.cpp +++ b/tools/debugserver/source/RNBSocket.cpp @@ -12,8 +12,10 @@ //===----------------------------------------------------------------------===// #include "RNBSocket.h" +#include <arpa/inet.h> #include <errno.h> #include <fcntl.h> +#include <netdb.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <termios.h> @@ -106,6 +108,55 @@ RNBSocket::Listen (in_port_t listen_port_num) return rnb_success; } +rnb_err_t +RNBSocket::Connect (const char *host, uint16_t port) +{ + Disconnect (false); + + // Create the socket + m_conn_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (m_conn_port == -1) + return rnb_err; + + // Enable local address reuse + SetSocketOption (m_conn_port, SOL_SOCKET, SO_REUSEADDR, 1); + + struct sockaddr_in sa; + ::memset (&sa, 0, sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (port); + + if (host == NULL) + host = "localhost"; + + int inet_pton_result = ::inet_pton (AF_INET, host, &sa.sin_addr); + + if (inet_pton_result <= 0) + { + struct hostent *host_entry = gethostbyname (host); + if (host_entry) + { + std::string host_str (::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list)); + inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); + if (inet_pton_result <= 0) + { + Disconnect (false); + return rnb_err; + } + } + } + + if (-1 == ::connect (m_conn_port, (const struct sockaddr *)&sa, sizeof(sa))) + { + Disconnect (false); + return rnb_err; + } + + // Keep our TCP packets coming without any delays. + SetSocketOption (m_conn_port, IPPROTO_TCP, TCP_NODELAY, 1); + return rnb_success; +} + #if defined (__arm__) rnb_err_t RNBSocket::ConnectToService() diff --git a/tools/debugserver/source/RNBSocket.h b/tools/debugserver/source/RNBSocket.h index de3db806d..56608bb17 100644 --- a/tools/debugserver/source/RNBSocket.h +++ b/tools/debugserver/source/RNBSocket.h @@ -36,6 +36,8 @@ public: } rnb_err_t Listen (in_port_t listen_port_num); + rnb_err_t Connect (const char *host, uint16_t port); + #if defined (__arm__) rnb_err_t ConnectToService(); #endif diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp index 6c149f3c2..6e08d5dd8 100644 --- a/tools/debugserver/source/debugserver.cpp +++ b/tools/debugserver/source/debugserver.cpp @@ -374,6 +374,8 @@ signal_handler(int signo) case eStateStepping: DNBProcessSignal (g_pid, SIGSTOP); return; + default: + break; } } } @@ -455,6 +457,7 @@ HandleProcessStateChange (RNBRemote *remote, bool initialize) case eStateExited: remote->HandlePacket_last_signal(NULL); + case eStateDetached: return eRNBRunLoopModeExit; } |