forked from OSchip/llvm-project
<rdar://problem/12647273>
Added the ability to get the full process list when using the --applist option in debugserver. llvm-svn: 167502
This commit is contained in:
parent
1c89744f32
commit
9eb4e03873
|
@ -40,7 +40,7 @@ typedef std::map<nub_process_t, MachProcessSP> ProcessMap;
|
|||
typedef ProcessMap::iterator ProcessMapIter;
|
||||
typedef ProcessMap::const_iterator ProcessMapConstIter;
|
||||
|
||||
static size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
|
||||
size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
|
||||
static size_t GetAllInfosMatchingName (const char *process_name, std::vector<struct kinfo_proc>& matching_proc_infos);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -391,10 +391,10 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_
|
|||
return INVALID_NUB_PROCESS;
|
||||
}
|
||||
|
||||
static size_t
|
||||
size_t
|
||||
GetAllInfos (std::vector<struct kinfo_proc>& proc_infos)
|
||||
{
|
||||
size_t size;
|
||||
size_t size = 0;
|
||||
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
|
||||
u_int namelen = sizeof(name)/sizeof(int);
|
||||
int err;
|
||||
|
|
|
@ -14,7 +14,11 @@
|
|||
#import "RNBServices.h"
|
||||
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#include <libproc.h>
|
||||
#import <unistd.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include "CFString.h"
|
||||
#include <vector>
|
||||
#import "DNBLog.h"
|
||||
#include "MacOSX/CFUtils.h"
|
||||
|
||||
|
@ -22,10 +26,101 @@
|
|||
#import <SpringBoardServices/SpringBoardServices.h>
|
||||
#endif
|
||||
|
||||
// From DNB.cpp
|
||||
size_t GetAllInfos (std::vector<struct kinfo_proc>& proc_infos);
|
||||
|
||||
int
|
||||
GetPrcoesses (CFMutableArrayRef plistMutableArray, bool all_users)
|
||||
{
|
||||
if (plistMutableArray == NULL)
|
||||
return -1;
|
||||
|
||||
// Running as root, get all processes
|
||||
std::vector<struct kinfo_proc> proc_infos;
|
||||
const size_t num_proc_infos = GetAllInfos(proc_infos);
|
||||
if (num_proc_infos > 0)
|
||||
{
|
||||
const pid_t our_pid = getpid();
|
||||
const uid_t our_uid = getuid();
|
||||
uint32_t i;
|
||||
CFAllocatorRef alloc = kCFAllocatorDefault;
|
||||
|
||||
for (i=0; i<num_proc_infos; i++)
|
||||
{
|
||||
struct kinfo_proc &proc_info = proc_infos[i];
|
||||
|
||||
bool kinfo_user_matches;
|
||||
// Special case, if lldb is being run as root we can attach to anything.
|
||||
if (all_users)
|
||||
kinfo_user_matches = true;
|
||||
else
|
||||
kinfo_user_matches = proc_info.kp_eproc.e_pcred.p_ruid == our_uid;
|
||||
|
||||
|
||||
const pid_t pid = proc_info.kp_proc.p_pid;
|
||||
// Skip zombie processes and processes with unset status
|
||||
if (kinfo_user_matches == false || // User is acceptable
|
||||
pid == our_pid || // Skip this process
|
||||
pid == 0 || // Skip kernel (kernel pid is zero)
|
||||
proc_info.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains...
|
||||
proc_info.kp_proc.p_flag & P_TRACED || // Being debugged?
|
||||
proc_info.kp_proc.p_flag & P_WEXIT || // Working on exiting?
|
||||
proc_info.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta)
|
||||
continue;
|
||||
|
||||
// Create a new mutable dictionary for each application
|
||||
CFReleaser<CFMutableDictionaryRef> appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
|
||||
|
||||
// Get the process id for the app (if there is one)
|
||||
const int32_t pid_int32 = pid;
|
||||
CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid_int32));
|
||||
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get());
|
||||
|
||||
// Set the a boolean to indicate if this is the front most
|
||||
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse);
|
||||
|
||||
const char *pid_basename = proc_info.kp_proc.p_comm;
|
||||
char proc_path_buf[PATH_MAX];
|
||||
|
||||
int return_val = proc_pidpath (pid, proc_path_buf, PATH_MAX);
|
||||
if (return_val > 0)
|
||||
{
|
||||
// Okay, now search backwards from that to see if there is a
|
||||
// slash in the name. Note, even though we got all the args we don't care
|
||||
// because the list data is just a bunch of concatenated null terminated strings
|
||||
// so strrchr will start from the end of argv0.
|
||||
|
||||
pid_basename = strrchr(proc_path_buf, '/');
|
||||
if (pid_basename)
|
||||
{
|
||||
// Skip the '/'
|
||||
++pid_basename;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We didn't find a directory delimiter in the process argv[0], just use what was in there
|
||||
pid_basename = proc_path_buf;
|
||||
}
|
||||
CFString cf_pid_path (proc_path_buf);
|
||||
if (cf_pid_path.get())
|
||||
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, cf_pid_path.get());
|
||||
}
|
||||
|
||||
if (pid_basename && pid_basename[0])
|
||||
{
|
||||
CFString pid_name (pid_basename);
|
||||
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, pid_name.get());
|
||||
}
|
||||
|
||||
// Append the application info to the plist array
|
||||
::CFArrayAppendValue (plistMutableArray, appInfoDict.get());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
|
||||
{
|
||||
#ifdef WITH_SPRINGBOARD
|
||||
int result = -1;
|
||||
|
||||
CFAllocatorRef alloc = kCFAllocatorDefault;
|
||||
|
@ -33,6 +128,18 @@ ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
|
|||
// Create a mutable array that we can populate. Specify zero so it can be of any size.
|
||||
CFReleaser<CFMutableArrayRef> plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks));
|
||||
|
||||
const uid_t our_uid = getuid();
|
||||
|
||||
#ifdef WITH_SPRINGBOARD
|
||||
|
||||
|
||||
if (our_uid == 0)
|
||||
{
|
||||
bool all_users = true;
|
||||
result = GetPrcoesses (plistMutableArray.get(), all_users);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFReleaser<CFStringRef> sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ());
|
||||
CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));
|
||||
|
||||
|
@ -82,6 +189,12 @@ ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
|
|||
// Append the application info to the plist array
|
||||
::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get());
|
||||
}
|
||||
}
|
||||
#else
|
||||
// When root, show all processes
|
||||
bool all_users = (our_uid == 0);
|
||||
result = GetPrcoesses (plistMutableArray.get(), all_users);
|
||||
#endif
|
||||
|
||||
CFReleaser<CFDataRef> plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get()));
|
||||
|
||||
|
@ -108,11 +221,7 @@ ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
|
|||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
// TODO: list all current processes
|
||||
DNBLogError("SBS doesn't support getting application list.");
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue