New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 752081 link

Starred by 8 users

Issue metadata

Status: Fixed
Owner:
Closed: Oct 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Mac
Pri: 1
Type: Bug-Regression

Blocked on:
issue v8:6964


Show other hotlists

Hotlists containing this issue:
Hotlist-ChromeExpert


Sign in to add a comment

Uncaught RangeError: Maximum call stack size exceeded

Reported by loorong...@gmail.com, Aug 3 2017

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

Steps to reproduce the problem:
1. Go to sg.diviwebdesign.com/admin/
2. Login with username: rongjie, password: rongjie 
3. Navigate to Pages and Open up the page title "For Google Chrome"
4. Click on the setting button of Perky Animate.

What is the expected behavior?
Expect a HTML modal dialog opens. No error in developer console.

What went wrong?
No HTML modal dialog. Developer console shows the following error message:

...[SNIP]...
Uncaught RangeError: Maximum call stack size exceeded
    at new Function (<anonymous>)
    at Function.m.template
...[SNIP]...

Did this work before? N/A 

Chrome version: 60.0.3112.90  Channel: stable
OS Version: 10.0
Flash Version: 

This does not work for Chrome 60.0.3112.78 on Win10 (x64) even with chrome.exe --user-data-dir=/new/folder.

Forum user reported that it also does not work for Chrome Stable on Linux. However, it works for Chrome Stable on Mac, Edge, Firefox, raw Chromium and Chromium-based browsers. Chrome Canary 62.0.3175.2 works too.

Chrome Product Forum Thread:
https://productforums.google.com/forum/#!topic/chrome/r_6Y56chONY
 
See screenshot for step 4.
b67d200e-23bf-415d-bc3d-94b170c09ba5.png
13.4 KB View Download
Components: -Blink Blink>JavaScript
Labels: -Type-Bug -Pri-2 Needs-Bisect OS-Android OS-Mac Pri-1 Type-Bug-Regression
Status: Untriaged (was: Unconfirmed)
Summary: Uncaught RangeError: Maximum call stack size exceeded (was: Uncaught RangeError: Maximum call stack size exceeded (but works on Chrome Canary))
It was a huge generated function (600,000+ characters).

Here is a reduced test case -
eval("{" + "(a=a)+''+".repeat(1422)+"(a=a)+''}")
This fails on Windows.

All of the tests below were run using BrowserStack.

Works in Chrome 59 and 62. Fails in Chrome 60 and 61.


This fails on Windows and macOS, using Chrome 59, 62 -
eval("{" + "(a=a)+''+".repeat(1951)+"(a=a)+''}")
Works in Chrome 58.

This fails on Windows, using Chrome 58 -
eval("{" + "(a=a)+''+".repeat(3920)+"(a=a)+''}")

This fails on macOS, using Chrome 58 -
eval("{" + "(a=a)+''+".repeat(3120)+"(a=a)+''}")

This (arbitrary, not a breaking point) fails on Chrome 58 for Android on Samsung Galaxy S8+ -
eval("{" + "(a=a)+''+".repeat(9920)+"(a=a)+''}")

I tried this using Firefox 54 on macOS, Safari 10.1 on macOS, Firefox 54 on Windows -
eval("{" + "(a=a)+''+".repeat(59920)+"(a=a)+''}")
Works, but fails using Edge 15 on Windows.
This works on Edge 15 -
eval("{" + "(a=a)+''+".repeat(32458)+"(a=a)+''}")

This works using Internet Explorer 11 -
eval("{" + "(a=a)+''+".repeat(11495)+"(a=a)+''}")

I even went up to an arbitrary 1599200 using Firefox 54 on Windows and it worked.


The original function is attached (I wrapped it within function a() { %s }).
generated-function.txt
582 KB View Download
Labels: Hotlist-Interop
Labels: Needs-Triage-M60
Cc: phistuck@chromium.org hdodda@chromium.org
Labels: Needs-Feedback
Tested the issue on Mac os 10.12.5 and  windows 7 using chrome M60 #60.0.3112.90 and M62 #62.0.3176.0 using steps mentioned in comment #2.

In windows 7 , using M60 the issue is reproduced with the (eval("{" + "(a=a)+''+".repeat(1422)+"(a=a)+''}")).
               using M62 the uncaught reference error is displayed as attached in screenshot.

In Mac OS , using M60 & M62 , the uncaught reference error is displayed in console on pasting (eval("{" + "(a=a)+''+".repeat(1422)+"(a=a)+''}")).

@phistuck -- Could you please help us in bisecting the issue with the common test case for all the OS , that would help in bisecting the range better.

Thanks!


