Greenlet error cannot switch to a different thread

Hi, I installed 0.4.9 via pip3 on ubuntu 16.04 and receive this error. The same package on 14.04 seems to work fine, not sure if that is related or not yet but its the only difference i can think o...
…opagate to another greenlet and corrupt memory

Hello up there. While working on Pygolang I've faced the following
problem: a C++ exception thrown in one greenlet, without any try/catch
block on that greenlet, might become propagated and "handled" by
try/catch block established at another greenlet that happened to switch to
the greenlet in question. "Handled" comes in quotes because the program
usually segfaults after that.

I've also observed segfaults before exception reaches user-level
try/catch block - internally in __cxa_throw. Both this issues are likely
of the same origin - due to the fact that C-level stack of a greenlet
does not start from scratch and starts from C-level stack of the program
state when the greenlet is switched to the first time.

We already have one test for C++ exception handling in test_cpp that
@snaury initially added in d9cb12a. However in that test all greenlets
that throw C++ exceptions also put try/catch at the top of their
C-stack.

In the problem, that I describe, and that added test reproduces, there is
no intended top-level try/catch block in C-stack of the greenlet in
question that throws. As the test shows the exception becomes propagated
to switcher's greenlet context and the program then dies with SIGSEGV:

    test_exception_switch_and_throw (greenlet.tests.test_cpp.CPPTests) ... terminate called after throwing an instance of 'exception_t'
    C++ exception unexpectedly caught in g1		<-- NOTE
    FAIL

    ======================================================================
    FAIL: test_exception_switch_and_throw (greenlet.tests.test_cpp.CPPTests)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/kirr/src/tools/py/gevent/greenlet/src/greenlet/tests/test_cpp.py", line 62, in test_exception_switch_and_throw
        (ret, sig, " (core dumped)" if core else ""))
    AssertionError: failed with ret=0 sig=11 (core dumped)

