def strace(work, syscalls, timeout=10):
    """Runs strace whilst executing the function work() in the current process,
    captures the listed syscalls (list of strings). Takes an optional timeout in
    seconds, default is 10, if this is exceeded the process will be sent a
    SIGKILL. Returns a list of lines that are output by strace.
    """

    # Open a tmpfile for strace to write into.
    with tempfile.NamedTemporaryFile('w+t') as ntf:

        parent_pid = os.getpid()
        strace_binary = shutil.which('strace')
        if strace_binary is None:
            raise ValueError("No valid 'strace' binary could be found")
        cmd = [strace_binary, # strace
               '-q', # quietly (no attach/detach print out)
               '-p', str(parent_pid), # this PID
               '-e', ','.join(syscalls), # these syscalls
               '-o', ntf.name] # put output into this file

        # redirect stdout, stderr is handled by the `-o` flag to strace.
        popen = subprocess.Popen(cmd, stdout=subprocess.PIPE,)
        strace_pid = popen.pid
        thread_timeout = threading.Timer(timeout, popen.kill)
        thread_timeout.start()

        def check_return(problem=''):
            ret = popen.returncode
            if ret != 0:
                msg = ("strace exited non-zero, process return code was:"
                       f"{ret}. {problem}")
                raise RuntimeError(msg)
        try:
            # push the communication onto a thread so it doesn't block.
            # start comms thread
            thread_comms = threading.Thread(target=popen.communicate)
            thread_comms.start()

            # do work
            work()
            # Flush the output buffer file
            ntf.flush()
            # interrupt the strace process to stop it if it's still running
            if popen.poll() is None:
                os.kill(strace_pid, signal.SIGINT)
            else:
                # it's not running, probably an issue, raise
                problem="If this is SIGKILL, increase the timeout?"
                check_return(problem)
            # Make sure the return code is 0, SIGINT to detach is considered
            # a successful exit.
            popen.wait()
            check_return()
            # collect the data
            strace_data = ntf.readlines()
        finally:
            # join communication, should be stopped now as process has
            # exited
            thread_comms.join()
            # should be stopped already
            thread_timeout.cancel()

    return strace_data
Runs strace whilst executing the function work() in the current process,
    captures the listed syscalls (list of strings). Takes an optional timeout in
    seconds, default is 10, if this is exceeded the process will be sent a
    SIGKILL. Returns a list of lines that are output by strace.
    
numba/tests/support.py