752081.png
20.6 KB View Download

Comment 6 by phistuck@gmail.com, Aug 4 2017

Windows needs a reverse bisect -
For Windows, try this - 
eval("var a='';{" + "(a=a)+''+".repeat(1422)+"(a=a)+''}")

macOS needs a normal bisect, though I reckon it is https://chromium.googlesource.com/chromium/src/+/5e921f820bc0a86566e25b279019ba965535230e
For macOS, try this -
eval("var a='';" + "(a=a)+''+".repeat(1951)+"(a=a)+''")
Cc: -phistuck@chromium.org
I'm also seeing a RangeError problem, but I'm running code generated by Bucklescript. It started with Chrome 60, on both windows and mac, and I can reproduce it with Canary 62. Sometimes the problem goes away if I re-run the function, other times a reload of the page fixes it, but mostly it just never works. Firefox, Safari, even Edge has zero issues with this code.

I can't really attach my code in an open forum, but I'll see if I can create a smaller test case.
In our case it seems to be caused due to this bug(??) in chrome along with some HTML code (which contains angular widgets)
I've tracked my problem down to some mutually tail-recursive functions. Using `Error.stackTraceLimit = Infinity` I can see my code is failing in Chrome 60 on macOS Sierra at a stack size of about 5000.

I've created a small pure JS test case showing the pattern of the code created by Bucklescript. The example continues recursing until it counts up to a maximum. The "max" variable is global so it can be adjusted from the console; it defaults to 10000. I used console commands such as `max=20000;main()` to update and re-run the test.

Chrome does optimise the example code after a few runs, so I'm including two values for it. I'm only using round numbers for testing given that the limit is likely dependent on the environment and other context.

- Chrome 60 fails. After lowering max it can only do about 8900 on load, optimised it can reach 50k
- Chrome 59 passes, in fact it can do about 19k on page load, after optimisation I can push it to 90k
- Firefox 54 passes, can do 400k on page load
- Safari with PTC has no limit, I tested as far as 10 million and figured that was enough

I generated these numbers using Chrome on Windows 10 for ease of comparison between 60 and 59. I used macOS Sierra for FF54 and Safari. I also tried copy/pasting the code into a Node.js v8.2.1 repl - 17k on load, 48k after optimisation.

The problem here is not that I want infinite recursion and PTC. I understand that's a hard problem. But the available stack space for recursion appears to be significantly reduced in 60 vs 59.
recursion.zip
841 bytes Download
#10 - that is a different issue. This issue is about the parser recursing (I am guessing), rather than an actual JavaScript recursion. You should file a new issue for your problem.
Will do, thanks :)
In case it turns out to be the same problem and my new issue should be merged into this one, it's logged as  issue 753705 
I am confused, what is the difference to 753705?

Comment 15 by phistuck@gmail.com, Aug 15 2017

#14 - this issue is about a recursion in the V8 parser itself (no JavaScript stack trace).
 Issue 753705  is about a recursion in JavaScript code (a large JavaScript stack trace).

Comment 16 by phistuck@gmail.com, Aug 15 2017

#14 - see reduced test cases in comments 2 and 6.
Basically, a function with a lot of (a = a) + '' + (a = a) + '' (no calls, so no recursion) exhausts the stack at parse time.
This is being used by JavaScript templating engines.
Components: Blink>JavaScript>Parser
Labels: OS-Linux
Adding parser component since this seems to be parser related.

Comment 18 by ke...@outlook.com, Aug 27 2017

I am the one who reported this and I can confirm that the latest Chrome 60.0.3112.11 does fixes this issue. Now the popup is opening up on Windows OS Chrome Browser.
Owner: marja@chromium.org
Status: Assigned (was: Untriaged)
According to #2 this shouldn't work in 60. 

Kenng, what about 61 and 62?

Comment 20 by ke...@outlook.com, Aug 31 2017

Tested on 61 and 62.

The recent 60 update is working. 62 is working and 61 is not. I am thinking like what phistuck is saying. It could be the parser issue related?

Comment 21 by ke...@outlook.com, Aug 31 2017

of course the Mac version chrome do not have such issue. 

Comment 22 by marja@chromium.org, Aug 31 2017

In the similar cases I've seen before, the ignition byte code generator runs out of stack space sooner than the parser (i.e., there are examples which the parser can still parse but the bytecode generator cannot handle.

I'll try to dig up the previous bug we had about this...

Comment 24 by marja@chromium.org, Aug 31 2017

Cc: marja@chromium.org
Owner: rmcilroy@chromium.org
Repro case I used on Linux: eval("{" + "(a=a)+''+".repeat(1951)+"(a=a)+''}")


