aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/lldb/Core/Broadcaster.h9
-rw-r--r--include/lldb/Target/Process.h53
-rw-r--r--source/Commands/CommandObjectPlatform.cpp137
-rw-r--r--source/Core/Communication.cpp6
-rw-r--r--source/Host/macosx/Host.mm142
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp2
-rw-r--r--source/Target/Process.cpp129
-rw-r--r--tools/debugserver/source/RNBSocket.cpp51
-rw-r--r--tools/debugserver/source/RNBSocket.h2
-rw-r--r--tools/debugserver/source/debugserver.cpp3
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;
}