pychroot icon indicating copy to clipboard operation
pychroot copied to clipboard

Process leak in nested context managers and exception handling

Open cmatsuoka opened this issue 4 years ago • 2 comments

I tried to run pychroot 0.10.4 inside a context manager that mounts and umounts a filesystem using subprocess.run, and the result is odd: the unmount call fails because the filesystem is busy, and the context ending method is called multiple times. The same thing happens when calling pychroot inside an equivalent try/finally block.

My initial attempt was on a filesystem containing a valid OS tree, but this simpler example illustrates what's happening:

print("mount")
subprocess.run(["/bin/mount", "-ttmpfs", "none", "/mnt"])

try:
    with contextlib.suppress(SystemExit), pychroot.Chroot("/mnt"):
        pass
finally:
    print("finally umount")
    subprocess.run(["/bin/umount", "/mnt"])

The snippet above returns:

mount
finally umount
umount: /mnt: target is busy.
finally umount
Traceback (most recent call last):
  File "./w2.py", line 16, in <module>
    subprocess.run(["/bin/umount", "/mnt"])
  File "/usr/lib/python3.8/subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1637, in _execute_child
    self.pid = _posixsubprocess.fork_exec(
OSError: [Errno 12] Cannot allocate memory
finally umount

Note that the finally block runs three times and actually works in the third attempt, but the result is very ugly. Is that a known problem or expected behavior when using pychroot? Any advice on how to handle this situation?

cmatsuoka avatar Mar 16 '21 20:03 cmatsuoka

The reason for the multiple finally handlers is that they're running in different processes, so exiting those that are not the one we were previously running seems to solve this issue. Thanks @cjp256 for investigating this!

cmatsuoka avatar Mar 16 '21 22:03 cmatsuoka

Well, ideally this process leak should be handled internally by pychroot so I'll keep this open.

cmatsuoka avatar Mar 16 '21 22:03 cmatsuoka