K.  _ K. _ - 2 months ago 11
Node.js Question

Why `(console.error = console.trace)();` gives `heap out of memory` in Node.js?

I'm using Node.js v5.8.0.

I wanted to make

console.error
work as
console.trace
, so I used
console.error = console.trace;
. But when I called the
console.error
, a fatal memory error occurred:

<--- Last few GCs --->

29296 ms: Mark-sweep 1328.1 (1403.1) -> 1328.1 (1404.1) MB, 32.8 / 0.0 ms [allocation failure] [GC in old space requested].
29314 ms: Mark-sweep 1328.1 (1404.1) -> 1328.1 (1404.1) MB, 17.8 / 0.0 ms [allocation failure] [GC in old space requested].
29333 ms: Mark-sweep 1328.1 (1404.1) -> 1338.8 (1403.1) MB, 19.7 / 0.0 ms [last resort gc].
29353 ms: Mark-sweep 1338.8 (1403.1) -> 1349.7 (1403.1) MB, 19.3 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 00000318EFDCFB61 <JS Object>
1: DoJoin(aka DoJoin) [native array.js:~129] [pc=00000130FFFB1B73] (this=00000318EFD04381 <undefined>,w=000001FBBADF90E1 <JS Array[17]>,x=17,N=00000318EFD043C1 <true>,J=000003D7BECEC771 <String[1]\: \n>,I=00000318EFDB46F1 <JS Function ConvertToString (SharedFunctionInfo 00000318EFD52DC9)>)
2: Join(aka Join) [native array.js:180] [pc=00000130FFF08772] (this=00000318EFD04381 <undefined>...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory


What's the reason? Does
console.trace
use
console.error
internally?

Answer

In NodeJS, console.error and console.warn are used to print to the standard error output. console.trace uses console.error internally to print to the standard error output as console.trace is often used for errors.

Here is a link to the line where console.trace calls console.error: https://github.com/nodejs/node/blob/1c84579031e34326742c9c264f54625c5918197c/lib/console.js#L89

You can try this code:

console.trace = function trace() {
  var err = new Error();
  err.name = 'Trace';
  err.message = util.format.apply(null, arguments);
  Error.captureStackTrace(err, trace);
  this.oldWarn(err.stack);
};

console.oldWarn = console.warn;
console.error = console.warn = console.trace;