The C-level backtrace from the dumped core is attached in Appendix I. There the
program dies somehow after running the code from _test_extension_cpp.cpp
module. However with the following dirty-patch the situation becomes more clear:

    --- a/src/greenlet/tests/_test_extension_cpp.cpp
    +++ b/src/greenlet/tests/_test_extension_cpp.cpp
    @@ -70,6 +70,7 @@ test_exception_switch(PyObject* self, PyObject* args)
     static PyObject*
     py_test_exception_throw(PyObject* self, PyObject* args)
     {
    +    abort();
         if (!PyArg_ParseTuple(args, ""))
             return NULL;
         p_test_exception_throw(0);

The C-level backtrace of this abort when, run from under g2, shows that g2
C-stack starts from what was there before for first greenlet with try/catch block:

    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    #1  0x00007f8be31e9537 in __GI_abort () at abort.c:79
    #2  0x00007f8be3529423 in py_test_exception_throw (self=0x0, args=0x7f8be317f050)
        at src/greenlet/tests/_test_extension_cpp.cpp:73
    #3  0x00005584d0389903 in PyObject_Call (func=0x7f8be2cdd690, arg=<optimized out>, kw=<optimized out>)
        at ../Objects/abstract.c:2544
    #4  0x00007f8be3530d63 in g_initialstub (mark=0x7ffe6d1b1c88) at src/greenlet/greenlet.c:931
    #5  0x00007f8be3530290 in g_switch (target=0x7f8be2cd6230, args=0x7f8be317f050, kwargs=0x0) at src/greenlet/greenlet.c:692
    #6  0x00007f8be35329e2 in PyGreenlet_Switch (g=0x7f8be2cd6230, args=0x7f8be317f050, kwargs=0x0) at src/greenlet/greenlet.c:1806     <- first switch to G2
    #7  0x00007f8be35294da in test_exception_switch_and_do_in_g2 (self=0x0, args=0x7f8be2ce33d0)                                        <- this code runs in G1
        at src/greenlet/tests/_test_extension_cpp.cpp:105
    #8  0x00005584d039de7a in call_function (oparg=<optimized out>, pp_stack=0x7ffe6d1b1e28) at ../Python/ceval.c:4376
    #9  PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
    #10 0x00005584d039c3cc in PyEval_EvalCodeEx (co=0x7f8be2cd9cb0, globals=<optimized out>, locals=<optimized out>,
        args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
        at ../Python/ceval.c:3608
    #11 0x00005584d03b6b9b in function_call (func=func@entry=0x7f8be2cde650, arg=0x7f8be317f050, kw=0x0)
        at ../Objects/funcobject.c:523
    #12 0x00005584d0389903 in PyObject_Call (func=0x7f8be2cde650, arg=<optimized out>, kw=<optimized out>)
        at ../Objects/abstract.c:2544
    #13 0x00007f8be3530d63 in g_initialstub (mark=0x7ffe6d1b20b8) at src/greenlet/greenlet.c:931
    #14 0x00007f8be3530290 in g_switch (target=0x7f8be2cd6410, args=0x7f8be317f050, kwargs=0x0) at src/greenlet/greenlet.c:692
    #15 0x00007f8be3531c4c in green_switch (self=0x7f8be2cd6410, args=0x7f8be317f050, kwargs=0x0) at src/greenlet/greenlet.c:1321       <- switch to G1
    ...

The problem might be worked-around with putting try/catch on C-stack for
every greenlet, but a more proper fix would be to unlink return address
and C-stack-frame of created greenlet from other greenlets completely
(i.e. rewrite first frame of C-stack for created greenlet to return to NULL).

Thanks beforehand,
Kirill

P.S. The problem described at
  #197 (comment) and
  #205 might be related
  to hereby issue (/cc @ThePrez, @kadler, @jamadden).

P.P.S. The test does not fail on master. I see there @jamadden switched
  the codebase to C++ almost completely and there is some explicit
  attempts to save/restore exception state added in
  87edf955. However
  that exception save/restore is specific to Win32 and the test succeeds
  for me on Linux. I still see the following comment in
  UserGreenlet::inner_bootstrap

    // C++ exceptions cannot propagate to the parent greenlet from
    // here. (TODO: Do we need a catch(...) clause, perhaps on the
    // function itself? ALl we could do is terminate the program.)

    ( https://github.com/python-greenlet/greenlet/blob/3e534d6b/src/greenlet/greenlet.cpp#L1085-L1104 )

  probably this indeed works only by luck, or due to G_NOEXCEPT modifier
  of UserGreenlet::inner_bootstrap upon seeing which __cxa_throw stops
  unwinding C-stack and just calls std::terminate.

--------

Appendix I. C-level backtrace after the test died with SIGSEGV

  #0  0x0000556bdc30d394 in PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3351
  #1  0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a03acb0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #2  0x0000556bdc325b9b in function_call (func=func@entry=0x7f0b8a03f650, arg=0x7f0b8a4e0050, kw=0x0)
      at ../Objects/funcobject.c:523
  #3  0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a03f650, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #4  0x00007f0b8a891d63 in g_initialstub (mark=0x7ffc3ef97988) at src/greenlet/greenlet.c:931
  #5  0x00007f0b8a891290 in g_switch (target=0x7f0b8a037410, args=0x7f0b8a4e0050, kwargs=0x0) at src/greenlet/greenlet.c:692
  #6  0x00007f0b8a892c4c in green_switch (self=0x7f0b8a037410, args=0x7f0b8a4e0050, kwargs=0x0) at src/greenlet/greenlet.c:1321
  #7  0x0000556bdc30ce7a in call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef97ac8) at ../Python/ceval.c:4376
  #8  PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #9  0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a03ad30, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #10 0x0000556bdc312953 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef97ca8,
      func=0x7f0b8a03aed0) at ../Python/ceval.c:4471
  #11 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef97ca8) at ../Python/ceval.c:4396
  #12 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #13 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a03ac30, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #14 0x0000556bdc312953 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef97e88,
      func=0x7f0b8a03af50) at ../Python/ceval.c:4471
  #15 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef97e88) at ../Python/ceval.c:4396
  #16 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #17 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a03adb0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #18 0x0000556bdc312953 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef98068,
      func=0x7f0b8a03f250) at ../Python/ceval.c:4471
  #19 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef98068) at ../Python/ceval.c:4396
  #20 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #21 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a04bd30, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a0752a8, defcount=1,
      closure=0x0) at ../Python/ceval.c:3608
  #22 0x0000556bdc325cc2 in function_call (func=0x7f0b8a0771d0, arg=0x7f0b8a3bd5a0, kw=0x7f0b8a042dd0)
      at ../Objects/funcobject.c:523
  #23 0x0000556bdc30fa96 in PyObject_Call (kw=0x7f0b8a042dd0, arg=0x7f0b8a3bd5a0, func=0x7f0b8a0771d0)
      at ../Objects/abstract.c:2544
  #24 ext_do_call (nk=<optimized out>, na=1, flags=<optimized out>, pp_stack=0x7ffc3ef982a0, func=0x7f0b8a0771d0)
      at ../Python/ceval.c:4690
  #25 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3052
  #26 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a04bf30, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #27 0x0000556bdc325b9b in function_call (func=0x7f0b8a0772d0, arg=arg@entry=0x7f0b8a3bd550, kw=kw@entry=0x0)
      at ../Objects/funcobject.c:523
  #28 0x0000556bdc33f553 in PyObject_Call (kw=0x0, arg=0x7f0b8a3bd550, func=<optimized out>) at ../Objects/abstract.c:2544
  #29 instancemethod_call (func=<optimized out>, func@entry=0x7f0b8a3c6a00, arg=0x7f0b8a3bd550, kw=0x0)
      at ../Objects/classobject.c:2600
  #30 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a3c6a00, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #31 0x0000556bdc37eff8 in slot_tp_call (self=self@entry=0x7f0b8a03cfd0, args=0x7f0b8a044210, kwds=0x0)
      at ../Objects/typeobject.c:5609
  #32 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a03cfd0, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #33 0x0000556bdc3128dd in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7ffc3ef98798, func=0x7f0b8a03cfd0)
      at ../Python/ceval.c:4593
  #34 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef98798) at ../Python/ceval.c:4398
  #35 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #36 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d530, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a076ee8, defcount=1,
      closure=0x0) at ../Python/ceval.c:3608
  #37 0x0000556bdc325cc2 in function_call (func=0x7f0b8a07f950, arg=0x7f0b8a3bd780, kw=0x7f0b8a042cb0)
      at ../Objects/funcobject.c:523
  #38 0x0000556bdc30fa96 in PyObject_Call (kw=0x7f0b8a042cb0, arg=0x7f0b8a3bd780, func=0x7f0b8a07f950)
      at ../Objects/abstract.c:2544
  #39 ext_do_call (nk=<optimized out>, na=1, flags=<optimized out>, pp_stack=0x7ffc3ef989d0, func=0x7f0b8a07f950)
      at ../Python/ceval.c:4690
  #40 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3052
  #41 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d2b0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #42 0x0000556bdc325b9b in function_call (func=0x7f0b8a07f850, arg=arg@entry=0x7f0b8a3bd730, kw=kw@entry=0x0)
      at ../Objects/funcobject.c:523
  #43 0x0000556bdc33f553 in PyObject_Call (kw=0x0, arg=0x7f0b8a3bd730, func=<optimized out>) at ../Objects/abstract.c:2544
  #44 instancemethod_call (func=<optimized out>, func@entry=0x7f0b8a427190, arg=0x7f0b8a3bd730, kw=0x0)
      at ../Objects/classobject.c:2600
  #45 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a427190, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #46 0x0000556bdc37eff8 in slot_tp_call (self=self@entry=0x7f0b8a03cf90, args=0x7f0b8a044150, kwds=0x0)
      at ../Objects/typeobject.c:5609
  #47 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a03cf90, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #48 0x0000556bdc3128dd in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7ffc3ef98ec8, func=0x7f0b8a03cf90)
      at ../Python/ceval.c:4593
  #49 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef98ec8) at ../Python/ceval.c:4398
  #50 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #51 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d530, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a076ee8, defcount=1,
      closure=0x0) at ../Python/ceval.c:3608
  #52 0x0000556bdc325cc2 in function_call (func=0x7f0b8a07f950, arg=0x7f0b8a3bdaf0, kw=0x7f0b8a042b90)
      at ../Objects/funcobject.c:523
  #53 0x0000556bdc30fa96 in PyObject_Call (kw=0x7f0b8a042b90, arg=0x7f0b8a3bdaf0, func=0x7f0b8a07f950)
      at ../Objects/abstract.c:2544
  #54 ext_do_call (nk=<optimized out>, na=1, flags=<optimized out>, pp_stack=0x7ffc3ef99100, func=0x7f0b8a07f950)
      at ../Python/ceval.c:4690
  #55 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3052
  #56 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d2b0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #57 0x0000556bdc325b9b in function_call (func=0x7f0b8a07f850, arg=arg@entry=0x7f0b8a3bdb40, kw=kw@entry=0x0)
      at ../Objects/funcobject.c:523
  #58 0x0000556bdc33f553 in PyObject_Call (kw=0x0, arg=0x7f0b8a3bdb40, func=<optimized out>) at ../Objects/abstract.c:2544
  #59 instancemethod_call (func=<optimized out>, func@entry=0x7f0b8a3c6820, arg=0x7f0b8a3bdb40, kw=0x0)
      at ../Objects/classobject.c:2600
  #60 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a3c6820, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #61 0x0000556bdc37eff8 in slot_tp_call (self=self@entry=0x7f0b8a033c50, args=0x7f0b8a03c0d0, kwds=0x0)
      at ../Objects/typeobject.c:5609
  #62 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a033c50, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #63 0x0000556bdc3128dd in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7ffc3ef995f8, func=0x7f0b8a033c50)
      at ../Python/ceval.c:4593
  #64 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef995f8) at ../Python/ceval.c:4398
  #65 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #66 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d530, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a076ee8, defcount=1,
      closure=0x0) at ../Python/ceval.c:3608
  #67 0x0000556bdc325cc2 in function_call (func=0x7f0b8a07f950, arg=0x7f0b8a3bd500, kw=0x7f0b8a042a70)
      at ../Objects/funcobject.c:523
  #68 0x0000556bdc30fa96 in PyObject_Call (kw=0x7f0b8a042a70, arg=0x7f0b8a3bd500, func=0x7f0b8a07f950)
      at ../Objects/abstract.c:2544
  #69 ext_do_call (nk=<optimized out>, na=1, flags=<optimized out>, pp_stack=0x7ffc3ef99830, func=0x7f0b8a07f950)
      at ../Python/ceval.c:4690
  #70 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3052
  #71 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a07d2b0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #72 0x0000556bdc325b9b in function_call (func=0x7f0b8a07f850, arg=arg@entry=0x7f0b8a3bd9b0, kw=kw@entry=0x0)
      at ../Objects/funcobject.c:523
  #73 0x0000556bdc33f553 in PyObject_Call (kw=0x0, arg=0x7f0b8a3bd9b0, func=<optimized out>) at ../Objects/abstract.c:2544
  #74 instancemethod_call (func=<optimized out>, func@entry=0x7f0b8a4310a0, arg=0x7f0b8a3bd9b0, kw=0x0)
      at ../Objects/classobject.c:2600
  #75 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a4310a0, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #76 0x0000556bdc37eff8 in slot_tp_call (self=self@entry=0x7f0b8a033c10, args=0x7f0b8a033fd0, kwds=0x0)
      at ../Objects/typeobject.c:5609
  #77 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a033c10, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #78 0x0000556bdc3128dd in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7ffc3ef99d28, func=0x7f0b8a033c10)
      at ../Python/ceval.c:4593
  #79 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef99d28) at ../Python/ceval.c:4398
  #80 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #81 0x0000556bdc3125fe in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef99e38,
      func=0x7f0b8a01ecd0) at ../Python/ceval.c:4461
  #82 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef99e38) at ../Python/ceval.c:4396
  #83 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #84 0x0000556bdc3125fe in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef99f48,
      func=0x7f0b8a01edd0) at ../Python/ceval.c:4461
  #85 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef99f48) at ../Python/ceval.c:4396
  #86 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #87 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a081d30, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=1, defs=0x7f0b8a008ba8, defcount=10,
      closure=0x0) at ../Python/ceval.c:3608
  #88 0x0000556bdc325cc2 in function_call (func=0x7f0b8a00ddd0, arg=arg@entry=0x7f0b8a033610, kw=kw@entry=0x7f0b8a014a70)
      at ../Objects/funcobject.c:523
  #89 0x0000556bdc33f553 in PyObject_Call (kw=0x7f0b8a014a70, arg=0x7f0b8a033610, func=<optimized out>)
      at ../Objects/abstract.c:2544
  #90 instancemethod_call (func=<optimized out>, func@entry=0x7f0b8a427140, arg=0x7f0b8a033610, arg@entry=0x7f0b8a4e0050,
      kw=kw@entry=0x7f0b8a014a70) at ../Objects/classobject.c:2600
  #91 0x0000556bdc33f10f in PyObject_Call (kw=0x7f0b8a014a70, arg=0x7f0b8a4e0050, func=0x7f0b8a427140)
      at ../Objects/abstract.c:2544
  #92 slot_tp_init (self=self@entry=0x7f0b8a3ebb10, args=args@entry=0x7f0b8a4e0050, kwds=kwds@entry=0x7f0b8a014a70)
      at ../Objects/typeobject.c:5869
  #93 0x0000556bdc2feb87 in type_call (type=<optimized out>, type@entry=0x556bdd2a85c0, args=0x7f0b8a4e0050, kwds=0x7f0b8a014a70)
      at ../Objects/typeobject.c:765
  #94 0x0000556bdc2f8903 in PyObject_Call (func=0x556bdd2a85c0, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #95 0x0000556bdc3128dd in do_call (nk=<optimized out>, na=<optimized out>, pp_stack=0x7ffc3ef9a458, func=0x556bdd2a85c0)
      at ../Python/ceval.c:4593
  #96 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef9a458) at ../Python/ceval.c:4398
  #97 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #98 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a37d830, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0, defcount=0, closure=0x0)
      at ../Python/ceval.c:3608
  #99 0x0000556bdc311886 in PyEval_EvalCode (locals=0x7f0b8a4ae170, globals=0x7f0b8a4ae170, co=<optimized out>)
      at ../Python/ceval.c:669
  #100 exec_statement (locals=0x7f0b8a4ae170, globals=0x7f0b8a4ae170, prog=<optimized out>, f=<optimized out>)
      at ../Python/ceval.c:5093
  #101 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:2122
  #102 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a3ea4b0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a381068, defcount=5,
      closure=0x0) at ../Python/ceval.c:3608
  #103 0x0000556bdc312953 in fast_function (nk=<optimized out>, na=<optimized out>, n=<optimized out>, pp_stack=0x7ffc3ef9a818,
      func=0x7f0b8a37d8d0) at ../Python/ceval.c:4471
  #104 call_function (oparg=<optimized out>, pp_stack=0x7ffc3ef9a818) at ../Python/ceval.c:4396
  #105 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3013
  #106 0x0000556bdc30b3cc in PyEval_EvalCodeEx (co=0x7f0b8a37d4b0, globals=<optimized out>, locals=<optimized out>,
      args=<optimized out>, argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x7f0b8a379ce8, defcount=1,
      closure=0x0) at ../Python/ceval.c:3608
  #107 0x0000556bdc325b9b in function_call (func=func@entry=0x7f0b8a37de50, arg=0x7f0b8a3b5be0, kw=0x0)
      at ../Objects/funcobject.c:523
  #108 0x0000556bdc2f8903 in PyObject_Call (func=0x7f0b8a37de50, arg=<optimized out>, kw=<optimized out>)
      at ../Objects/abstract.c:2544
  #109 0x0000556bdc3b87e1 in RunModule (module=<optimized out>, set_argv0=1) at ../Modules/main.c:197
  #110 0x0000556bdc3a68ed in Py_Main (argc=<optimized out>, argv=<optimized out>) at ../Modules/main.c:592#111 0x00007f0b8a54bd0a in __libc_start_main (main=0x556bdc3a6530 <main>, argc=5, argv=0x7ffc3ef9ac08, init=<optimized out>,
      fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc3ef9abf8) at ../csu/libc-start.c:308
  #112 0x0000556bdc3a646a in _start ()

