Hi all, :)

I'm playing with Chromium and some of its components (majorly Blink and V8)
trying to add some interesting features. Unfortunately there's an
unexpected error that has already cost me some time before seeking help
here.

*1. Brief Description*

One of my attempts is to register an API function with another JS function
embedded (as the optional "data" parameter when initializing
a FunctionTemplate object). However I soon encountered errors with such
practices when working with snapshots. (Snapshots are used by Blink by
default when invoking V8).

The errors may be in different forms depending on the building option:
- When making a production build, the Chromium process would crash after a
few seconds when being launched.
- When making a debug build (with v8_enable_debugging_features=true), the
snapshot creation would fail.
(Please see below for detailed information on the errors.)

*2. A Minimal Example*

I managed to create a test case to reproduce the issue, which is attached
as the "test_snapshot_function_data.diff" file.
The change was made on commit 408a0c7 (version 8.1.44) and shall work for
also other recent versions.

- When launched in a production build, the test finishes properly. Please
see the attached "test_outcome_prod.txt" file for further details.
- When launched in a debugging build, the test would fail when trying to
create the snapshot (in "v8/src/snapshot/startup-serializer.cc" it says
"JSFunction should be added through the context snapshot instead of the
isolate snapshot"). Please see the attached "test_outcome_debug.txt" file
for further details.

*3. Crashes with Chromium*

When trying to do the same thing (embedding a JS function within
a FunctionTemplate, as illustrated in the
"test_snapshot_function_data.diff" file) as part of the whole Chromium
build, the debugging build wouldn't finish due to failure in creating the
snapshot (same as in the "test_outcome_debug.txt" file), while the
production build finishes successfully but leads to crashes when launching
the browser.

The crash happens almost instantly (a few seconds) after launching the
browser, and does not require any further action than launching the browser
(therefore the inserted JS function is not launched at all). Please find in
the attached "chromium_crash_log_prod.txt" file for the error logs.

*4. Help Wanted*

Can you please suggest whether the error happened because my approach was
wrong? if yes, could you point the right way of achieving the same
objective (to have a JS function embedded in a FunctionTemplate's "data"
parameter for later use)?

Or did the error happen because of an issue of V8's? I'm rather unsure of
this, thus I'd ask in the mailing list before trying to submit an issue.

Regards,
P. Chen
-- 
..for science, you monster.

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/v8-users/CAAfU8AFf8oX-X0hN9gUVWtnOW3AHu%2BxH02%2BJOZNT5%3D21aDe-LA%40mail.gmail.com.
$ cat /tmp/out/Prod/args.gn
is_debug=false
symbol_level=0
blink_symbol_level=0
enable_nacl=false
v8_enable_object_print=true
v8_enable_debugging_features=false

$ autoninja -C /tmp/out/Prod/ v8/test/cctest
ninja: Entering directory `/tmp/out/Prod/'
ninja: no work to do.

$ /tmp/out/Prod/cctest test-serialize/SnapshotCreatorFunctionAsCallbackData && 
echo "good :)"
good :)
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index f37b623504..2dfb3d32b5 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -3715,6 +3715,71 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
   FreeCurrentEmbeddedBlob();
 }
 
+static void CallbackUsingEmbeddedFunction(const FunctionCallbackInfo<Value>& info) {
+  auto func = v8::Handle<Function>::Cast(info.Data());
+  Local<Value> argv[] = {info[0]};
+  auto ret = func->Call(
+    info.GetIsolate()->GetCurrentContext(),
+    info.This(),
+    1,
+    argv
+  );
+  info.GetReturnValue().Set(ret.ToLocalChecked());
+}
+
+UNINITIALIZED_TEST(SnapshotCreatorFunctionAsCallbackData) {
+  DisableAlwaysOpt();
+  DisableEmbeddedBlobRefcounting();
+  v8::StartupData blob;
+  intptr_t external_references[] = {
+    reinterpret_cast<intptr_t>(CallbackUsingEmbeddedFunction),
+    0
+  };
+  {
+    v8::SnapshotCreator creator(external_references);
+    v8::Isolate* isolate = creator.GetIsolate();
+    {
+      v8::HandleScope handle_scope(isolate);
+      v8::Local<v8::Context> context = v8::Context::New(isolate);
+      v8::Context::Scope context_scope(context);
+      CompileRun("var f = function(n) { return n + 1; }");
+      {
+        v8::Local<FunctionTemplate> function_template = v8::FunctionTemplate::New(
+          isolate,
+          CallbackUsingEmbeddedFunction,
+          context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "f").ToLocalChecked()).ToLocalChecked()
+        );
+        context->Global()->Set(context, v8::String::NewFromUtf8(isolate, "g").ToLocalChecked(), function_template->GetFunction(context).ToLocalChecked()).FromJust();
+      }
+      creator.SetDefaultContext(context);
+    }
+    blob = creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+  }
+
+  ReadOnlyHeap::ClearSharedHeapForTest();
+  v8::Isolate::CreateParams params;
+  params.snapshot_blob = &blob;
+  params.array_buffer_allocator = CcTest::array_buffer_allocator();
+  params.external_references = external_references;
+  // Test-appropriate equivalent of v8::Isolate::New.
+  v8::Isolate* isolate = TestSerializer::NewIsolate(params);
+  {
+    v8::Isolate::Scope isolate_scope(isolate);
+    {
+      v8::HandleScope handle_scope(isolate);
+      v8::Local<v8::Context> context = v8::Context::New(isolate);
+      v8::Context::Scope context_scope(context);
+      ExpectInt32("f(1)", 2);
+      ExpectInt32("g(1)", 2);
+    }
+  }
+
+  isolate->Dispose();
+  delete[] blob.data;
+  FreeCurrentEmbeddedBlob();
+}
+
+
 UNINITIALIZED_TEST(ReinitializeHashSeedNotRehashable) {
   DisableAlwaysOpt();
   i::FLAG_rehash_snapshot = true;
$ cat /tmp/out/Prod-with-debug-v8/args.gn
is_debug=false
symbol_level=0
blink_symbol_level=0
enable_nacl=false
v8_enable_object_print=true
v8_enable_debugging_features=true

$ autoninja -C /tmp/out/Prod-with-debug-v8/ v8/test/cctest
ninja: Entering directory `/tmp/out/Prod-with-debug-v8/'
ninja: no work to do.

$ /tmp/out/Prod-with-debug-v8/cctest 
test-serialize/SnapshotCreatorFunctionAsCallbackData
Reference stack:
0x21880824d5a9: [SharedFunctionInfo] in OldSpace
 - map: 0x2188080405a1 <Map[40]>
 - name: 0x21880804047d <String[#0]: >
 - kind: NormalFunction
 - syntax kind: AnonymousExpression
 - function_map_index: 169
 - formal_parameter_count: 65535
 - expected_nof_properties: 0
 - language_mode: sloppy
 - data: 0x21880824d561 <FunctionTemplateInfo>
 - code (from data): 0x2188000435a1 <Code BUILTIN HandleApiCall>
 - function token position: 0
 - start position: 0
 - end position: 0
 - no debug info
 - scope info: 0x2188080406e1 <ScopeInfo[0]>
 - length: 0
 - feedback_metadata: <none>

0x21880824d561: [FunctionTemplateInfo] in OldSpace
 - map: 0x218808043351 <Map[56]>
 - class name: 0x21880804030d <undefined>
 - tag: 0
 - serial_number: 1
 - property_list: 0x21880804030d <undefined>
 - call_code: 0x21880824d599 <CallHandlerInfo callback= 0x218808240ea9 
<Foreign>, js_callback= 0x218808243549 <Foreign>, data= 0x218808240e89 
<JSFunction f (sfi = 0x21880824d459)>, side_effect_free= false>
 - property_accessors: 0x21880804030d <undefined>
 - signature: 0x21880804030d <undefined>
 - cached_property_name: 0x218808040385 <the_hole>
 - undetectable: false
 - need_access_check: false
 - instantiated: true
 - rare_data: 0x21880804030d <undefined>

0x21880824d599: [CallHandlerInfo] in OldSpace
 - map: 0x218808040c1d <Map[16]>
 - callback: 0x218808240ea9 <Foreign>
 - js_callback: 0x218808243549 <Foreign>
 - data: 0x218808240e89 <JSFunction f (sfi = 0x21880824d459)>
 - side_effect_free: false

0x218808240e89: [Function] in OldSpace
 - map: 0x218808200289 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x2188082405b9 <JSFunction (sfi = 0x218808184f1d)>
 - elements: 0x2188080406e9 <FixedArray[0]> [HOLEY_ELEMENTS]
 - function prototype: 
 - initial_map: 
 - shared_info: 0x21880824d459 <SharedFunctionInfo f>
 - name: 0x21880824d3d5 <String[#1]: f>
 - builtin: CompileLazy
 - formal_parameter_count: 1
 - kind: NormalFunction
 - context: 0x218808240121 <NativeContext[263]>
 - code: 0x218800043481 <Code BUILTIN CompileLazy>
 - source code: (n) { return n + 1; }
 - properties: 0x2188080406e9 <FixedArray[0]> {
    #length: 0x218808180341 <AccessorInfo> (const accessor descriptor)
    #name: 0x2188081802fd <AccessorInfo> (const accessor descriptor)
    #arguments: 0x218808180275 <AccessorInfo> (const accessor descriptor)
    #caller: 0x2188081802b9 <AccessorInfo> (const accessor descriptor)
    #prototype: 0x218808180385 <AccessorInfo> (const accessor descriptor)
 }
 - feedback vector: feedback metadata is not available in SFI


#
# Fatal error in 
../../../home/pengyu/temp/chromium/src/v8/src/snapshot/startup-serializer.cc, 
line 80
# JSFunction should be added through the context snapshot instead of the 
isolate snapshot
#
#
#
#FailureMessage Object: 0x7fffc0171190
==== C stack trace ===============================

    /tmp/out/Prod-with-debug-v8/cctest(+0x347b093) [0x55c0eb240093]
    /tmp/out/Prod-with-debug-v8/cctest(+0x347a79d) [0x55c0eb23f79d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x3321333) [0x55c0eb0e6333]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fc1d9c) [0x55c0e9d86d9c]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fc2212) [0x55c0e9d87212]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fc2212) [0x55c0e9d87212]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1d5b669) [0x55c0e9b20669]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fc2212) [0x55c0e9d87212]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa2ee8) [0x55c0e9d67ee8]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fc2c39) [0x55c0e9d87c39]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0949) [0x55c0e9d65949]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0bea) [0x55c0e9d65bea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0bea) [0x55c0e9d65bea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0bea) [0x55c0e9d65bea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0bea) [0x55c0e9d65bea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbc9ea) [0x55c0e9d819ea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1a912fd) [0x55c0e98562fd]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbf6e) [0x55c0e9d80f6e]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbb02d) [0x55c0e9d8002d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fbbd6d) [0x55c0e9d80d6d]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa0bea) [0x55c0e9d65bea]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fb8549) [0x55c0e9d7d549]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1fa042c) [0x55c0e9d6542c]
    /tmp/out/Prod-with-debug-v8/cctest(+0x1786368) [0x55c0e954b368]
    /tmp/out/Prod-with-debug-v8/cctest(+0x160519f) [0x55c0e93ca19f]
    /tmp/out/Prod-with-debug-v8/cctest(+0x10d1173) [0x55c0e8e96173]
    /tmp/out/Prod-with-debug-v8/cctest(+0x10d2514) [0x55c0e8e97514]
    /usr/lib/libc.so.6(__libc_start_main+0xf3) [0x7f5339214153]
    /tmp/out/Prod-with-debug-v8/cctest(_start+0x2a) [0x55c0e8e95eea]
