prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  get_children_pids_of_thread(): process.py:57:get_children_pids_of_thread:ProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'
  Here's another Fedora report.
  
  https://bugzilla.redhat.com/show_bug.cgi?id=1686988
  
  cmdline:        /usr/bin/python3 -s /usr/bin/lutris-wrapper 0 0 /home/u13881/.local/share/lutris/runtime/winetricks/winetricks --unattended
  crash_function: get_children_pids_of_thread
  exception_type: ProcessLookupError
  executable:     /usr/bin/lutris-wrapper
  interpreter:    python3-3.7.2-4.fc29.x86_64
  kernel:         4.20.13-200.fc29.x86_64
  runlevel:       N 5
  type:           Python3
  uid:            1000
  
  Truncated backtrace:
  process.py:57:get_children_pids_of_thread:ProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'
  
  Traceback (most recent call last):
    File "/usr/bin/lutris-wrapper", line 110, in <module>
      main()
    File "/usr/bin/lutris-wrapper", line 91, in main
      if not monitor.refresh_process_status():
    File "/usr/lib/python3.7/site-packages/lutris/util/monitor.py", line 98, in refresh_process_status
      for child in self.iter_children(Process(os.getpid())):
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 20, in __init__
      self.get_children()
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 67, in get_children
      self.children.append(Process(child_pid, parent=self))
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 20, in __init__
      self.get_children()
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 67, in get_children
      self.children.append(Process(child_pid, parent=self))
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 20, in __init__
      self.get_children()
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 66, in get_children
      for child_pid in self.get_children_pids_of_thread(tid):
    File "/usr/lib/python3.7/site-packages/lutris/util/process.py", line 57, in get_children_pids_of_thread
      with open(children_path) as children_file:
  ProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'
  
  Local variables in innermost frame:
  self: Process 25892
  tid: '25892'
  children_path: '/proc/25892/task/25892/children'
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lutris/util/process.py`
  Content:
  ```
  1 """Class to manipulate a process"""
  2 import os
  3 from lutris.util.log import logger
  4 from lutris.util.system import path_exists
  5 
  6 
  7 class InvalidPid(Exception):
  8     """Exception raised when an operation on a non-existent PID is called"""
  9 
  10 
  11 class Process:
  12     """Python abstraction a Linux process"""
  13     def __init__(self, pid, parent=None):
  14         try:
  15             self.pid = int(pid)
  16         except ValueError:
  17             raise InvalidPid("'%s' is not a valid pid" % pid)
  18         self.children = []
  19         self.parent = None
  20         self.get_children()
  21 
  22     def __repr__(self):
  23         return "Process {}".format(self.pid)
  24 
  25     def __str__(self):
  26         return "{} ({}:{})".format(self.name, self.pid, self.state)
  27 
  28     def get_stat(self, parsed=True):
  29         stat_filename = "/proc/{}/stat".format(self.pid)
  30         if not path_exists(stat_filename):
  31             return None
  32         with open(stat_filename) as stat_file:
  33             try:
  34                 _stat = stat_file.readline()
  35             except (ProcessLookupError, FileNotFoundError):
  36                 logger.warning("Unable to read stat for process %s", self.pid)
  37                 return None
  38         if parsed:
  39             return _stat[_stat.rfind(")") + 1:].split()
  40         return _stat
  41 
  42     def get_thread_ids(self):
  43         """Return a list of thread ids opened by process."""
  44         basedir = "/proc/{}/task/".format(self.pid)
  45         if os.path.isdir(basedir):
  46             try:
  47                 return [tid for tid in os.listdir(basedir)]
  48             except FileNotFoundError:
  49                 return []
  50         else:
  51             return []
  52 
  53     def get_children_pids_of_thread(self, tid):
  54         """Return pids of child processes opened by thread `tid` of process."""
  55         children_path = "/proc/{}/task/{}/children".format(self.pid, tid)
  56         try:
  57             with open(children_path) as children_file:
  58                 children_content = children_file.read()
  59         except FileNotFoundError:
  60             children_content = ""
  61         return children_content.strip().split()
  62 
  63     def get_children(self):
  64         self.children = []
  65         for tid in self.get_thread_ids():
  66             for child_pid in self.get_children_pids_of_thread(tid):
  67                 self.children.append(Process(child_pid, parent=self))
  68 
  69     @property
  70     def name(self):
  71         """Filename of the executable."""
  72         _stat = self.get_stat(parsed=False)
  73         if _stat:
  74             return _stat[_stat.find("(") + 1:_stat.rfind(")")]
  75         return None
  76 
  77     @property
  78     def state(self):
  79         """One character from the string "RSDZTW" where R is running, S is
  80         sleeping in an interruptible wait, D is waiting in uninterruptible disk
  81         sleep, Z is zombie, T is traced or stopped (on a signal), and W is
  82         paging.
  83         """
  84         _stat = self.get_stat()
  85         if _stat:
  86             return _stat[0]
  87         return None
  88 
  89     @property
  90     def cmdline(self):
  91         """Return command line used to run the process `pid`."""
  92         cmdline_path = "/proc/{}/cmdline".format(self.pid)
  93         with open(cmdline_path) as cmdline_file:
  94             _cmdline = cmdline_file.read().replace("\x00", " ")
  95         return _cmdline
  96 
  97     @property
  98     def cwd(self):
  99         """Return current working dir of process"""
  100         cwd_path = "/proc/%d/cwd" % int(self.pid)
  101         return os.readlink(cwd_path)
  102
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lutris/util/process.py b/lutris/util/process.py
  --- a/lutris/util/process.py
  +++ b/lutris/util/process.py
  @@ -56,7 +56,7 @@
           try:
               with open(children_path) as children_file:
                   children_content = children_file.read()
  -        except FileNotFoundError:
  +        except (FileNotFoundError, ProcessLookupError):
               children_content = ""
           return children_content.strip().split()
  
