uint32_t Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { process_infos.Clear(); AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); if (!snapshot.IsValid()) return 0; PROCESSENTRY32 pe = {0}; pe.dwSize = sizeof(PROCESSENTRY32); if (Process32First(snapshot.get(), &pe)) { do { AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr); ProcessInstanceInfo process; process.SetExecutableFile(FileSpec(pe.szExeFile, false), true); process.SetProcessID(pe.th32ProcessID); process.SetParentProcessID(pe.th32ParentProcessID); GetProcessExecutableAndTriple(handle, process); if (match_info.MatchAllProcesses() || match_info.Matches(process)) process_infos.Append(process); } while (Process32Next(snapshot.get(), &pe)); } return process_infos.GetSize(); }
uint32_t Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { static const char procdir[] = "/proc/"; DIR *dirproc = opendir (procdir); if (dirproc) { struct dirent *direntry = NULL; const uid_t our_uid = getuid(); const lldb::pid_t our_pid = getpid(); bool all_users = match_info.GetMatchAllUsers(); while ((direntry = readdir (dirproc)) != NULL) { if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name)) continue; lldb::pid_t pid = atoi (direntry->d_name); // Skip this process. if (pid == our_pid) continue; lldb::pid_t tracerpid; ProcessStatInfo stat_info; ProcessInstanceInfo process_info; if (!GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid)) continue; // Skip if process is being debugged. if (tracerpid != 0) continue; // Skip zombies. if (stat_info.fProcessState & eProcessStateZombie) continue; // Check for user match if we're not matching all users and not running as root. if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid)) continue; if (match_info.Matches (process_info)) { process_infos.Append (process_info); } } closedir (dirproc); } return process_infos.GetSize(); }
uint32_t Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { std::vector<struct kinfo_proc> kinfos; int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; size_t pid_data_size = 0; if (::sysctl (mib, 3, NULL, &pid_data_size, NULL, 0) != 0) return 0; // 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, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0) return 0; const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); bool all_users = match_info.GetMatchAllUsers(); const ::pid_t our_pid = getpid(); const uid_t our_uid = getuid(); for (size_t i = 0; i < actual_pid_count; i++) { const struct kinfo_proc &kinfo = kinfos[i]; const bool kinfo_user_matches = (all_users || (kinfo.ki_ruid == our_uid) || // Special case, if lldb is being run as root we can attach to anything. (our_uid == 0) ); if (kinfo_user_matches == false || // Make sure the user is acceptable kinfo.ki_pid == our_pid || // Skip this process kinfo.ki_pid == 0 || // Skip kernel (kernel pid is zero) kinfo.ki_stat == SZOMB || // Zombies are bad, they like brains... kinfo.ki_flag & P_TRACED || // Being debugged? kinfo.ki_flag & P_WEXIT) // Working on exiting continue; // Every thread is a process in FreeBSD, but all the threads of a single process // have the same pid. Do not store the process info in the result list if a process // with given identifier is already registered there. bool already_registered = false; for (uint32_t pi = 0; !already_registered && (const int)kinfo.ki_numthreads > 1 && pi < (const uint32_t)process_infos.GetSize(); pi++) already_registered = (process_infos.GetProcessIDAtIndex(pi) == (uint32_t)kinfo.ki_pid); if (already_registered) continue; ProcessInstanceInfo process_info; process_info.SetProcessID (kinfo.ki_pid); process_info.SetParentProcessID (kinfo.ki_ppid); process_info.SetUserID (kinfo.ki_ruid); process_info.SetGroupID (kinfo.ki_rgid); process_info.SetEffectiveUserID (kinfo.ki_svuid); process_info.SetEffectiveGroupID (kinfo.ki_svgid); // Make sure our info matches before we go fetch the name and cpu type if (match_info.Matches (process_info) && GetFreeBSDProcessArgs (&match_info, process_info)) { GetFreeBSDProcessCPUType (process_info); if (match_info.Matches (process_info)) process_infos.Append (process_info); } } return process_infos.GetSize(); }
uint32_t Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { const ::pid_t our_pid = ::getpid(); const ::uid_t our_uid = ::getuid(); const bool all_users = match_info.GetMatchAllUsers() || // Special case, if lldb is being run as root we can attach to anything (our_uid == 0); kvm_t *kdp; char errbuf[_POSIX2_LINE_MAX]; /* XXX: error string unused */ if ((kdp = ::kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) return 0; struct ::kinfo_proc2 *proc_kinfo; int nproc; if ((proc_kinfo = ::kvm_getproc2(kdp, KERN_PROC_ALL, 0, sizeof(struct ::kinfo_proc2), &nproc)) == NULL) { ::kvm_close(kdp); return 0; } for (int i = 0; i < nproc; i++) { if (proc_kinfo[i].p_pid < 1) continue; /* not valid */ /* Make sure the user is acceptable */ if (!all_users && proc_kinfo[i].p_ruid != our_uid) continue; if (proc_kinfo[i].p_pid == our_pid || // Skip this process proc_kinfo[i].p_pid == 0 || // Skip kernel (kernel pid is 0) proc_kinfo[i].p_stat == LSZOMB || // Zombies are bad proc_kinfo[i].p_flag & P_TRACED || // Being debugged? proc_kinfo[i].p_flag & P_WEXIT) // Working on exiting continue; // Every thread is a process in NetBSD, but all the threads of a single // process have the same pid. Do not store the process info in the // result list if a process with given identifier is already registered // there. if (proc_kinfo[i].p_nlwps > 1) { bool already_registered = false; for (size_t pi = 0; pi < process_infos.GetSize(); pi++) { if (process_infos.GetProcessIDAtIndex(pi) == proc_kinfo[i].p_pid) { already_registered = true; break; } } if (already_registered) continue; } ProcessInstanceInfo process_info; process_info.SetProcessID (proc_kinfo[i].p_pid); process_info.SetParentProcessID (proc_kinfo[i].p_ppid); process_info.SetUserID (proc_kinfo[i].p_ruid); process_info.SetGroupID (proc_kinfo[i].p_rgid); process_info.SetEffectiveUserID (proc_kinfo[i].p_uid); process_info.SetEffectiveGroupID (proc_kinfo[i].p_gid); // Make sure our info matches before we go fetch the name and cpu type if (match_info.Matches (process_info) && GetNetBSDProcessArgs (&match_info, process_info)) { GetNetBSDProcessCPUType (process_info); if (match_info.Matches (process_info)) process_infos.Append (process_info); } } kvm_close(kdp); /* XXX: we don't check for error here */ return process_infos.GetSize(); }