New submission from lincheney <linche...@gmail.com>:

Under unix, when creating a asyncio subprocess, the child process watcher will 
call waitpid() to reap the child, but if you call send_signal() (or terminate() 
or kill() ) on the asyncio subprocess, this will also call waitpid(), causing 
exactly one of these to fail, as you cannot call waitpid() on a PID more than 
once.

If the send_signal() fails, this doesn't seem much of an issue.
If the child process watcher fails however, it sets the returncode to 255 and 
also returns 255 when running wait() and also emits a warning.

I've seen this behaviour with the ThreadedChildWatcher, but possibly other Unix 
child watchers that use waitpid() suffer from the same problem.

The behaviour is racey (it depends on which one completes the waitpid() first), 
but if you try it enough it will appear:
```
import asyncio
import signal

async def main():
    while True:
        proc = await asyncio.create_subprocess_exec('sleep', '0.1')
        await asyncio.sleep(0.1)
        try:
            proc.send_signal(signal.SIGUSR1)
        except ProcessLookupError:
            pass
        assert (await proc.wait() != 255)

asyncio.run(main())

```

The output looks like:
```
Unknown child process pid 1394331, will report returncode 255
Traceback (most recent call last):
  File "/tmp/bob.py", line 14, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in 
run_until_complete
    return future.result()
  File "/tmp/bob.py", line 12, in main
    assert (await proc.wait() != 255)
AssertionError
```

This would be expected behaviour if I were explicitly calling waitpid() myself 
(ie I'm shooting my own foot, so I'd deserve the bad behaviour), but that's not 
the case here nor any other exotic code.

----------
components: asyncio
messages: 389218
nosy: asvetlov, lincheney, yselivanov
priority: normal
severity: normal
status: open
title: With asyncio subprocess, send_signal() and the child process watcher 
will both call waitpid()
type: behavior
versions: Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue43578>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to