redbicycle / pyv8

Automatically exported from code.google.com/p/pyv8
0 stars 0 forks source link

PyV8 segmentation fault with CherryPy #248

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Built on Fedora 19, roughly using the instructions on:
https://andrewwilkinson.wordpress.com/2012/01/23/integrating-python-and-javascri
pt-with-pyv8/

Python 2.7

2. Download CherryPy 3.7.0

3. Run the following:

import cherrypy
import PyV8

class Hello(object):

    def index(self):
        ctx = PyV8.JSContext()
        return "Hello World!"
    index.exposed = True

cherrypy.quickstart(Hello())

4: Access in browser: http://localhost:8080 through browser.

What is the expected output? What do you see instead?

Expected: "Hello World" on web browser
Instead: Segmentation Fault

Example:

python test_cherrypy.py
[12/Jun/2015:05:36:57] ENGINE Listening for SIGHUP.
[12/Jun/2015:05:36:57] ENGINE Listening for SIGTERM.
[12/Jun/2015:05:36:57] ENGINE Listening for SIGUSR1.
[12/Jun/2015:05:36:57] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.

[12/Jun/2015:05:36:57] ENGINE Started monitor thread 'Autoreloader'.
[12/Jun/2015:05:36:57] ENGINE Started monitor thread '_TimeoutMonitor'.
[12/Jun/2015:05:36:57] ENGINE Serving on http://localhost:8080
[12/Jun/2015:05:36:57] ENGINE Bus STARTED
Segmentation fault

What version of the product are you using? On what operating system?

Python 2.7.5
CherryPy 3.7.0
PyV8 1.0 (trunk)
V8 (trunk)

Please provide any additional information below.

Everything seems to work fine with scripts from the command line.  I tested 
much of my needed functionality with Unit tests with no issues.  However, as 
soon as the line:

        ctx = PyV8.JSContext()

is executed through CherryPy, a segmentation fault occurs, crashing out the 
entire web service.

Original issue reported on code.google.com by re...@southpawtech.com on 15 Jun 2015 at 1:54

GoogleCodeExporter commented 8 years ago
I managed to get a stack trace running gdb:

(gdb) run tt2.py
Starting program: /usr/bin/python tt2.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7fffecd7e700 (LWP 11592)]
[New Thread 0x7ffff7ba3700 (LWP 11593)]
[New Thread 0x7ffff7b92700 (LWP 11594)]
CherryPy:  3.7.0
[12/Jun/2015:07:59:22] ENGINE Listening for SIGHUP.
[12/Jun/2015:07:59:22] ENGINE Listening for SIGTERM.
[12/Jun/2015:07:59:22] ENGINE Listening for SIGUSR1.
[12/Jun/2015:07:59:22] ENGINE Bus STARTING
CherryPy Checker:
The Application mounted at '' has an empty config.

[New Thread 0x7fffec57d700 (LWP 11595)]
[12/Jun/2015:07:59:22] ENGINE Started monitor thread 'Autoreloader'.
[New Thread 0x7fffebd7c700 (LWP 11596)]
[12/Jun/2015:07:59:22] ENGINE Started monitor thread '_TimeoutMonitor'.
[New Thread 0x7fffeb57b700 (LWP 11597)]
[New Thread 0x7fffead7a700 (LWP 11598)]
[New Thread 0x7fffea579700 (LWP 11599)]
[New Thread 0x7fffe9d78700 (LWP 11600)]
[New Thread 0x7fffe9577700 (LWP 11601)]
[New Thread 0x7fffe8d76700 (LWP 11602)]
[New Thread 0x7fffcbfff700 (LWP 11603)]
[New Thread 0x7fffcb7fe700 (LWP 11604)]
[New Thread 0x7fffcaffd700 (LWP 11605)]
[New Thread 0x7fffca7fc700 (LWP 11606)]
[New Thread 0x7fffc9ffb700 (LWP 11607)]
[12/Jun/2015:07:59:23] ENGINE Serving on http://192.168.205.130
[12/Jun/2015:07:59:23] ENGINE Bus STARTED

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffea579700 (LWP 11599)]
0x00007fffed9d7bc3 in v8::HandleScope::Initialize(v8::Isolate*) ()
   from /usr/lib64/python2.7/site-packages/PyV8-1.0_dev-py2.7-linux-x86_64.egg/_PyV8.so
(gdb) bt
#0  0x00007fffed9d7bc3 in v8::HandleScope::Initialize(v8::Isolate*) ()
   from /usr/lib64/python2.7/site-packages/PyV8-1.0_dev-py2.7-linux-x86_64.egg/_PyV8.so
