[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
Fred Grim via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 14 14:48:03 PDT 2024
================
@@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
return error;
}
+std::optional<ELFLinuxPrPsInfo>
+ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) {
+ ELFLinuxPrPsInfo prpsinfo{};
+ prpsinfo.pr_pid = process_sp->GetID();
+ ProcessInstanceInfo info;
+ if (!process_sp->GetProcessInfo(info)) {
+ return std::nullopt;
+ }
+ prpsinfo.pr_nice = info.GetPriorityValue().value_or(0);
+ prpsinfo.pr_zomb = 0;
+ if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) {
+ prpsinfo.pr_zomb = 1;
+ }
+ /**
+ * In the linux kernel this comes from:
+ * state = READ_ONCE(p->__state);
+ * i = state ? ffz(~state) + 1 : 0;
+ * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i];
+ *
+ * So we replicate that here. From proc_pid_stats(5)
+ * R = Running
+ * S = Sleeping on uninterrutible wait
+ * D = Waiting on uninterruptable disk sleep
+ * T = Tracing stop
+ * Z = Zombie
+ * W = Paging
+ */
+ lldb::StateType process_state = process_sp->GetState();
+ switch (process_state) {
+ case lldb::StateType::eStateSuspended:
+ prpsinfo.pr_sname = 'S';
+ prpsinfo.pr_state = 1;
+ break;
+ case lldb::StateType::eStateStopped:
+ [[fallthrough]];
+ case lldb::StateType::eStateStepping:
+ prpsinfo.pr_sname = 'T';
+ prpsinfo.pr_state = 3;
+ break;
+ case lldb::StateType::eStateUnloaded:
+ [[fallthrough]];
+ case lldb::StateType::eStateRunning:
+ prpsinfo.pr_sname = 'R';
+ prpsinfo.pr_state = 0;
+ break;
+ default:
+ break;
+ }
+
+ /**
+ * pr_flags is left as 0. The values (in linux) are specific
+ * to the kernel. We recover them from the proc filesystem
+ * but don't put them in ProcessInfo because it would really
+ * become very linux specific and the utility here seems pretty
+ * dubious
+ */
+
+ if (info.EffectiveUserIDIsValid()) {
+ prpsinfo.pr_uid = info.GetUserID();
+ }
+ if (info.EffectiveGroupIDIsValid()) {
+ prpsinfo.pr_gid = info.GetGroupID();
+ }
+
+ if (info.ParentProcessIDIsValid()) {
+ prpsinfo.pr_ppid = info.GetParentProcessID();
+ }
+
+ if (info.ProcessGroupIDIsValid()) {
+ prpsinfo.pr_pgrp = info.GetProcessGroupID();
+ }
+
+ if (info.ProcessSessionIDIsValid()) {
+ prpsinfo.pr_sid = info.GetProcessSessionID();
+ }
+ constexpr size_t fname_len = std::extent_v<decltype(prpsinfo.pr_fname)>;
+ static_assert(fname_len > 0, "This should always be non zero");
+ const llvm::StringRef fname = info.GetNameAsStringRef();
+ auto fname_begin = fname.begin();
+ std::copy(fname_begin,
+ std::next(fname_begin, std::min(fname_len, fname.size())),
+ prpsinfo.pr_fname);
+ prpsinfo.pr_fname[fname_len - 1] = '\0';
+ auto args = info.GetArguments();
+ if (!args.empty()) {
+ constexpr size_t psargs_len = std::extent_v<decltype(prpsinfo.pr_psargs)>;
+ static_assert(psargs_len > 0, "This should always be non zero");
+ size_t i = psargs_len;
+ auto argentry_iterator = std::begin(args);
+ char *psargs = prpsinfo.pr_psargs;
+ while (i > 0 && argentry_iterator != args.end()) {
+ llvm::StringRef argentry = argentry_iterator->ref();
+ size_t len = std::min(i, argentry.size());
+ auto arg_iterator = std::begin(argentry);
+ std::copy(arg_iterator, std::next(arg_iterator, len), psargs);
+ i -= len;
+ psargs += len;
+ if (i > 0) {
+ *(psargs++) = ' ';
+ --i;
+ }
+ ++argentry_iterator;
+ }
----------------
feg208 wrote:
I do indeed like iterators. Adding to the universal stock of iterators seems like a positive step in any case. Done.
https://github.com/llvm/llvm-project/pull/104109
More information about the lldb-commits
mailing list