New issue 2745: cpyext: exceptions in greenlets running cython kill the process
https://bitbucket.org/pypy/pypy/issues/2745/cpyext-exceptions-in-greenlets-running

Jason Madden:

This is on macOS 10.13.3 running pypy2-5.10.0 as downloaded from pypy.org and 
pypy2-5.9.0 as downloaded from pypy.org, gevent 1.2.2 and master, and Cython 
0.25.2, 0.27.3 and 0.28a (master). There are a few variations on this.

First, the python code:
```python
import sys
import gevent
print(gevent.__version__)
from gevent.resolver_ares import Resolver
resolver = Resolver()
greenlet = gevent.spawn(resolver.gethostbyname, 'foo not found 2')
gevent.sleep(1) # if this line is omitted, no crash occurs
greenlet.join()
```

We spawn a greenlet that will use the ares extension compiled with cython to 
look up a name, and we expect that name to raise `socket.gaierror`. gevent's 
error handling will catch this uncaught error and print it.

Here's what happens with PyPy2 5.10 when compiled with either Cython 0.27.3 or 
0.28a (current master) (gevent 1.3):
```
$ python --version
Python 2.7.13 (0e7ea4fe15e8, Dec 22 2017, 08:44:21)
[PyPy 5.10.0 with GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)]
$ python /tmp/crash.py
1.3.0.dev0
Traceback (most recent call last):
  File "//src/gevent/greenlet.py", line 537, in run
    result = self._run(*self.args, **self.kwargs)
  File "//src/gevent/resolver/ares.py", line 118, in gethostbyname
    return self.gethostbyname_ex(hostname, family)[-1][0]
  File "//src/gevent/resolver/ares.py", line 137, in gethostbyname_ex
    result = waiter.get()
  File "//src/gevent/hub.py", line 931, in get
    return self.hub.switch()
  File "//src/gevent/hub.py", line 648, in switch
    return RawGreenlet.switch(self)
  File "//bin/pypy/lib_pypy/greenlet.py", line 53, in switch
    return self.__switch('switch', (args, kwds))
  File "//bin/pypy/lib_pypy/greenlet.py", line 92, in __switch
    args, kwds = unbound_method(current, *baseargs, to=target)
gaierror: [Errno 4] ARES_ENOTFOUND: Domain name not found
Thu Feb  1 13:41:48 2018 Error in cpyext, CPython compatibility layer:
The function PyThreadState_Get was not supposed to fail
Fatal error in cpyext, CPython compatibility layer, calling PyThreadState_Get
Either report a bug or consider not using this particular extension
<SystemError object at 0x1053aea50>
RPython traceback:
  File "pypy_module_cpyext_1.c", line 14805, in wrapper_second_level__star_0_14
  File "pypy_module_cpyext_1.c", line 35718, in not_supposed_to_fail
Segmentation fault: 11
```

If the code was compiled with Cython 0.25.2, like the released gevent 1.2.2, 
running `python /tmp/crash.py` *does not crash*. But running it interactively 
at the console does, and without the need to `gevent.sleep`:
```
$ python
Python 2.7.13 (0e7ea4fe15e8, Dec 22 2017, 08:44:21)
[PyPy 5.10.0 with GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on 
darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> import gevent
>>>> print(gevent.__version__)
1.2.2
None
>>>> from gevent.resolver_ares import Resolver
>>>> resolver = Resolver()
>>>> greenlet = gevent.spawn(resolver.gethostbyname, 'foo not found 2')
>>>> greenlet.join()
Traceback (most recent call last):
  File "//VirtualEnvs/tmp-3646e066322dd8ec/site-packages/gevent/greenlet.py", 
line 536, in run
    result = self._run(*self.args, **self.kwargs)
  File 
"//VirtualEnvs/tmp-3646e066322dd8ec/site-packages/gevent/resolver_ares.py", 
line 98, in gethostbyname
    return self.gethostbyname_ex(hostname, family)[-1][0]
  File 
"//VirtualEnvs/tmp-3646e066322dd8ec/site-packages/gevent/resolver_ares.py", 
line 117, in gethostbyname_ex
    result = waiter.get()
  File "//VirtualEnvs/tmp-3646e066322dd8ec/site-packages/gevent/hub.py", line 
898, in get
    return self.hub.switch()
  File "//VirtualEnvs/tmp-3646e066322dd8ec/site-packages/gevent/hub.py", line 
630, in switch
    return RawGreenlet.switch(self)
  File "//bin/pypy/lib_pypy/greenlet.py", line 53, in switch
    return self.__switch('switch', (args, kwds))
  File "/bin/pypy/lib_pypy/greenlet.py", line 92, in __switch
    args, kwds = unbound_method(current, *baseargs, to=target)
gaierror: [Errno 4] ARES_ENOTFOUND: Domain name not found
Thu Feb  1 13:49:58 2018 Fatal error in cpyext, CPython compatibility layer, 
calling PyString_FromString
Either report a bug or consider not using this particular extension
<StackOverflow object at 0x10618df78>
RPython traceback:
  File "pypy_module_cpyext.c", line 12855, in wrapper_second_level__star_1_10
  File "pypy_module_cpyext_1.c", line 36771, in 
make_ref__StdObjSpaceConst_SomeInstance_NoneCons
  File "pypy_module_cpyext_2.c", line 4241, in create_ref
  File "pypy_module_cpyext_4.c", line 351, in bytes_attach
  File "pypy_objspace.c", line 2788, in hash
  File "pypy_interpreter.c", line 38981, in BuiltinCode1_fastcall_1
  File "rpython_rlib.c", line 9723, in stack_check_slowpath
Segmentation fault: 11
```

pypy2-5.9 crashes with substantially the same stack trace. -X faulthandler 
doesn't add any additional information:
```
Stack (most recent call first, approximate line numbers):
  File 
"/VirtualEnvs/tmp-189eafb7c968f1f6/site-packages/gevent/libev/corecffi.py", 
line 774 in __repr__
  File 
"//VirtualEnvs/tmp-189eafb7c968f1f6/site-packages/gevent/libev/corecffi.py", 
line 774 in __repr__
  File 
"//VirtualEnvs/tmp-189eafb7c968f1f6/site-packages/gevent/libev/corecffi.py", 
line 774 in __repr__
  File 
"//VirtualEnvs/tmp-189eafb7c968f1f6/site-packages/gevent/libev/corecffi.py", 
line 774 in __repr__
...
```

I consider this minor since gevent doesn't encourage the use of the Cython ares 
extension, it just came up during some benchmarking 
(https://github.com/gevent/gevent/pull/1088). I just wanted to let you know of 
a reproducible test case for a crash (I'm sorry I don't have anything 
simpler!). Let me know if I can be of any help.


_______________________________________________
pypy-issue mailing list
pypy-issue@python.org
https://mail.python.org/mailman/listinfo/pypy-issue

Reply via email to