[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