oom/core dump in repl with buffer property tab completionΒ #3136
Copy link
Copy link
Closed
Labels
good first issueIssues that are suitable for first-time contributors.Issues that are suitable for first-time contributors.replIssues and PRs related to the REPL subsystem.Issues and PRs related to the REPL subsystem.
Description
Noticed with a sufficiently large Buffer (or ArrayBuffer) tab completion in the repl will crash the process with out of memory + core dump
$ node
> var b = Buffer(1e8)
undefined
> b.l
<--- Last few GCs --->
10335 ms: Mark-sweep 1397.5 (1445.0) -> 1397.4 (1445.0) MB, 264.7 / 0 ms [allocation failure] [GC in old space requested].
10652 ms: Mark-sweep 1397.5 (1445.0) -> 1397.4 (1445.0) MB, 263.0 / 0 ms [allocation failure] [GC in old space requested].
11009 ms: Mark-sweep 1397.5 (1445.0) -> 1397.4 (1445.0) MB, 264.6 / 0 ms [last resort gc].
11330 ms: Mark-sweep 1397.4 (1445.0) -> 1397.4 (1445.0) MB, 321.3 / 0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x3bd157b37339 <JS Object>
2: ObjectGetOwnPropertyKeys(aka ObjectGetOwnPropertyKeys) [native v8natives.js:~688] [pc=0x1e2e0302e4b3] (this=0x3bd157b04131 <undefined>,J=0x5c7b14041d1 <an Uint8Array with map 0x20a90d01d2d9>,as=48)
3: getOwnPropertyNames [native v8natives.js:752] [pc=0x1e2e0302e31b] (this=0x3bd157b36b61 <JS Function Object (SharedFunctionInfo 0x3bd157b36ad1)>,J=0x5c7b14041d1 <an Uint8Array with map 0...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Aborted (core dumped)
$ node -pe 'var b = Buffer(1e8); b.length'
100000000
$ node -v
v4.1.1
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
good first issueIssues that are suitable for first-time contributors.Issues that are suitable for first-time contributors.replIssues and PRs related to the REPL subsystem.Issues and PRs related to the REPL subsystem.
Activity
trevnorris commentedon Sep 30, 2015
Pretty sure the issue is from the following in
lib/repl.js:As can be demonstrated by the following:
harry8525 commentedon Nov 12, 2015
Could this be why there are ton of these issues reported on git hub with version 4.0+?
CALL_AND_RETRY_LAST Allocation failed - process out of memory
I'm getting random reports for some internal tools we use and haven't been able to pin point what causes it. It is scary if its related to inspecting properties that are buffers...especially using tools like gulp (where we are seeing all the issues) that have pass buffers around all the time...
trevnorris commentedon Nov 12, 2015
@harry8525 Since Buffers are now iterable, it would be possible to run through the list of all properties and remove any that are indices. Would probably crawl, but at least it wouldn't die.
tjwebb commentedon Feb 13, 2016
I just ran into this using winston + repl: trailsjs/trailpack-repl#20
Logging a small-ish object works fine. If I try to log a larger object (a couple dozen ES6 classes) it fails.
JordanMajd commentedon Mar 21, 2016
I'm investigating the issue.
JordanMajd commentedon Mar 21, 2016
Edit: Seems I was mistaken:
@trevnorris
filteredOwnPropertyNamesseems to be the issue. Digging in further.Original:
@trevnorris Thanks for the suggestions,but I'm afraid they are dead ends.I've commented out all invocations of.filteredOwnPropertyNamesto see if it is the causeThe issue still persists.In addition, you recommended.run through the list of all properties and remove any that are indices.It seems thatfilteredOwnPropertyNamesinvokesintFilterwhich should remove any indicesThanks for those suggestions, I'm still investigating the issue and open to any more advice.JordanMajd commentedon Mar 21, 2016
So the issue has to do with
Object.getOwnPropertyNamesinfilteredOwnPropertyNamesreturns such a massive list the repl runs out of memory.getOwnPropertyNamesreturns an array of the objectsenumerableandnonenumerableproperties.I've tried replacing this line with more memory efficient custom code, and succeeded with
enumerableproperties but I'm having trouble figuring out an alternative way to effectively get the objectsnonenumarableproperties.Any advice is welcome.
bnoordhuis commentedon Mar 22, 2016
@JordanMajd There is currently no good way to do that. Presumably V8 would need to grow a C++ API that either lets you iterate over non-enumerable properties, or fails gracefully when creating the property name array fails (by creating an empty handle.) Node would then need to be updated to make use of this new API.
JordanMajd commentedon Mar 23, 2016
Thanks @bnoordhuis,
Follow up question, does tab completion need to have nonenumerable properties? If it doesn't, I already have a working solution for only tab completing enumerable properties.
bnoordhuis commentedon Mar 23, 2016
I'd say so. For example, methods are normally non-enumerable; only considering enumerable properties would break completion for
Object.getOwn<TAB>.JordanMajd commentedon Mar 24, 2016
Great point, I had forgotten that methods were non-enumerable.
If anyone has advice on where to go from here I am all ears. Otherwise it would seem this issue is not going to be resolved anytime in the near future.
XadillaX commentedon Jun 20, 2017
How about to do
Bufferwith special treatment?eg.
and then do
process.emitWarning.repl: fix crash with large buffer tab completion
repl: fix crash with large buffer tab completion
repl: fix crash with large buffer tab completion
repl: fix crash with large buffer tab completion