Author njs
Recipients Mark.Shannon, deleted0524, ncoghlan, njs, yselivanov
Date 2017-05-25.05:37:14
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1495690634.94.0.421284128478.issue29988@psf.upfronthosting.co.za>
In-reply-to
Content
On further thought, I think the way I'd write a test for this is:

(1) add a testing primitive that waits for N instructions and then injects a SIGINT. Probably this would require tweaking the definition of Py_MakePendingCalls like I described in my previous comment, and then some code like:

int sigint_timebomb(void* count_ptr) {
    intptr_t count = (intptr_t) count_ptr;
    if (count == 0)
        raise(SIGINT);
    else
        Py_AddPendingCall(sigint_timebomb, (void*) (count - 1));
    return 0;
}

(2) write a test like:

reached_crashpad = False
lock = threading.Lock()
i = 0
while not reached_crashpad:
    i += 1
    try:
        sigint_timebomb(i)
        with lock:
            1 + 1
        # this loop keeps executing instructions until any still-armed
        # timebombs go off
        while True:
            reached_crashpad = True
    except KeyboardInterrupt:
        # key invariant: signal can't leave the lock held
        assert not lock.locked()
    else:
        assert False  # can't happen

The idea here is that this sets off SIGINTs at every possible place throughout the execution of the 'with lock', while checking that the lock is always released, and without needing to hard code any information at all about what bytecode the compiler generated.
History
Date User Action Args
2017-05-25 05:37:14njssetrecipients: + njs, ncoghlan, Mark.Shannon, yselivanov, deleted0524
2017-05-25 05:37:14njssetmessageid: <1495690634.94.0.421284128478.issue29988@psf.upfronthosting.co.za>
2017-05-25 05:37:14njslinkissue29988 messages
2017-05-25 05:37:14njscreate