#1  0x00007fffed9606bb in CContext::CContext (this=0x7fffd800d1b0, global=...,
    extensions=...) at src/Context.cpp:107
#2  0x00007fffed965a78 in 
value_holder<boost::python::objects::reference_to_value<boost::python::api::obje
ct>, boost::python::objects::reference_to_value<boost::python::list> > (a1=..., 
a0=..., self=0x7fffe403c6d8, this=0x7fffd800d1a0)
    at /usr/include/boost/python/object/value_holder.hpp:137
#3  
boost::python::objects::make_holder<2>::apply<boost::python::objects::value_hold
er<CContext>, boost::mpl::vector2<boost::python::api::object, 
boost::python::list> >::execute (p=0x7fffe403c6d8, a0=..., a1=...)
    at /usr/include/boost/python/object/make_holder.hpp:95
#4  0x00007fffed9646d9 in invoke<int, void (*)(_object*, 
boost::python::api::object, boost::python::list), 
boost::python::arg_from_python<_object*>, 
boost::python::arg_from_python<boost::python::api::object>, 
boost::python::arg_from_python<boost::python::list> >
    (
    f=@0xbdfd88: 0x7fffed965a00 <boost::python::objects::make_holder<2>::apply<boost::python::objects::value_holder<CContext>, boost::mpl::vector2<boost::python::api::object, boost::python::list> >::execute(_object*, boost::python::api::object, boost::python::list)>, ac2=<synthetic pointer>, ac1=<synthetic pointer>, ac0=<synthetic pointer>)
    at /usr/include/boost/python/detail/invoke.hpp:81
#5  operator() (args_=<optimized out>, this=0xbdfd88)
    at /usr/include/boost/python/detail/caller.hpp:223
#6  
boost::python::objects::caller_py_function_impl<boost::python::detail::caller<vo
id (*)(_object*, boost::python::api::object, boost::python::list), 
boost::python::default_call_policies, boost::mpl::vector4<void, _object*, 
boost::python::api::object, boost::python::list> > >::operator() 
(this=0xbdfd80, args=<optimized out>, kw=<optimized out>)
    at /usr/include/boost/python/object/py_function.hpp:38
#7  0x00007fffed3c746a in boost::python::objects::function::call(_object*, 
_object*) const () from /lib64/libboost_python.so.1.53.0
#8  0x00007fffed3c77d8 in 
boost::detail::function::void_function_ref_invoker0<boost::python::objects::(ano
nymous namespace)::bind_return, 
void>::invoke(boost::detail::function::function_buffer&) () from 
/lib64/libboost_python.so.1.53.0
#9  0x00007fffed3d1713 in 
boost::python::detail::exception_handler::operator()(boost::function0<void> 
const&) const () from /lib64/libboost_python.so.1.53.0
#10 0x00007fffed959113 in operator() (this=<optimized out>,
    translate=0x7fffed957310 <ExceptionTranslator::Translate(CJavascriptException const&)>, f=..., handler=...) at /usr/include/boost/python/detail/translate_exception.hpp:48
#11 operator()<bool, 
boost::python::detail::translate_exception<CJavascriptException, void (*)(const 
CJavascriptException&)>, boost::_bi::list2<const 
boost::python::detail::exception_handler&, const boost::function0<void>&> > 
(f=..., a=<synthetic pointer>,
    this=<optimized out>) at /usr/include/boost/bind/bind.hpp:382
#12 operator()<boost::python::detail::exception_handler, boost::function0<void> 
> (
    a2=..., a1=..., this=<optimized out>)
---Type <return> to continue, or q <return> to quit---
    at /usr/include/boost/bind/bind_template.hpp:102
#13 boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, 
boost::python::detail::translate_exception<CJavascriptException, void 
(*)(CJavascriptException const&)>, boost::_bi::list3<boost::arg<1>, 
boost::arg<2>, boost::_bi::value<void (*)(CJavascriptException const&)> > >, 
bool, boost::python::detail::exception_handler const&, boost::function0<void> 
const&>::invoke (function_obj_ptr=..., a0=..., a1=...)
    at /usr/include/boost/function/function_template.hpp:132
#14 0x00007fffed3d14dd in 
boost::python::handle_exception_impl(boost::function0<void>)
    () from /lib64/libboost_python.so.1.53.0
