Exemplo n.º 1
0
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();
}
Exemplo n.º 3
0
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();
}
Exemplo n.º 4
0
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();
}