Closed

greenlet.error: cannot switch to a different thread #65

Issue Opened

Vayel Opened Issue On Oct 27th 2014, 6:01

Vayel

Hi!

I installed Flask-SocketIO on my Fedora and the following error displays :

[vincent@localhost controller]$ python server.py 
 * Running on http://0.0.0.0:5000/
 * Restarting with reloader
Unhandled exception in thread started by <function run_server at 0x8ee456c>
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/flask_socketio/__init__.py", line 242, in run_server
    self.server.serve_forever()
  File "/usr/lib/python2.7/site-packages/gevent/baseserver.py", line 284, in serve_forever
    self._stop_event.wait()
  File "/usr/lib/python2.7/site-packages/gevent/event.py", line 77, in wait
    result = self.hub.switch()
  File "/usr/lib/python2.7/site-packages/gevent/hub.py", line 331, in switch
    return greenlet.switch(self)
greenlet.error: cannot switch to a different thread 

*server.py : *

# -*-coding: utf-8 -*-
from flask import Flask
from flask.ext.socketio import SocketIO, emit

from controller import Controller
from map import Map
from doser import Doser
from locator import Locator

app = Flask(__name__)
app.debug = True
socket = SocketIO(app)

@socket.on("load-map")
def load_map(data):
    map_ = Map(data)

    # Notify modules
    if map_.is_valid():
        emit("map", map_.data) # Client
    else:
        emit("map", {}) # Client

