[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From d01efd10f8a4b7d908acaa3237541bf6a83b4c7c Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 94 +++-- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 11 ++- lldb/unittests/Host/linux/HostTest.cpp | 21 ++ 4 files changed, 109 insertions(+), 49 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..995873a6869e0 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,72 +148,71 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } - uint32_t GetEffectiveGroupID() const { return m_egid; } + uint32_t GetEffectiveGroupID() const { return m_egid.value(); } - bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } + bool EffectiveUserIDIsValid() const { return m_euid.has_value(); } - bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } + bool EffectiveGroupIDIsValid() const { return m_egid.has_value(); } void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } - lldb::pid_t GetParentProcessID() const { return m_parent_pid; } + lldb::pid_t GetParentProcessID() const { return m_parent_pid.value(); } void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } - bool ParentProcessIDIsValid() const { -return m_parent_pid != LLDB_INVALID_PROCESS_ID; - } + bool ParentProcessIDIsValid() const { return m_parent_pid.has_value(); } - lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id.value(); } void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } - bool ProcessGroupIDIsValid() const { -return m_process_group_id != LLDB_INVALID_PROCESS_ID; - } + bool ProcessGroupIDIsValid() const { return m_process_group_id.has_value(); } - lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + lldb::pid_t GetProcessSessionID() const { +return m_process_session_id.value(); + } void SetProcessSessionID(lldb::pid_t session) { m_process_session_id = session; } bool ProcessSessionIDIsValid() const { -return m_process_session_id != LLDB_INVALID_PROCESS_ID; +return m_process_session_id.has_value(); } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { @@ -220,12 +220,13 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeUserTimeIsValid() cons
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -86,4 +89,22 @@ TEST_F(HostTest, GetProcessInfo) { ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || user_time.tv_usec <= next_user_time.tv_usec); + + struct rlimit rlim; + EXPECT_EQ(getrlimit(RLIMIT_NICE, &rlim), 0); + // getpriority can return -1 so we zero errno first + errno = 0; + int prio = getpriority(PRIO_PROCESS, PRIO_PROCESS); + ASSERT_TRUE((prio < 0 && errno == 0) || prio >= 0); + ASSERT_EQ(Info.GetPriorityValue(), prio); + // If we can't raise our nice level then this test can't be performed feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -115,13 +124,19 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, return ts; }; + // priority (nice) values run from 19 to -20 inclusive (in linux). In the + // prpsinfo struct pr_nice is a char feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -115,13 +124,19 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, return ts; }; + // priority (nice) values run from 19 to -20 inclusive (in linux). In the feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // in proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo we adopt the documented + // naming here feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // in proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo we adopt the documented feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // in proc_pid_stat(5) this field is specified as priority feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: > Sorry for the nits! I am not smart enough to contribute on the technical > merits, so I am trying to find some way to help! Ehhh grammar is not where I shine. I rolled them up https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -147,96 +148,111 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } feg208 wrote: I don't have particularly strong feelings here but we should keep it consistent between this class and the parent class which has GetUID and GetGID neither of which returns a std::optional. Given the risk of std::bad_optional_access getting thrown thoughout I am coming to the notion that maybe we shouldn't use optionals here? If we have optionals I guess we are mandating that the paired IsValid must exist and must always be called. That seems like it'll create challenges. Can we go back to using invalid values like UINT32_MAX and maybe alter the interface to use optionals in a subsequent pr? This way we could debate the merits of this approach independent of adding a niceness field. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -147,96 +148,111 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } feg208 wrote: Maybe a better approach is to keep the optionals in the members that are particular to ProcessInstanceInfo (i.e. the time fields, priority, and the zombie fields) and revert the pid fields and the pid and uid/gid fields to the previous and punt that to a later pr. How does that sound? https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From dbb4b4126754be15ffd9d12d9997e4969f7ba5cf Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 94 +++-- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 11 ++- lldb/unittests/Host/linux/HostTest.cpp | 21 ++ 4 files changed, 109 insertions(+), 49 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..995873a6869e0 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,72 +148,71 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } - uint32_t GetEffectiveGroupID() const { return m_egid; } + uint32_t GetEffectiveGroupID() const { return m_egid.value(); } - bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } + bool EffectiveUserIDIsValid() const { return m_euid.has_value(); } - bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } + bool EffectiveGroupIDIsValid() const { return m_egid.has_value(); } void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } - lldb::pid_t GetParentProcessID() const { return m_parent_pid; } + lldb::pid_t GetParentProcessID() const { return m_parent_pid.value(); } void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } - bool ParentProcessIDIsValid() const { -return m_parent_pid != LLDB_INVALID_PROCESS_ID; - } + bool ParentProcessIDIsValid() const { return m_parent_pid.has_value(); } - lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id.value(); } void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } - bool ProcessGroupIDIsValid() const { -return m_process_group_id != LLDB_INVALID_PROCESS_ID; - } + bool ProcessGroupIDIsValid() const { return m_process_group_id.has_value(); } - lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + lldb::pid_t GetProcessSessionID() const { +return m_process_session_id.value(); + } void SetProcessSessionID(lldb::pid_t session) { m_process_session_id = session; } bool ProcessSessionIDIsValid() const { -return m_process_session_id != LLDB_INVALID_PROCESS_ID; +return m_process_session_id.has_value(); } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { @@ -220,12 +220,13 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeUserTimeIsValid() cons
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From b35ded1c20bb67df941bb7c54aece789a18cde99 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 64 - lldb/source/Host/linux/Host.cpp | 32 + lldb/source/Utility/ProcessInfo.cpp | 11 +++-- lldb/unittests/Host/linux/HostTest.cpp | 21 4 files changed, 94 insertions(+), 34 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..363a81d4e874f 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -173,19 +173,17 @@ class ProcessInstanceInfo : public ProcessInfo { void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } - bool ParentProcessIDIsValid() const { -return m_parent_pid != LLDB_INVALID_PROCESS_ID; - } + bool ParentProcessIDIsValid() const { return m_parent_pid != LLDB_INVALID_PROCESS_ID; } lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } - bool ProcessGroupIDIsValid() const { -return m_process_group_id != LLDB_INVALID_PROCESS_ID; - } + bool ProcessGroupIDIsValid() const { return m_process_group_id != LLDB_INVALID_PROCESS_ID; } - lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + lldb::pid_t GetProcessSessionID() const { +return m_process_session_id; + } void SetProcessSessionID(lldb::pid_t session) { m_process_session_id = session; @@ -195,24 +193,26 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { @@ -220,12 +220,13 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { @@ -233,10 +234,25 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); + } + + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priorit
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -147,96 +148,111 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } feg208 wrote: @clayborg I made the changes referenced above (i.e. backed out the optionals for the pid/uid/gid fields). Is this a dealbreaker for you? Or do you think we can revisit at a later time? https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From 8b9ffe9bfb20c5c911c1c08ef966b4ac1ac587a0 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 52 + lldb/source/Host/linux/Host.cpp | 32 +++ lldb/source/Utility/ProcessInfo.cpp | 11 -- lldb/unittests/Host/linux/HostTest.cpp | 21 ++ 4 files changed, 89 insertions(+), 27 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..6844211f05c74 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -195,24 +195,26 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { @@ -220,12 +222,13 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { @@ -233,10 +236,25 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); } + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + bool PriorityValueIsValid() const; + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + bool IsZombieValid() const { return m_zombie.has_value(); } + + bool IsZombie() const { return m_zombie.value(); } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -250,10 +268,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + std::optional m_user_time = std::nullopt; + std::optional m_system_time = std::nullopt; + std::optional m_cumulative_user_time = std::nullopt
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: Hello all. I am wondering what I can do to advance this patch? I think it is required to support process save-core in linux for lldb. I'd love to move this before adding static methods in ThreadEfCore.h to produce populated prpsinfo and prstatus structs for inclusion in a generated corefile. Is there someone else I should include on review here? @JDevlieghere? I am happy to amend this in whatever way the community thinks works best for lldb. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From e7b1cf56dae4c93b871aeeeafc5b40752baf823e Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 52 + lldb/source/Host/linux/Host.cpp | 32 +++ lldb/source/Utility/ProcessInfo.cpp | 11 -- lldb/unittests/Host/linux/HostTest.cpp | 21 ++ 4 files changed, 89 insertions(+), 27 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..6844211f05c74 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -195,24 +195,26 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { @@ -220,12 +222,13 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { @@ -233,10 +236,25 @@ class ProcessInstanceInfo : public ProcessInfo { } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); } + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + bool PriorityValueIsValid() const; + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + bool IsZombieValid() const { return m_zombie.has_value(); } + + bool IsZombie() const { return m_zombie.value(); } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -250,10 +268,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + std::optional m_user_time = std::nullopt; + std::optional m_system_time = std::nullopt; + std::optional m_cumulative_user_time = std::nullopt
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: > A message like this that the PR is ready for re-review should be all you > need. Several folks left comments and they might be waiting for all of them > to be addressed before they take another look. Ok. @clayborg I think I have addressed your concerns but I'd love another look as you have time. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From 8f694b7ab4436c0540284cbbf280ad557a750920 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 24 ++- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 7 +++--- lldb/unittests/Host/linux/HostTest.cpp | 21 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..78ade4bbb1ee6 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -237,6 +237,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + std::optional GetPriorityValue() const { return m_priority_value; } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + std::optional IsZombie() const { return m_zombie; } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -250,10 +260,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + struct timespec m_user_time; + struct timespec m_system_time; + struct timespec m_cumulative_user_time; + struct timespec m_cumulative_system_time; + std::optional m_priority_value = std::nullopt; + std::optional m_zombie = std::nullopt; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..5545f9ef4d70e 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,6 +37,7 @@ using namespace lldb; using namespace lldb_private; namespace { + enum class ProcessState { Unknown, Dead, @@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // In proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo, we adopt the documented + // naming here. + long realtime_priority; + long priority; // other things. We don't need them below }; } @@ -91,14 +98,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - &stat_fields.pid, stat_fields.comm, &stat_fields.state, - &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, - &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, - &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, - &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + &stat_fields.pid, stat_fields.comm, &stat_fields.state, + &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, + &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, + &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, + &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, + &stat_fields.cutime, &stat_fields.cstime
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -147,96 +148,111 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); -m_euid = UINT32_MAX; -m_egid = UINT32_MAX; -m_parent_pid = LLDB_INVALID_PROCESS_ID; +m_euid = std::nullopt; +m_egid = std::nullopt; +m_parent_pid = std::nullopt; } - uint32_t GetEffectiveUserID() const { return m_euid; } + uint32_t GetEffectiveUserID() const { return m_euid.value(); } feg208 wrote: yeah. I of the same view https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 edited https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -250,10 +268,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + std::optional m_user_time = std::nullopt; + std::optional m_system_time = std::nullopt; + std::optional m_cumulative_user_time = std::nullopt; + std::optional m_cumulative_system_time = std::nullopt; feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -250,10 +268,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + std::optional m_user_time = std::nullopt; + std::optional m_system_time = std::nullopt; + std::optional m_cumulative_user_time = std::nullopt; + std::optional m_cumulative_system_time = std::nullopt; + std::optional m_priority_value = std::nullopt; + std::optional m_zombie = std::nullopt; feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -195,48 +195,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { m_cumulative_user_time = cutime; } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { m_cumulative_system_time = cstime; } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); } + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + bool PriorityValueIsValid() const; + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + bool IsZombieValid() const { return m_zombie.has_value(); } + + bool IsZombie() const { return m_zombie.value(); } feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -195,48 +195,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { m_cumulative_user_time = cutime; } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { m_cumulative_system_time = cstime; } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); } + int8_t GetPriorityValue() const { return m_priority_value.value(); } feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -195,48 +195,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_process_session_id != LLDB_INVALID_PROCESS_ID; } - struct timespec GetUserTime() const { return m_user_time; } + struct timespec GetUserTime() const { return m_user_time.value(); } void SetUserTime(struct timespec utime) { m_user_time = utime; } bool UserTimeIsValid() const { -return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; +return m_user_time.has_value() && + (m_user_time->tv_sec > 0 || m_user_time->tv_usec > 0); } - struct timespec GetSystemTime() const { return m_system_time; } + struct timespec GetSystemTime() const { return m_system_time.value(); } void SetSystemTime(struct timespec stime) { m_system_time = stime; } bool SystemTimeIsValid() const { -return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; +return m_system_time.has_value() && + (m_system_time->tv_sec > 0 || m_system_time->tv_usec > 0); } struct timespec GetCumulativeUserTime() const { -return m_cumulative_user_time; +return m_cumulative_user_time.value(); } void SetCumulativeUserTime(struct timespec cutime) { m_cumulative_user_time = cutime; } bool CumulativeUserTimeIsValid() const { -return m_cumulative_user_time.tv_sec > 0 || - m_cumulative_user_time.tv_usec > 0; +return m_cumulative_user_time.has_value() && + (m_cumulative_user_time->tv_sec > 0 || +m_cumulative_user_time->tv_usec > 0); } struct timespec GetCumulativeSystemTime() const { -return m_cumulative_system_time; +return m_cumulative_system_time.value(); } void SetCumulativeSystemTime(struct timespec cstime) { m_cumulative_system_time = cstime; } bool CumulativeSystemTimeIsValid() const { -return m_cumulative_system_time.tv_sec > 0 || - m_cumulative_system_time.tv_usec > 0; +return m_cumulative_system_time.has_value() && + (m_cumulative_system_time->tv_sec > 0 || +m_cumulative_system_time->tv_usec > 0); } + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + bool PriorityValueIsValid() const; feg208 wrote: done https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @clayborg I rolled up those requested changes. That'll make a nicer interface https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @clayborg This pr is ready for re-review https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @clayborg This pr is ready for re-review https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From b1f09900d764a9b9cbdf839f83817e23dd89851a Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 24 ++- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 7 +++--- lldb/unittests/Host/linux/HostTest.cpp | 21 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..78ade4bbb1ee6 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -237,6 +237,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + std::optional GetPriorityValue() const { return m_priority_value; } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + std::optional IsZombie() const { return m_zombie; } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -250,10 +260,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + struct timespec m_user_time; + struct timespec m_system_time; + struct timespec m_cumulative_user_time; + struct timespec m_cumulative_system_time; + std::optional m_priority_value = std::nullopt; + std::optional m_zombie = std::nullopt; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..5545f9ef4d70e 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,6 +37,7 @@ using namespace lldb; using namespace lldb_private; namespace { + enum class ProcessState { Unknown, Dead, @@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // In proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo, we adopt the documented + // naming here. + long realtime_priority; + long priority; // other things. We don't need them below }; } @@ -91,14 +98,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - &stat_fields.pid, stat_fields.comm, &stat_fields.state, - &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, - &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, - &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, - &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + &stat_fields.pid, stat_fields.comm, &stat_fields.state, + &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, + &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, + &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, + &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, + &stat_fields.cutime, &stat_fields.cstime
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @clayborg this pr is ready for re-review. I have also rebased to top of master if that is helpful https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From a162f04d6d9f6c879398e4a6883f026bbfbd1e8f Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 24 ++- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 7 +++--- lldb/unittests/Host/linux/HostTest.cpp | 22 + 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..78ade4bbb1ee6 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -237,6 +237,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + std::optional GetPriorityValue() const { return m_priority_value; } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + std::optional IsZombie() const { return m_zombie; } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -250,10 +260,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + struct timespec m_user_time; + struct timespec m_system_time; + struct timespec m_cumulative_user_time; + struct timespec m_cumulative_system_time; + std::optional m_priority_value = std::nullopt; + std::optional m_zombie = std::nullopt; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..5545f9ef4d70e 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,6 +37,7 @@ using namespace lldb; using namespace lldb_private; namespace { + enum class ProcessState { Unknown, Dead, @@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // In proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo, we adopt the documented + // naming here. + long realtime_priority; + long priority; // other things. We don't need them below }; } @@ -91,14 +98,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - &stat_fields.pid, stat_fields.comm, &stat_fields.state, - &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, - &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, - &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, - &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + &stat_fields.pid, stat_fields.comm, &stat_fields.state, + &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, + &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, + &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, + &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, + &stat_fields.cutime, &stat_fields.cstim
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -86,4 +89,22 @@ TEST_F(HostTest, GetProcessInfo) { ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || user_time.tv_usec <= next_user_time.tv_usec); + + struct rlimit rlim; + EXPECT_EQ(getrlimit(RLIMIT_NICE, &rlim), 0); + // getpriority can return -1 so we zero errno first + errno = 0; + int prio = getpriority(PRIO_PROCESS, PRIO_PROCESS); + ASSERT_TRUE((prio < 0 && errno == 0) || prio >= 0); + ASSERT_EQ(Info.GetPriorityValue(), prio); + // If we can't raise our nice level then this test can't be performed. + int max_incr = PRIO_MAX - rlim.rlim_cur; + if (max_incr < prio) { +EXPECT_EQ(setpriority(PRIO_PROCESS, PRIO_PROCESS, prio - 1), 0); +ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); +ASSERT_EQ(Info.GetPriorityValue().value(), prio - 1); feg208 wrote: Done. Thanks for all your effort reviewing this work https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @clayborg I don't have commit access. Can you merge this? https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @JDevlieghere could I talk you into merging this? Somehow I got shifted from the committers group to the triagers group but it's taking time to resolve. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
feg208 wrote: @JDevlieghere and @clayborg sorry for the line noise. It's merged https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/104109 To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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.GetParent
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + 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); feg208 wrote: Yeah that's nicer https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/2] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + 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; +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 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + 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()) { feg208 wrote: removed https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -0,0 +1,162 @@ +//===-- ThreadElfCoreTest.cpp *- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +#include "Plugins/Process/elf-core/ThreadElfCore.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Listener.h" +#include "llvm/TargetParser/Triple.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include + +using namespace lldb_private; + +namespace { + +struct ElfCoreTest : public testing::Test { + static void SetUpTestCase() { +FileSystem::Initialize(); +HostInfo::Initialize(); +platform_linux::PlatformLinux::Initialize(); +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + } + static void TearDownTestCase() { +platform_linux::PlatformLinux::Terminate(); +HostInfo::Terminate(); +FileSystem::Terminate(); + } +}; + +struct DummyProcess : public Process { + DummyProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp) + : Process(target_sp, listener_sp) { +SetID(getpid()); + } + + bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { +return true; + } + Status DoDestroy() override { return {}; } + void RefreshStateAfterStop() override {} + size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + Status &error) override { +return 0; + } + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override { +return false; + } + llvm::StringRef GetPluginName() override { return "Dummy"; } +}; + +struct DummyThread : public Thread { + using Thread::Thread; + + ~DummyThread() override { DestroyThread(); } + + void RefreshStateAfterStop() override {} + + lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override { +return nullptr; + } + + bool CalculateStopInfo() override { return false; } +}; + +lldb::TargetSP CreateTarget(lldb::DebuggerSP &debugger_sp, ArchSpec &arch) { + lldb::PlatformSP platform_sp; + lldb::TargetSP target_sp; + debugger_sp->GetTargetList().CreateTarget( + *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); + return target_sp; +} + +lldb::ThreadSP CreateThread(lldb::ProcessSP &process_sp) { + lldb::ThreadSP thread_sp = + std::make_shared(*process_sp.get(), gettid()); + if (thread_sp == nullptr) { +return nullptr; + } + process_sp->GetThreadList().AddThread(thread_sp); + + return thread_sp; +} + +} // namespace + +TEST_F(ElfCoreTest, PopulatePrpsInfoTest) { + ArchSpec arch{HostInfo::GetTargetTriple()}; + lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + lldb::TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + lldb::ListenerSP listener_sp(Listener::MakeListener("dummy")); + lldb::ProcessSP process_sp = + std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + auto prpsinfo_opt = ELFLinuxPrPsInfo::Populate(process_sp); feg208 wrote: Yeah this is a good idea. I'll alter the interface and add more testing https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/3] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -0,0 +1,162 @@ +//===-- ThreadElfCoreTest.cpp *- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +#include "Plugins/Process/elf-core/ThreadElfCore.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Listener.h" +#include "llvm/TargetParser/Triple.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include + +using namespace lldb_private; + +namespace { + +struct ElfCoreTest : public testing::Test { + static void SetUpTestCase() { +FileSystem::Initialize(); +HostInfo::Initialize(); +platform_linux::PlatformLinux::Initialize(); +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + } + static void TearDownTestCase() { +platform_linux::PlatformLinux::Terminate(); +HostInfo::Terminate(); +FileSystem::Terminate(); + } +}; + +struct DummyProcess : public Process { + DummyProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp) + : Process(target_sp, listener_sp) { +SetID(getpid()); + } + + bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { +return true; + } + Status DoDestroy() override { return {}; } + void RefreshStateAfterStop() override {} + size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + Status &error) override { +return 0; + } + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override { +return false; + } + llvm::StringRef GetPluginName() override { return "Dummy"; } +}; + +struct DummyThread : public Thread { + using Thread::Thread; + + ~DummyThread() override { DestroyThread(); } + + void RefreshStateAfterStop() override {} + + lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override { +return nullptr; + } + + bool CalculateStopInfo() override { return false; } +}; + +lldb::TargetSP CreateTarget(lldb::DebuggerSP &debugger_sp, ArchSpec &arch) { + lldb::PlatformSP platform_sp; + lldb::TargetSP target_sp; + debugger_sp->GetTargetList().CreateTarget( + *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); + return target_sp; +} + +lldb::ThreadSP CreateThread(lldb::ProcessSP &process_sp) { + lldb::ThreadSP thread_sp = + std::make_shared(*process_sp.get(), gettid()); + if (thread_sp == nullptr) { +return nullptr; + } + process_sp->GetThreadList().AddThread(thread_sp); + + return thread_sp; +} + +} // namespace + +TEST_F(ElfCoreTest, PopulatePrpsInfoTest) { + ArchSpec arch{HostInfo::GetTargetTriple()}; + lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + lldb::TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + lldb::ListenerSP listener_sp(Listener::MakeListener("dummy")); + lldb::ProcessSP process_sp = + std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + auto prpsinfo_opt = ELFLinuxPrPsInfo::Populate(process_sp); feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { feg208 wrote: yes we should. In linux (and I guess in FreeBSD as well) a prstatus object is created for each thread which you can see in ProcessELFCore ``` 904 case ELF::NT_PRSTATUS: { 905 have_prstatus = true; 906 ELFLinuxPrStatus prstatus; 907 Status status = prstatus.Parse(note.data, arch); 908 if (status.Fail()) 909 return status.ToError(); 910 thread_data.prstatus_sig = prstatus.pr_cursig; 911 thread_data.tid = prstatus.pr_pid; 912 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch); 913 size_t len = note.data.GetByteSize() - header_size; 914 thread_data.gpregset = DataExtractor(note.data, header_size, len); 915 break; ``` The tid is the pid. So in SaveCore we'll need to iterate over all the threads to build each struct. https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/4] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/5] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This should always be non zero"); + const llvm::StringRef fname = info.GetNameAsStringRef(); + auto fname_begin = fname.begin(); + std::copy_n(fname_begin, std::min(fname_len, fname.size()), + prpsinfo.pr_fname); + prpsinfo.pr_fname[fname_len - 1] = '\0'; + auto args = info.GetArguments(); + auto argentry_iterator = std::begin(args); + char *psargs = prpsinfo.pr_psargs; + char *psargs_end = std::end(prpsinfo.pr_psargs); + while (psargs < psargs_end && argentry_iterator != args.end()) { +llvm::StringRef argentry = argentry_iterator->ref(); +size_t len = +std::min(std::distance(psargs, psargs_end), argentry.size()); +auto arg_iterator = std::begin(argentry); +psargs = std::copy_n(arg_iterator, len, psargs); +if (psargs != psargs_end) { + *(psargs++) = ' '; +} feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/6] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/7] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +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; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } feg208 wrote: blech. You are right. Fixed. Sorry. https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
feg208 wrote: The build failure here was a timeout in ``` TEST 'lldb-api :: functionalities/fork/concurrent_vfork/TestConcurrentVFork.py' FAILED Script: -- /usr/bin/python3.10 /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env ARCHIVER=/usr/bin/ar --env OBJCOPY=/usr/bin/objcopy --env LLVM_LIBS_DIR=/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./lib --env LLVM_INCLUDE_DIR=/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/include --env LLVM_TOOLS_DIR=/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./bin --arch x86_64 --build-dir /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/lldb-test-build.noindex --lldb-module-cache-dir /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./bin/lldb --compiler /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./bin/clang --dsymutil /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./bin/dsymutil --llvm-tools-dir /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./bin --lldb-obj-root /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/tools/lldb --lldb-libs-dir /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/build/./lib /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-j5dcb-1/llvm-project/github-pull-requests/lldb/test/API/functionalities/fork/concurrent_vfork -p TestConcurrentVFork.py -- Exit Code: -9 Timeout: Reached timeout of 1200 seconds ``` https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
feg208 wrote: Added issue https://github.com/llvm/llvm-project/issues/104609 to track the timeout https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] PopulatePrpsInfoTest can fail due to hardcoded priority value (PR #104617)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/104617 In implementing this test one of the assertions assumes that the priority is the default in linux (0) but, evidently, some of the build runners prioritize the test to, at least, 5. This ensures that regardless of the priority the test passes by validating that its the process's priority ``` fgrim@host001 :~/llvm-project/debug_build> nice -n 15 tools/lldb/unittests/Process/elf-core/ProcessElfCoreTests [==] Running 2 tests from 1 test suite. [--] Global test environment set-up. [--] 2 tests from ElfCoreTest [ RUN ] ElfCoreTest.PopulatePrpsInfoTest [ OK ] ElfCoreTest.PopulatePrpsInfoTest (4 ms) [ RUN ] ElfCoreTest.PopulatePrStatusTest [ OK ] ElfCoreTest.PopulatePrStatusTest (3 ms) [--] 2 tests from ElfCoreTest (7 ms total) [--] Global test environment tear-down [==] 2 tests from 1 test suite ran. (8 ms total) [ PASSED ] 2 tests. ===(10:03)=== fgrim@host001 :~/llvm-project/debug_build> ``` >From 69450e4be6c639bb263f3e604219ff1310e1582e Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Fri, 16 Aug 2024 10:04:49 -0700 Subject: [PATCH] [lldb] PopulatePrpsInfoTest can fail due to hardcoded priority value In implementing this test one of the assertions assumes that the priority is the default in linux (0) but, evidently, some of the build runners prioritize the test to, at least, 5. This ensures that regardless of the priority the test passes by validating that its the process's priority ``` fgrim@host001 :~/llvm-project/debug_build> nice -n 15 tools/lldb/unittests/Process/elf-core/ProcessElfCoreTests [==] Running 2 tests from 1 test suite. [--] Global test environment set-up. [--] 2 tests from ElfCoreTest [ RUN ] ElfCoreTest.PopulatePrpsInfoTest [ OK ] ElfCoreTest.PopulatePrpsInfoTest (4 ms) [ RUN ] ElfCoreTest.PopulatePrStatusTest [ OK ] ElfCoreTest.PopulatePrStatusTest (3 ms) [--] 2 tests from ElfCoreTest (7 ms total) [--] Global test environment tear-down [==] 2 tests from 1 test suite ran. (8 ms total) [ PASSED ] 2 tests. ===(10:03)=== fgrim@host001 :~/llvm-project/debug_build> ``` --- lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp b/lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp index ce146f62b0d826..3bc8b9053d2009 100644 --- a/lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp +++ b/lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp @@ -21,6 +21,7 @@ #include #include +#include #include using namespace lldb_private; @@ -120,7 +121,10 @@ TEST_F(ElfCoreTest, PopulatePrpsInfoTest) { ASSERT_EQ(prpsinfo_opt->pr_state, 0); ASSERT_EQ(prpsinfo_opt->pr_sname, 'R'); ASSERT_EQ(prpsinfo_opt->pr_zomb, 0); - ASSERT_EQ(prpsinfo_opt->pr_nice, 0); + int priority = getpriority(PRIO_PROCESS, getpid()); + if (priority == -1) +ASSERT_EQ(errno, 0); + ASSERT_EQ(prpsinfo_opt->pr_nice, priority); ASSERT_EQ(prpsinfo_opt->pr_flag, 0UL); ASSERT_EQ(prpsinfo_opt->pr_uid, getuid()); ASSERT_EQ(prpsinfo_opt->pr_gid, getgid()); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] PopulatePrpsInfoTest can fail due to hardcoded priority value (PR #104617)
@@ -120,7 +121,10 @@ TEST_F(ElfCoreTest, PopulatePrpsInfoTest) { ASSERT_EQ(prpsinfo_opt->pr_state, 0); ASSERT_EQ(prpsinfo_opt->pr_sname, 'R'); ASSERT_EQ(prpsinfo_opt->pr_zomb, 0); - ASSERT_EQ(prpsinfo_opt->pr_nice, 0); + int priority = getpriority(PRIO_PROCESS, getpid()); + if (priority == -1) feg208 wrote: In this test the process for which the prpsinfo object is being populated is the test process. The issue I saw in the build kites was that, rather than the test process being prioritized at the default for linux, it got 5. So the fix here is just to make sure that, whatever the priority of the test process, what is verified that the populated value in the prpsinfo object matches the priority that we know the process runs as. https://github.com/llvm/llvm-project/pull/104617 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] PopulatePrpsInfoTest can fail due to hardcoded priority value (PR #104617)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/104617 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/88995 This adds some additional bits into a ProcessInfo structure that will be of use in filling structs in an elf core file. This is a demand for implementing process save-core >From 9b8ec4d0c31ad1b228add56bc27cd79457e515c7 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 16 Apr 2024 14:46:37 -0700 Subject: [PATCH] adds additional information to the ProcessInfo object for elf processes --- lldb/include/lldb/Utility/ProcessInfo.h | 71 ++ lldb/source/Host/linux/Host.cpp | 125 lldb/unittests/Host/linux/HostTest.cpp | 6 ++ 3 files changed, 182 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 7fb5b37be0f48f..e9fe71e1b851d1 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -139,6 +139,11 @@ class ProcessInfo { // to that process. class ProcessInstanceInfo : public ProcessInfo { public: + struct timespec { +time_t tv_sec = 0; +long int tv_usec = 0; + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -172,6 +177,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_parent_pid != LLDB_INVALID_PROCESS_ID; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + + void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } + + bool ProcessGroupIDIsValid() const { +return m_process_group_id != LLDB_INVALID_PROCESS_ID; + } + + lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + + void SetProcessSessionID(lldb::pid_t session) { +m_process_session_id = session; + } + + bool ProcessSessionIDIsValid() const { +return m_process_session_id != LLDB_INVALID_PROCESS_ID; + } + + struct timespec GetUserTime() const { return m_user_time; } + + void SetUserTime(struct timespec utime) { m_user_time = utime; } + + bool UserTimeIsValid() const { +return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; + } + + struct timespec GetSystemTime() const { return m_system_time; } + + void SetSystemTime(struct timespec stime) { m_system_time = stime; } + + bool SystemTimeIsValid() const { +return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; + } + + struct timespec GetCumulativeUserTime() const { +return m_cumulative_user_time; + } + + void SetCumulativeUserTime(struct timespec cutime) { +m_cumulative_user_time = cutime; + } + + bool CumulativeUserTimeIsValid() const { +return m_cumulative_user_time.tv_sec > 0 || + m_cumulative_user_time.tv_usec > 0; + } + + struct timespec GetCumulativeSystemTime() const { +return m_cumulative_system_time; + } + + void SetCumulativeSystemTime(struct timespec cstime) { +m_cumulative_system_time = cstime; + } + + bool CumulativeSystemTimeIsValid() const { +return m_cumulative_system_time.tv_sec > 0 || + m_cumulative_system_time.tv_sec > 0; + } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -183,6 +248,12 @@ class ProcessInstanceInfo : public ProcessInfo { uint32_t m_euid = UINT32_MAX; uint32_t m_egid = UINT32_MAX; lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; + struct timespec m_user_time {}; + struct timespec m_system_time {}; + struct timespec m_cumulative_user_time {}; + struct timespec m_cumulative_system_time {}; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 6c57384aa38a13..c6490f2fc9e2f5 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -49,6 +49,29 @@ enum class ProcessState { TracedOrStopped, Zombie, }; + +constexpr int task_comm_len = 16; + +struct StatFields { + ::pid_t pid = LLDB_INVALID_PROCESS_ID; + char comm[task_comm_len]; + char state; + ::pid_t ppid = LLDB_INVALID_PROCESS_ID; + ::pid_t pgrp = LLDB_INVALID_PROCESS_ID; + ::pid_t session = LLDB_INVALID_PROCESS_ID; + int tty_nr; + int tpgid; + unsigned flags; + long unsigned minflt; + long unsigned cminflt; + long unsigned majflt; + long unsigned cmajflt; + long unsigned utime; + long unsigned stime; + long cutime; + long cstime; + // other things. We don't need them below +}; } namespace lldb_private { @@ -60,11 +83,92 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, ::pid_t &Tgid) { Log *log = GetLog(LLDBLog::Host); - auto BufferOrError = getProcFile(Pid, "status"); + auto BufferOrError = getProcFile(Pid, "stat"); if (!BufferOrError) return false; llvm
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > These seem like fairly POSIX-y bits of data, is there not a Posix way to get > these (so other posix systems will also get this info?) Not that I know of for arbitrary processes in linux. fwiw the original code without these values got similar bits out of the proc filesystem > > Also, it looks like you added user time and system time information, but you > didn't test that those get valid values. I did not. My concern here is that this would make for flaky tests. The issue is that these times are going to be very dependent on the cpus they are scheduled to, what else is running on that same machine and so on. I guess we could do a bunch of stuff to pin the unit test process in place and make it more controllable but that tends to imply permissions for the host executing the unit test. Or maybe you were thinking of another way? I am all ears if so. https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > The user and system times should be monotonically increasing. So you could > stop at a breakpoint, fetch the times, then run your program through a little > spin loop to burn some CPU before hitting a second breakpoint. Then get the > times again and assert that they are > the first set. You could also set a > timer in the test between the first and second stop and assert that the > difference in system and user time is less than or equal to the timer > difference. A single threaded program can only run on one core at a time, so > that should always be true. Ok let me add a test along these lines. I'll run the test a bunch locally and in this pr to make sure I don't make a mess https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/88995 >From 9b8ec4d0c31ad1b228add56bc27cd79457e515c7 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 16 Apr 2024 14:46:37 -0700 Subject: [PATCH 1/2] adds additional information to the ProcessInfo object for elf processes --- lldb/include/lldb/Utility/ProcessInfo.h | 71 ++ lldb/source/Host/linux/Host.cpp | 125 lldb/unittests/Host/linux/HostTest.cpp | 6 ++ 3 files changed, 182 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 7fb5b37be0f48f..e9fe71e1b851d1 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -139,6 +139,11 @@ class ProcessInfo { // to that process. class ProcessInstanceInfo : public ProcessInfo { public: + struct timespec { +time_t tv_sec = 0; +long int tv_usec = 0; + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -172,6 +177,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_parent_pid != LLDB_INVALID_PROCESS_ID; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + + void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } + + bool ProcessGroupIDIsValid() const { +return m_process_group_id != LLDB_INVALID_PROCESS_ID; + } + + lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + + void SetProcessSessionID(lldb::pid_t session) { +m_process_session_id = session; + } + + bool ProcessSessionIDIsValid() const { +return m_process_session_id != LLDB_INVALID_PROCESS_ID; + } + + struct timespec GetUserTime() const { return m_user_time; } + + void SetUserTime(struct timespec utime) { m_user_time = utime; } + + bool UserTimeIsValid() const { +return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; + } + + struct timespec GetSystemTime() const { return m_system_time; } + + void SetSystemTime(struct timespec stime) { m_system_time = stime; } + + bool SystemTimeIsValid() const { +return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; + } + + struct timespec GetCumulativeUserTime() const { +return m_cumulative_user_time; + } + + void SetCumulativeUserTime(struct timespec cutime) { +m_cumulative_user_time = cutime; + } + + bool CumulativeUserTimeIsValid() const { +return m_cumulative_user_time.tv_sec > 0 || + m_cumulative_user_time.tv_usec > 0; + } + + struct timespec GetCumulativeSystemTime() const { +return m_cumulative_system_time; + } + + void SetCumulativeSystemTime(struct timespec cstime) { +m_cumulative_system_time = cstime; + } + + bool CumulativeSystemTimeIsValid() const { +return m_cumulative_system_time.tv_sec > 0 || + m_cumulative_system_time.tv_sec > 0; + } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -183,6 +248,12 @@ class ProcessInstanceInfo : public ProcessInfo { uint32_t m_euid = UINT32_MAX; uint32_t m_egid = UINT32_MAX; lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; + struct timespec m_user_time {}; + struct timespec m_system_time {}; + struct timespec m_cumulative_user_time {}; + struct timespec m_cumulative_system_time {}; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 6c57384aa38a13..c6490f2fc9e2f5 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -49,6 +49,29 @@ enum class ProcessState { TracedOrStopped, Zombie, }; + +constexpr int task_comm_len = 16; + +struct StatFields { + ::pid_t pid = LLDB_INVALID_PROCESS_ID; + char comm[task_comm_len]; + char state; + ::pid_t ppid = LLDB_INVALID_PROCESS_ID; + ::pid_t pgrp = LLDB_INVALID_PROCESS_ID; + ::pid_t session = LLDB_INVALID_PROCESS_ID; + int tty_nr; + int tpgid; + unsigned flags; + long unsigned minflt; + long unsigned cminflt; + long unsigned majflt; + long unsigned cmajflt; + long unsigned utime; + long unsigned stime; + long cutime; + long cstime; + // other things. We don't need them below +}; } namespace lldb_private { @@ -60,11 +83,92 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, ::pid_t &Tgid) { Log *log = GetLog(LLDBLog::Host); - auto BufferOrError = getProcFile(Pid, "status"); + auto BufferOrError = getProcFile(Pid, "stat"); if (!BufferOrError) return false; llvm::StringRef Rest = BufferOrError.get()->getBuffer(); + if (Rest.empty()) +return false; + StatFields stat_fields; + if (sscanf(Rest.data(), + "%d %s %c
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > The user and system times should be monotonically increasing. So you could > stop at a breakpoint, fetch the times, then run your program through a little > spin loop to burn some CPU before hitting a second breakpoint. Then get the > times again and assert that they are > the first set. You could also set a > timer in the test between the first and second stop and assert that the > difference in system and user time is less than or equal to the timer > difference. A single threaded program can only run on one core at a time, so > that should always be true. I added a test for user time. System time seems really likely to be flaky in the unittest. It'll increase with kernel time. However if I use side-effect free system calls like getpid() to try and increase that counter it seems like that'll move around a lot from different kernels on different machines https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/88995 >From 9b8ec4d0c31ad1b228add56bc27cd79457e515c7 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 16 Apr 2024 14:46:37 -0700 Subject: [PATCH 1/2] adds additional information to the ProcessInfo object for elf processes --- lldb/include/lldb/Utility/ProcessInfo.h | 71 ++ lldb/source/Host/linux/Host.cpp | 125 lldb/unittests/Host/linux/HostTest.cpp | 6 ++ 3 files changed, 182 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 7fb5b37be0f48f..e9fe71e1b851d1 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -139,6 +139,11 @@ class ProcessInfo { // to that process. class ProcessInstanceInfo : public ProcessInfo { public: + struct timespec { +time_t tv_sec = 0; +long int tv_usec = 0; + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -172,6 +177,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_parent_pid != LLDB_INVALID_PROCESS_ID; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + + void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } + + bool ProcessGroupIDIsValid() const { +return m_process_group_id != LLDB_INVALID_PROCESS_ID; + } + + lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + + void SetProcessSessionID(lldb::pid_t session) { +m_process_session_id = session; + } + + bool ProcessSessionIDIsValid() const { +return m_process_session_id != LLDB_INVALID_PROCESS_ID; + } + + struct timespec GetUserTime() const { return m_user_time; } + + void SetUserTime(struct timespec utime) { m_user_time = utime; } + + bool UserTimeIsValid() const { +return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; + } + + struct timespec GetSystemTime() const { return m_system_time; } + + void SetSystemTime(struct timespec stime) { m_system_time = stime; } + + bool SystemTimeIsValid() const { +return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; + } + + struct timespec GetCumulativeUserTime() const { +return m_cumulative_user_time; + } + + void SetCumulativeUserTime(struct timespec cutime) { +m_cumulative_user_time = cutime; + } + + bool CumulativeUserTimeIsValid() const { +return m_cumulative_user_time.tv_sec > 0 || + m_cumulative_user_time.tv_usec > 0; + } + + struct timespec GetCumulativeSystemTime() const { +return m_cumulative_system_time; + } + + void SetCumulativeSystemTime(struct timespec cstime) { +m_cumulative_system_time = cstime; + } + + bool CumulativeSystemTimeIsValid() const { +return m_cumulative_system_time.tv_sec > 0 || + m_cumulative_system_time.tv_sec > 0; + } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -183,6 +248,12 @@ class ProcessInstanceInfo : public ProcessInfo { uint32_t m_euid = UINT32_MAX; uint32_t m_egid = UINT32_MAX; lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; + struct timespec m_user_time {}; + struct timespec m_system_time {}; + struct timespec m_cumulative_user_time {}; + struct timespec m_cumulative_system_time {}; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 6c57384aa38a13..c6490f2fc9e2f5 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -49,6 +49,29 @@ enum class ProcessState { TracedOrStopped, Zombie, }; + +constexpr int task_comm_len = 16; + +struct StatFields { + ::pid_t pid = LLDB_INVALID_PROCESS_ID; + char comm[task_comm_len]; + char state; + ::pid_t ppid = LLDB_INVALID_PROCESS_ID; + ::pid_t pgrp = LLDB_INVALID_PROCESS_ID; + ::pid_t session = LLDB_INVALID_PROCESS_ID; + int tty_nr; + int tpgid; + unsigned flags; + long unsigned minflt; + long unsigned cminflt; + long unsigned majflt; + long unsigned cmajflt; + long unsigned utime; + long unsigned stime; + long cutime; + long cstime; + // other things. We don't need them below +}; } namespace lldb_private { @@ -60,11 +83,92 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, ::pid_t &Tgid) { Log *log = GetLog(LLDBLog::Host); - auto BufferOrError = getProcFile(Pid, "status"); + auto BufferOrError = getProcFile(Pid, "stat"); if (!BufferOrError) return false; llvm::StringRef Rest = BufferOrError.get()->getBuffer(); + if (Rest.empty()) +return false; + StatFields stat_fields; + if (sscanf(Rest.data(), + "%d %s %c
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > That test looks good. It seems unlikely that you would buggily always produce > monotonically increasing times... > > Not to be a pest, but since this info is only provided on Linux, we should > maybe add a test to make sure that asking for this information on systems > that don't provide it fails gracefully? Not at all. I'll add it https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > That test looks good. It seems unlikely that you would buggily always produce > monotonically increasing times... > > Not to be a pest, but since this info is only provided on Linux, we should > maybe add a test to make sure that asking for this information on systems > that don't provide it fails gracefully? Actually looking at lldb/unittest/Host/CMakeLists.txt I see: ``` if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") list(APPEND FILES linux/HostTest.cpp linux/SupportTest.cpp ) endif() ``` which should ensure the test is never built nor executed outside of linux https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > It should never decrease, however. If you were just getting garbage values, > then there should be a roughly even chance the second value will be less than > the first. So this still gives some confidence this isn't totally bogus... For sure. My concern is that it wouldn't increase either. The granularity is microseconds but with a call like getpid() for example the kernel might just return a cached value which, I assume after enough loops, would increase the timer but what is enough? And enough will change I think as build environments get faster machines faster kernels and so on. https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/88995 >From 9b8ec4d0c31ad1b228add56bc27cd79457e515c7 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 16 Apr 2024 14:46:37 -0700 Subject: [PATCH 1/3] adds additional information to the ProcessInfo object for elf processes --- lldb/include/lldb/Utility/ProcessInfo.h | 71 ++ lldb/source/Host/linux/Host.cpp | 125 lldb/unittests/Host/linux/HostTest.cpp | 6 ++ 3 files changed, 182 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 7fb5b37be0f48f..e9fe71e1b851d1 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -139,6 +139,11 @@ class ProcessInfo { // to that process. class ProcessInstanceInfo : public ProcessInfo { public: + struct timespec { +time_t tv_sec = 0; +long int tv_usec = 0; + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -172,6 +177,66 @@ class ProcessInstanceInfo : public ProcessInfo { return m_parent_pid != LLDB_INVALID_PROCESS_ID; } + lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } + + void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } + + bool ProcessGroupIDIsValid() const { +return m_process_group_id != LLDB_INVALID_PROCESS_ID; + } + + lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } + + void SetProcessSessionID(lldb::pid_t session) { +m_process_session_id = session; + } + + bool ProcessSessionIDIsValid() const { +return m_process_session_id != LLDB_INVALID_PROCESS_ID; + } + + struct timespec GetUserTime() const { return m_user_time; } + + void SetUserTime(struct timespec utime) { m_user_time = utime; } + + bool UserTimeIsValid() const { +return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; + } + + struct timespec GetSystemTime() const { return m_system_time; } + + void SetSystemTime(struct timespec stime) { m_system_time = stime; } + + bool SystemTimeIsValid() const { +return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; + } + + struct timespec GetCumulativeUserTime() const { +return m_cumulative_user_time; + } + + void SetCumulativeUserTime(struct timespec cutime) { +m_cumulative_user_time = cutime; + } + + bool CumulativeUserTimeIsValid() const { +return m_cumulative_user_time.tv_sec > 0 || + m_cumulative_user_time.tv_usec > 0; + } + + struct timespec GetCumulativeSystemTime() const { +return m_cumulative_system_time; + } + + void SetCumulativeSystemTime(struct timespec cstime) { +m_cumulative_system_time = cstime; + } + + bool CumulativeSystemTimeIsValid() const { +return m_cumulative_system_time.tv_sec > 0 || + m_cumulative_system_time.tv_sec > 0; + } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -183,6 +248,12 @@ class ProcessInstanceInfo : public ProcessInfo { uint32_t m_euid = UINT32_MAX; uint32_t m_egid = UINT32_MAX; lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; + lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; + struct timespec m_user_time {}; + struct timespec m_system_time {}; + struct timespec m_cumulative_user_time {}; + struct timespec m_cumulative_system_time {}; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 6c57384aa38a13..c6490f2fc9e2f5 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -49,6 +49,29 @@ enum class ProcessState { TracedOrStopped, Zombie, }; + +constexpr int task_comm_len = 16; + +struct StatFields { + ::pid_t pid = LLDB_INVALID_PROCESS_ID; + char comm[task_comm_len]; + char state; + ::pid_t ppid = LLDB_INVALID_PROCESS_ID; + ::pid_t pgrp = LLDB_INVALID_PROCESS_ID; + ::pid_t session = LLDB_INVALID_PROCESS_ID; + int tty_nr; + int tpgid; + unsigned flags; + long unsigned minflt; + long unsigned cminflt; + long unsigned majflt; + long unsigned cmajflt; + long unsigned utime; + long unsigned stime; + long cutime; + long cstime; + // other things. We don't need them below +}; } namespace lldb_private { @@ -60,11 +83,92 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, ::pid_t &Tgid) { Log *log = GetLog(LLDBLog::Host); - auto BufferOrError = getProcFile(Pid, "status"); + auto BufferOrError = getProcFile(Pid, "stat"); if (!BufferOrError) return false; llvm::StringRef Rest = BufferOrError.get()->getBuffer(); + if (Rest.empty()) +return false; + StatFields stat_fields; + if (sscanf(Rest.data(), + "%d %s %c
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
feg208 wrote: > Yes, you'd have to put this test into a host test for a system that doesn't > support this, like use the Posix one or make one for the Windows or Darwin > Hosts. Done! https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] adds additional information to the ProcessInfo object for elf processes (PR #88995)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/88995 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] this test is flakey on arm in linux because I got too clever (PR #89267)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/89267 the assembly jazz doesn't work on arm. oops >From 13e982588d75b240ce515c8ff1b2d9c89a595908 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Thu, 18 Apr 2024 10:13:03 -0700 Subject: [PATCH] this test is flakey on arm in linux because I got too clever --- lldb/unittests/Host/linux/HostTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 046736dce18d7a..27d1898969fb44 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -71,8 +71,9 @@ TEST_F(HostTest, GetProcessInfo) { // Test timings ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); + static volatile unsigned u = 0; for (unsigned i = 0; i < 10'000'000; i++) { -__asm__ __volatile__("" : "+g"(i) : :); +u = i; } ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] this test is flakey on arm in linux because I got too clever (PR #89267)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/89267 >From 24fa0fc2f54ef4141302ed7178ee0dc1b6d6af4e Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Thu, 18 Apr 2024 10:13:03 -0700 Subject: [PATCH] this test is flakey on arm in linux because I got too clever --- lldb/unittests/Host/linux/HostTest.cpp | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 046736dce18d7a..733909902474d7 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -69,13 +69,17 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); // Test timings + /* + * This is flaky in the buildbots on all archs ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); + static volatile unsigned u = 0; for (unsigned i = 0; i < 10'000'000; i++) { -__asm__ __volatile__("" : "+g"(i) : :); +u = i; } ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || user_time.tv_usec < next_user_time.tv_usec); + */ } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] this test is flakey on arm in linux because I got too clever (PR #89267)
feg208 wrote: I had to just comment this test out because it randomly fails on at least x86_64 and arm https://github.com/llvm/llvm-project/pull/89267 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] this test is flakey on arm in linux because I got too clever (PR #89267)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/89267 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] I left some commented code in. This test doesn't run reliably in the different build bots (PR #89637)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/89637 @jimingham I am wondering if you are ok removing this test? It caused failures in some of the build bots because the user time was less than a microsecond. Alternatively we can increase the number of loops or maybe I need some other approach? I had commented it out just to not impact others >From 21ae49be17c829281a0f9b1beef95712f0b19046 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Mon, 22 Apr 2024 10:17:14 -0700 Subject: [PATCH] I left some commented code in. This test doesn't run reliably in the different build bots --- lldb/unittests/Host/linux/HostTest.cpp | 14 -- 1 file changed, 14 deletions(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 733909902474d7..5599e4349c8291 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -68,18 +68,4 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_TRUE(Info.GetArchitecture().IsValid()); EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); - // Test timings - /* - * This is flaky in the buildbots on all archs - ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); - ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); - static volatile unsigned u = 0; - for (unsigned i = 0; i < 10'000'000; i++) { -u = i; - } - ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); - ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); - ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || - user_time.tv_usec < next_user_time.tv_usec); - */ } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] I left some commented code in. This test doesn't run reliably in the different build bots (PR #89637)
feg208 wrote: > A potential compromise would be to check that the time is great or equal? That's a good idea. I'll make that change and add a note https://github.com/llvm/llvm-project/pull/89637 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] I left some commented code in. This test doesn't run reliably in the different build bots (PR #89637)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/89637 >From 9ef4220b01a9cb18c3f23b78ae7aa3b80c2a7851 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Mon, 22 Apr 2024 10:17:14 -0700 Subject: [PATCH] I left some commented code in. This test doesn't run reliably in the different build bots --- lldb/unittests/Host/linux/HostTest.cpp | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 733909902474d7..787127de2952a0 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -69,8 +69,6 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); // Test timings - /* - * This is flaky in the buildbots on all archs ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); static volatile unsigned u = 0; @@ -79,7 +77,6 @@ TEST_F(HostTest, GetProcessInfo) { } ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); - ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || - user_time.tv_usec < next_user_time.tv_usec); - */ + ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || + user_time.tv_usec <= next_user_time.tv_usec); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] I left some commented code in. This test doesn't run reliably in the different build bots (PR #89637)
feg208 wrote: > Hi @feg208 , I noticed that your [previous commit > ](https://github.com/llvm/llvm-project/pull/89267) has a very.. unusual > commit title and message. The same thing applies to this PR. > > I'd appreciate it if you could follow a more standard commit title and > message, so that the logs are more easily parseable. Here's the official LLVM > docs on the matter: https://llvm.org/docs/DeveloperPolicy.html#commit-messages > > You can also get a good sample by doing a `git log --one-line` inside the > llvm repo. Sure thing. I apologize for deviating from expectations. https://github.com/llvm/llvm-project/pull/89637 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] I left some commented code in. This test doesn't run reliably in the different build bots (PR #89637)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/89637 >From bd0416d37d61e71f36e9afc435f9209b544bdb78 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Mon, 22 Apr 2024 10:17:14 -0700 Subject: [PATCH] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints This test was commented out which, besides being bad form, disabled the test entirely. But we do want to validate that this timings are not decreasing. The test is modified to reflact those expectations. --- lldb/unittests/Host/linux/HostTest.cpp | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 733909902474d7..787127de2952a0 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -69,8 +69,6 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); // Test timings - /* - * This is flaky in the buildbots on all archs ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); static volatile unsigned u = 0; @@ -79,7 +77,6 @@ TEST_F(HostTest, GetProcessInfo) { } ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); - ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || - user_time.tv_usec < next_user_time.tv_usec); - */ + ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || + user_time.tv_usec <= next_user_time.tv_usec); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints This test was commented out which, besides being bad form, disabled the test entirely. But we do want to val
https://github.com/feg208 edited https://github.com/llvm/llvm-project/pull/89637 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints. (PR #89637)
https://github.com/feg208 edited https://github.com/llvm/llvm-project/pull/89637 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints. (PR #89637)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/89637 >From edc21c6ec34486b6155ef0ec6f6be97a9bd0f0bb Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Mon, 22 Apr 2024 10:17:14 -0700 Subject: [PATCH] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints This test was commented out which, besides being bad form, disabled the test entirely. But we do want to validate that this timings are not decreasing. The test is modified to reflect those expectations. --- lldb/unittests/Host/linux/HostTest.cpp | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 733909902474d7..787127de2952a0 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -69,8 +69,6 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); // Test timings - /* - * This is flaky in the buildbots on all archs ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); static volatile unsigned u = 0; @@ -79,7 +77,6 @@ TEST_F(HostTest, GetProcessInfo) { } ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); - ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || - user_time.tv_usec < next_user_time.tv_usec); - */ + ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || + user_time.tv_usec <= next_user_time.tv_usec); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints. (PR #89637)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/89637 >From 41175787b1f5d1451d5ea88618ca6c229a415c0f Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Mon, 22 Apr 2024 10:17:14 -0700 Subject: [PATCH] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints This test was commented out which, besides being bad form, disabled the test entirely. But we do want to validate that this timings are not decreasing. The test is modified to reflect those expectations. --- lldb/unittests/Host/linux/HostTest.cpp | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lldb/unittests/Host/linux/HostTest.cpp b/lldb/unittests/Host/linux/HostTest.cpp index 733909902474d7..8ecaf3ec0decb0 100644 --- a/lldb/unittests/Host/linux/HostTest.cpp +++ b/lldb/unittests/Host/linux/HostTest.cpp @@ -69,17 +69,21 @@ TEST_F(HostTest, GetProcessInfo) { EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), Info.GetArchitecture()); // Test timings - /* - * This is flaky in the buildbots on all archs + // In some sense this is a pretty trivial test. What it is trying to + // accomplish is just to validate that these values are never decreasing + // which would be unambiguously wrong. We can not reliably show them + // to be always increasing because the microsecond granularity means that, + // with hardware variations the number of loop iterations need to always + // be increasing for faster and faster machines. ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec user_time = Info.GetUserTime(); static volatile unsigned u = 0; for (unsigned i = 0; i < 10'000'000; i++) { -u = i; +u += i; } + ASSERT_TRUE(u > 0); ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); - ASSERT_TRUE(user_time.tv_sec < next_user_time.tv_sec || - user_time.tv_usec < next_user_time.tv_usec); - */ + ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || + user_time.tv_usec <= next_user_time.tv_usec); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Reenable test HostTest.GetProcessInfo with relaxed constraints. (PR #89637)
https://github.com/feg208 closed https://github.com/llvm/llvm-project/pull/89637 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 created https://github.com/llvm/llvm-project/pull/91544 To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations >From 8355e9f14b898572d81721118e6a842d63652a33 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 33 + lldb/source/Host/linux/Host.cpp | 29 +++--- lldb/source/Utility/ProcessInfo.cpp | 5 lldb/unittests/Host/linux/HostTest.cpp | 21 4 files changed, 74 insertions(+), 14 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..ddaa93c6d5c91 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -144,6 +144,19 @@ class ProcessInstanceInfo : public ProcessInfo { long int tv_usec = 0; }; + enum class ProcessState { +Unknown, +Dead, +DiskSleep, +Idle, +Paging, +Parked, +Running, +Sleeping, +TracedOrStopped, +Zombie, + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -237,6 +250,24 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetNiceValue() const { +return m_nice_value; + } + + void SetNiceValue(int8_t nice_value) { +m_nice_value = nice_value; + } + + bool NiceValueIsValid() const; + + void SetIsZombie() { +m_zombie = true; + } + + bool IsZombie() const { +return m_zombie; + } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -254,6 +285,8 @@ class ProcessInstanceInfo : public ProcessInfo { struct timespec m_system_time {}; struct timespec m_cumulative_user_time {}; struct timespec m_cumulative_system_time {}; + int8_t m_nice_value = INT8_MAX; + bool m_zombie = false; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..c12bd259c5a7d 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,18 +37,8 @@ using namespace lldb; using namespace lldb_private; namespace { -enum class ProcessState { - Unknown, - Dead, - DiskSleep, - Idle, - Paging, - Parked, - Running, - Sleeping, - TracedOrStopped, - Zombie, -}; + +using ProcessState = typename ProcessInstanceInfo::ProcessState; constexpr int task_comm_len = 16; @@ -70,6 +60,8 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + long priority; + long nice; // other things. We don't need them below }; } @@ -92,13 +84,14 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, return false; StatFields stat_fields; if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", &stat_fields.pid, stat_fields.comm, &stat_fields.state, &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + &stat_fields.cutime, &stat_fields.cstime, &stat_fields.priority, + &stat_fields.nice) < 0) { return false; } @@ -115,6 +108,12 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, return ts; }; + // nice values run from 19 to -20 inclusive (in linux). In the prpsinfo struct + // pr_nice is a char + auto nice_value = static_cast( +(stat_fields.nice < 0 ? 0x80 : 0x00) | (stat_fields.nice & 0x7f) + ); + ProcessInfo.SetParentProcessID(stat_fields.ppid); ProcessInfo.SetProcessGroupID(stat_fields.pgrp); ProcessInfo.SetProcessSessionID(stat_fields.session); @@ -122,6 +121,7 @@ static bool GetStatusInfo(::pid_t Pid, Proce
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From 57e47b53682d43d2b1febba721688c6931c43291 Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 25 +++ lldb/source/Host/linux/Host.cpp | 41 + lldb/source/Utility/ProcessInfo.cpp | 5 +++ lldb/unittests/Host/linux/HostTest.cpp | 20 4 files changed, 71 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..fb0fca2cccbe3 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -144,6 +144,19 @@ class ProcessInstanceInfo : public ProcessInfo { long int tv_usec = 0; }; + enum class ProcessState { +Unknown, +Dead, +DiskSleep, +Idle, +Paging, +Parked, +Running, +Sleeping, +TracedOrStopped, +Zombie, + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -237,6 +250,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetNiceValue() const { return m_nice_value; } + + void SetNiceValue(int8_t nice_value) { m_nice_value = nice_value; } + + bool NiceValueIsValid() const; + + void SetIsZombie() { m_zombie = true; } + + bool IsZombie() const { return m_zombie; } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -254,6 +277,8 @@ class ProcessInstanceInfo : public ProcessInfo { struct timespec m_system_time {}; struct timespec m_cumulative_user_time {}; struct timespec m_cumulative_system_time {}; + int8_t m_nice_value = INT8_MAX; + bool m_zombie = false; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..ba2323990adac 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,18 +37,8 @@ using namespace lldb; using namespace lldb_private; namespace { -enum class ProcessState { - Unknown, - Dead, - DiskSleep, - Idle, - Paging, - Parked, - Running, - Sleeping, - TracedOrStopped, - Zombie, -}; + +using ProcessState = typename ProcessInstanceInfo::ProcessState; constexpr int task_comm_len = 16; @@ -70,6 +60,8 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + long priority; + long nice; // other things. We don't need them below }; } @@ -91,14 +83,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - &stat_fields.pid, stat_fields.comm, &stat_fields.state, - &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, - &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, - &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, - &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + &stat_fields.pid, stat_fields.comm, &stat_fields.state, + &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, + &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, + &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, + &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, + &stat_fields.cutime, &stat_fields.cstime, &stat_fields.priority, + &stat_fields.nice) < 0) { return false; } @@ -115,6 +109,11 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, return ts; }; + // nice values run from 19 to -20 inclusive (in linux). In the prpsinfo struct + // pr_nice is a char + auto nice_value = static_cast((stat_fields.nice < 0 ? 0x80 : 0x00) | +(stat_fields.nice & 0x7f)); + ProcessInfo.SetParentProcessID(stat_fields.ppid); ProcessInfo.SetProcessGroupID(stat_fields.pgrp); ProcessInfo.SetProcessSessionID(stat_fields.session); @@ -122,6 +121,7 @@ static boo
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -144,6 +144,19 @@ class ProcessInstanceInfo : public ProcessInfo { long int tv_usec = 0; }; + enum class ProcessState { +Unknown, +Dead, +DiskSleep, +Idle, +Paging, +Parked, +Running, +Sleeping, +TracedOrStopped, +Zombie, + }; + feg208 wrote: yeah. So if you look at the definition of ELFLinuxPrPsInfo there is a char member `pr_state` that will be something like T or Z or whatever. So we'd need these available to set that assuming we didn't want OS specific codes in there which are very linux specific (I found the mapping in the linux kernel code). Maybe we should move it back though? I mean for the purpose of generating a core the state is always going to be TraceOrStopped in any case. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -254,6 +277,8 @@ class ProcessInstanceInfo : public ProcessInfo { struct timespec m_system_time {}; struct timespec m_cumulative_user_time {}; struct timespec m_cumulative_system_time {}; + int8_t m_nice_value = INT8_MAX; feg208 wrote: yeah. I'll make this change. Especially here since priority can be in a range that has zero near the center https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -12,6 +12,9 @@ #include "lldb/Utility/ProcessInfo.h" #include "gtest/gtest.h" +#include +#include feg208 wrote: yeah. The cmake file enforces a linux-only build as well. However as @jimingham pointed out someone could plausibly move this into a non-linux build. Maybe I should place guards here and below? The functionality is in POSIX I think and my understanding is that windows would conform to POSIX to some degree. But to be honest I know very little about what happens on the windows side of the fence. https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From 18b0d55d1c4e04842e531c7f7e304998f2b2ad4e Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 28 +++ lldb/source/Host/linux/Host.cpp | 45 ++--- lldb/source/Utility/ProcessInfo.cpp | 4 +++ lldb/unittests/Host/linux/HostTest.cpp | 20 +++ 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc..240f78d1c4e4 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -144,6 +145,19 @@ class ProcessInstanceInfo : public ProcessInfo { long int tv_usec = 0; }; + enum class ProcessState { +Unknown, +Dead, +DiskSleep, +Idle, +Paging, +Parked, +Running, +Sleeping, +TracedOrStopped, +Zombie, + }; + ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) @@ -237,6 +251,18 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetPriorityValue() const { return m_priority_value.value(); } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + bool PriorityValueIsValid() const; + + void SetIsZombie(bool is_zombie = true) { m_zombie = is_zombie; } + + bool IsZombie() const { return m_zombie; } + void Dump(Stream &s, UserIDResolver &resolver) const; static void DumpTableHeader(Stream &s, bool show_args, bool verbose); @@ -254,6 +280,8 @@ class ProcessInstanceInfo : public ProcessInfo { struct timespec m_system_time {}; struct timespec m_cumulative_user_time {}; struct timespec m_cumulative_system_time {}; + std::optional m_priority_value = std::nullopt; + bool m_zombie = false; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2..186323393c14 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,18 +37,8 @@ using namespace lldb; using namespace lldb_private; namespace { -enum class ProcessState { - Unknown, - Dead, - DiskSleep, - Idle, - Paging, - Parked, - Running, - Sleeping, - TracedOrStopped, - Zombie, -}; + +using ProcessState = typename ProcessInstanceInfo::ProcessState; constexpr int task_comm_len = 16; @@ -70,6 +60,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // in proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo we adopt the documented + // naming here + long realtime_priority; + long priority; // other things. We don't need them below }; } @@ -91,14 +87,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - &stat_fields.pid, stat_fields.comm, &stat_fields.state, - &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, - &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, - &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, - &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, - &stat_fields.cutime, &stat_fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + &stat_fields.pid, stat_fields.comm, &stat_fields.state, + &stat_fields.ppid, &stat_fields.pgrp, &stat_fields.session, + &stat_fields.tty_nr, &stat_fields.tpgid, &stat_fields.flags, + &stat_fields.minflt, &stat_fields.cminflt, &stat_fields.majflt, + &stat_fields.cmajflt, &stat_fields.utime, &stat_fields.stime, + &stat_fields.cutime, &stat_fields.cstime, + &stat_fields.realtime_priority, &stat_fields.priority) < 0) { return false; } @@ -115,6 +113,11 @@ static bool GetStatusInfo(::pid_t
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -117,6 +118,10 @@ bool ProcessInfo::IsScriptedProcess() const { return m_scripted_metadata_sp && *m_scripted_metadata_sp; } +bool ProcessInstanceInfo::NiceValueIsValid() const { + return m_nice_value >= PRIO_MIN && m_nice_value <= PRIO_MAX; feg208 wrote: I removed this and just made the check to be a value stored in the optional https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -17,6 +17,7 @@ #include #include +#include feg208 wrote: removed https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -237,6 +250,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetNiceValue() const { return m_nice_value; } + + void SetNiceValue(int8_t nice_value) { m_nice_value = nice_value; } + + bool NiceValueIsValid() const; + + void SetIsZombie() { m_zombie = true; } feg208 wrote: There is now https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -237,6 +250,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetNiceValue() const { return m_nice_value; } feg208 wrote: Done. Agreed. I also added a note in the linux specific code. In linuxland priority implies a realtime priority while nice is nice https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -237,6 +250,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + int8_t GetNiceValue() const { return m_nice_value; } feg208 wrote: prpsinfo has pr_nice field to be populated https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h#L99 https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits