Skip to content

Segmentation fault while calling loop.create_future in finalizer (__del__) when a custom sys.excepthook is used #143

@pbasista

Description

@pbasista
  • uvloop version: 0.9.1
  • Python version: 3.6.5rc1
  • Platform: linux
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: yes, in fact, it is reproducible only when the asyncio debug is enabled

When using uvloop and having a custom sys.excepthook which uses a variable from the outer scope, which has a finalizer (the __del__ method) that creates a new future using AbstractEventLoop.create_future() method, Python interpreter crashes with a segmentation fault.

Example code:

#!/usr/bin/env python3
import asyncio
import sys

import uvloop

class LoopWrapper():
    def __init__(self, loop):
        self.loop = loop

    def __del__(self):
        print('finalizing', self.loop)
        self.loop.create_future()  # assertion fails here


async def store_event_loop(loop):
    wrapped_loop = LoopWrapper(loop)

    def custom_excepthook(*exc_info):
        print('unhandled_exception', exc_info)
        # commenting the below line causes the failed assertion to disappear
        print(wrapped_loop)

    sys.excepthook = custom_excepthook


if __name__ == '__main__':
    # commenting the below line causes the failed assertion to disappear
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

    event_loop = asyncio.get_event_loop()
    # commenting the below line disables the assertions
    event_loop.set_debug(True)

    event_loop.run_until_complete(store_event_loop(event_loop))

When run, the above example code fails like this:

$ ./uvloop_test.py                                                               
finalizing <uvloop.Loop running=False closed=False debug=True>
Segmentation fault (core dumped)

When uvloop is not used, the code fails at this AttributeError:

Traceback (most recent call last):
  File "./uvloop_test.py", line 13, in __del__
  File "/usr/lib/python3.6/asyncio/base_events.py", line 276, in create_future
AttributeError: 'NoneType' object has no attribute 'Future'

When a Python interpreter compiled with --with-pydebug option is used, it crashes on the following assertion failure:

python3: ../Objects/abstract.c:2300: _PyObject_FastCallDict: Assertion `func != NULL' failed.

GDB backtrace (py-bt) shows this:

(gdb) py-bt
Traceback (most recent call first):
  <built-in method create_future of Loop object at remote 0x7f7ecfafe048>
  File "./uvloop_test.py", line 13, in __del__
    self.loop.create_future()  # assertion fails here

The issue here is that uvloop causes Python interpreter to crash. I believe that a regular Python exception should be raised instead.

Apart from addressing this issue, if someone can explain the details of what is happening in the example code mentioned above, in particular why it fails even without uvloop and why a finalizer triggered from a custom sys.excepthook is not able to call create_future(), it would also be helpful.

Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions