node-java: Segfault in `../src/javaObject.cpp:116`
Hi!
Thank you for the project! On some of our servers, we started getting the segfault recently.
Our JS initialisation:
java = require('java');
java.asyncOptions = {
asyncSuffix: 'Async',
syncSuffix: 'Sync'
};
const closureCompilerPath = path.parse(require.resolve('google-closure-compiler')).dir;
java.classpath.push(path.join(closureCompilerPath, 'compiler.jar'));
classPaths.forEach(classPath => {
java.classpath.push(classPath);
});
ArrayList = java.import('java.util.ArrayList'); // here segfault happens
gdb with debugging symbols shows that the following code from javaObject.cpp:116 causes the problem:
v8::Local<v8::Function> ctor = funcTemplate->GetFunction();
v8::Local<v8::Object> javaObjectObj = ctor->NewInstance();
GetFunction call seems to be returning empty Local in some cases (gdb shows ctor = {val_ = 0x0} in locals). v8 headers suggest using maybe version instead, so I can conclude that the Local(0) might be expected and it’s not a v8 problem.
/** Returns the unique function instance in the current execution context.*/
V8_DEPRECATE_SOON("Use maybe version", Local<Function> GetFunction());
V8_WARN_UNUSED_RESULT MaybeLocal<Function> GetFunction(
Local<Context> context);
Calling NewInstance on an empty local then causes V8 to crash in OS::Abort because of a failed assertion.
Full gdb output with locals:
#0 v8::base::OS::Abort () at ../deps/v8/src/base/platform/platform-posix.cc:255
No locals.
#1 0x0000000002afeb60 in V8_Fatal (file=0x2c798b9 "../deps/v8/src/api.h", line=349, format=0x2c78ded "Check failed: %s.") at ../deps/v8/src/base/logging.cc:74
arguments = {{gp_offset = 32, fp_offset = 48, overflow_arg_area = 0xffeffd4c0, reg_save_area = 0xffeffd400}}
#2 0x0000000001a706c5 in v8::Utils::OpenHandle (that=0x0, allow_empty_handle=false) at ../deps/v8/src/api.h:349
No locals.
#3 0x0000000001a9915d in v8::Function::NewInstance (this=0x0, context=..., argc=0, argv=0x0) at ../deps/v8/src/api.cc:5186
trace_event_unique_atomic5184 = 65754077
__state__ = {isolate_ = 0x60514c0, previous_tag_ = v8::EXTERNAL}
isolate = 0x60514c0
timer_scope = {isolate_ = 0x60514c0}
self = {<v8::internal::HandleBase> = {location_ = 0xffeffd550}, <No data fields>}
trace_event_unique_category_group_enabled5184 = 0x3eb53dd <v8::platform::DefaultPlatform::GetCategoryGroupEnabled(char const*)::no> ""
trace_event_unique_tracer5184 = {has_parent_scope_ = 177, p_data_ = 0x0, data_ = {category_group_enabled = 0xffeffd620 "",
name = 0x1a6f2e0 <v8::Utils::ToLocal(v8::internal::Handle<v8::internal::Context>)+24> "\311\303UH\211\345H\203\354\020H\211}\360H\213E\360H\211\307\350F/\004",
isolate = 0x60c4c18}}
handle_scope = {<v8::EscapableHandleScope> = {<v8::HandleScope> = {isolate_ = 0x60514c0, prev_next_ = 0x60c4c28, prev_limit_ = 0x60c5150},
escape_slot_ = 0x60c4c20}, <No data fields>}
call_depth_scope = {isolate_ = 0x60514c0, context_ = {val_ = 0x0}, escaped_ = false, do_callback_ = 214}
_runtime_timer = {stats_ = 0x0, timer_ = {counter_ = 0x0, parent_ = {value_ = 0}, start_ticks_ = {<v8::base::time_internal::TimeBase<v8::base::TimeTicks>> = {
static kHoursPerDay = <optimized out>, static kMillisecondsPerSecond = <optimized out>, static kMillisecondsPerDay = <optimized out>,
static kMicrosecondsPerMillisecond = <optimized out>, static kMicrosecondsPerSecond = <optimized out>, static kMicrosecondsPerMinute = <optimized out>,
static kMicrosecondsPerHour = <optimized out>, static kMicrosecondsPerDay = <optimized out>, static kMicrosecondsPerWeek = <optimized out>,
static kNanosecondsPerMicrosecond = <optimized out>, static kNanosecondsPerSecond = <optimized out>, us_ = 0}, <No data fields>}, elapsed_ = {delta_ = 0}}}
has_pending_exception = false
args = 0xffeffd5d0
result = {val_ = 0xffeffd570}
#4 0x0000000001a98f50 in v8::Function::NewInstance (this=0x0) at ../deps/v8/src/api.cc:5176
No locals.
#5 0x0000000009c82903 in JavaObject::New (java=0x8c56a70, obj=0x9750e90) at ../src/javaObject.cpp:116
scope = {scope = {<v8::HandleScope> = {isolate_ = 0x60514c0, prev_next_ = 0x60c3c88, prev_limit_ = 0x60c5150}, escape_slot_ = 0x60c3c80}}
env = 0x935e210
className = "nodeJava_java_lang_Class"
__PRETTY_FUNCTION__ = "static v8::Local<v8::Object> JavaObject::New(Java*, jobject)"
javaScope = {m_env = 0x935e210, m_result = 0x0}
objClazz = 0x9868c30
classNameJava = 0x9868c40
ctor = {val_ = 0x0}
javaObjectObj = {val_ = 0xffeffd880}
self = 0x9c54468
classClazz = 0x9868c38
class_getName = 0x1e809c18
promisify = {val_ = 0x0}
funcTemplate = {val_ = 0x60c3c88}
#6 0x0000000009c8d660 in javaToV8 (java=0x8c56a70, env=0x935e210, obj=0x9750e90, dynamicProxyData=0x0) at ../src/utils.cpp:756
objClazz = 0x9750e98
resultType = TYPE_OBJECT
__PRETTY_FUNCTION__ = "v8::Local<v8::Value> javaToV8(Java*, JNIEnv*, jobject, DynamicProxyData*)"
#7 0x0000000009c8ccf0 in javaToV8 (java=0x8c56a70, env=0x935e210, obj=0x9750e90) at ../src/utils.cpp:657
No locals.
#8 0x0000000009c7899c in Java::findClassSync (info=...) at ../src/java.cpp:721
scope = {scope = {isolate_ = 0x60514c0, prev_next_ = 0x60c3a90, prev_limit_ = 0x60c5150}}
env = 0x935e210
className = "java.util.ArrayList"
self = 0x8c56a70
javaScope = {m_env = 0x935e210, m_result = 0x0}
_className_val = {str_ = 0x62664d0 "java.util.ArrayList", length_ = 19}
ensureJvmResults = {val_ = 0x6051538}
argsStart = 1
_className_obj = {val_ = 0xffeffe0b0}
clazz = 0x9750e90
result = {val_ = 0x4258afb9}
#9 0x0000000009c71c93 in Nan::imp::FunctionCallbackWrapper (info=...) at ../../nan/nan_callbacks_12_inl.h:174
obj = {val_ = 0xffeffded8}
callback = 0x9c785ee <Java::findClassSync(Nan::FunctionCallbackInfo<v8::Value> const&)>
cbinfo = {info_ = @0xffeffdd50, data_ = {val_ = 0x60c3a88}, static kHolderIndex = <optimized out>, static kIsolateIndex = <optimized out>,
static kReturnValueDefaultValueIndex = <optimized out>, static kReturnValueIndex = <optimized out>, static kDataIndex = <optimized out>,
static kCalleeIndex = <optimized out>, static kContextSaveIndex = <optimized out>, static kArgsLength = <optimized out>}
#10 0x0000000001acd746 in v8::internal::FunctionCallbackArguments::Call (this=0xffeffdea0,
f=0x9c71be6 <Nan::imp::FunctionCallbackWrapper(v8::FunctionCallbackInfo<v8::Value> const&)>) at ../deps/v8/src/api-arguments.cc:25
isolate = 0x60514c0
timer = {stats_ = 0x0, timer_ = {counter_ = 0x0, parent_ = {value_ = 0}, start_ticks_ = {<v8::base::time_internal::TimeBase<v8::base::TimeTicks>> = {
static kHoursPerDay = <optimized out>, static kMillisecondsPerSecond = <optimized out>, static kMillisecondsPerDay = <optimized out>,
static kMicrosecondsPerMillisecond = <optimized out>, static kMicrosecondsPerSecond = <optimized out>, static kMicrosecondsPerMinute = <optimized out>,
static kMicrosecondsPerHour = <optimized out>, static kMicrosecondsPerDay = <optimized out>, static kMicrosecondsPerWeek = <optimized out>,
static kNanosecondsPerMicrosecond = <optimized out>, static kNanosecondsPerSecond = <optimized out>, us_ = 0}, <No data fields>}, elapsed_ = {delta_ = 0}}}
state = {isolate_ = 0x60514c0, previous_tag_ = v8::JS}
info = {static kArgsLength = <optimized out>, static kHolderIndex = <optimized out>, static kIsolateIndex = <optimized out>,
static kReturnValueDefaultValueIndex = <optimized out>, static kReturnValueIndex = <optimized out>, static kDataIndex = <optimized out>,
static kCalleeIndex = <optimized out>, static kContextSaveIndex = <optimized out>, static kNewTargetIndex = <optimized out>, implicit_args_ = 0xffeffdeb8,
values_ = 0xffeffe0b0, length_ = 1}
call_scope = {isolate_ = 0x60514c0,
callback_ = 0x9c71be6 <Nan::imp::FunctionCallbackWrapper(v8::FunctionCallbackInfo<v8::Value> const&)> "UH\211\345H\203\354@H\211}\310H\213E\310H\211\307\350\262\320\377\377H\211E\360H\215E\360H\211\307\350b\362\377\377H\211E\320H\215E\320H\211\307\350\302\334\377\377\276\001", previous_scope_ = 0x0}
#11 0x0000000001bd97c3 in v8::internal::(anonymous namespace)::HandleApiCallHelper<false> (isolate=0x60514c0, function=..., new_target=..., fun_data=..., receiver=..., args=...)
at ../deps/v8/src/builtins/builtins-api.cc:111
call_data = 0x3eacfab78219
data_obj = 0x23db30e4cfe1
callback_obj = 0x23db30e4cfd1
callback = 0x9c71be6 <Nan::imp::FunctionCallbackWrapper(v8::FunctionCallbackInfo<v8::Value> const&)>
custom = {<v8::internal::CustomArguments<v8::FunctionCallbackInfo<v8::Value> >> = {<v8::internal::CustomArgumentsBase<8>> = {<v8::internal::Relocatable> = {
_vptr.Relocatable = 0x2ca40b0 <vtable for v8::internal::FunctionCallbackArguments+16>, isolate_ = 0x60514c0, prev_ = 0x0}, values_ = {0x23db30e0a901, 0x60514c0,
0xabca0f02351, 0xabca0f02351, 0x23db30e4cfe1, 0x3eacfab7a9e1, 0xabca0f02351, 0xabca0f02311}}, static kReturnValueOffset = 3}, static kArgsLength = 8,
static kHolderIndex = 0, static kDataIndex = 4, static kReturnValueDefaultValueIndex = 2, static kIsolateIndex = 1, static kCalleeIndex = 5,
static kContextSaveIndex = 6, static kNewTargetIndex = 7, argv_ = 0xffeffe0b0, argc_ = 1}
result = {<v8::internal::HandleBase> = {location_ = 0x60c3a78}, <No data fields>}
js_receiver = {<v8::internal::HandleBase> = {location_ = 0xffeffe0b8}, <No data fields>}
raw_holder = 0x23db30e0a901
raw_call_data = 0x3eacfab78219
#12 0x0000000001bd7a2f in v8::internal::Builtin_Impl_HandleApiCall (args=..., isolate=0x60514c0) at ../deps/v8/src/builtins/builtins-api.cc:140
__result__ = {<v8::internal::HandleBase> = {location_ = 0x0}, <No data fields>}
__isolate__ = 0x60514c0
function = {<v8::internal::HandleBase> = {location_ = 0xffeffe0a0}, <No data fields>}
new_target = {<v8::internal::HandleBase> = {location_ = 0xffeffe098}, <No data fields>}
fun_data = {<v8::internal::HandleBase> = {location_ = 0x60c3a78}, <No data fields>}
scope = {static kCheckHandleThreshold = 30720, isolate_ = 0x60514c0, prev_next_ = 0x60c3a78, prev_limit_ = 0x60c3a78}
receiver = {<v8::internal::HandleBase> = {location_ = 0xffeffe0b8}, <No data fields>}
#13 0x0000000001bd77db in v8::internal::Builtin_HandleApiCall (args_length=5, args_object=0xffeffe0b8, isolate=0x60514c0) at ../deps/v8/src/builtins/builtins-api.cc:128
args = {<v8::internal::Arguments> = {length_ = 5, arguments_ = 0xffeffe0b8}, static kNewTargetOffset = 0, static kTargetOffset = 1, static kArgcOffset = 2,
static kNumExtraArgs = 3, static kNumExtraArgsWithReceiver = 4}
#14 0x00001881e3d04264 in ?? ()
No symbol table info available.
#15 0x00001881e3d04181 in ?? ()
No symbol table info available.
#16 0x0000000ffeffe070 in ?? ()
No symbol table info available.
#17 0x0000000000000006 in ?? ()
No symbol table info available.
#18 0x0000000ffeffe0e0 in ?? ()
No symbol table info available.
#19 0x00001881e3e6ba0a in ?? ()
No symbol table info available.
#20 0x00000abca0f02311 in ?? ()
No symbol table info available.
#21 0x00003eacfab7a9e1 in ?? ()
No symbol table info available.
#22 0x0000000500000000 in ?? ()
No symbol table info available.
#23 0x00003c61323aaef1 in ?? ()
No symbol table info available.
#24 0x000023db30e0a901 in ?? ()
No symbol table info available.
Unfortunately, I don’t have much context about the intended logic of the JavaObject::New method, maybe you could provide more context or some suggestions on how to fix it?
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 3
- Comments: 20 (4 by maintainers)
The above also worked on the 3.13.0-121-generic kernel running on Ubuntu 14.04
Adding:
java.options.push('-Xss1280k');to our Java init seemed to fix the issue for us on 4.4.0-81-generic@juckerf I can reproduce this problem only on AWS. Since Heroku uses AWS under the hood (as far as I know), it makes sense.
It looks like the problem appeared after applying the following update:
That update includes a security fix (https://www.ubuntu.com/usn/usn-3331-1/) that could potentially lead to this problem. My guess is that the bug has always been there, but only after the security fix, it started leading to segfault.
Rolled back our ubuntu server to linux-image-3.13-0-119-generic for now.
apt-get install linux-image-3.13.0-119-generic linux-headers-3.13.0-119apt-get remove linux-image-3.13.0-121-generic linux-headers-3.13.0-121and reboot
according to USN-3344-1 (https://www.ubuntu.com/usn/usn-3344-1) the issue (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1699772) should be fixed with the corresponding kernel updates. can someone confirm?
I upgraded to 4.4.0-83-generic on my ubuntu and it works well without the -Xss1280K flag
@shawn-mcginty sounds related. @all at least on heroku the segfault disappeared now (uname: Linux 08db0321-1a9b-4d5a-843d-78c66aecf11d 3.13.0-112-generic #159-Ubuntu SMP Fri Mar 3 15:26:07 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux) if it still does not run, can someone check the JVM option “-Xss1280k”? (from the debian bug)
Is this related? https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865311
I just pushed a fix (https://github.com/joeferner/node-java/commit/0b8a730d6777c080330a38021a71b5176f8c1dfd) to some of the compiler warnings that were being caused by newer versions of Node. One of the changes affects the line of code causing the crash, if someone could test the new code that would be a great help.