@app.route("/")
def home():
    with open("templates/home.html", "r") as f:
        return f.read()

if __name__ == "__main__":
    # app.run(host="0.0.0.0")
    socket.run(app, host="0.0.0.0") 

I get the same message on Raspbian.

Is it due to Flask-SocketIO ?

Thanks!

Edit : with debug mode disabled, it seems to work :

[vincent@localhost controller]$ python server.py 
127.0.0.1 - - [2014-10-26 13:05:42] "GET / HTTP/1.1" 200 1142 0.014441
^CKeyboardInterrupt
Traceback (most recent call last):
  File "server.py", line 31, in <module>
    socket.run(app, host="0.0.0.0")
  File "/usr/lib/python2.7/site-packages/flask_socketio/__init__.py", line 247, in run
    self.server.serve_forever()
  File "/usr/lib/python2.7/site-packages/gevent/baseserver.py", line 284, in serve_forever
    self._stop_event.wait()
  File "/usr/lib/python2.7/site-packages/gevent/event.py", line 77, in wait
    result = self.hub.switch()
  File "/usr/lib/python2.7/site-packages/gevent/hub.py", line 331, in switch
    return greenlet.switch(self)
KeyboardInterrupt
[vincent@localhost controller]$ 

Miguelgrinberg

Sadly this appears to be a side effect of the removal of the gevent monkey-patching. It appears that is needed when running the reloader. Add the following two lines at the top of your server.py, above all the imports:

