77// ===----------------------------------------------------------------------===//
88
99#include " lldb/Host/Host.h"
10- #include " lldb/Host/linux /Support.h"
10+ #include " lldb/Host/posix /Support.h"
1111#include " lldb/Utility/LLDBLog.h"
1212#include " lldb/Utility/Log.h"
1313#include " lldb/Utility/ProcessInfo.h"
1414#include " lldb/Utility/Status.h"
1515#include " llvm/BinaryFormat/XCOFF.h"
16+ #include < sys/proc.h>
1617#include < sys/procfs.h>
1718
1819using namespace llvm ;
@@ -34,67 +35,53 @@ enum class ProcessState {
3435};
3536}
3637
37- static bool GetStatusInfo (::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
38- ProcessState &State, ::pid_t &TracerPid,
39- ::pid_t &Tgid) {
40- Log *log = GetLog (LLDBLog::Host);
41- auto BufferOrError = getProcFile (Pid, " status" );
38+ ProcessInstanceInfo::timespec convert (pr_timestruc64_t t) {
39+ ProcessInstanceInfo::timespec ts;
40+ ts.tv_sec = t.tv_sec ;
41+ ts.tv_usec = t.tv_nsec / 1000 ; // nanos to micros
42+ return ts;
43+ }
44+
45+ static bool GetStatusInfo (::pid_t pid, ProcessInstanceInfo &processInfo,
46+ ProcessState &State) {
47+ struct pstatus pstatusData;
48+ auto BufferOrError = getProcFile (pid, " status" );
4249 if (!BufferOrError)
4350 return false ;
4451
45- llvm::StringRef Rest = BufferOrError.get ()->getBuffer ();
46- while (!Rest.empty ()) {
47- llvm::StringRef Line;
48- std::tie (Line, Rest) = Rest.split (' \n ' );
49- if (Line.consume_front (" Gid:" )) {
50- // Real, effective, saved set, and file system GIDs. Read the first two.
51- Line = Line.ltrim ();
52- uint32_t RGid, EGid;
53- Line.consumeInteger (10 , RGid);
54- Line = Line.ltrim ();
55- Line.consumeInteger (10 , EGid);
56- ProcessInfo.SetGroupID (RGid);
57- ProcessInfo.SetEffectiveGroupID (EGid);
58- } else if (Line.consume_front (" Uid:" )) {
59- // Real, effective, saved set, and file system UIDs. Read the first two.
60- Line = Line.ltrim ();
61- uint32_t RUid, EUid;
62- Line.consumeInteger (10 , RUid);
63- Line = Line.ltrim ();
64- Line.consumeInteger (10 , EUid);
65- ProcessInfo.SetUserID (RUid);
66- ProcessInfo.SetEffectiveUserID (EUid);
67- } else if (Line.consume_front (" PPid:" )) {
68- ::pid_t PPid;
69- Line.ltrim ().consumeInteger (10 , PPid);
70- ProcessInfo.SetParentProcessID (PPid);
71- } else if (Line.consume_front (" State:" )) {
72- State = llvm::StringSwitch<ProcessState>(Line.ltrim ().take_front (1 ))
73- .Case (" D" , ProcessState::DiskSleep)
74- .Case (" I" , ProcessState::Idle)
75- .Case (" R" , ProcessState::Running)
76- .Case (" S" , ProcessState::Sleeping)
77- .CaseLower (" T" , ProcessState::TracedOrStopped)
78- .Case (" W" , ProcessState::Paging)
79- .Case (" P" , ProcessState::Parked)
80- .Case (" X" , ProcessState::Dead)
81- .Case (" Z" , ProcessState::Zombie)
82- .Default (ProcessState::Unknown);
83- if (State == ProcessState::Unknown) {
84- LLDB_LOG (log, " Unknown process state {0}" , Line);
85- }
86- } else if (Line.consume_front (" TracerPid:" )) {
87- Line = Line.ltrim ();
88- Line.consumeInteger (10 , TracerPid);
89- } else if (Line.consume_front (" Tgid:" )) {
90- Line = Line.ltrim ();
91- Line.consumeInteger (10 , Tgid);
92- }
52+ std::unique_ptr<llvm::MemoryBuffer> StatusBuffer = std::move (*BufferOrError);
53+ // Ensure there's enough data for psinfoData
54+ if (StatusBuffer->getBufferSize () < sizeof (pstatusData))
55+ return false ;
56+
57+ std::memcpy (&pstatusData, StatusBuffer->getBufferStart (),
58+ sizeof (pstatusData));
59+ switch (pstatusData.pr_stat ) {
60+ case SIDL:
61+ State = ProcessState::Idle;
62+ break ;
63+ case SACTIVE:
64+ State = ProcessState::Running;
65+ break ;
66+ case SSTOP:
67+ State = ProcessState::TracedOrStopped;
68+ break ;
69+ case SZOMB:
70+ State = ProcessState::Zombie;
71+ break ;
72+ default :
73+ State = ProcessState::Unknown;
74+ break ;
9375 }
76+ processInfo.SetIsZombie (State == ProcessState::Zombie);
77+ processInfo.SetUserTime (convert (pstatusData.pr_utime ));
78+ processInfo.SetSystemTime (convert (pstatusData.pr_stime ));
79+ processInfo.SetCumulativeUserTime (convert (pstatusData.pr_cutime ));
80+ processInfo.SetCumulativeSystemTime (convert (pstatusData.pr_cstime ));
9481 return true ;
9582}
9683
97- static bool GetExePathAndArch (::pid_t pid, ProcessInstanceInfo &process_info) {
84+ static bool GetExePathAndIds (::pid_t pid, ProcessInstanceInfo &process_info) {
9885 struct psinfo psinfoData;
9986 auto BufferOrError = getProcFile (pid, " psinfo" );
10087 if (!BufferOrError)
@@ -107,29 +94,35 @@ static bool GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
10794
10895 std::memcpy (&psinfoData, PsinfoBuffer->getBufferStart (), sizeof (psinfoData));
10996 llvm::StringRef PathRef (&(psinfoData.pr_psargs [0 ]));
110- if (!PathRef.empty ()) {
111- process_info.GetExecutableFile ().SetFile (PathRef, FileSpec::Style::native);
112- ArchSpec arch_spec = ArchSpec ();
113- arch_spec.SetArchitecture (eArchTypeXCOFF, XCOFF::TCPU_PPC64,
114- LLDB_INVALID_CPUTYPE, llvm::Triple::AIX);
115- process_info.SetArchitecture (arch_spec);
116- return true ;
117- }
118- return false ;
97+ if (PathRef.empty ())
98+ return false ;
99+
100+ process_info.GetExecutableFile ().SetFile (PathRef, FileSpec::Style::native);
101+ ArchSpec arch_spec = ArchSpec ();
102+ arch_spec.SetArchitecture (eArchTypeXCOFF, XCOFF::TCPU_PPC64,
103+ LLDB_INVALID_CPUTYPE, llvm::Triple::AIX);
104+ process_info.SetArchitecture (arch_spec);
105+ process_info.SetParentProcessID (psinfoData.pr_ppid );
106+ process_info.SetGroupID (psinfoData.pr_gid );
107+ process_info.SetEffectiveGroupID (psinfoData.pr_egid );
108+ process_info.SetUserID (psinfoData.pr_uid );
109+ process_info.SetEffectiveUserID (psinfoData.pr_euid );
110+ process_info.SetProcessGroupID (psinfoData.pr_pgid );
111+ process_info.SetProcessSessionID (psinfoData.pr_sid );
112+ return true ;
119113}
120114
121115static bool GetProcessAndStatInfo (::pid_t pid,
122116 ProcessInstanceInfo &process_info,
123- ProcessState &State, ::pid_t &tracerpid) {
124- ::pid_t tgid;
125- tracerpid = 0 ;
117+ ProcessState &State) {
126118 process_info.Clear ();
127119 process_info.SetProcessID (pid);
128120
129- if (!GetExePathAndArch (pid, process_info))
121+ // Get Executable path/Arch and Get User and Group IDs.
122+ if (!GetExePathAndIds (pid, process_info))
130123 return false ;
131- // Get User and Group IDs and get tracer pid .
132- if (!GetStatusInfo (pid, process_info, State, tracerpid, tgid ))
124+ // Get process status and timing info .
125+ if (!GetStatusInfo (pid, process_info, State))
133126 return false ;
134127
135128 return true ;
@@ -141,9 +134,8 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
141134}
142135
143136bool Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) {
144- ::pid_t tracerpid;
145137 ProcessState State;
146- return GetProcessAndStatInfo (pid, process_info, State, tracerpid );
138+ return GetProcessAndStatInfo (pid, process_info, State);
147139}
148140
149141Status Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) {
0 commit comments