basic_string out_of_range while parsing node crash
We had a node crash, and while attempting to analyze its core file with llnode 1.7.1 lldb 360.1.70:
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string
zsh: abort lldb node -c ./core.node.7.1531852031
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
HandleCommand(command = "v8 findjsobjects")
abort() called
terminating with uncaught exception of type std::out_of_range: basic_string
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fffa0771f06 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff926874ec pthread_kill + 90
2 libsystem_c.dylib 0x00007fff992486df abort + 129
3 libc++abi.dylib 0x00007fffa0d7eb31 abort_message + 257
4 libc++abi.dylib 0x00007fffa0da4def default_terminate_handler() + 243
5 libobjc.A.dylib 0x00007fff9d4de4a6 _objc_terminate() + 124
6 libc++abi.dylib 0x00007fffa0da1ffe std::__terminate(void (*)()) + 8
7 libc++abi.dylib 0x00007fffa0da1a6a __cxa_throw + 121
8 libc++.1.dylib 0x00007fff94c200c1 std::__1::__basic_string_common<true>::__throw_out_of_range() const + 71
9 libc++.1.dylib 0x00007fff94c2056c std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long, std::__1::allocator<char> const&) + 68
10 llnode.dylib 0x0000000110c8c9c4 llnode::v8::SlicedString::ToString(llnode::v8::Error&) + 628
11 llnode.dylib 0x0000000110c876ab llnode::v8::String::ToString(llnode::v8::Error&) + 559
12 llnode.dylib 0x0000000110c8a81c llnode::v8::HeapObject::ToString(llnode::v8::Error&) + 208
13 llnode.dylib 0x0000000110c89105 llnode::v8::Value::ToString(llnode::v8::Error&) + 243
14 llnode.dylib 0x0000000110c9a8c7 llnode::FindJSObjectsVisitor::MapCacheEntry::Load(llnode::v8::Map, llnode::v8::HeapObject, llnode::v8::LLV8*, llnode::v8::Error&) + 1025
15 llnode.dylib 0x0000000110c9a2a9 llnode::FindJSObjectsVisitor::Visit(unsigned long long, unsigned long long) + 651
16 llnode.dylib 0x0000000110c9b86c llnode::LLScan::ScanMemoryRanges(llnode::FindJSObjectsVisitor&) + 282
17 llnode.dylib 0x0000000110c9570c llnode::LLScan::ScanHeapForObjects(lldb::SBTarget, lldb::SBCommandReturnObject&) + 352
18 llnode.dylib 0x0000000110c95512 llnode::FindObjectsCmd::DoExecute(lldb::SBDebugger, char**, lldb::SBCommandReturnObject&) + 138
19 com.apple.LLDB.framework 0x000000010caeab37 CommandPluginInterfaceImplementation::DoExecute(lldb_private::Args&, lldb_private::CommandReturnObject&) + 183
20 com.apple.LLDB.framework 0x000000010efe3c4b lldb_private::CommandObjectParsed::Execute(char const*, lldb_private::CommandReturnObject&) + 407
21 com.apple.LLDB.framework 0x000000010efd8c0c lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, lldb_private::ExecutionContext*, bool, bool) + 2314
22 com.apple.LLDB.framework 0x000000010efdb55a lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) + 206
23 com.apple.LLDB.framework 0x000000010eff517f lldb_private::IOHandlerEditline::Run() + 283
24 com.apple.LLDB.framework 0x000000010eee3d89 lldb_private::Debugger::ExecuteIOHandlers() + 63
25 com.apple.LLDB.framework 0x000000010efdbe65 lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool, lldb_private::CommandInterpreterRunOptions&) + 117
26 com.apple.LLDB.framework 0x000000010cae6c86 lldb::SBDebugger::RunCommandInterpreter(bool, bool) + 68
27 lldb 0x000000010cab6e44 Driver::MainLoop() + 2228
28 lldb 0x000000010cab73b1 main + 268
29 libdyld.dylib 0x00007fff9f3105ad start + 1
The failure is 100% reproducible with the core file I have (2.1GB, though, so I can't easily share it)
Looks like an incorrect parsing of a sliced string, what's the version of Node.js that produced the core dump?
It probably won't be actionable if we cannot reproduce the string that results in the crash.
core is from node 8.9.3
I totally understand llnode may not be able to parse out all strings -- the process crashed, it's quite possible some of the heap is corrupt. But seeing as this is a debugging utility maybe it can be more robust -- print out a warning that the string could not be rendered and replace it with invalid string #1 length 123405 for example, instead of allowing an uncaught exception to terminate lldb.
@stevenschlansker
But seeing as this is a debugging utility maybe it can be more robust -- print out a warning that the string could not be rendered and replace it with invalid string #1 length 123405 for example, instead of allowing an uncaught exception to terminate lldb.
I agree, this is more of an oversight in the code base (we don't usually do enough checks in the inspectors and just assume the values are legit). I opened https://github.com/nodejs/llnode/pull/217