from gevent import monkey
monkey.patch_all() 

It is important that these are above the imports, in lines 1 & 2. Let me know if this addresses the problem for you.

Comment

Vayel commented on 8 years ago

Vayel

Perfect! Thanks a lot!

Comment

JanBenes commented on 8 years ago

JanBenes

I would like to add that I monkey patch only in the __main__ guard and that works as well.

if __name__ == '__main__':
    from gevent import monkey
    monkey.patch_all() 

For me, this is important so that Celery, which imports some of my scripts, wouldn’t hang, see https://github.com/miguelgrinberg/Flask-SocketIO/issues/61.

Finally, if you’re using PyCharm/PyDev, enabling File->Settings..->Python Debugger->Gevent compatible debugging might be required.

Piejanssens

@miguelgrinberg This also appears to be needed in combination with flask-apscheduler: https://github.com/miguelgrinberg/Flask-SocketIO/issues/65

Advance512

If you see this in the context of debugging using PyCharm, try this:

Go to Settings —> Build, Execution, Deployment -> Python Debugger.
In that dialog, you’ll see a «Gevent compatible» checkbox. Not sure how it got unticked in the new project.

Tick that option and enjoy!

Comment

Akapit commented on 4 years ago

Akapit

Could be that also happens when using blueprints?

Miguelgrinberg

@akapit using Flask blueprints should not have any effect on gevent, but what you do in those blueprints might.

Databasedav

Is there any solution to this in the context of debugging using vscode?

Miguelgrinberg

There is a gevent configuration option for vscode that needs to be True. See https://code.visualstudio.com/docs/python/debugging#_gevent. In my experience this option also allows eventlet apps to be debugged.

Comment

Cedricdv commented on 3 years ago

Cedricdv

If you see this in the context of debugging using PyCharm, try this:

Go to Settings —> Build, Execution, Deployment -> Python Debugger.
In that dialog, you’ll see a «Gevent compatible» checkbox. Not sure how it got unticked in the new project.

Tick that option and enjoy!

This!

Gerazenobi

Hi @miguelgrinberg, although we are not using Flask-SocketIO we have seen this issue within our Flask APIs (that end up using a library that imports grequests); since you might know more about this subject I though I’d test my luck and ask you:

would you have any idea why we seem to see this issue only when running an API locally ? e.g.:

#api.py
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=9999, debug=False) 

but not seen when the API is run through uwsgi in a production environment ?

#run.py
from ....api import app # called by uwsgi 

For the moment we only have the patch all solution mentioned in this thread within the __name__ == "__main__" shown above.

Thanks in advance for any insights :)

Miguelgrinberg

My understanding is that this error comes up when you are mixing gevent greenlets with real threads. If you were to make sure you use greenlets for everything then you should be fine. If you do need to have some real threads in there, then you should use greenlets in a single thread to avoid this problem.

Gerazenobi