#15 0x00007fffed3c5f93 in function_call () from /lib64/libboost_python.so.1.53.0
#16 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#17 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#18 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#19 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#20 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#21 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#22 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#23 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#24 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#25 0x00007ffff7cc98a7 in ?? () from /lib64/libpython2.7.so.1.0
#26 0x00007ffff7cc860f in ?? () from /lib64/libpython2.7.so.1.0
#27 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#28 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#29 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#30 0x00007ffff7c98ccd in ?? () from /lib64/libpython2.7.so.1.0
#31 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#32 0x00007ffff7d04e5d in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#33 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#34 0x00007ffff7c98ccd in ?? () from /lib64/libpython2.7.so.1.0
#35 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#36 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#37 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#38 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#39 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#40 0x00007ffff7d04e5d in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#41 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#42 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#43 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#44 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#45 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#46 0x00007ffff7c7f928 in ?? () from /lib64/libpython2.7.so.1.0
#47 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#48 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#49 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
---Type <return> to continue, or q <return> to quit---
#50 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#51 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#52 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#53 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#54 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#55 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#56 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#57 0x00007ffff7cc98a7 in ?? () from /lib64/libpython2.7.so.1.0
#58 0x00007ffff7cc860f in ?? () from /lib64/libpython2.7.so.1.0
#59 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#60 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#61 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#62 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#63 0x00007ffff7c98ccd in ?? () from /lib64/libpython2.7.so.1.0
#64 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#65 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#66 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#67 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#68 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#69 0x00007ffff7d04e5d in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#70 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#71 0x00007ffff7d086a9 in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#72 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#73 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#74 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#75 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#76 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#77 0x00007ffff7cc98a7 in ?? () from /lib64/libpython2.7.so.1.0
#78 0x00007ffff7cc860f in ?? () from /lib64/libpython2.7.so.1.0
#79 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#80 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#81 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#82 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#83 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#84 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#85 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#86 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#87 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#88 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#89 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#90 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#91 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#92 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#93 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
---Type <return> to continue, or q <return> to quit---
#94 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#95 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#96 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#97 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#98 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#99 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#100 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#101 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#102 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#103 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#104 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#105 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#106 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#107 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#108 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#109 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#110 0x00007ffff7cc9c47 in ?? () from /lib64/libpython2.7.so.1.0
#111 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#112 0x00007ffff7d0661c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#113 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#114 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#115 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#116 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#117 0x00007ffff7d0874c in PyEval_EvalFrameEx () from /lib64/libpython2.7.so.1.0
#118 0x00007ffff7d09bbd in PyEval_EvalCodeEx () from /lib64/libpython2.7.so.1.0
#119 0x00007ffff7c98bf0 in ?? () from /lib64/libpython2.7.so.1.0
#120 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#121 0x00007ffff7c83515 in ?? () from /lib64/libpython2.7.so.1.0
#122 0x00007ffff7c74db3 in PyObject_Call () from /lib64/libpython2.7.so.1.0
#123 0x00007ffff7d03a37 in PyEval_CallObjectWithKeywords ()
   from /lib64/libpython2.7.so.1.0
#124 0x00007ffff7d371c2 in ?? () from /lib64/libpython2.7.so.1.0
#125 0x0000003bc3407c53 in start_thread () from /lib64/libpthread.so.0
#126 0x0000003bc2cf5e1d in clone () from /lib64/libc.so.6

Original comment by re...@southpawtech.com on 15 Jun 2015 at 4:07

GoogleCodeExporter commented 8 years ago
After poking around, it looks like that PyV8 has a huge problem with threads, 
which CherryPy has in abundance.  It becomes very easy to crash with a 
segmentation fault when mixing PyV8 with Python threads.   However, there is a 
"hidden" mechanism to prevent this, JsLocker and JsUnlocker, which need to be 
called to make it no crash.

This is a more complete and working example that avoids the crashing:

import cherrypy
import PyV8

with PyV8.JSLocker():
    ctx = PyV8.JSContext()

class Hello(object):

    def index(my):
        data_str = ""
        with PyV8.JSLocker():
            ctx.enter()
            data = ctx.eval('''
            var data = {
                a: 123,
                b: "wwwww"
            }
            data
            ''')
            data = PyV8.convert(data)
            PyV8.JSUnlocker()
            ctx.leave()
            return data
    index.exposed = True

if __name__ == '__main__':
    cherrypy.quickstart(Hello())

Unless there are particular performance reasons, I believe that these locking 
and unlocking calls should be built in so that the application developer 
doesn't have to worry about it.  Diagnosing the source of the problem was 
rather painful.  Or at least have proper error messaging and documentation so 
that the debugging time can be reduced.

Original comment by re...@southpawtech.com on 16 Jun 2015 at 1:49