[Lldb-commits] [lldb] r167502 - in /lldb/trunk/tools/debugserver/source: DNB.cpp RNBServices.cpp
Greg Clayton
gclayton at apple.com
Tue Nov 6 15:36:26 PST 2012
Author: gclayton
Date: Tue Nov 6 17:36:26 2012
New Revision: 167502
URL: http://llvm.org/viewvc/llvm-project?rev=167502&view=rev
Log:
<rdar://problem/12647273>
Added the ability to get the full process list when using the --applist option in debugserver.
Modified:
lldb/trunk/tools/debugserver/source/DNB.cpp
lldb/trunk/tools/debugserver/source/RNBServices.cpp
Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=167502&r1=167501&r2=167502&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue Nov 6 17:36:26 2012
@@ -40,8 +40,8 @@
typedef ProcessMap::iterator ProcessMapIter;
typedef ProcessMap::const_iterator ProcessMapConstIter;
-static 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);
+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);
//----------------------------------------------------------------------
// A Thread safe singleton to get a process map pointer.
@@ -391,10 +391,10 @@
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;
Modified: lldb/trunk/tools/debugserver/source/RNBServices.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBServices.cpp?rev=167502&r1=167501&r2=167502&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBServices.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBServices.cpp Tue Nov 6 17:36:26 2012
@@ -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,69 +26,178 @@
#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;
-
+
// Create a mutable array that we can populate. Specify zero so it can be of any size.
CFReleaser<CFMutableArrayRef> plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks));
- CFReleaser<CFStringRef> sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ());
- CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));
-
- // Need to check the return value from SBSCopyApplicationDisplayIdentifiers.
- CFIndex count = sbsAppIDs.get() ? ::CFArrayGetCount (sbsAppIDs.get()) : 0;
- CFIndex i = 0;
- for (i = 0; i < count; i++)
- {
- CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);
-
- // 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)
- pid_t pid = INVALID_NUB_PROCESS;
- if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true)
- {
- CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid));
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get());
- }
-
- // Set the a boolean to indicate if this is the front most
- if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo))
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue);
- else
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse);
+ const uid_t our_uid = getuid();
+#ifdef WITH_SPRINGBOARD
- CFReleaser<CFStringRef> executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier));
- if (executablePath.get() != NULL)
- {
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get());
- }
+
+ 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));
- CFReleaser<CFStringRef> iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ;
- if (iconImagePath.get() != NULL)
- {
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get());
- }
+ // Need to check the return value from SBSCopyApplicationDisplayIdentifiers.
+ CFIndex count = sbsAppIDs.get() ? ::CFArrayGetCount (sbsAppIDs.get()) : 0;
+ CFIndex i = 0;
+ for (i = 0; i < count; i++)
+ {
+ CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);
+
+ // 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)
+ pid_t pid = INVALID_NUB_PROCESS;
+ if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true)
+ {
+ CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid));
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get());
+ }
+
+ // Set the a boolean to indicate if this is the front most
+ if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo))
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue);
+ else
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse);
+
+
+ CFReleaser<CFStringRef> executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier));
+ if (executablePath.get() != NULL)
+ {
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get());
+ }
+
+ CFReleaser<CFStringRef> iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ;
+ if (iconImagePath.get() != NULL)
+ {
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get());
+ }
+
+ CFReleaser<CFStringRef> localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier));
+ if (localizedDisplayName.get() != NULL)
+ {
+ ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get());
+ }
- CFReleaser<CFStringRef> localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier));
- if (localizedDisplayName.get() != NULL)
- {
- ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get());
+ // Append the application info to the plist array
+ ::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get());
}
-
- // 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()));
-
+
// write plist to service port
if (plistData.get() != NULL)
{
@@ -106,13 +219,9 @@
DNBLogError("serializing task list.");
result = -3;
}
-
+
return result;
-#else
- // TODO: list all current processes
- DNBLogError("SBS doesn't support getting application list.");
- return -1;
-#endif
+
}
More information about the lldb-commits
mailing list