Thanks for your suggestion
After debugging the serialize/deserialize implementation, I found the
root cause is that I entered a context before serialize the heap, so,
the saved context was dumped to the snapshot file. When I load the
snapshot, I can't enter a context, because Context::New will automatic
initialize the v8 VM; it means, I missed a saved context in snapshot,
and the verification will be failed.
So, I just avoid to call the Context::enter and the load will be ok.
Even so, I'm confused why the cctest code could do this?
static void Serialize() {
#ifdef DEBUG
FLAG_debug_serialization = true;
#endif
StatsTable::SetCounterFunction(counter_function);
v8::HandleScope scope;
const int kExtensionCount = 1;
const char* extension_list[kExtensionCount] = { "v8/gc" };
v8::ExtensionConfiguration extensions(kExtensionCount,
extension_list);
Serializer::Enable();
v8::Persistent<v8::Context> env = v8::Context::New(&extensions);
env->Enter();
Snapshot::WriteToFile(FLAG_testing_serialization_file);
}
static void Deserialize() {
#ifdef DEBUG
FLAG_debug_serialization = true;
#endif
CHECK(Snapshot::Initialize(FLAG_testing_serialization_file));
}
The other problem is that after I call the v8::internal::V8::Initialize
(&deserializer) method, the stack around deserializer the will be
destroyed. I'm not sure where is the root cause, so, just use a
pointer of deserializer and leave it with memory leak :(
On the other hand, I found the user registered extension will not be
restore after load the snapshot. I could find the extension name and
script int the snapshot file, but I can't find it in the
RegisteredExtension::first_extension_ chain. Could you give me some
hints how to use it after load a snapshot? I believe it should be
work, because I could find v8/gc extension in that list after load the
same snapshot.
Thanks
On 10月19日, 下午3时45分, Erik Corry <[email protected]> wrote:
> 2009/10/19 Flier Lu <[email protected]>:
>
>
>
> > So, do you mean that I need fire a GC before serialize/deserialize
> > heap? and how can I ensure the GC roots keep same numbers? Are there
> > any tools could dump the whole heap and make a difference for
> > troubleshoting?
>
> You should try running the debug version of the VM and using the
> --debug-serialization flag. This will insert tags in the
> serialization stream which will be checked when deserializing.
> Looking at where this happens in gdb may tell you where the serializer
> and the deserializer are getting out of sync. Good luck!
>
>
>
>
>
> > Thanks any way, I think I could try to adjust context later.
>
> > On 10月18日, 下午5时25分, Erik Corry <[email protected]> wrote:
> >> The serialization/deserialization code is very sensitive to what the
> >> VM has done since it started up. Installing extensions and probably
> >> many other API calls like context creation etc. will cause garbage
> >> collection roots to be created. These are traversed when serializing
> >> and deserializing and if the number of them doesn't match up then you
> >> will probably get a crash.
>
> >> I realize this is not very detailed help. It may help to compile in
> >> debug mode to get the asserts etc. which could give you more of a clue
> >> as to what is going on.
>
> >> 2009/10/18 Flier Lu <[email protected]>:
>
> >> > I'm trying to add serialize/deserialize supports to pyv8, a two-way
> >> > python and v8 wrapper, base on the v8 internal APIs.
>
> >> > Till now, I could dump the snapshot with Serializer.Serialize, but
> >> > fail to use it to initialize v8 again. The
> >> > Deserializer::GetContextStack function failed, because the expected
> >> > format is wrong. I'm confused because the snapshot was generated with
> >> > same v8 version, even the size seems too smaller (262K) than cctest
> >> > generated serdes (432K).
>
> >> > Could you give me some hints, what I missed when dumping the snapshot?
> >> > I just refer the test-serialze.cc code and translate it to python
> >> > wrapper.
>
> >> > Thanks
>
> >> > # test code with pyv8
> >> > #!/usr/bin/env python
> >> > import sys
>
> >> > from PyV8 import *
>
> >> > if len(sys.argv) == 1:
> >> > extSrc = """function hello(name) { return "hello " + name + " from
> >> > javascript"; }"""
> >> > extJs = JSExtension("hello/javascript", extSrc)
>
> >> > JSEngine.serializeEnabled = True
>
> >> > with JSContext(extensions=['hello/javascript']) as ctxt:
> >> > data = JSEngine.serialize()
>
> >> > open('snapshot.dat', 'wb').write(data)
>
> >> > print "write %d bytes to snapshot.dat" % len(data)
> >> > else:
> >> > data = open(sys.argv[1], 'rb').read()
>
> >> > print "read %d bytes from %s" % (len(data), sys.argv[1])
>
> >> > raw_input()
>
> >> > JSEngine.deserialize(data)
>
> >> > with JSContext() as ctxt:
> >> > print ctxt.eval("hello('flier')")
>
> >> > # implementation code in pyv8
> >> > #http://code.google.com/p/pyv8/source/browse/trunk/src/Engine.cpp
> >> > py::object CEngine::Serialize(void)
> >> > {
> >> > v8::internal::byte* data = NULL;
> >> > int size = 0;
>
> >> > Py_BEGIN_ALLOW_THREADS
>
> >> > v8::internal::StatsTable::SetCounterFunction
> >> > (&CEngine::CounterLookup);
>
> >> > v8::internal::Serializer serializer;
>
> >> > serializer.Serialize();
>
> >> > serializer.Finalize(&data, &size);
>
> >> > Py_END_ALLOW_THREADS
>
> >> > py::object obj(py::handle<>(::PyBuffer_New(size)));
>
> >> > void *buf = NULL;
> >> > Py_ssize_t len = 0;
>
> >> > if (0 == ::PyObject_AsWriteBuffer(obj.ptr(), &buf, &len) && buf &&
> >> > len > 0)
> >> > {
> >> > memcpy(buf, data, len);
> >> > }
> >> > else
> >> > {
> >> > obj = py::object();
> >> > }
>
> >> > return obj;
> >> > }
> >> > void CEngine::Deserialize(py::object snapshot)
> >> > {
> >> > const void *buf = NULL;
> >> > Py_ssize_t len = 0;
>
> >> > if (PyBuffer_Check(snapshot.ptr()))
> >> > {
> >> > if (0 != ::PyObject_AsReadBuffer(snapshot.ptr(), &buf, &len))
> >> > {
> >> > buf = NULL;
> >> > }
> >> > }
> >> > else if(PyString_CheckExact(snapshot.ptr()) || PyUnicode_CheckExact
> >> > (snapshot.ptr()))
> >> > {
> >> > if (0 != ::PyString_AsStringAndSize(snapshot.ptr(), (char **)&buf,
> >> > &len))
> >> > {
> >> > buf = NULL;
> >> > }
> >> > }
>
> >> > if (buf && len > 0)
> >> > {
> >> > Py_BEGIN_ALLOW_THREADS
>
> >> > v8::internal::Deserializer deserializer((const v8::internal::byte
> >> > *) buf, len);
>
> >> > deserializer.GetFlags();
>
> >> > v8::internal::V8::Initialize(&deserializer);
>
> >> > Py_END_ALLOW_THREADS
> >> > }
> >> > }
>
> >> > # error message when execute the test code
> >> > #
> >> > # Fatal error in d:\javascript\google-v8\src\serialize.h, line 221
> >> > # CHECK(c == expected) failed
> >> > #
>
> >> > # call stack for error
> >> >> _PyV8.pyd!v8::internal::OS::DebugBreak() Line 882 C++
> >> > _PyV8.pyd!v8::internal::OS::Abort() Line 877 C++
> >> > _PyV8.pyd!V8_Fatal(const char * file=0x1052ddfc, int line=221,
> >> > const
> >> > char * format=0x10527e68, ...) Line 57 C++
> >> > _PyV8.pyd!CheckHelper(const char * file=0x1052ddfc, int line=221,
> >> > const char * source=0x1052e0bc, bool condition=false) Line 62 + 0x16
> >> > bytes C++
> >> > _PyV8.pyd!v8::internal::SnapshotReader::ExpectC(char expected='C')
> >> > Line 221 + 0x22 bytes C++
> >> > _PyV8.pyd!v8::internal::Deserializer::GetContextStack() Line
> >> > 1595 C+
> >> > +
> >> > _PyV8.pyd!v8::internal::Deserializer::Deserialize() Line 1431
> >> > C++
> >> > _PyV8.pyd!v8::internal::V8::Initialize(v8::internal::Deserializer
> >> > *
> >> > des=0x0021f300) Line 106 C++
> >> > _PyV8.pyd!CEngine::Deserialize(boost::python::api::object
> >> > snapshot=
> >> > {...}) Line 182 + 0xc bytes C++
> >> > _PyV8.pyd!boost::python::detail::invoke<int,void (__cdecl*)
> >> > (boost::python::api::object),boost::python::arg_from_python<boost::python::
> >> > api::object>
> >> >>(boost::python::detail::invoke_tag_<1,0> __formal={...},
> >> > boost::python::detail::invoke_tag_<1,0> __formal={...}, void
> >> > (boost::python::api::object)* & f=0x101a8cf4,
> >> > boost::python::arg_from_python<boost::python::api::object> & ac0=
> >> > {...}) Line 81 + 0x1f bytes C++
> >> > _PyV8.pyd!boost::python::detail::caller_arity<1>::impl<void
> >> > (__cdecl*)
> >> > (boost::python::api::object),boost::python::default_call_policies,boost::mp
> >> > l::vector2<void,boost::python::api::object>
> >> >>::operator()(_object * args_=0x01312610, _object *
> >> > __formal=0x00000000) Line 223 + 0x37 bytes C++
> >> > _PyV8.pyd!
> >> > boost::python::objects::caller_py_function_impl<boost::python::detail::call
> >> > er<void
> >> > (__cdecl*)
> >> > (boost::python::api::object),boost::python::default_call_policies,boost::mp
> >> > l::vector2<void,boost::python::api::object>
> >> >> >::operator()(_object * args=0x01312610, _object * kw=0x00000000)
> >> > Line 39 C++
> >> > _PyV8.pyd!boost::python::objects::py_function::operator()(_object
> >> > *
> >> > args=0x01312610, _object * kw=0x00000000) Line 144 C++
> >> > _PyV8.pyd!boost::python::objects::function::call(_object *
> >> > args=0x01312610, _object * keywords=0x00000000) Line 226 + 0x24 bytes
> >> > C++
> >> > _PyV8.pyd!boost::python::objects::`anonymous
> >> > namespace'::bind_return::operator()() Line 581 + 0x19 bytes C++
> >> > _PyV8.pyd!
> >> > boost::detail::function::void_function_ref_invoker0<boost::python::objects:
> >> > :`anonymous
> >> > namespace'::bind_return,void>::invoke
> >> > (boost::detail::function::function_buffer & function_obj_ptr={...})
> >> > Line 189 C++
> >> > _PyV8.pyd!boost::function0<void>::operator()() Line 1013 + 0x14
> >> > bytes C++
> >> >
> >> > _PyV8.pyd!boost::python::detail::exception_handler::operator()(const
> >> > boost::function0<void> & f={...}) Line 75 C++
> >> > _PyV8.pyd!
> >> > boost::python::detail::translate_exception<CJavascriptException,void
> >> > (__cdecl*)(CJavascriptException const &)>::operator()(const
> >> > boost::python::detail::exception_handler & handler={...}, const
> >> > boost::function0<void> & f={...}, void (const CJavascriptException &)*
> >> > const translate=0x101a98a2) Line 46 + 0xc bytes C++
> >> > _PyV8.pyd!
> >> > boost::_bi::list3<boost::arg<1>,boost::arg<2>,boost::_bi::value<void
> >> > (__cdecl*)(CJavascriptException const &)> >::operator()
> >> > <bool,boost::python::detail::translate_exception<CJavascriptException,void
> >> > (__cdecl*)(CJavascriptException const &)
> >> >>,boost::_bi::list2<boost::python::detail::exception_handler const
> >> > &,boost::function0<void> const &> >(boost::_bi::type<bool> __formal=
> >> > {...},
> >> > boost::python::detail::translate_exception<CJavascriptException,void
> >> > (__cdecl*)(CJavascriptException const &)> & f={...},
> >> > boost::_bi::list2<boost::python::detail::exception_handler const
> >> > &,boost::function0<void> const &> & a={...}, boost::_bi::type<bool>
> >> > __formal={...}) Line 376 C++
> >> > _PyV8.pyd!
> >> > boost::_bi::bind_t<bool,boost::python::detail::translate_exception<CJavascr
> >> > iptException,void
> >> > (__cdecl*)(CJavascriptException const &)
> >> >>,boost::_bi::list3<boost::arg<1>,boost::arg<2>,boost::_bi::value<void
> >> > (__cdecl*)(CJavascriptException const &)> > >::operator()
> >> > <boost::python::detail::exception_handler,boost::function0<void> >
> >> > (const boost::python::detail::exception_handler & a1={...}, const
> >> > boost::function0<void> & a2={...}) Line 103 C++
> >> > _PyV8.pyd!
> >> > boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool,boos
> >> > t::python::detail::translate_exception<CJavascriptException,void
> >> > (__cdecl*)(CJavascriptException const &)
> >> >>,boost::_bi::list3<boost::arg<1>,boost::arg<2>,boost::_bi::value<void
> >> > (__cdecl*)(CJavascriptException const &)> >
> >> >>,bool,boost::python::detail::exception_handler
>
> ...
>
> 阅读更多 >>
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---