From: Greg Clayton Date: Tue, 6 Nov 2012 23:36:26 +0000 (+0000) Subject: X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9eb4e03873d0492b2bfcad5755deea3ffaf1907a;p=platform%2Fupstream%2Fllvm.git Added the ability to get the full process list when using the --applist option in debugserver. llvm-svn: 167502 --- diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index 401cefc..a9d3645 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -40,8 +40,8 @@ typedef std::map ProcessMap; typedef ProcessMap::iterator ProcessMapIter; typedef ProcessMap::const_iterator ProcessMapConstIter; -static size_t GetAllInfos (std::vector& proc_infos); -static size_t GetAllInfosMatchingName (const char *process_name, std::vector& matching_proc_infos); +size_t GetAllInfos (std::vector& proc_infos); +static size_t GetAllInfosMatchingName (const char *process_name, std::vector& matching_proc_infos); //---------------------------------------------------------------------- // A Thread safe singleton to get a process map pointer. @@ -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& 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; diff --git a/lldb/tools/debugserver/source/RNBServices.cpp b/lldb/tools/debugserver/source/RNBServices.cpp index ea74962..6eb16b0 100644 --- a/lldb/tools/debugserver/source/RNBServices.cpp +++ b/lldb/tools/debugserver/source/RNBServices.cpp @@ -14,7 +14,11 @@ #import "RNBServices.h" #import +#include #import +#include +#include "CFString.h" +#include #import "DNBLog.h" #include "MacOSX/CFUtils.h" @@ -22,69 +26,178 @@ #import #endif +// From DNB.cpp +size_t GetAllInfos (std::vector& proc_infos); + int -ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable) +GetPrcoesses (CFMutableArrayRef plistMutableArray, bool all_users) { -#ifdef WITH_SPRINGBOARD - int result = -1; - - CFAllocatorRef alloc = kCFAllocatorDefault; + if (plistMutableArray == NULL) + return -1; - // Create a mutable array that we can populate. Specify zero so it can be of any size. - CFReleaser plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks)); - - CFReleaser sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ()); - CFReleaser 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++) + // Running as root, get all processes + std::vector proc_infos; + const size_t num_proc_infos = GetAllInfos(proc_infos); + if (num_proc_infos > 0) { - CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i); - - // Create a new mutable dictionary for each application - CFReleaser appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + const pid_t our_pid = getpid(); + const uid_t our_uid = getuid(); + uint32_t i; + CFAllocatorRef alloc = kCFAllocatorDefault; - // Get the process id for the app (if there is one) - pid_t pid = INVALID_NUB_PROCESS; - if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true) + for (i=0; i pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid)); + 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 appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + + // Get the process id for the app (if there is one) + const int32_t pid_int32 = pid; + CFReleaser 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 - if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo)) - ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue); - else + + // 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) +{ + int result = -1; + + CFAllocatorRef alloc = kCFAllocatorDefault; + + // Create a mutable array that we can populate. Specify zero so it can be of any size. + CFReleaser plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks)); + const uid_t our_uid = getuid(); - CFReleaser executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier)); - if (executablePath.get() != NULL) - { - ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get()); - } +#ifdef WITH_SPRINGBOARD - CFReleaser iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ; - if (iconImagePath.get() != NULL) - { - ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get()); - } + + if (our_uid == 0) + { + bool all_users = true; + result = GetPrcoesses (plistMutableArray.get(), all_users); + } + else + { + CFReleaser sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ()); + CFReleaser sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable)); - CFReleaser localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier)); - if (localizedDisplayName.get() != NULL) + // 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++) { - ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get()); + CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i); + + // Create a new mutable dictionary for each application + CFReleaser 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 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 executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier)); + if (executablePath.get() != NULL) + { + ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get()); + } + + CFReleaser iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ; + if (iconImagePath.get() != NULL) + { + ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get()); + } + + CFReleaser 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 plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get())); - + // write plist to service port if (plistData.get() != NULL) { @@ -106,13 +219,9 @@ ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable) 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 + }