0

I have this code:

subprocess.run(['perf', 'record', 'yes'], timeout=1)

This code kills the perf subprocess after 1 second; however, its child yes process is left running.

I expected that this code would behave similarly to running perf record yes in a terminal and Ctrl+C'ing it after 1 second. When you do that, the Ctrl+C kills both perf and yes.

How can I write the code such that both the perf child process and the yes grandchild process are killed?

Kerrick Staley
  • 1,583
  • 2
  • 20
  • 28
  • I think this question was previously asked at https://stackoverflow.com/questions/71622530/how-to-kill-perf-record-with-python-subprocess, which hasn't received an answer. I think that question does not have a MRE and has a lot of extraneous detail. I decided to re-ask the question in hopes of getting an answer this time. – Kerrick Staley Jul 05 '23 at 14:52

1 Answers1

0

I think that this happens because subprocess.run calls Popen.kill when the timeout expires, which sends a SIGKILL signal to the perf subprocess. This doesn't give the perf process time to do any clean-up, so it leaves its child process running and may also write a malformed output file.

You can instead use Popen.terminate to send a SIGTERM, which gives the subprocess a chance to terminate.

proc = subprocess.Popen(['perf', 'record', 'yes'])
try:
    proc.wait(timeout=1)
except subprocess.TimeoutExpired:
    proc.terminate()

I'm not aware of a one-liner to achieve this.

Kerrick Staley
  • 1,583
  • 2
  • 20
  • 28