89

I am getting some client-side Javascript stack overflow issues specifically in IE browser, this is happening inside a third party library that makes some function calls and for some reason they occasionally brake in IE only due to it's low stack limit.

I then coded a small test HTML to test the stack size limit for some browsers and found that IE8 has actually a small stack limit if compared to FF 7 or Chrome 14 running on a Laptop with Windows 7 OS, 8Gb RAM:

<html>
<body>

<!-- begin Script: -->
<script type="text/javascript">

function doSomething(){

  var i = 3200;
  doSomethingElse(i);

}

function doSomethingElse(i){
  if (i == 0) return -1;
  doSomethingElse(i-1);
}

doSomething(); 

</script>
<!-- END OF PAGE -->

</body>
</html>

IE raises stack overflow when the values are around 3200, Firefox and Chrome can handle a very deep recursion if compared to IE.

I would like to know if there's a way to tie the stack-overflow exception with the Javascript function that raised it during runtime in IE or any other browser and if it could give the stacktrace with the chain of function in the stack at the moment the error was raised.

L84
  • 45,514
  • 58
  • 177
  • 257
guilhebl
  • 8,330
  • 10
  • 47
  • 66
  • 2
    3200 calls is plenty of stack space. Python programmers (well, those not bent on writing recursive descent parsers or replacing perfectly simple loops with recursion for the heck of it) get along just fine with a 1000 call limit. What are you doing? –  Oct 19 '11 at 19:35
  • 4
    It's not worded strickly in an interrogative mode, but the last sentence "I wonder if there's ..." could be started with "Are there" and ended with a question mark, yielding a fairly direct question. – jball Oct 19 '11 at 19:35
  • Thanks for the feedback, I'll clarify better the question – guilhebl Oct 19 '11 at 20:26
  • "those not bent on writing recursive descent parsers" Is there any other type of parser than rec descent? – Avin Kavish Sep 11 '22 at 06:59

2 Answers2

162

Using a simple test:

var i = 0;
function inc() {
  i++;
  inc();
}
    
try {
  inc();
}
catch(e) {
  // The StackOverflow sandbox adds one frame that is not being counted by this code
  // Incrementing once manually
  i++;
  console.log('Maximum stack size is', i, 'in your current browser');
}

Internet Explorer

  • IE6: 1130
  • IE7: 2553
  • IE8: 1475
  • IE9: 20678
  • IE10: 20677

Mozilla Firefox

  • 3.6: 3000
  • 4.0: 9015
  • 5.0: 9015
  • 6.0: 9015
  • 7.0: 65533
  • 8b3: 63485
  • 17: 50762
  • 18: 52596
  • 19: 52458
  • 42: 281810
  • 89: 10746
  • 91: 26441

Google Chrome

  • 14: 26177
  • 15: 26168
  • 16: 26166
  • 25: 25090
  • 47: 20878
  • 51: 41753
  • 93: 13903

Safari

  • 4: 52426
  • 5: 65534
  • 9: 63444
  • 14: 45606

Safari iOS

  • 15: 7909

Opera

  • 10.10: 9999
  • 10.62: 32631
  • 11: 32631
  • 12: 32631
  • 78: 13908

Edge

  • 87: 13970
  • 93: 13903

Yandex

  • 21: 13909

In regard to your question, use your browser's developer tools to see the stack. In IE 8+, hit F12, go to the Script tab, and click Start Debugging. It will break when an exception is thrown, and you can see the call stack. You can also use Chrome's developer tools, Ctrl+Shift+J.

Aykhan Huseyn
  • 94
  • 1
  • 7
josh3736
  • 139,160
  • 33
  • 216
  • 263
  • 8
    You can use F12 for Chrome too – Ruan Mendes Oct 19 '11 at 22:11
  • 1
    With test http://jsfiddle.net/9YMDF/show/ I've got ~21000 for Chrome 28, 26000..53000 for Firefox 20+, and ~3000 for IE10 on Windows 7 SP1 64-bit. Opera 12.X has stack depth pretty near to 32768. And I've found one unfortunate IE8 installation with stack depth equal to 276! – Victor Jul 30 '13 at 17:34
  • You can compare these results with [the BrowserScope linked here](http://stackoverflow.com/questions/2805172/what-are-the-js-recursion-limits-for-firefox-chrome-safari-ie-etc) – Janus Troelsen Jan 10 '15 at 13:50
  • This gives me 151102 on Microsoft Edge, while on IE11 its 54375! – Gaurav Ojha Dec 16 '16 at 07:25
  • 9
    I think that the numbers don't map to the browser, but to the memory _currently_ reserved by the application. because of this, answers vary widely. For exampl,e I just ran that test and I get 20922 for Chrome 56 (with a lot of extensions), and 8921 for a rather plain vanilla Firefox 49. With an *absolutely stock* edge browser, I get 16615. – roberto tomás Dec 17 '16 at 15:33
  • Node.js scores about 7800 on both macOS (v8.4.0) and Debian Linux (v8.6.0). – Kaivosukeltaja Oct 09 '17 at 10:22
  • Why does it give sometimes 15686 and sometimes 15711 on Chrome 65? Any assumptions? – oleedd Jun 24 '21 at 16:02
8

This is browser specific, not only the stack size, but also optimizations, things like tail recursion optimization and stuff. I guess the only reliable thing here is to code in a way that doesn't put tons of stuff into the stack, or manually testing(reading deep into the documentation of) each browser. After all, when you see the "too much recursion" error or similar you already know there's something really wrong with your code.

Nikoloff
  • 4,050
  • 1
  • 17
  • 19
  • is TCO really done in JavaScript? I read ES6 may get support but I don't think it has been implemented yet. – Janus Troelsen Jan 10 '15 at 14:07
  • TCO is behind a flag in chrome right now (two different implementations are being evaluated). I'm not aware of any browsers that have it implemented by default. – Jethro Larson May 12 '16 at 00:47
  • 1
    @JanusTroelsen: ES2015 ("ES6") does indeed require engines to do TCO. V8 has it, but the V8 team don't consider it "stable" yet so you have to enable it. (V8 classifies features they've started at all as "shipping" [done], "stable," and "in progress". TCO remains "in progress" but the basics are there for all three of V8's code generators. I think they haven't promoted it to "stable" yet because they're still optimizing/bugfinding/bugfixing. More here: http://stackoverflow.com/a/30369729/157247) – T.J. Crowder Jun 26 '16 at 11:54
  • Currently safari is only browser with proper TCO – ridderhoff Aug 14 '20 at 23:11
  • one use case to 'put tons of stuff on the stack' is `array1.push(...array2)` which is much faster than `array1 = array1.concat(array2)` but throws 'max stack size exceeded' when array2 is too long. see [here](https://dev.to/uilicious/javascript-array-push-is-945x-faster-than-array-concat-1oki) – milahu Sep 25 '20 at 09:32