Confirmed that the stack overflow in this case happens while generating bytecode (stack overflow check in CompileTopLevel).


Comment 25 by phistuck@gmail.com, Aug 31 2017

I think this needs to be prioritized, as templating engines create many additions like this one (see the description of this issue for a real world use case). The fact that this bug is sometimes reproducible and that the results vary on multiple operating systems means that the stack space is simply different per execution and it sometimes happens.

It depends on how long and complex the template is, but looks like templates that are not extremely large already cause this issue to appear...
Components: -Blink>JavaScript Blink>JavaScript>Compiler Blink>JavaScript>Interpreter
also cf. https://bugs.chromium.org/p/chromium/issues/detail?id=731861, where we did get a bit closer to FCGs stack use as of M61.

Note that this is a fundamentally difficult problem to fix in the bytecode generation, because the AST traversal can't be written in a tail recursive way. In this case, if you have control over the template engine, you could break up the sequence of "p+=a+b+c+..." into "p+=a;p+=b;p+=c;..." or "[a,b,c,...].join('')"

Comment 28 by phistuck@gmail.com, Aug 31 2017

I assume they do not have any control over it, it is just a WordPress plugin and I assume it is being created on the fly (Function(...)).
We had a look at this in issue 731861, there isn't much more that can be done without fundamentally rearchitecting the compiler. 

One other option, we could possibly expand the amount of stack space we allocate on Chrome, although as far as I remember from looking at this previously, there were reasons why it was as small as it is (I think it is around 1MB), and even if those no longer apply it would increase memory overheads of all of Chrome's threads so I'm not completely convinced it would be worth it, particularly since there is always going to be some limit to the number of "+"'s we can support - does it matter if this is 2000 or 4000, in either case it is much larger than could reasonably be written manually and any templating engine could just as easily go over the higher limit. 

It seems to me that Leszek's suggestion in #27 of restructuring the code produced by the templating engine would work best here.
Blockedon: v8:6964
Owner: leszeks@chromium.org
Project Member

Comment 32 by bugdroid1@chromium.org, Oct 25 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/v8/v8.git/+/52ef2a1c270e612906936d64419c335d62fc5822

commit 52ef2a1c270e612906936d64419c335d62fc5822
Author: Leszek Swirski <leszeks@chromium.org>
Date: Wed Oct 25 11:28:55 2017

[parser] Add an n-ary node for large binop chains

Expressions of the form

    a_0 + a_1 + a_2 + a_3 + ... + a_n

seem to be reasonably common for cases such as building templates.
However, parsing these expressions results in a n-deep expression tree:

           ...
          /
         +
        / \
       +  a_2
      / \
    a_0 a_1

Traversing this tree during compilation can cause a stack overflow when n is
large.

Instead, for left-associate operations such as add, we now build up an
n-ary node in the parse tree, of the form

         n-ary +
       /  |      \
      /   |  ...  \
    a_0  a_1      a_n

The bytecode compiler can now iterate through the child expressions
rather than recursing.

This patch only supports arithmetic operations -- subsequent patches
will enable the same optimization for logical tests and comma
expressions.

Bug:  v8:6964 
Bug:  chromium:724961 
Bug: chromium:731861
Bug:  chromium:752081 
Bug:  chromium:771653 
Bug: chromium:777302
Change-Id: Ie97e4ce42506fe62a7bc4ffbdaa90a9f698352cb
Reviewed-on: https://chromium-review.googlesource.com/733120
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48920}
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/ast/ast-expression-rewriter.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/ast/ast-numbering.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/ast/ast-traversal-visitor.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/ast/ast.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/ast/prettyprinter.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/interpreter/bytecode-array-builder.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/interpreter/bytecode-generator.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/interpreter/bytecode-generator.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/parsing/parser-base.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/parsing/parser.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/parsing/parser.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/parsing/pattern-rewriter.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/src/parsing/preparser.h
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/test/cctest/interpreter/bytecode_expectations/StringConcat.golden
[add] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/test/mjsunit/compiler/nary-binary-ops.js
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc
[modify] https://crrev.com/52ef2a1c270e612906936d64419c335d62fc5822/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc

Status: Fixed (was: Assigned)
We should now accept arbitrarily long chains of additions, marking as fixed.
password and login user are not working , i m facing this problem my verison is 68.0.3440.106
#34 - if you see very long JavaScript stack traces, then it is probably not this problem, even though the error is the same. You might have an infinite recursion in your code. If you find that this is indeed a Chrome issue and not some coding issue, you should file a new issue here, rather than re-use this one.

Sign in to add a comment