I see. Our uwsgi is not configured in gevent mode hence why I would’t have though it should fail in some sort when half patched by the library grequests (curious_george.patch_all(thread=False, select=False)

If I gather more info on this I will happily share it 👍

Thanks for your response!

Miguelgrinberg

The problem is that greenlets are bound to the thread in which they were created. What you are doing with grequests is likely causing greenlets to be accessed from different threads.

Gerazenobi

well the problem is that it seems to work fine but I was expecting the opposite given the behaviour when executing locally hence my confusion on the subject 😅

PravinRanjan10

I would like to add that I monkey patch only in the __main__ guard and that works as well.

if __name__ == '__main__':
    from gevent import monkey
    monkey.patch_all() 

For me, this is important so that Celery, which imports some of my scripts, wouldn’t hang, see #61.

Finally, if you’re using PyCharm/PyDev, enabling File->Settings..->Python Debugger->Gevent compatible debugging might be required.

Thanks. It resolved my issues.

Comment

Sylnsr commented on 2 years ago

Sylnsr

Regarding «Gevent compatible» setting .. it wont work in every situation. As of now, there is confirmed issue («reproduced» status) that JetBrains support confirmed themselves. See https://youtrack.jetbrains.com/issue/PY-43676

Comment

Netwang commented on 7 months ago

Netwang

greenlet.error: cannot switch to a different thread

using eventlet in windows 11 for Flask-SocketIO, use CQN of cx_Oracle to check table changes.

if records changed in oracle, python callback will be called. The python callback thread will call socketio.emit(msg) to browser. But browser never receive the msg. Even use socketio.start_background_task to call socketio.emit(msg), browser still never receive the msg.

if use timer to check table changes, when records changed in oracle, use socketio.start_background_task to call socketio.emit(msg), browser successfully receive the msg

when program start, it shows:

Server initialized for eventlet.
Traceback (most recent call last):
File «C:myprojectsQMOS ProjectQMOS-pyDSpyenvlibsite-packageseventlethubshub.py», line 476, in fire_timers
timer()
File «C:myprojectsQMOS ProjectQMOS-pyDSpyenvlibsite-packageseventlethubstimer.py», line 59, in call cb(*args, **kw)
File «C:myprojectsQMOS ProjectQMOS-pyDSpyenvlibsite-packageseventletsemaphore.py», line 147, in _do_acquire
waiter.switch()
greenlet.error: cannot switch to a different thread

Miguelgrinberg

@netwang You have an issue between eventlet and one or more packages that you are using. This library has nothing to do with this problem. You either need to ensure that all the packages that you use are compatible with eventlet, or else not use eventlet.

Comment

Netwang commented on 7 months ago

Netwang

here is the requirements.txt. Could you help me to check which package is not compatible with eventlet? Thanks!

atomicwrites==1.4.0
attrs==21.4.0
bidict==0.22.0
click==8.1.3
colorama==0.4.5
cx-Oracle==8.3.0
dnspython==2.2.1
eventlet==0.33.1
Flask==2.1.2
Flask-Cors==3.0.10
Flask-SocketIO==5.2.0
greenlet==1.1.2
importlib-metadata==4.12.0
iniconfig==1.1.1
itsdangerous==2.1.2
Jinja2==3.1.2
ldap3==2.9.1
MarkupSafe==2.1.1
numpy==1.23.0
packaging==21.3
pandas==1.4.3
pip==22.0.4
pluggy==1.0.0
py==1.11.0
pyasn1==0.4.8
PyJWT==2.4.0
pyparsing==3.0.9
pytest==7.1.2
python-dateutil==2.8.2
python-engineio==4.3.2
python-socketio==5.6.0
pytz==2022.1
setuptools==58.1.0
six==1.16.0
tabulate==0.8.10
tomli==2.0.1
Werkzeug==2.1.2
zipp==3.8.0

Sincerely,
Net Wang (Mingwang Wang)001-416-391-3755 Ext. 388(Office)
001-416-786-0319 (Cell)

On Thursday, June 30, 2022 at 10:31:30 a.m. EDT, Miguel Grinberg ***@***.***> wrote: 

@netwang You have an issue between eventlet and one or more packages that you are using. This package has nothing to do with this problem. You either need to ensure that all the packages that you use are compatible with eventlet, or else not use eventlet.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: @.***>

Miguelgrinberg

@netwang I’m sorry, I can’t go through every package and check, as it is too time consuming. If you are using any packages that are written in native (C/C++) code those are likely suspects to be incompatible with eventlet. If you really don’t understand how eventlet works and why compatibility is an issue, then I recommend that you don’t use it, and then everything should work just fine.

Comment

Netwang commented on 6 months ago

Netwang

solved by using celery

celery = make_celery(app)

@celery.task(name=»task.message»)
def push_to_client(group_name, message_name, jsn):
socketio.emit(message_name, jsn, to=group_name)

# not work
#socketio1 = SocketIO(message_queue='amqp://')
#socketio1.emit(message_name, jsn, to=group_name)

# not work
#socketio.start_background_task(socketio.emit, message_name, jsn, to=group_name) 

Thanks!

Comment

Netwang commented on 3 months ago

Netwang

I successfully used Flask and Flask-Socketio with eventlet on Windows. I want to add async / await to access Oracle. As Miguel Grinberg said Flask-Socketio didn’t support async / await. Need to use python-socketio which uses asyncio.

I successfully setup Flask with python-socketio in async_mode=’threading’

sio = socketio.Server(async_mode=’threading’, logger=True, engineio_logger=True, cors_allowed_origins=’*’)

app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app, static_files=None, socketio_path=’/QMOSDS/socket.io’)

http://localhost:5000/QMOSDS/assets/images/QUAD-DS-logo-2.1.svg

http://localhost:5000/QMOSDS/socket.io/?EIO=4&transport=polling&t=OFMbSOj&sid=vY6aX2_07Gpk3-ZZAAAC http://localhost:5000/QMOSDS/api/Home/GetConfigurations (POST)

everything works well.

But I failed in async_mode=’eventlet’

sio = socketio.Server(async_mode=’eventlet’, logger=True, engineio_logger=True, cors_allowed_origins=’*’)

socketio_app = socketio.WSGIApp(sio, app, static_files=None, socketio_path=’/QMOSDS/socket.io’)

eventlet.wsgi.server(eventlet.listen((HOST, PORT)), socketio_app)

405 Method not allowed because CORS allow methods: GET, HEAD, OPTIONS http://localhost:5000/QMOSDS/api/Home/GetConfigurations (POST)

If I changed to method «GET», then method is allowed but method not found

when call socketio.Server, how to set CORS allow methods? how to fix the method not found issue? Thanks!

Miguelgrinberg

@netwang you are ignoring something very important. Flask doesn’t support async/await. Eventlet does not support async/await. The threading mode in python-socketio does not support async/await. This will never work.

Comment

Netwang commented on 3 months ago

Netwang

@miguelgrinberg Sorry, I explained my case wrongly. My code still in sync mode, not async / await.

I successfully used Flask and Flask-Socketio with eventlet on Windows. I am trying Flask and python-Socketio with eventlet on Windows in sync mode. I successfully setup Flask with python-socketio in async_mode=’threading’

sio = socketio.Server(async_mode=’threading’, logger=True, engineio_logger=True, cors_allowed_origins=’*’)

app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app, static_files=None, socketio_path=’/QMOSDS/socket.io’)

http://localhost:5000/QMOSDS/assets/images/QUAD-DS-logo-2.1.svg

http://localhost:5000/QMOSDS/socket.io/?EIO=4&transport=polling&t=OFMbSOj&sid=vY6aX2_07Gpk3-ZZAAAC http://localhost:5000/QMOSDS/api/Home/GetConfigurations (POST)

everything works well.

But I failed in async_mode=’eventlet’