Illegal instruction (core dumped)

$ /tmp/out/Prod/chrome --profile-directory=tmpprofile
[3600893:1:0115/174459.537518:ERROR:child_process_sandbox_support_impl_linux.cc(79)]
 FontService unique font name matching request did not receive a response.
[3600893:1:0115/174459.538360:ERROR:child_process_sandbox_support_impl_linux.cc(79)]
 FontService unique font name matching request did not receive a response.
[0115/174507.336980:ERROR:process_memory_range.cc(86)] read out of range
[0115/174507.337019:ERROR:elf_image_reader.cc(594)] missing nul-terminator
Received signal 11 SEGV_MAPERR 5646052aa9e0
#0 0x55df99ef1499 base::debug::CollectStackTrace()
#1 0x55df99e54ff3 base::debug::StackTrace::StackTrace()
#2 0x55df99ef0fe1 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#3 0x7f1e69cc6930 <unknown>
#4 0x55df9967662c blink::UnifiedHeapController::RegisterV8References()
#5 0x55df98d49464 
v8::internal::LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope()
#6 0x55df98d85a79 v8::internal::IncrementalMarking::EmbedderStep()
#7 0x55df98d86191 v8::internal::IncrementalMarking::AdvanceWithDeadline()
#8 0x55df98d82794 v8::internal::IncrementalMarkingJob::Task::RunInternal()
#9 0x55df99e9dc9b base::TaskAnnotator::RunTask()
#10 0x55df99eae68e 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl()
#11 0x55df99eae421 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork()
#12 0x55df99e6adba base::MessagePumpDefault::Run()
#13 0x55df99eaef19 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run()
#14 0x55df99e86922 base::RunLoop::Run()
#15 0x55df9e5d017b content::RendererMain()
#16 0x55df99a5e40b content::RunZygote()
#17 0x55df99a5f628 content::ContentMainRunnerImpl::Run()
#18 0x55df99aadda3 service_manager::Main()
#19 0x55df99a5d931 content::ContentMain()
#20 0x55df975d54aa ChromeMain
#21 0x7f1e686b8153 __libc_start_main
#22 0x55df975d522a _start
  r8: 000029b6f7d9d003  r9: 00007ffe861ca738 r10: 00007ffe861ca730 r11: 
