@@ -201,68 +201,91 @@ def _run_check(self, env: NimpEnvironment):
201201 logging .debug ("\t %s (%s) %s" , ignored_process .exe (), ignored_process .pid , ignored_process .cmdline ())
202202
203203 for process in psutil .process_iter ():
204+ if not process .is_running ():
205+ continue
206+
204207 logging .debug ("Checking process %d" , process .pid )
205208 if process .pid in ignore_process_ids :
206209 logging .debug ("[Process(%d)] ignore process (self, parent or child)" , process .pid )
207210 continue
208211
209212 if current_user is not None :
210- process_user = None
211- try :
212- process_user = process .username ()
213- except psutil .AccessDenied :
214- logging .debug (
215- "[Process(%d)] Failed to retrieve process user" ,
216- process .pid ,
217- )
218- continue
219-
220- if current_user != process_user :
221- logging .debug (
222- "[Process(%d)] ignore process from other user (self: %s, process user: %s)" ,
223- process .pid ,
224- current_user ,
225- process_user ,
226- )
213+ if not _Processes ._process_owned_by_user (process , current_user ):
227214 continue
228215
229216 checked_processes_count += 1
230217 if not _Processes ._process_matches_filters (process , env .filters ):
231218 continue
232219
233- process_executable_path = process .exe ()
234- process_basename = os .path .basename (process_executable_path )
235- if any (p .match (process_basename ) for p in _Processes .PROCESS_IGNORE_PATTERNS ):
236- logging .info ('[Process(%d)] process (%s) will be kept alive' , process .pid , process_executable_path )
220+ try :
221+ process_exe = process .exe ()
222+ except psutil .Error as exc :
223+ logging .debug ('[Process(%d)] failed to retrieve process executable' , process .pid , exc_info = exc )
224+ process_exe = "[UNKOWN]"
225+
226+ if _Processes ._should_ignore_process (process ):
227+ logging .info ('[Process(%d)] process (%s) will be kept alive' , process .pid , process_exe )
237228 continue
238229
239230 problematic_processes .append (process )
240- logging .warning ('[Process(%d)] Found problematic process (%s)' , process .pid , process_executable_path )
241- if (parent_process := process .parent ()) is not None :
242- logging .warning ('\t Parent is %s (%s)' , parent_process .pid , parent_process .exe ())
231+ logging .warning ('[Process(%d)] Found problematic process (%s)' , process .pid , process_exe )
232+ try :
233+ if (parent_process := process .parent ()) is not None :
234+ logging .warning ('\t Parent is %s (%s)' , parent_process .pid , parent_process .exe ())
235+ except psutil .Error as exc :
236+ logging .debug (
237+ '[Process(%d)] failed to get parent process information for process "%s"' ,
238+ process .pid , process_exe , exc_info = exc
239+ )
243240
244241 logging .info ('%d processes checked.' , checked_processes_count )
245242 if not problematic_processes :
246243 # no problematic processes running, nothing to do.
247244 return True
248245
246+ sleep_time = 5.0
249247 if not env .kill :
250248 # Wait a bit, give a chance to problematic processes to end,
251249 # even if not killed
252- sleep_time = 5.0
250+
253251 logging .debug ("Wait %.2fs. Giving a chance to processes for a natural exit" , sleep_time )
254252 time .sleep (sleep_time )
255253 else :
256254 for p in problematic_processes :
257- logging .info ('Requesting process %s termination' , p .pid )
258- p .terminate ()
259- _ , alive = psutil .wait_procs (problematic_processes , timeout = 5 )
255+ if p .is_running ():
256+ logging .info ('Requesting process %s termination' , p .pid )
257+ p .terminate ()
258+ _ , alive = psutil .wait_procs (problematic_processes , timeout = sleep_time )
260259 for p in alive :
261- logging .info ('Process %s not terminated. Send kill.' , p .pid )
262- p .kill ()
260+ if p .is_running ():
261+ logging .info ('Process %s not terminated. Send kill.' , p .pid )
262+ p .kill ()
263263
264264 return False
265265
266+ @staticmethod
267+ def _process_owned_by_user (process : psutil .Process , username : str ):
268+ try :
269+ process_user = process .username ()
270+ except psutil .Error as exception :
271+ logging .debug (
272+ "[Process(%d)] Failed to retrieve process user" ,
273+ process .pid ,
274+ exc_info = exception ,
275+ )
276+ return False
277+
278+ is_same_user = username == process_user
279+
280+ logging .debug (
281+ "[Process(%d)] ignore process from other user (self: %s, process user: %s)" ,
282+ process .pid ,
283+ username ,
284+ process_user ,
285+ )
286+
287+ return is_same_user
288+
266289 @staticmethod
267290 def _process_matches_filters (process : psutil .Process , filters : list [str ]) -> bool :
268291 """Returns True if the process should be filtered out"""
@@ -293,14 +316,27 @@ def _process_matches_filters(process: psutil.Process, filters: list[str]) -> boo
293316 popen_file .path ,
294317 )
295318 return True
296- except psutil .AccessDenied as exc :
297- logging .debug ("[Process(%d)] Access Denied !" , process .pid , exc_info = exc )
319+ except psutil .Error as exc :
320+ logging .debug ("[Process(%d)] Error !" , process .pid , exc_info = exc )
298321 # failed to access a property of the process,
299322 # assume it does not match to be safe
300323 return False
301324
302325 return False
303326
327+ @staticmethod
328+ def _should_ignore_process (process : psutil .Process ) -> bool :
329+ try :
330+ process_executable_path = process .exe ()
331+ process_basename = os .path .basename (process_executable_path )
332+ except psutil .Error :
333+ logging .debug (
334+ "[Process(%d)] failed to retrieve process exe/basename" ,
335+ process .pid ,
336+ )
337+ return True
338+ return any (p .match (process_basename ) for p in _Processes .PROCESS_IGNORE_PATTERNS )
339+
304340
305341class _Disks (CheckCommand ):
306342 def __init__ (self ):
0 commit comments