Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call stack size within JavaScript

I want to test for large call stacks. Specifically, I want a console warning when the call stack length reaches 1000. This usually means I did something stupid, and can lead to subtle bugs.

Can I compute the call stack length within JavaScript?

like image 844
Randomblue Avatar asked Sep 18 '11 14:09

Randomblue


People also ask

How do I fix call stack size?

The call stack is limited in size, and when it's exceeded, the RangeError is thrown. This can happen when a deeply nested function is called, or when a lot of new variables are created. The most common way to fix this error is to reduce the number of function calls, or to limit the number of variables that are created.

How do I fix maximum call stack size exceeded see JavaScript console for details?

The "RangeError: Maximum call stack size exceeded" error occurs when a function is called so many times that the invocations exceed the call stack limit. To solve the error, specify a base case that has to be met to exit the recursion.

Does JavaScript have a call stack?

JavaScript engine uses a call stack to manage execution contexts. The call stack use the stack data structure that works based on the LIFO (last-in first-out) principle.

How do you calculate maximum call stack size exceeded?

Sometimes you get Maximum call stack size exceeded error if you accidentally import/embed the same JavaScript file twice. So its worth checking in your resources tab of the inspector to solve this issue.


2 Answers

Here's a function that will work in all major browsers, although it won't work in ECMAScript 5 strict mode because arguments.callee and caller have been removed in strict mode.

function getCallStackSize() {     var count = 0, fn = arguments.callee;     while ( (fn = fn.caller) ) {         count++;     }     return count; } 

Example:

function f() { g(); }        function g() { h(); }        function h() { alert(getCallStackSize()); }         f(); // Alerts 3 

UPDATE 1 November 2011

In ES5 strict mode, there is simply no way to navigate the call stack. The only option left is to parse the string returned by new Error().stack, which is non-standard, not universally supported and obviously problematic, and even this may not be possible for ever.

UPDATE 13 August 2013

This method is also limited by the fact that a function that is called more than once in a single call stack (e.g. via recursion) will throw getCallStackSize() into an infinite loop (as pointed out by @Randomblue in the comments). An improved version of getCallStackSize() is below: it keeps track of functions it has seen before to avoid going into an infinite loop. However, the returned value is the number of different function objects in the callstack before encountering a repeat rather than the true size of the complete call stack. This is the best you can do, unfortunately.

var arrayContains = Array.prototype.indexOf ?     function(arr, val) {         return arr.indexOf(val) > -1;     } :     function(arr, val) {         for (var i = 0, len = arr.length; i < len; ++i) {             if (arr[i] === val) {                 return true;             }         }         return false;     };  function getCallStackSize() {     var count = 0, fn = arguments.callee, functionsSeen = [fn];      while ( (fn = fn.caller) && !arrayContains(functionsSeen, fn) ) {         functionsSeen.push(fn);         count++;     }      return count; } 
like image 76
Tim Down Avatar answered Sep 20 '22 14:09

Tim Down


You can use this module: https://github.com/stacktracejs/stacktrace.js

Calling printStackTrace returns the stack trace inside an array, then you can check its length:

var trace = printStackTrace(); console.log(trace.length()); 
like image 23
Yonatan Naor Avatar answered Sep 22 '22 14:09

Yonatan Naor