Stefan Schuermans commited on 2021-03-09 20:37:39
Showing 4 changed files, with 26 additions and 21 deletions.
A child process of fork() does not have a begin event and thus, nothing was known about its parent. Adding the ppid to the end event establishes the relationship to its parent process.
... | ... |
@@ -34,6 +34,10 @@ int uptev_proc_end(void **data, size_t *size) { |
34 | 34 |
|
35 | 35 |
struct _Uproctrace__ProcEnd proc_end = UPROCTRACE__PROC_END__INIT; |
36 | 36 |
proc_end.pid = getpid(); |
37 |
+ // ppid also in end event because child of fork() has no begin event |
|
38 |
+ proc_end.has_ppid = 1; |
|
39 |
+ proc_end.ppid = getppid(); |
|
40 |
+ |
|
37 | 41 |
proc_end.cpu_time = &cpu_time; |
38 | 42 |
|
39 | 43 |
struct rusage usage; |
... | ... |
@@ -82,6 +82,7 @@ class ProcBeginOrEnd(BaseEvent): |
82 | 82 |
super().__init__(pb2_ev) |
83 | 83 |
self._process = None |
84 | 84 |
self._pid = None |
85 |
+ self._ppid = None |
|
85 | 86 |
|
86 | 87 |
@property |
87 | 88 |
def pid(self) -> int: |
... | ... |
@@ -90,6 +91,13 @@ class ProcBeginOrEnd(BaseEvent): |
90 | 91 |
""" |
91 | 92 |
return self._pid |
92 | 93 |
|
94 |
+ @property |
|
95 |
+ def ppid(self) -> int: |
|
96 |
+ """ |
|
97 |
+ ID of parent process. |
|
98 |
+ """ |
|
99 |
+ return self._ppid |
|
100 |
+ |
|
93 | 101 |
@property |
94 | 102 |
def process(self): |
95 | 103 |
""" |
... | ... |
@@ -123,13 +131,6 @@ class ProcBegin(ProcBeginOrEnd): |
123 | 131 |
self._environ = self._pb2GetStringList( |
124 | 132 |
p_b.environ) if p_b.HasField('environ') else None |
125 | 133 |
|
126 |
- @property |
|
127 |
- def ppid(self) -> int: |
|
128 |
- """ |
|
129 |
- ID of parent process. |
|
130 |
- """ |
|
131 |
- return self._ppid |
|
132 |
- |
|
133 | 134 |
@property |
134 | 135 |
def exe(self) -> str: |
135 | 136 |
""" |
... | ... |
@@ -173,6 +174,7 @@ class ProcEnd(ProcBeginOrEnd): |
173 | 174 |
super().__init__(pb2_ev) |
174 | 175 |
p_e = pb2_ev.proc_end |
175 | 176 |
self._pid = p_e.pid |
177 |
+ self._ppid = p_e.ppid if p_e.HasField('ppid') else None |
|
176 | 178 |
self._cpu_time = self._pb2GetTimespec( |
177 | 179 |
p_e.cpu_time) if p_e.HasField('cpu_time') else None |
178 | 180 |
self._user_time = self._pb2GetTimespec( |
... | ... |
@@ -188,13 +190,6 @@ class ProcEnd(ProcBeginOrEnd): |
188 | 190 |
self._n_v_csw = p_e.n_v_csw if p_e.HasField('n_v_csw') else None |
189 | 191 |
self._n_iv_csw = p_e.n_iv_csw if p_e.HasField('n_iv_csw') else None |
190 | 192 |
|
191 |
- @property |
|
192 |
- def pid(self) -> int: |
|
193 |
- """ |
|
194 |
- ID of process. |
|
195 |
- """ |
|
196 |
- return self._pid |
|
197 |
- |
|
198 | 193 |
@property |
199 | 194 |
def cpu_time(self) -> float: |
200 | 195 |
""" |
... | ... |
@@ -171,20 +171,20 @@ class Process(): |
171 | 171 |
""" |
172 | 172 |
Linux process ID. |
173 | 173 |
""" |
174 |
- if self._begin is not None: |
|
175 |
- return self._begin.pid |
|
176 |
- if self._end is not None: |
|
177 |
- return self._end.pid |
|
178 |
- return None |
|
174 |
+ return self._pid |
|
179 | 175 |
|
180 | 176 |
@property |
181 | 177 |
def ppid(self): |
182 | 178 |
""" |
183 | 179 |
Linux process ID of parent process. |
184 | 180 |
""" |
185 |
- if self._begin is None: |
|
186 |
- return None |
|
181 |
+ if self._begin is not None: |
|
182 |
+ if self._begin.ppid is not None: |
|
187 | 183 |
return self._begin.ppid |
184 |
+ if self._end is not None: |
|
185 |
+ if self._end.ppid: |
|
186 |
+ return self._end.ppid |
|
187 |
+ return None |
|
188 | 188 |
|
189 | 189 |
@property |
190 | 190 |
def proc_id(self): |
... | ... |
@@ -355,6 +355,10 @@ class Processes(uproctrace.parse.Visitor): |
355 | 355 |
# set end event of process and process of end event |
356 | 356 |
proc.setEnd(proc_end) |
357 | 357 |
proc_end.setProcess(proc) |
358 |
+ # add process to parent if available |
|
359 |
+ if proc_end.ppid is not None: |
|
360 |
+ parent = self._getProcess(proc_end.ppid) |
|
361 |
+ self._parentChild(parent, proc) |
|
358 | 362 |
# remove process from dict of current processes (it ended) |
359 | 363 |
# - it is guaranteed to be in it, because it came from _getProcess() |
360 | 364 |
del self._current_processes[proc_end.pid] |
... | ... |
@@ -22,6 +22,8 @@ message proc_begin { |
22 | 22 |
|
23 | 23 |
message proc_end { |
24 | 24 |
required int32 pid = 1; |
25 |
+ optional int32 ppid = 12; ///< pid of parent process (important for fork(), |
|
26 |
+ ///< because child of fork has no proc_begin event) |
|
25 | 27 |
/// fields from clock_gettime |
26 | 28 |
//@{ |
27 | 29 |
optional timespec cpu_time = 2; ///< CPU time usage |
28 | 30 |