Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

locks cannot be interrupted on OpenBSD #64763

Closed
rpointel mannequin opened this issue Feb 8, 2014 · 15 comments
Closed

locks cannot be interrupted on OpenBSD #64763

rpointel mannequin opened this issue Feb 8, 2014 · 15 comments
Labels
tests Tests in the Lib/test dir

Comments

@rpointel
Copy link
Mannequin

rpointel mannequin commented Feb 8, 2014

BPO 20564
Nosy @vstinner
Files
  • interrupt_lock_acquire.py
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2014-02-18.08:21:18.749>
    created_at = <Date 2014-02-08.18:19:44.602>
    labels = ['tests']
    title = 'locks cannot be interrupted on OpenBSD'
    updated_at = <Date 2014-02-18.08:36:18.166>
    user = 'https://bugs.python.org/rpointel'

    bugs.python.org fields:

    activity = <Date 2014-02-18.08:36:18.166>
    actor = 'rpointel'
    assignee = 'none'
    closed = True
    closed_date = <Date 2014-02-18.08:21:18.749>
    closer = 'vstinner'
    components = ['Tests']
    creation = <Date 2014-02-08.18:19:44.602>
    creator = 'rpointel'
    dependencies = []
    files = ['34054']
    hgrepos = []
    issue_num = 20564
    keywords = []
    message_count = 15.0
    messages = ['210672', '210678', '210682', '210684', '210685', '210995', '210996', '211017', '211051', '211057', '211061', '211462', '211483', '211485', '211490']
    nosy_count = 4.0
    nosy_names = ['vstinner', 'neologix', 'python-dev', 'rpointel']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue20564'
    versions = ['Python 3.3', 'Python 3.4']

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 8, 2014

    Hi,

    I have 2 tests which "failed" on OpenBSD (tested on i386, amd64 and sparc64) in:

    • test_threadsignals.py/test_lock_acquire_interruption
    • test_threadsignals.py/test_rlock_acquire_interruption

    ======================================================================
    FAIL: test_lock_acquire_interruption (main.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "Lib/test/test_threadsignals.py", line 94, in test_lock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.020112991333008 not less than 3.0

    ======================================================================
    FAIL: test_rlock_acquire_interruption (main.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "Lib/test/test_threadsignals.py", line 122, in test_rlock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.0101478099823 not less than 3.0

    On the 3 machines it took ~ 5sec.
    I'm asking why it's 3 seconds by default in the tests? Could we modify the value to 6 instead of 3, is it acceptable?

    Thanks for your response,

    Remi.

    @rpointel rpointel mannequin added the tests Tests in the Lib/test dir label Feb 8, 2014
    @neologix
    Copy link
    Mannequin

    neologix mannequin commented Feb 8, 2014

    I'm asking why it's 3 seconds by default in the tests?
    Could we modify the value to 6 instead of 3, is it acceptable?

    No, see this comment:
    """
    self.assertRaises(KeyboardInterrupt, lock.acquire, timeout=5)
    dt = time.time() - t1
    # Checking that KeyboardInterrupt was raised is not sufficient.
    # We want to assert that lock.acquire() was interrupted because
    # of the signal, not that the signal handler was called immediately
    # after timeout return of lock.acquire() (which can fool assertRaises).
    """

    5s corresponds exactly to the timeout passed to acquire(), which means that it didn't get interrupted, which is precisely the goal of the test.

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 8, 2014

    arf, sorry for the noise... I didn't seen this.

    @vstinner
    Copy link
    Member

    vstinner commented Feb 8, 2014

    What is your OpenBSD version? Before 5.2, there were many issues with signals.

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 8, 2014

    I'm in -current (5.5-beta).

    @neologix
    Copy link
    Mannequin

    neologix mannequin commented Feb 11, 2014

    So this looks like a bug.

    When running the test, is faulthandler enabled (--timeout option)?

    @neologix
    Copy link
    Mannequin

    neologix mannequin commented Feb 11, 2014

    So this looks like a bug.

    I mean an OpenBSD bug.

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 11, 2014

    Thanks for your response.

    When running the test, is faulthandler enabled (--timeout option)?

    It seems yes:

    #############################################################################################
    $ PYTHONPATH=. ./python Tools/scripts/run_tests.py -j 1 -W --timeout=3600 test_threadsignals
    /home/remi/dev/cpython/python -W default -bb -E -R -m test -r -w -u all,-largefile,-audio,-gui -j 1 -W --timeout=3600 test_threadsignals
    Using random seed 8501335
    [1/1] test_threadsignals
    test_interrupted_timed_acquire (test.test_threadsignals.ThreadSignals) ... ok
    test_lock_acquire_interruption (test.test_threadsignals.ThreadSignals) ... FAIL
    test_lock_acquire_retries_on_intr (test.test_threadsignals.ThreadSignals) ... ok
    test_rlock_acquire_interruption (test.test_threadsignals.ThreadSignals) ... FAIL
    test_rlock_acquire_retries_on_intr (test.test_threadsignals.ThreadSignals) ... ok
    test_signals (test.test_threadsignals.ThreadSignals) ... ok

    ======================================================================
    FAIL: test_lock_acquire_interruption (test.test_threadsignals.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/home/remi/dev/cpython/Lib/test/test_threadsignals.py", line 94, in test_lock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.019763469696045 not less than 3.0

    ======================================================================
    FAIL: test_rlock_acquire_interruption (test.test_threadsignals.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/home/remi/dev/cpython/Lib/test/test_threadsignals.py", line 122, in test_rlock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.020080804824829 not less than 3.0

    Ran 6 tests in 13.295s

    FAILED (failures=2)
    test test_threadsignals failed
    1 test failed:
    test_threadsignals
    Re-running failed tests in verbose mode
    Re-running test 'test_threadsignals' in verbose mode
    test_interrupted_timed_acquire (test.test_threadsignals.ThreadSignals) ... ok
    test_lock_acquire_interruption (test.test_threadsignals.ThreadSignals) ... FAIL
    test_lock_acquire_retries_on_intr (test.test_threadsignals.ThreadSignals) ... ok
    test_rlock_acquire_interruption (test.test_threadsignals.ThreadSignals) ... FAIL
    test_rlock_acquire_retries_on_intr (test.test_threadsignals.ThreadSignals) ... ok
    test_signals (test.test_threadsignals.ThreadSignals) ... ok

    ======================================================================
    FAIL: test_lock_acquire_interruption (test.test_threadsignals.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/home/remi/dev/cpython/Lib/test/test_threadsignals.py", line 94, in test_lock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.019940614700317 not less than 3.0

    ======================================================================
    FAIL: test_rlock_acquire_interruption (test.test_threadsignals.ThreadSignals)
    ----------------------------------------------------------------------

    Traceback (most recent call last):
      File "/home/remi/dev/cpython/Lib/test/test_threadsignals.py", line 122, in test_rlock_acquire_interruption
        self.assertLess(dt, 3.0)
    AssertionError: 5.020142078399658 not less than 3.0

    Ran 6 tests in 13.293s

    FAILED (failures=2)
    test test_threadsignals failed

    #############################################################################################

    Do I miss a thing?

    @vstinner
    Copy link
    Member

    To make test_lock_acquire_interruption and test_rlock_acquire_interruption more reliable, the test should maybe run a fresh Python process to get a well known number of threads. Some Python modules create C threads like Tkinter. faulthandler creates also an hiding C thread, but it is supposed to ignore all signals (it calls pthread_sigmask).

    @remi: Can you please test interrupt_lock_acquire.py? It should be the same than the unit test, but in a fresh Python process.

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 12, 2014

    Can you please test interrupt_lock_acquire.py? It should be the same than the unit test, but in a fresh Python process.

    Thanks for your response, this is what I have:

    $ PYTHONPATH=. ./python ./interrupt_lock_acquire.py 
    Traceback (most recent call last):
      File "./interrupt_lock_acquire.py", line 30, in <module>
        raise Exception("dt > 3: dt=%s" % dt)
    Exception: dt > 3: dt=5.011708974838257

    Remi.

    @neologix
    Copy link
    Mannequin

    neologix mannequin commented Feb 12, 2014

    Well, then it's definitely an OpenBSD bug, and we can't do anything
    more than skip the test.

    @vstinner
    Copy link
    Member

    So this looks like a bug.

    Or a different design choice?

    It looks like the kernel restarts the wait if it was interrupted.

    "ignore interruptions other than cancelation"
    http://ftp.cc.uoc.gr/mirrors/OpenBSD/src/lib/librthread/rthread_sem.c

    "test that sem_timedwait() resumes after handling a signal"
    http://mirrors.ircam.fr/pub/OpenBSD/src/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c

    POSIX says that "The sem_timedwait() function shall fail if: [EINTR] A signal interrupted this function."
    http://pubs.opengroup.org/onlinepubs/009604599/functions/sem_timedwait.html

    Right now, the best we can do is to skip the test on OpenBSD (maybe only on OpenBSD <= 5.4 to see if it changes later).

    @vstinner vstinner changed the title test_threadsignals.py "failed" on OpenBSD because too slow (> 3sec) locks cannot be interrupted on OpenBSD Feb 18, 2014
    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Feb 18, 2014

    New changeset a3d54bb04cbb by Victor Stinner in branch 'default':
    Issue bpo-20564: Skip tests on lock+signals on OpenBSD
    http://hg.python.org/cpython/rev/a3d54bb04cbb

    @vstinner
    Copy link
    Member

    @remi: You may report the feature request to OpenBSD kernel if you want. Until OpenBSD implements it, the test is now skipped in Python.

    @rpointel
    Copy link
    Mannequin Author

    rpointel mannequin commented Feb 18, 2014

    You may report the feature request to OpenBSD kernel if you want. Until OpenBSD implements it, the test is now skipped in Python.

    Yes, it's done yet.
    However, it's good to skip it until it's implemented.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    tests Tests in the Lib/test dir
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant