Added the ability to get a broadcaster event name for a given broadcaster
event.
Modified the ProcessInfo structure to contain all process arguments. Using the
new function calls on MacOSX allows us to see the full process name, not just
the first 16 characters.
Added a new platform command: "platform process info <pid> [<pid> <pid> ...]"
that can be used to get detailed information for a process including all
arguments, user and group info and more.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@128694 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 42ede89..12515ce 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -237,10 +237,10 @@
{
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 @@
{
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 @@
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 @@
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 @@
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 @@
}
else
{
- Stream &ostrm = result.GetOutputStream();
ProcessInfo::DumpTableHeader (ostrm, platform_sp.get());
for (uint32_t i=0; i<matches; ++i)
@@ -684,6 +686,106 @@
{ 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 @@
{
// 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 @@
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 789228a..a603d6c 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -42,6 +42,12 @@
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 adf5327..65d60d7 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 @@
}
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 @@
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)
+ int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+
+ size_t pid_data_size = 0;
+ if (::sysctl (mib, 4, NULL, &pid_data_size, NULL, 0) != 0)
return 0;
-
- num_pids = size_of_pids/sizeof(int);
- 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)
+ // 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;
-
- lldb::pid_t our_pid = getpid();
-
- for (int i = 0; i < num_pids; i++)
+
+ 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)
+ 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;
-
- // 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;
-
+
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 @@
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 d640d5b..39efd35 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1169,7 +1169,7 @@
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 a2b17e5..ec07fbe 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -134,6 +134,8 @@
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 1b0a864..1a9bc8b 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -42,76 +42,133 @@
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);
- 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);
+ 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);
- s.Printf ("%-24s %s\n",
- m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "",
- m_name.c_str());
+ 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 ("%-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.PutCString (GetName());
+ }
+
+ s.EOL();
}
}