sio = socketio.Server(async_mode=’eventlet’, logger=True, engineio_logger=True, cors_allowed_origins=’*’)

socketio_app = socketio.WSGIApp(sio, app, static_files=None, socketio_path=’/QMOSDS/socket.io’)

eventlet.wsgi.server(eventlet.listen((HOST, PORT)), socketio_app)

405 Method not allowed because CORS allow methods: GET, HEAD, OPTIONS http://localhost:5000/QMOSDS/api/Home/GetConfigurations (POST)

If I changed to method «GET», then method is allowed but method not found

how to add ‘QMOSDS’ subdirectory into eventlet.listen((HOST, PORT)) ??

Thanks!

Miguelgrinberg

@netwang The error is not in the Socket.IO endpoint, it is for an endpoint of your own Flask application, correct? So the way to address the error is to configure CORS for your Flask application. Have you done that? The Flask-CORS extension can be useful.

Сообщение об ошибке

greenlet.error: cannot switch to a different thread

Решение

Настройка-> Build-> Python Debugger-> Gevent совместимо (проверка)


Интеллектуальная рекомендация

Java.lang.unsatisfiedLinkErrrror Решение

Иногда у нас есть доступ к некоторым так библиотекам, пока у нас есть доступ к стороннему SDK. После использования операции будет сообщено следующее исключение. Java.lang.unsatisfiedLinker.  &nbs…

Android Загрузка изображения (2) Краткое введение и простое использование

An image loading and caching library for Android focused on smooth scrolling https://bumptech.github.io/glide/ Перевод: нагрузки на Android нагрузки и библиотеки кеша, предназначенные для сглажив…

Установка оттенка

1. Загрузите и разархивируйте установочный пакет. cd /export/soft/ tar -zxvf hue-3.9.0-cdh5.14.0.tar.gz -C ../servers два,Работа по инициализации компиляции   1. Установите различные необходимые …

Небольшие проблемы решения для написания кода в Eclipse

Когда Eclipse записывает программу, иногда вы можете ошибочно нажать цифровую блокировку или клавишу вставки, чтобы курсор на экране менялся с | к черному квадратному кадру, который будет охватывать я…

Процедура хранения пейджинга

   Перепечатано: https://www.cnblogs.com/muxueyuan/p/5025521.html…

Вам также может понравиться

После нажатия кнопки кнопку, поле ввода на странице автоматически снова получает фокус

Требование: нажмите кнопку кнопки. После успешного ввода поле ввода на странице автоматически фокусируется на следующей записи, чтобы повысить эффективность Я начал пробовать несколько способов и не д…

Шестнадцатеричное преобразование

Различные механизмы преобразования функций функция strtol Его функция заключается в преобразовании произвольного шестнадцатеричного числа 1-36 в десятичное число и возвращении длинного типа int. Функц…

Выпадающий фильтр мини-программы плюс сброс

Для большинства сценариев со списками требуется фильтрация списка, поэтому вам нужно превратить раскрывающийся список в компонентный компонент для выбора. Далее следует рендеринг (не очень красивый) С…

Одна статья сделана путем использования чтения и написания библиотеки классов NPOI и написания чтения, написания и написания файла потока iO

Одна статья сделана путем использования чтения и написания библиотеки классов NPOI и написания чтения и написания файла потока iO Сегодня мы используем библиотеки класса NPOI для чтения и записи файло…

Почему ты пришел сюда?

Почему ты пришел сюда? Джейн Лаги Три….

Статьи по теме

  • Ошибка импорта тензорного потока в Pycharm
  • Pycharm Start не удался (внутренняя ошибка) Решение измерения
  • Ошибка начала Pycharm: не удалось создать JVM.
  • Ошибка компиляции Python3: не удается найти -lboost_python3
  • Ошибка Python3: Typerror: не удается составить байты на Str
  • Установите ошибку композитора: не удалось декодировать поток zlib
  • Ошибка ошибки установки Pycharm
  • О проблеме импорта Python3 (может работать pycharm, ошибка импорта из командной строки)
  • Ошибка записи Python3 Версия Установка Коляска в Pycharm и запустите Hello World
  • Ошибка: не удалось создать дочерний цикл событий в pycharm в centos 7

популярные статьи

  • Глава 5 Заявление о тернарной операции JavaScript
  • Весенняя архитектура исходного кода-кода
  • [ACMcoder] Number Sequence
  • Там, где есть люди, есть реки и озера, тише ~~!
  • Python выходной XML-файл
  • HDU 1733 Escape (максимальный поток + алгоритм динамики)
  • Hiveerver2 Конфигурация сервера и начать
  • Windowsphone7 пользовательский -покраснение ввода пароля
  • Spring Boot Integrate MongoDB Learning Notes (2020.11.23)
  • Узнайте Ethereum Deployed Smart Contracts (4) -Remix пишет первый смарт -контракт (Ubuntu20.04)

рекомендованная статья

  • SQL Server 2016: статистика запросов в реальном времени
  • Tomcat
  • MINDSPORE! Я любил эту существующую структуру глубины обучения!
  • Пример устранения неполадок при установке Microsoft Office Communications Server 2007 R2
  • Удовольствие с javascript — сводка баллов знаний
  • Нарисуйте маленький Gif-домик с помощью ps (1)
  • Технология сеанса Приложение — Код подтверждения Вход в систему
  • Процесс компиляции и запуска Android
  • Демонстрация двухслойной простой нейронной сети
  • PHP извлекает возвращенные данные, последующий код продолжает выполнять инкапсулированную функцию

Связанные теги

  • pycharm
  • tensorflow
  • Нейронные сети
  • python
  • Pycharm может работать, ошибка импорта командной строки
  • Проблема импорта Python3
  • Импорт той же папки
  • Импорт под разными папками
  • flask
  • unsatisfiedlinkerror