verification_info: {"golden_diff": "diff --git a/lutris/util/process.py b/lutris/util/process.py\n--- a/lutris/util/process.py\n+++ b/lutris/util/process.py\n@@ -56,7 +56,7 @@\n         try:\n             with open(children_path) as children_file:\n                 children_content = children_file.read()\n-        except FileNotFoundError:\n+        except (FileNotFoundError, ProcessLookupError):\n             children_content = \"\"\n         return children_content.strip().split()\n", "issue": "get_children_pids_of_thread(): process.py:57:get_children_pids_of_thread:ProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'\nHere's another Fedora report.\r\n\r\nhttps://bugzilla.redhat.com/show_bug.cgi?id=1686988\r\n\r\ncmdline:        /usr/bin/python3 -s /usr/bin/lutris-wrapper 0 0 /home/u13881/.local/share/lutris/runtime/winetricks/winetricks --unattended\r\ncrash_function: get_children_pids_of_thread\r\nexception_type: ProcessLookupError\r\nexecutable:     /usr/bin/lutris-wrapper\r\ninterpreter:    python3-3.7.2-4.fc29.x86_64\r\nkernel:         4.20.13-200.fc29.x86_64\r\nrunlevel:       N 5\r\ntype:           Python3\r\nuid:            1000\r\n\r\nTruncated backtrace:\r\nprocess.py:57:get_children_pids_of_thread:ProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/bin/lutris-wrapper\", line 110, in <module>\r\n    main()\r\n  File \"/usr/bin/lutris-wrapper\", line 91, in main\r\n    if not monitor.refresh_process_status():\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/monitor.py\", line 98, in refresh_process_status\r\n    for child in self.iter_children(Process(os.getpid())):\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 20, in __init__\r\n    self.get_children()\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 67, in get_children\r\n    self.children.append(Process(child_pid, parent=self))\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 20, in __init__\r\n    self.get_children()\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 67, in get_children\r\n    self.children.append(Process(child_pid, parent=self))\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 20, in __init__\r\n    self.get_children()\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 66, in get_children\r\n    for child_pid in self.get_children_pids_of_thread(tid):\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/process.py\", line 57, in get_children_pids_of_thread\r\n    with open(children_path) as children_file:\r\nProcessLookupError: [Errno 3] No such process: '/proc/25892/task/25892/children'\r\n\r\nLocal variables in innermost frame:\r\nself: Process 25892\r\ntid: '25892'\r\nchildren_path: '/proc/25892/task/25892/children'\n", "before_files": [{"content": "\"\"\"Class to manipulate a process\"\"\"\nimport os\nfrom lutris.util.log import logger\nfrom lutris.util.system import path_exists\n\n\nclass InvalidPid(Exception):\n    \"\"\"Exception raised when an operation on a non-existent PID is called\"\"\"\n\n\nclass Process:\n    \"\"\"Python abstraction a Linux process\"\"\"\n    def __init__(self, pid, parent=None):\n        try:\n            self.pid = int(pid)\n        except ValueError:\n            raise InvalidPid(\"'%s' is not a valid pid\" % pid)\n        self.children = []\n        self.parent = None\n        self.get_children()\n\n    def __repr__(self):\n        return \"Process {}\".format(self.pid)\n\n    def __str__(self):\n        return \"{} ({}:{})\".format(self.name, self.pid, self.state)\n\n    def get_stat(self, parsed=True):\n        stat_filename = \"/proc/{}/stat\".format(self.pid)\n        if not path_exists(stat_filename):\n            return None\n        with open(stat_filename) as stat_file:\n            try:\n                _stat = stat_file.readline()\n            except (ProcessLookupError, FileNotFoundError):\n                logger.warning(\"Unable to read stat for process %s\", self.pid)\n                return None\n        if parsed:\n            return _stat[_stat.rfind(\")\") + 1:].split()\n        return _stat\n\n    def get_thread_ids(self):\n        \"\"\"Return a list of thread ids opened by process.\"\"\"\n        basedir = \"/proc/{}/task/\".format(self.pid)\n        if os.path.isdir(basedir):\n            try:\n                return [tid for tid in os.listdir(basedir)]\n            except FileNotFoundError:\n                return []\n        else:\n            return []\n\n    def get_children_pids_of_thread(self, tid):\n        \"\"\"Return pids of child processes opened by thread `tid` of process.\"\"\"\n        children_path = \"/proc/{}/task/{}/children\".format(self.pid, tid)\n        try:\n            with open(children_path) as children_file:\n                children_content = children_file.read()\n        except FileNotFoundError:\n            children_content = \"\"\n        return children_content.strip().split()\n\n    def get_children(self):\n        self.children = []\n        for tid in self.get_thread_ids():\n            for child_pid in self.get_children_pids_of_thread(tid):\n                self.children.append(Process(child_pid, parent=self))\n\n    @property\n    def name(self):\n        \"\"\"Filename of the executable.\"\"\"\n        _stat = self.get_stat(parsed=False)\n        if _stat:\n            return _stat[_stat.find(\"(\") + 1:_stat.rfind(\")\")]\n        return None\n\n    @property\n    def state(self):\n        \"\"\"One character from the string \"RSDZTW\" where R is running, S is\n        sleeping in an interruptible wait, D is waiting in uninterruptible disk\n        sleep, Z is zombie, T is traced or stopped (on a signal), and W is\n        paging.\n        \"\"\"\n        _stat = self.get_stat()\n        if _stat:\n            return _stat[0]\n        return None\n\n    @property\n    def cmdline(self):\n        \"\"\"Return command line used to run the process `pid`.\"\"\"\n        cmdline_path = \"/proc/{}/cmdline\".format(self.pid)\n        with open(cmdline_path) as cmdline_file:\n            _cmdline = cmdline_file.read().replace(\"\\x00\", \" \")\n        return _cmdline\n\n    @property\n    def cwd(self):\n        \"\"\"Return current working dir of process\"\"\"\n        cwd_path = \"/proc/%d/cwd\" % int(self.pid)\n        return os.readlink(cwd_path)\n", "path": "lutris/util/process.py"}], "after_files": [{"content": "\"\"\"Class to manipulate a process\"\"\"\nimport os\nfrom lutris.util.log import logger\nfrom lutris.util.system import path_exists\n\n\nclass InvalidPid(Exception):\n    \"\"\"Exception raised when an operation on a non-existent PID is called\"\"\"\n\n\nclass Process:\n    \"\"\"Python abstraction a Linux process\"\"\"\n    def __init__(self, pid, parent=None):\n        try:\n            self.pid = int(pid)\n        except ValueError:\n            raise InvalidPid(\"'%s' is not a valid pid\" % pid)\n        self.children = []\n        self.parent = None\n        self.get_children()\n\n    def __repr__(self):\n        return \"Process {}\".format(self.pid)\n\n    def __str__(self):\n        return \"{} ({}:{})\".format(self.name, self.pid, self.state)\n\n    def get_stat(self, parsed=True):\n        stat_filename = \"/proc/{}/stat\".format(self.pid)\n        if not path_exists(stat_filename):\n            return None\n        with open(stat_filename) as stat_file:\n            try:\n                _stat = stat_file.readline()\n            except (ProcessLookupError, FileNotFoundError):\n                logger.warning(\"Unable to read stat for process %s\", self.pid)\n                return None\n        if parsed:\n            return _stat[_stat.rfind(\")\") + 1:].split()\n        return _stat\n\n    def get_thread_ids(self):\n        \"\"\"Return a list of thread ids opened by process.\"\"\"\n        basedir = \"/proc/{}/task/\".format(self.pid)\n        if os.path.isdir(basedir):\n            try:\n                return [tid for tid in os.listdir(basedir)]\n            except FileNotFoundError:\n                return []\n        else:\n            return []\n\n    def get_children_pids_of_thread(self, tid):\n        \"\"\"Return pids of child processes opened by thread `tid` of process.\"\"\"\n        children_path = \"/proc/{}/task/{}/children\".format(self.pid, tid)\n        try:\n            with open(children_path) as children_file:\n                children_content = children_file.read()\n        except (FileNotFoundError, ProcessLookupError):\n            children_content = \"\"\n        return children_content.strip().split()\n\n    def get_children(self):\n        self.children = []\n        for tid in self.get_thread_ids():\n            for child_pid in self.get_children_pids_of_thread(tid):\n                self.children.append(Process(child_pid, parent=self))\n\n    @property\n    def name(self):\n        \"\"\"Filename of the executable.\"\"\"\n        _stat = self.get_stat(parsed=False)\n        if _stat:\n            return _stat[_stat.find(\"(\") + 1:_stat.rfind(\")\")]\n        return None\n\n    @property\n    def state(self):\n        \"\"\"One character from the string \"RSDZTW\" where R is running, S is\n        sleeping in an interruptible wait, D is waiting in uninterruptible disk\n        sleep, Z is zombie, T is traced or stopped (on a signal), and W is\n        paging.\n        \"\"\"\n        _stat = self.get_stat()\n        if _stat:\n            return _stat[0]\n        return None\n\n    @property\n    def cmdline(self):\n        \"\"\"Return command line used to run the process `pid`.\"\"\"\n        cmdline_path = \"/proc/{}/cmdline\".format(self.pid)\n        with open(cmdline_path) as cmdline_file:\n            _cmdline = cmdline_file.read().replace(\"\\x00\", \" \")\n        return _cmdline\n\n    @property\n    def cwd(self):\n        \"\"\"Return current working dir of process\"\"\"\n        cwd_path = \"/proc/%d/cwd\" % int(self.pid)\n        return os.readlink(cwd_path)\n", "path": "lutris/util/process.py"}]}