Added real user/group id, effective user/group id, and parent

process ID to the ProcessInfo.

llvm-svn: 128023
This commit is contained in:
Greg Clayton 2011-03-21 21:25:07 +00:00
parent 1cd7bd62e4
commit 45aea640a0
3 changed files with 304 additions and 112 deletions

View File

@ -228,6 +228,10 @@ class ProcessInfo
public: public:
ProcessInfo () : ProcessInfo () :
m_name (), m_name (),
m_real_uid (UINT32_MAX),
m_real_gid (UINT32_MAX),
m_effective_uid (UINT32_MAX),
m_effective_gid (UINT32_MAX),
m_arch(), m_arch(),
m_pid (LLDB_INVALID_PROCESS_ID) m_pid (LLDB_INVALID_PROCESS_ID)
{ {
@ -236,7 +240,11 @@ public:
ProcessInfo (const char *name, ProcessInfo (const char *name,
const ArchSpec &arch, const ArchSpec &arch,
lldb::pid_t pid) : lldb::pid_t pid) :
m_name (name), m_name (),
m_real_uid (UINT32_MAX),
m_real_gid (UINT32_MAX),
m_effective_uid (UINT32_MAX),
m_effective_gid (UINT32_MAX),
m_arch (arch), m_arch (arch),
m_pid (pid) m_pid (pid)
{ {
@ -246,6 +254,10 @@ public:
Clear () Clear ()
{ {
m_name.clear(); m_name.clear();
m_real_uid = UINT32_MAX;
m_real_gid = UINT32_MAX;
m_effective_uid = UINT32_MAX;
m_effective_gid = UINT32_MAX;
m_arch.Clear(); m_arch.Clear();
m_pid = LLDB_INVALID_PROCESS_ID; m_pid = LLDB_INVALID_PROCESS_ID;
} }
@ -265,12 +277,60 @@ public:
void void
SetName (const char *name) SetName (const char *name)
{ {
if (name) if (name && name[0])
m_name.assign (name); m_name.assign (name);
else else
m_name.clear(); m_name.clear();
} }
uint32_t
GetRealUserID() const
{
return m_real_uid;
}
uint32_t
GetRealGroupID() const
{
return m_real_gid;
}
uint32_t
GetEffectiveUserID() const
{
return m_effective_uid;
}
uint32_t
GetEffectiveGroupID() const
{
return m_effective_gid;
}
void
SetRealUserID (uint32_t uid)
{
m_real_uid = uid;
}
void
SetRealGroupID (uint32_t gid)
{
m_real_gid = gid;
}
void
SetEffectiveUserID (uint32_t uid)
{
m_effective_uid = uid;
}
void
SetEffectiveGroupID (uint32_t gid)
{
m_effective_gid = gid;
}
ArchSpec & ArchSpec &
GetArchitecture () GetArchitecture ()
{ {
@ -295,10 +355,39 @@ public:
m_pid = pid; m_pid = pid;
} }
bool
ProcessIDIsValid() const
{
return m_pid != LLDB_INVALID_PROCESS_ID;
}
lldb::pid_t
GetParentProcessID () const
{
return m_parent_pid;
}
void
SetParentProcessID (lldb::pid_t pid)
{
m_parent_pid = pid;
}
bool
ParentProcessIDIsValid() const
{
return m_parent_pid != LLDB_INVALID_PROCESS_ID;
}
protected: protected:
std::string m_name; std::string m_name;
uint32_t m_real_uid;
uint32_t m_real_gid;
uint32_t m_effective_uid;
uint32_t m_effective_gid;
ArchSpec m_arch; ArchSpec m_arch;
pid_t m_pid; lldb::pid_t m_pid;
lldb::pid_t m_parent_pid;
}; };
class ProcessInfoList class ProcessInfoList

View File

@ -1029,130 +1029,22 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
return false; return false;
} }
#if defined (__APPLE__) #if !defined (__APPLE__) // see macosx/Host.mm
static bool
GetMacOSXProcessName (lldb::pid_t pid,
NameMatchType name_match_type,
const char *name_match,
ProcessInfo &proc_info)
{
char process_name[MAXCOMLEN * 2 + 1];
int name_len = ::proc_name(pid, process_name, MAXCOMLEN * 2);
if (name_len == 0)
return false;
if (NameMatches(process_name, name_match_type, name_match))
{
proc_info.SetName (process_name);
return true;
}
else
{
proc_info.SetName (NULL);
return false;
}
}
static bool
GetMacOSXProcessCPUType (lldb::pid_t pid, ProcessInfo &proc_info)
{
// Make a new mib to stay thread safe
int mib[CTL_MAXNAME]={0,};
size_t mib_len = CTL_MAXNAME;
if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len))
return false;
mib[mib_len] = pid;
mib_len++;
cpu_type_t cpu, sub;
size_t cpu_len = sizeof(cpu);
if (::sysctl (mib, mib_len, &cpu, &cpu_len, 0, 0) == 0)
{
switch (cpu)
{
case llvm::MachO::CPUTypeI386: sub = llvm::MachO::CPUSubType_I386_ALL; break;
case llvm::MachO::CPUTypeX86_64: sub = llvm::MachO::CPUSubType_X86_64_ALL; break;
default: break;
}
proc_info.GetArchitecture ().SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
return true;
}
return false;
}
#endif
uint32_t uint32_t
Host::FindProcessesByName (const char *name, NameMatchType name_match_type, ProcessInfoList &process_infos) Host::FindProcessesByName (const char *name, NameMatchType name_match_type, ProcessInfoList &process_infos)
{ {
process_infos.Clear(); process_infos.Clear();
#if defined (__APPLE__)
int num_pids;
int size_of_pids;
std::vector<int> pid_list;
size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
if (size_of_pids == -1)
return 0;
num_pids = size_of_pids/sizeof(int);
pid_list.resize (size_of_pids);
size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, &pid_list[0], size_of_pids);
if (size_of_pids == -1)
return 0;
lldb::pid_t our_pid = getpid();
for (int i = 0; i < num_pids; i++)
{
struct proc_bsdinfo bsd_info;
int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
if (error == 0)
continue;
// Don't offer to attach to zombie processes, already traced or exiting
// processes, and of course, ourselves... It looks like passing the second arg of
// 0 to proc_listpids will exclude zombies anyway, but that's not documented so...
if (((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT)) != 0)
|| (bsd_info.pbi_status == SZOMB)
|| (bsd_info.pbi_pid == our_pid))
continue;
ProcessInfo process_info;
if (GetMacOSXProcessName (bsd_info.pbi_pid, name_match_type, name, process_info))
{
process_info.SetProcessID (bsd_info.pbi_pid);
GetMacOSXProcessCPUType (bsd_info.pbi_pid, process_info);
process_infos.Append (process_info);
}
}
#endif
return process_infos.GetSize(); return process_infos.GetSize();
} }
bool bool
Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
{ {
#if defined (__APPLE__)
if (GetMacOSXProcessName (pid, eNameMatchIgnore, NULL, process_info))
{
process_info.SetProcessID (pid);
if (GetMacOSXProcessCPUType (pid, process_info) == false)
process_info.GetArchitecture().Clear();
return true;
}
#endif
process_info.Clear(); process_info.Clear();
return false; return false;
} }
#if !defined (__APPLE__) // see macosx/Host.mm
bool bool
Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
{ {

View File

@ -11,10 +11,13 @@
#include <crt_externs.h> #include <crt_externs.h>
#include <execinfo.h> #include <execinfo.h>
#include <grp.h>
#include <libproc.h> #include <libproc.h>
#include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@ -25,6 +28,7 @@
#include "lldb/Core/Log.h" #include "lldb/Core/Log.h"
#include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h" #include "lldb/Core/StreamString.h"
#include "lldb/Target/Process.h"
#include "cfcpp/CFCBundle.h" #include "cfcpp/CFCBundle.h"
#include "cfcpp/CFCMutableArray.h" #include "cfcpp/CFCMutableArray.h"
@ -32,6 +36,9 @@
#include "cfcpp/CFCReleaser.h" #include "cfcpp/CFCReleaser.h"
#include "cfcpp/CFCString.h" #include "cfcpp/CFCString.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MachO.h"
#include <objc/objc-auto.h> #include <objc/objc-auto.h>
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
@ -874,4 +881,208 @@ Host::GetOSVersion
} }
static bool
GetMacOSXProcessName (NameMatchType name_match_type,
const char *name_match,
ProcessInfo &process_info)
{
if (process_info.ProcessIDIsValid())
{
char process_name[MAXCOMLEN * 2 + 1];
int name_len = ::proc_name(process_info.GetProcessID(), process_name, MAXCOMLEN * 2);
if (name_len == 0)
return false;
if (NameMatches(process_name, name_match_type, name_match))
{
process_info.SetName (process_name);
return true;
}
}
process_info.SetName (NULL);
return false;
}
static bool
GetMacOSXProcessCPUType (ProcessInfo &process_info)
{
if (process_info.ProcessIDIsValid())
{
// Make a new mib to stay thread safe
int mib[CTL_MAXNAME]={0,};
size_t mib_len = CTL_MAXNAME;
if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len))
return false;
mib[mib_len] = process_info.GetProcessID();
mib_len++;
cpu_type_t cpu, sub;
size_t cpu_len = sizeof(cpu);
if (::sysctl (mib, mib_len, &cpu, &cpu_len, 0, 0) == 0)
{
switch (cpu)
{
case llvm::MachO::CPUTypeI386: sub = llvm::MachO::CPUSubType_I386_ALL; break;
case llvm::MachO::CPUTypeX86_64: sub = llvm::MachO::CPUSubType_X86_64_ALL; break;
default: break;
}
process_info.GetArchitecture ().SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
return true;
}
}
process_info.GetArchitecture().Clear();
return false;
}
// TODO: move this into the platform
static bool
GetGroupName (uint32_t gid, std::string &group_name)
{
char group_buffer[PATH_MAX];
size_t group_buffer_size = sizeof(group_buffer);
struct group group_info;
struct group *group_info_ptr = &group_info;
// User the real user ID here, not the effective user ID
if (::getgrgid_r (gid,
&group_info,
group_buffer,
group_buffer_size,
&group_info_ptr) == 0)
{
if (group_info_ptr)
{
group_name.assign (group_info_ptr->gr_name);
return true;
}
}
group_name.clear();
return false;
}
// TODO: move this into the platform
static bool
GetUserName (uint32_t uid, std::string &user_name)
{
struct passwd user_info;
struct passwd *user_info_ptr = &user_info;
char user_buffer[PATH_MAX];
size_t user_buffer_size = sizeof(user_buffer);
if (::getpwuid_r (uid,
&user_info,
user_buffer,
user_buffer_size,
&user_info_ptr) == 0)
{
if (user_info_ptr)
{
user_name.assign (user_info_ptr->pw_name);
return true;
}
}
user_name.clear();
return false;
}
static bool
GetMacOSXProcessUserAndGroup (ProcessInfo &process_info)
{
if (process_info.ProcessIDIsValid())
{
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = process_info.GetProcessID();
struct kinfo_proc proc_kinfo;
size_t proc_kinfo_size = sizeof(struct kinfo_proc);
if (::sysctl (mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
{
if (proc_kinfo_size > 0)
{
process_info.SetParentProcessID (proc_kinfo.kp_eproc.e_ppid);
process_info.SetRealUserID (proc_kinfo.kp_eproc.e_pcred.p_ruid);
process_info.SetRealGroupID (proc_kinfo.kp_eproc.e_pcred.p_rgid);
process_info.SetEffectiveUserID (proc_kinfo.kp_eproc.e_ucred.cr_uid);
if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
process_info.SetEffectiveGroupID (proc_kinfo.kp_eproc.e_ucred.cr_groups[0]);
else
process_info.SetEffectiveGroupID (UINT32_MAX);
return true;
}
}
}
process_info.SetParentProcessID (LLDB_INVALID_PROCESS_ID);
process_info.SetRealUserID (UINT32_MAX);
process_info.SetRealGroupID (UINT32_MAX);
process_info.SetEffectiveUserID (UINT32_MAX);
process_info.SetEffectiveGroupID (UINT32_MAX);
return false;
}
uint32_t
Host::FindProcessesByName (const char *name, NameMatchType name_match_type, ProcessInfoList &process_infos)
{
int num_pids;
int size_of_pids;
std::vector<int> pid_list;
size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
if (size_of_pids == -1)
return 0;
num_pids = size_of_pids/sizeof(int);
pid_list.resize (size_of_pids);
size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, &pid_list[0], size_of_pids);
if (size_of_pids == -1)
return 0;
lldb::pid_t our_pid = getpid();
for (int i = 0; i < num_pids; i++)
{
struct proc_bsdinfo bsd_info;
int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
if (error == 0)
continue;
// Don't offer to attach to zombie processes, already traced or exiting
// processes, and of course, ourselves... It looks like passing the second arg of
// 0 to proc_listpids will exclude zombies anyway, but that's not documented so...
if (((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT)) != 0)
|| (bsd_info.pbi_status == SZOMB)
|| (bsd_info.pbi_pid == our_pid))
continue;
ProcessInfo process_info;
process_info.SetProcessID (bsd_info.pbi_pid);
if (GetMacOSXProcessName (name_match_type, name, process_info))
{
GetMacOSXProcessCPUType (process_info);
GetMacOSXProcessUserAndGroup (process_info);
process_infos.Append (process_info);
}
}
return process_infos.GetSize();
}
bool
Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
{
process_info.SetProcessID(pid);
if (GetMacOSXProcessName (eNameMatchIgnore, NULL, process_info))
{
GetMacOSXProcessCPUType (process_info);
GetMacOSXProcessUserAndGroup (process_info);
return true;
}
process_info.Clear();
return false;
}