00000000001dc84a
 r12: 000029b6f7f116f0 r13: 0000000000000000 r14: 000029b6f7f16010 r15: 
000016d23ba08018
  di: 00005646052aa9e0  si: 0000000000000001  bp: 00007ffe861ca890  bx: 
000029b6f7f16000
  dx: 0000000000000000  ax: 000055df9ee0d180  cx: 0000000000000210  sp: 
00007ffe861ca720
  ip: 000055df9967662c efl: 0000000000010287 cgf: 002b000000000033 erf: 
0000000000000004
 trp: 000000000000000e msk: 0000000000000000 cr2: 00005646052aa9e0
[end of stack trace]
Calling _exit(1). Core file will not be generated.
[0115/174507.626325:ERROR:process_memory_range.cc(86)] read out of range
[0115/174507.626345:ERROR:elf_image_reader.cc(594)] missing nul-terminator
Received signal 11 SEGV_MAPERR 5646052aa9e0
#0 0x55df99ef1499 base::debug::CollectStackTrace()
#1 0x55df99e54ff3 base::debug::StackTrace::StackTrace()
#2 0x55df99ef0fe1 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#3 0x7f1e69cc6930 <unknown>
#4 0x55df9967662c blink::UnifiedHeapController::RegisterV8References()
#5 0x55df98d49464 
v8::internal::LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope()
#6 0x55df98d85a79 v8::internal::IncrementalMarking::EmbedderStep()
#7 0x55df98d86191 v8::internal::IncrementalMarking::AdvanceWithDeadline()
#8 0x55df98d82794 v8::internal::IncrementalMarkingJob::Task::RunInternal()
#9 0x55df99e9dc9b base::TaskAnnotator::RunTask()
#10 0x55df99eae68e 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl()
#11 0x55df99eae421 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork()
#12 0x55df99e6adba base::MessagePumpDefault::Run()
#13 0x55df99eaef19 
base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run()
#14 0x55df99e86922 base::RunLoop::Run()
#15 0x55df9e5d017b content::RendererMain()
#16 0x55df99a5e40b content::RunZygote()
#17 0x55df99a5f628 content::ContentMainRunnerImpl::Run()
#18 0x55df99aadda3 service_manager::Main()
#19 0x55df99a5d931 content::ContentMain()
#20 0x55df975d54aa ChromeMain
#21 0x7f1e686b8153 __libc_start_main
#22 0x55df975d522a _start
  r8: 000029b6f7d9d003  r9: 00007ffe861ca738 r10: 00007ffe861ca730 r11: 
00000000001dc84a
 r12: 000029b6f7f10b10 r13: 0000000000000000 r14: 000029b6f8399a30 r15: 
00002b539bc08018
  di: 00005646052aa9e0  si: 00000f3cb7da6f08  bp: 00007ffe861ca890  bx: 
000029b6f8399260
  dx: 00000f3cb7da6f08  ax: 0000000000000040  cx: 0000000000000005  sp: 
00007ffe861ca720
  ip: 000055df9967662c efl: 0000000000010202 cgf: 002b000000000033 erf: 
0000000000000004
 trp: 000000000000000e msk: 0000000000000000 cr2: 00005646052aa9e0
[end of stack trace]
Calling _exit(1). Core file will not be generated.

Reply via email to