Consider this code snippet. It starts a background thread and exposes an attribute that allows switching to the main greenlet of the background thread. The main thread then attempts to call this switch method.

# bad_switch.py
from time import sleep as native_sleep
from threading import Thread as NativeThread
from threading import Event as NativeEvent

import greenlet


class Thread(NativeThread):
    def __init__(self):
        NativeThread.__init__(self)
        self.switch_to_greenlet = None
        self.running = NativeEvent()
        self.daemon = True

    def run(self):
        self.switch_to_greenlet = greenlet.getcurrent().switch
        def bg():
            self.running.set()
            native_sleep(10)

        glet = greenlet.greenlet(bg)
        glet.switch()
        print('T2: Resumed')


t = Thread()
t.start()
t.running.wait()
t.switch_to_greenlet() # line 29

Under CPython with any version of greenlet, this results in the main thread raising an exception:

$ python bad_switch.py
Traceback (most recent call last):
  File "/private/tmp/bad_switch.py", line 29, in <module>
    t.switch_to_greenlet()
greenlet.error: cannot switch to a different thread

Under PyPy, however, nothing appears to happen. The main thread raises no exception, but neither is the greenlet resumed («T2: Resumed» is not printed). I’ve tested this with PyPy 2.7-7.3.3 (macOS and Linux), PyPy 3.7-7.3.3 (mac only) and pypy-c-jit-101407-060e8d505b33-osx64.

The same thing happens if the bg greenlet is deleted and the background thread runs all the code itself in the main greenlet.

PyPy does raise the expected error if you attempt to switch to a non-main greenlet in a different thread; defining run like so:

    def run(self):

        run_main = greenlet.getcurrent().switch
        def bg():
            print("T2G2: running; switching to main")
            run_main()
            print("t2g2: resumed")
            native_sleep(10)

        glet = greenlet.greenlet(bg)
        self.switch_to_greenlet = glet.switch
        glet.switch()
        print('T2G1: Resumed')
        self.running.set()
        native_sleep(10)

results in:

$ pypy3 bad_switch.py
T2G2: running; switching to main
T2G1: Resumed
Traceback (most recent call last):
  File "bad_switch.py", line 35, in <module>
    t.switch_to_greenlet()
  File "//pypy3/lib_pypy/greenlet.py", line 54, in switch
    return self.__switch('switch', (args, kwds))
  File "//pypy3/lib_pypy/greenlet.py", line 93, in __switch
    args, kwds = unbound_method(current, *baseargs, to=target)
_continuation.error: inter-thread support is missing

This comes up in the context of gevent, where I’ve had a bug report that switching between different threads like in the first example just hangs. On CPython, this was a bug where gevent was silently catching and ignoring the greenlet.error but on PyPy, because there’s no error and nothing seems to happen when you switch(), I don’t know how to fix, or even detect, the hang.

can you include the complete traceback along with all versions in use?

I can run the wssh project with python2 and gevent-1.0.2.When I use python3 to run it, I modify some bugs in gevent_websocket.
This is the complete traceback in the debug mode and I haven’t passing parameters to paramiko.SSHClient:

After I add parameters to SSHclient, it was broken in self.spawn(fun,_args,_*kwds).get():

在 2015年11月23日,上午4:42,Jason Madden [email protected] 写道:

can you include the complete traceback along with all versions in use?


Reply to this email directly or view it on GitHub https://github.com/gevent/gevent/issues/689#issuecomment-158798188.

It looks like you tried to include two things in your message that didn’t make it through. Can you try again? Also, gevent-1.0.2 is not supported on Python 3. You need gevent >= 1.1rc1 on Python 3….but I don’t think gevent_websocket supports Python 3 at all.

GeventWebsocket doesn’t support Python3, so I have modified some bugs. I will try again, thank you very much.

在 2015年11月24日,上午12:40,Jason Madden [email protected] 写道:

It looks like you tried to include two things in your message that didn’t make it through. Can you try again? Also, gevent-1.0.2 is not supported on Python 3. You need gevent >= 1.1rc1 on Python 3….but I don’t think gevent_websocket supports Python 3 at all.


Reply to this email directly or view it on GitHub https://github.com/gevent/gevent/issues/689#issuecomment-158990508.

Are there any updates on this?

Closing in triage for 1.2a1 since there haven’t been any updates since February. Feel free to re-open if there is new information.

If you see this in the context of debugging using PyCharm, try this:

Go to Settings —> Build, Execution, Deployment -> Python Debugger.
In that dialog, you’ll see a «Gevent compatible» checkbox. Not sure how it got unticked in the new project.

Tick that option and enjoy!

@zwbzzp FYI gevent-websocket now supports Python 3

@advance512 Thanks, it works.

Not sure I completely understand what your issue is, but I have used the
configuration above for the last 3+ years, nowadays with Python 3.8, and I
have had no issues with breakpoints.

Try to update to the latest version of PyCharm and Python and see if that
helps.

I see. Well, their documentation states:

This parameter works for Python >= 2.7, Python >= 3.5

So, if you are using any modern version of Python (3.5 or newer) you can
expect debugging and breakpoints to work properly. If you are using Python
3.4 or older (or an EOL version of Python, like 2.x, specifically 2.6 or
older) then things indeed might will not work for you. Is this your case?

If you are running into issues with version 3.5 or newer of Python, then
you probably just need to upgrade your JetBrains tools, or have run into an
actual bug, in which case I recommend you report it.

Good luck! :)

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Green orxnge x nissan playa error mistake remix скачать
  • Green orange nissan playa error mistake remix скачать
  • Green hell unity error
  • Greedfall как изменить язык
  • Gree как посмотреть код ошибки

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии