diff options
Diffstat (limited to 'source/Host/freebsd/Host.cpp')
-rw-r--r-- | source/Host/freebsd/Host.cpp | 164 |
1 files changed, 86 insertions, 78 deletions
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp index 9415b2bb3fd0..f1abb49055e5 100644 --- a/source/Host/freebsd/Host.cpp +++ b/source/Host/freebsd/Host.cpp @@ -55,49 +55,53 @@ using namespace lldb_private; static bool GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, - (int)process_info.GetProcessID()}; - - char arg_data[8192]; - size_t arg_data_size = sizeof(arg_data); - if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) { - DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), - sizeof(void *)); - lldb::offset_t offset = 0; - const char *cstr; - - cstr = data.GetCStr(&offset); - if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, false); - - if (!(match_info_ptr == NULL || - NameMatches( - process_info.GetExecutableFile().GetFilename().GetCString(), - match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName()))) - return false; - - Args &proc_args = process_info.GetArguments(); - while (1) { - const uint8_t *p = data.PeekData(offset, 1); - while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { - ++offset; - p = data.PeekData(offset, 1); - } - if (p == NULL || offset >= arg_data_size) - return true; - - cstr = data.GetCStr(&offset); - if (cstr) - proc_args.AppendArgument(llvm::StringRef(cstr)); - else - return true; - } - } + if (!process_info.ProcessIDIsValid()) + return false; + + int pid = process_info.GetProcessID(); + + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) != 0) + return false; + + DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), + sizeof(void *)); + lldb::offset_t offset = 0; + const char *cstr; + + cstr = data.GetCStr(&offset); + if (!cstr) + return false; + + process_info.GetExecutableFile().SetFile(cstr, false); + + if (!(match_info_ptr == NULL || + NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName()))) + return false; + + Args &proc_args = process_info.GetArguments(); + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { + ++offset; + p = data.PeekData(offset, 1); } + if (p == NULL || offset >= arg_data_size) + break; + + cstr = data.GetCStr(&offset); + if (!cstr) + break; + + proc_args.AppendArgument(llvm::StringRef(cstr)); } - return false; + + return true; } static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { @@ -113,26 +117,31 @@ static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { struct kinfo_proc proc_kinfo; size_t proc_kinfo_size; + const int pid = process_info.GetProcessID(); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, - (int)process_info.GetProcessID()}; - 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.ki_ppid); - process_info.SetUserID(proc_kinfo.ki_ruid); - process_info.SetGroupID(proc_kinfo.ki_rgid); - process_info.SetEffectiveUserID(proc_kinfo.ki_uid); - if (proc_kinfo.ki_ngroups > 0) - process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); - else - process_info.SetEffectiveGroupID(UINT32_MAX); - return true; - } - } - } + if (!process_info.ProcessIDIsValid()) + goto error; + + proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) != 0) + goto error; + + if (proc_kinfo_size == 0) + goto error; + + process_info.SetParentProcessID(proc_kinfo.ki_ppid); + process_info.SetUserID(proc_kinfo.ki_ruid); + process_info.SetGroupID(proc_kinfo.ki_rgid); + process_info.SetEffectiveUserID(proc_kinfo.ki_uid); + if (proc_kinfo.ki_ngroups > 0) + process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + return true; + +error: process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); process_info.SetUserID(UINT32_MAX); process_info.SetGroupID(UINT32_MAX); @@ -143,7 +152,11 @@ static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { + const ::pid_t our_pid = ::getpid(); + const ::uid_t our_uid = ::getuid(); std::vector<struct kinfo_proc> kinfos; + // Special case, if lldb is being run as root we can attach to anything. + bool all_users = match_info.GetMatchAllUsers() || (our_uid == 0); int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; @@ -163,29 +176,24 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, 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 + + /* Make sure the user is acceptable */ + if (!all_users && kinfo.ki_ruid != our_uid) + continue; + + if (kinfo.ki_pid == our_pid || // Skip this process + kinfo.ki_pid == 0 || // Skip kernel (kernel pid is 0) + kinfo.ki_stat == SZOMB || // Zombies are bad + 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. + // 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 && |