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

Issue 656886 link

Starred by 5 users

Issue metadata

Status: Started
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 3
Type: Bug



Sign in to add a comment

Seeing Uncaught RangeError: Maximum call stack size exceeded on Chrome 54

Reported by eber...@linkedin.com, Oct 18 2016

Issue description

Chrome Version       : 54.0.2840.59 m (64-bit) / Windows 7 & Windows 10
URLs (if applicable) : www.linkedin.com/m/
Other browsers tested: 
  Add OK or FAIL, along with the version, after other browsers where you
have tested this issue:
     Chrome: 53.0.2785.116 (64-bit) / Mac OS OK
     Safari: 9.1 (11601.5.17.1) OK / Mac OS
    Firefox: 49.0.1 / Mac OS & Windows 10 OK
         IE:

What steps will reproduce the problem?
(1) On Chrome 54 on Windows 10, try to load the new (beta) Linkedin Homepage* but it fails to render
(2) Open console and see 'Uncaught RangeError: Maximum call stack size exceeded
(3) Note, this this is new on Chrome 54. The issue does not exist on Chrome 53 or on Chrome 54 on Mac.

* We must opt users into beta. 

What is the expected result?

The Homepage loads properly.

What happens instead?

The Homepage doesn't load, gets the error described above and in the screenshot attached below.

Please provide any additional information below. Attach a screenshot if
possible.

 
chrome 54.PNG
14.1 KB View Download
Cc: hablich@chromium.org jkummerow@chromium.org
Labels: OS-Windows
Seems like this is Win64+M54 only. Needs investigation.

Comment 2 Deleted

Additional data points:

Reproducible on 56.0.2891.0 canary (64-bit) on Windows 10
Not reproducible on Chromium (64-bit) builds 53-56 on Windows 10
Not reproducible on 54.0.2840.59 (64-bit) on Mac OS X El Capitan
Cc: kris.sel...@gmail.com marja@chromium.org verwa...@chromium.org
Cc: -marja@chromium.org
Owner: marja@chromium.org
Status: Assigned (was: Unconfirmed)
More info, it seems to be that Uglify 2.5 creates a very long sequence (comma operator) with the top level define() module calls.

When minifying with Uglify 2.7 the sequence is limited to 200 which does not cause the above.

Comment 8 by jochen@chromium.org, Oct 21 2016

Cc: marja@chromium.org
Owner: verwa...@chromium.org
Owner: vogelheim@chromium.org
Status: Started (was: Assigned)
Repros on Linux, tip-of-tree.

#5: Thanks for repro.
Meeh.

Bisect points (repeatably) to ecdecf5e9fec3c61496f3cedd78c0ba146eb5b91

But...  I used x64.debug build (for convenience), and the CL affects debug only. So it's rather unlikely to be also affecting release builds. So it's rather unlikely to be the problem we're actually after.

I'll try again...


[bisect over 32fd7c4c...a0216001; using content_shell w/ --user-data-dir=$(mktemp -d) --no-first-run --single-process --js-flags=--stack-size=650]

Comment 12 by marja@chromium.org, Oct 28 2016

Hmm, why the stack-size flag? Why not use the actual stack size of the platform?

When bisecting, would it help to print out the stack limit and how far from it we are currently (in ParserBase::Next or wherever the stack check is)?

I suspect something's wonky about the stack limit, but it's just a random guess.

Comment 13 by marja@chromium.org, Oct 28 2016

Ahm, now looking at the commit you linked to in more detail... Yeah, if bisect says it's that one, I believe it. Looks like it affects release builds too, so I'd say the most promising direction is to debug that. Maybe the build parameters are set so that that config path is hit...
Picking this up again.

#12/13:
- --stack-size, because it doesn't repro as-is on Linux, but I figured that whichever stack-eating change happened would surely affect all platforms, it's just that for whatever reason Win would be slightly closer from the threshold. So with the 'right' --stack-size, the same effect should happen, and I should be able to expose the root cause.
- "print out the stack limit". Yes, that would have helped. I've now settled for a slightly different (more automable) approach.
- The bisect correctly identified *a* change in stack consumption, but it was very minor. That was IMHO not the bug we're after, but some... other, minor change in behaviour. In other words, the bisect was 'technically correct', but also not very useful.
Am currently doing a double-bisect ("bi-bi-sect"? "quad-sect"? "holo-sect"?) where:
- I'm going through 1 year's worth of Chromium changes.
- For each version, I'm running through different stack sizes (at increment 5), to find the smallest --stack-size for which the repro still works.

That is, I'm bisecting over source code versions, and within a version I bisect over --stack-size. This is mostly automated, with some rather hacked-up scripts.

This is still running, but the first steps show that,
- current tip-of-tree: --stack-size 508
- 1 year ago: --stack-size 328

So within one year, stack consumption increased by ~55%. :-(

Will update when I have more.
         result: 0b5fe82535de96d22d0bd32704e0b3b57f6a07b7 at 508
probing: result: 20fa2832b2650a8654bfd8226561046760ebbfc9 at 328
probing: result: d50140bae570f519cea29a8b20e58511032cbfd7 at 363
probing: result: 987cb78dcfbb737f1042e2395ffba5a8ca1e590d at 510
probing: result: 4dbad9e386a6547eff369969b657f4ef3117a859 at 510
probing: result: dd2fb8355246a4c73576c4784797bf9e9f249de9 at 510
probing: result: 29d1fbe672ebcb1f6332f4109240e200e095b386 at 363
probing: result: 97c974e3f6f4c4a08a39032dd50b71a78e0351ca at 363
probing: result: 5a2a7ffb7245ca5d7491aafd2388ff94aeb95d47 at 363
probing: result: 4270da360229b4589b799dcc451bae17206824f6 at 510
probing: result: 8f4bbe1a28f03508517e99da1bc5e5bb791dd3d2 at 363
probing: result: d2442b6a47a8d188180aad0e5703bbfa71b05c97 at 510
probing: result: 68da48f3c013555d779a0a0c86634e53dfb65ce4 at 363
probing: result: 0f5c5f44fbaf89a0b53c95adc55264362624811a at 363
probing: result: 96a6dfa2c30ab9b22abd20c87ed0e0d6ae41c40e at 510
probing: result: 2c26385851a2425cb68a47da7f420c04e28b6c45 at 363
probing: result: 00dd0a05d86c5b2d3df2f8707ab93517300ed8d3 at 363
probing: result: 4d5335adc272d70da10f0f179ed494561afbb2f3 at 363

First bi-bi-sect run is through. The results look sane & stable, surprisingly. 

The result points to... https://codereview.chromium.org/2048163002. That this would be a ~25% stack increase is plausible, but astounding.

[I'll to another run tomorrow, to find the change between 328..363.]
Cool bi-bisecting :)

Another axis of this is that this reproes on Windows (just with out-of-the-box Chrome) but not on Linux, so somehow we seem to consume more stack on Windows.

Yet another is: what in that JS file in question causes high stack usage while parsing; we were discussing before that there's a long comma separated list, but we should parse that in a while loop, not with some recursive construct. So, what's the point where we run out of stack? Maybe we can do better there? Are we doing something silly and got away with it until now?

Btw, as some parsing funcs moved to ParserBase, we might now consume more stack for lazy parsing, since we might allocate some function-local objects we didn't previously need. Not sure if any of those changes are on the regression range.
#17:

- stack use Windows vs Linux: Yes, I agree. I have optimistically ignored that aspect yet; not sure if good idea.

- parsing + comma-separated expressions: Yes, I quite strongly suspected that as well. Since there've been a number of related changes, I was sure that the bisect would identify one of them; I could fix the likely recursion-vs-loop thing; and ride off into the sunset. Unfortunately, the bisect points to a tooling change so that theory looks incorrect.

(The regression range is a single CL. And results have been very consistent.)


Anyway... will update as I know more.
Second run through, this time exploring the jump from 328kB to 363kB. Also sane & stable result.

probing: result: 776ec2037f76a066854cee725bfc605fc92e511f at 363
probing: result: 122c0f59b37eb1a70055f0f8807267b1fd57c942 at 363
probing: result: 570de6587cd3a56da12d5b234e97ea1e31355f45 at 363
probing: result: 92fdd5d54a4e9a1f89004c53e3686c9af544e6a1 at 328
probing: result: 42f3b18fc539d578aff19a25792aaf19744f17d9 at 363
probing: result: 7278371ad4e9cbceb4b6abf84d43aacb3a8746fb at 328
probing: result: 1d8ea48cbe9dcea5c1e39a483d1c9aa1d2d820c4 at 363
probing: result: f1f1e579ebb2597f450f9de0c9baca514f616e37 at 363
probing: result: aee36769b10db06493038e23773234a2d4159c4a at 363
probing: result: 9f16faf17eb4250aaf392ee83316d6c7bad9a916 at 328
probing: result: 63429cb8585a725eb77615037ad35713e588b20e at 363
probing: result: 68cf0b8360a8ea1dbcd5efb524e7831e1c22bd66 at 363
probing: result: f2ffd5e5b85a66d28f45e21d8d4cc2a221e80403 at 363
probing: result: e16a7d3b1c2a6b0cfa9a240e7fdfa8cdda0729c7 at 328
probing: result: a423527b68fc52203b4b5ba3b2de2f2dc9842f66 at 328

Bisect points to f2ffd5e5b85a66d28f45e21d8d4cc2a221e80403


In other words:
- Nov  8, 2015: 328 kB stack space to parse repro case.
- Nov 24, 2015: 363 kB stack space (at f2ffd5e5)
- Jun  8, 2016: 508 kB stack space (at 96a6dfa)


[The funny thing is, I have no idea what to make of this. Will look again tomorrow.]
Next experiment: Building with gn vs gyp: (Since gyp has "always" used -O3 for V8, which 96a6dfa2 ported over to gn.)

4d5335adc272d70da10f0f179ed494561afbb2f3, gyp: 510, gn: 363
96a6dfa2c30ab9b22abd20c87ed0e0d6ae41c40e, gyp: 510, gn: 510

So... it's the compiler, -O2 vs -O3, clang.

Comment 21 by marja@chromium.org, Nov 11 2016

Interesting!

I'd be interested in the results of the following:
1) good chromium + what v8 was back then
vs.
2) good chromium + tot v8

That is, it would be interesting to know whether something we did on the V8 side increased the stack size at all, or is it just chromium side changes.

------

That said, to me this looks like we were "close" to the limit in some sense, and now the cited chromium changes pushed us beyond the limit. It would still be interesting to know what's the construct where we exceed the limit and what we can do about it.

Comment 22 by marja@chromium.org, Nov 16 2016

Cc: vogelheim@chromium.org
Owner: marja@chromium.org
Back @ work, picking up this bug again.

Comment 23 by marja@chromium.org, Nov 16 2016

dpranke@, fyi, as your commit ( https://codereview.chromium.org/2048163002 ) affects this.

Current working theory: the windows stack check is somehow messed up by O3 (with gn).

Comment 24 by marja@chromium.org, Nov 16 2016

Cc: dpranke@chromium.org
Now really cc += dpranke

Comment 25 by marja@chromium.org, Nov 16 2016

More info (for me):

Here's the stack check in ParserBase.

  INLINE(Token::Value Next()) {
    if (stack_overflow_) return Token::ILLEGAL;
    {
      if (GetCurrentStackPosition() < stack_limit_) {
        // Any further calls to Next or peek will return the illegal token.
        // The current call must return the next token, which might already
        // have been peek'ed.
        stack_overflow_ = true;
      }
    }
    return scanner()->Next();
  }

inline uintptr_t GetCurrentStackPosition() {
  // Takes the address of the limit variable in order to find out where
  // the top of stack is right now.
  uintptr_t limit = reinterpret_cast<uintptr_t>(&limit);
  return limit;
}

and I guess the stack size comes from here (real_climit):

bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
  bool should_set_stack_limits = false;
  if (real_climit_ == kIllegalLimit) {
    const uintptr_t kLimitSize = FLAG_stack_size * KB;
    DCHECK(GetCurrentStackPosition() > kLimitSize);
    uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
    real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    set_jslimit(SimulatorStack::JsLimitFromCLimit(isolate, limit));
    real_climit_ = limit;
    set_climit(limit);
    should_set_stack_limits = true;
  }
  postpone_interrupts_ = NULL;
  interrupt_flags_ = 0;
  return should_set_stack_limits;
}

Comment 26 by marja@chromium.org, Nov 16 2016

And the stack size should come from here:

#ifdef V8_TARGET_ARCH_ARM
// Set stack limit lower for ARM than for other architectures because
// stack allocating MacroAssembler takes 120K bytes.
// See issue crbug.com/405338
#define V8_DEFAULT_STACK_SIZE_KB 864
#else
// Slightly less than 1MB, since Windows' default stack size for
// the main execution thread is 1MB for both 32 and 64-bit.
#define V8_DEFAULT_STACK_SIZE_KB 984
#endif

More Linux investigations:

The stack is highest (lowest, depending on which way you look at it) at location 1452677 of the file.

At that point we are 283 steps deep in the recursive descend, namely here:

#2 ParserBase<PreParser>::ParseAssignmentExpression
#3 ParserBase<PreParser>::ParseArrayLiteral
#4 ParserBase<PreParser>::ParsePrimaryExpression
#5 ParserBase<PreParser>::ParseMemberExpression
#6 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#7 ParserBase<PreParser>::ParseLeftHandSideExpression
#8 ParserBase<PreParser>::ParsePostfixExpression
#9 ParserBase<PreParser>::ParseBinaryExpression
#10 ParserBase<PreParser>::ParseConditionalExpression
#11 ParserBase<PreParser>::ParseAssignmentExpression
#12 ParserBase<PreParser>::ParseArrayLiteral
#13 ParserBase<PreParser>::ParsePrimaryExpression
#14 ParserBase<PreParser>::ParseMemberExpression
#15 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#16 ParserBase<PreParser>::ParseLeftHandSideExpression
#17 ParserBase<PreParser>::ParsePostfixExpression
#18 ParserBase<PreParser>::ParseBinaryExpression
#19 ParserBase<PreParser>::ParseConditionalExpression
#20 ParserBase<PreParser>::ParseAssignmentExpression
#21 ParserBase<PreParser>::ParseArrayLiteral
#22 ParserBase<PreParser>::ParsePrimaryExpression
#23 ParserBase<PreParser>::ParseMemberExpression
#24 ParserBase<PreParser>::ParseMemberWithNewPrefixesEx
#25 ParserBase<PreParser>::ParseLeftHandSideExpression
#26 ParserBase<PreParser>::ParsePostfixExpression
#27 ParserBase<PreParser>::ParseBinaryExpression
#28 ParserBase<PreParser>::ParseConditionalExpression
#29 ParserBase<PreParser>::ParseAssignmentExpression
#30 ParserBase<PreParser>::ParseArrayLiteral
#31 ParserBase<PreParser>::ParsePrimaryExpression
#32 ParserBase<PreParser>::ParseMemberExpression
#33 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#34 ParserBase<PreParser>::ParseLeftHandSideExpression
#35 ParserBase<PreParser>::ParsePostfixExpression
#36 ParserBase<PreParser>::ParseBinaryExpression
#37 ParserBase<PreParser>::ParseConditionalExpression
#38 ParserBase<PreParser>::ParseAssignmentExpression
#39 ParserBase<PreParser>::ParseArrayLiteral
#40 ParserBase<PreParser>::ParsePrimaryExpression
#41 ParserBase<PreParser>::ParseMemberExpression
#42 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#43 ParserBase<PreParser>::ParseLeftHandSideExpression
#44 ParserBase<PreParser>::ParsePostfixExpression
#45 ParserBase<PreParser>::ParseBinaryExpression
#46 ParserBase<PreParser>::ParseConditionalExpression
#47 ParserBase<PreParser>::ParseAssignmentExpression
#48 ParserBase<PreParser>::ParseArrayLiteral
#49 ParserBase<PreParser>::ParsePrimaryExpression
#50 ParserBase<PreParser>::ParseMemberExpression
#51 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#52 ParserBase<PreParser>::ParseLeftHandSideExpression
#53 ParserBase<PreParser>::ParsePostfixExpression
#54 ParserBase<PreParser>::ParseBinaryExpression
#55 ParserBase<PreParser>::ParseConditionalExpression
#56 ParserBase<PreParser>::ParseAssignmentExpression
#57 ParserBase<PreParser>::ParseArrayLiteral
#58 ParserBase<PreParser>::ParsePrimaryExpression
#59 ParserBase<PreParser>::ParseMemberExpression
#60 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#61 ParserBase<PreParser>::ParseLeftHandSideExpression
#62 ParserBase<PreParser>::ParsePostfixExpression
#63 ParserBase<PreParser>::ParseBinaryExpression
#64 ParserBase<PreParser>::ParseConditionalExpression
#65 ParserBase<PreParser>::ParseAssignmentExpression
#66 ParserBase<PreParser>::ParseArrayLiteral
#67 ParserBase<PreParser>::ParsePrimaryExpression
#68 ParserBase<PreParser>::ParseMemberExpression
#69 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#70 ParserBase<PreParser>::ParseLeftHandSideExpression
#71 ParserBase<PreParser>::ParsePostfixExpression
#72 ParserBase<PreParser>::ParseBinaryExpression
#73 ParserBase<PreParser>::ParseConditionalExpression
#74 ParserBase<PreParser>::ParseAssignmentExpression
#75 ParserBase<PreParser>::ParseArrayLiteral
#76 ParserBase<PreParser>::ParsePrimaryExpression
#77 ParserBase<PreParser>::ParseMemberExpression
#78 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#79 ParserBase<PreParser>::ParseLeftHandSideExpression
#80 ParserBase<PreParser>::ParsePostfixExpression
#81 ParserBase<PreParser>::ParseBinaryExpression
#82 ParserBase<PreParser>::ParseConditionalExpression
#83 ParserBase<PreParser>::ParseAssignmentExpression
#84 ParserBase<PreParser>::ParseObjectPropertyDefinition
#85 ParserBase<PreParser>::ParseObjectLiteral
#86 ParserBase<PreParser>::ParsePrimaryExpression
#87 ParserBase<PreParser>::ParseMemberExpression
#88 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#89 ParserBase<PreParser>::ParseLeftHandSideExpression
#90 ParserBase<PreParser>::ParsePostfixExpression
#91 ParserBase<PreParser>::ParseBinaryExpression
#92 ParserBase<PreParser>::ParseConditionalExpression
#93 ParserBase<PreParser>::ParseAssignmentExpression
#94 ParserBase<PreParser>::ParseExpressionCoverGrammar
#95 ParserBase<PreParser>::ParseExpression
#96 ParserBase<PreParser>::ParseReturnStatement
#97 ParserBase<PreParser>::ParseStatementList
#98 ParseStatementList
#100 ParserBase<PreParser>::ParseMemberExpression
#101 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#102 ParserBase<PreParser>::ParseLeftHandSideExpression
#103 ParserBase<PreParser>::ParsePostfixExpression
#104 ParserBase<PreParser>::ParseBinaryExpression
#105 ParserBase<PreParser>::ParseConditionalExpression
#106 ParserBase<PreParser>::ParseAssignmentExpression
#107 ParserBase<PreParser>::ParseVariableDeclarations
#108 ParseVariableStatement
#110 ParserBase<PreParser>::ParseStatementList
#111 ParseStatementList
#113 ParserBase<PreParser>::ParseMemberExpression
#114 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#115 ParserBase<PreParser>::ParseLeftHandSideExpression
#116 ParserBase<PreParser>::ParsePostfixExpression
#117 ParserBase<PreParser>::ParseBinaryExpression
#118 ParserBase<PreParser>::ParseConditionalExpression
#119 ParserBase<PreParser>::ParseAssignmentExpression
#120 ParserBase<PreParser>::ParseVariableDeclarations
#121 ParseVariableStatement
#123 ParserBase<PreParser>::ParseStatementList
#124 ParseStatementList
#126 ParserBase<PreParser>::ParseMemberExpression
#127 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#128 ParserBase<PreParser>::ParseLeftHandSideExpression
#129 ParserBase<PreParser>::ParsePostfixExpression
#130 ParserBase<PreParser>::ParseBinaryExpression
#131 ParserBase<PreParser>::ParseConditionalExpression
#132 ParserBase<PreParser>::ParseAssignmentExpression
#133 ParserBase<PreParser>::ParseVariableDeclarations
#134 ParseVariableStatement
#136 ParserBase<PreParser>::ParseStatementList
#137 ParseStatementList
#139 ParserBase<PreParser>::ParseMemberExpression
#140 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#141 ParserBase<PreParser>::ParseLeftHandSideExpression
#142 ParserBase<PreParser>::ParsePostfixExpression
#143 ParserBase<PreParser>::ParseBinaryExpression
#144 ParserBase<PreParser>::ParseConditionalExpression
#145 ParserBase<PreParser>::ParseAssignmentExpression
#146 ParserBase<PreParser>::ParseVariableDeclarations
#147 ParseVariableStatement
#149 ParserBase<PreParser>::ParseStatementList
#150 ParseStatementList
#152 ParserBase<PreParser>::ParseMemberExpression
#153 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#154 ParserBase<PreParser>::ParseLeftHandSideExpression
#155 ParserBase<PreParser>::ParsePostfixExpression
#156 ParserBase<PreParser>::ParseBinaryExpression
#157 ParserBase<PreParser>::ParseConditionalExpression
#158 ParserBase<PreParser>::ParseAssignmentExpression
#159 ParserBase<PreParser>::ParseVariableDeclarations
#160 ParseVariableStatement
#162 ParserBase<PreParser>::ParseStatementList
#163 ParseStatementList
#165 ParserBase<PreParser>::ParseMemberExpression
#166 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#167 ParserBase<PreParser>::ParseLeftHandSideExpression
#168 ParserBase<PreParser>::ParsePostfixExpression
#169 ParserBase<PreParser>::ParseBinaryExpression
#170 ParserBase<PreParser>::ParseConditionalExpression
#171 ParserBase<PreParser>::ParseAssignmentExpression
#172 ParserBase<PreParser>::ParseVariableDeclarations
#173 ParseVariableStatement
#175 ParserBase<PreParser>::ParseStatementList
#176 ParseStatementList
#178 ParserBase<PreParser>::ParseMemberExpression
#179 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#180 ParserBase<PreParser>::ParseLeftHandSideExpression
#181 ParserBase<PreParser>::ParsePostfixExpression
#182 ParserBase<PreParser>::ParseBinaryExpression
#183 ParserBase<PreParser>::ParseConditionalExpression
#184 ParserBase<PreParser>::ParseAssignmentExpression
#185 ParserBase<PreParser>::ParseVariableDeclarations
#186 ParseVariableStatement
#188 ParserBase<PreParser>::ParseStatementList
#189 ParseStatementList
#191 ParserBase<PreParser>::ParseMemberExpression
#192 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#193 ParserBase<PreParser>::ParseLeftHandSideExpression
#194 ParserBase<PreParser>::ParsePostfixExpression
#195 ParserBase<PreParser>::ParseBinaryExpression
#196 ParserBase<PreParser>::ParseConditionalExpression
#197 ParserBase<PreParser>::ParseAssignmentExpression
#198 ParserBase<PreParser>::ParseVariableDeclarations
#199 ParseVariableStatement
#201 ParserBase<PreParser>::ParseStatementList
#202 ParseStatementList
#204 ParserBase<PreParser>::ParseMemberExpression
#205 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#206 ParserBase<PreParser>::ParseLeftHandSideExpression
#207 ParserBase<PreParser>::ParsePostfixExpression
#208 ParserBase<PreParser>::ParseBinaryExpression
#209 ParserBase<PreParser>::ParseConditionalExpression
#210 ParserBase<PreParser>::ParseAssignmentExpression
#211 ParserBase<PreParser>::ParseVariableDeclarations
#212 ParseVariableStatement
#214 ParserBase<PreParser>::ParseStatementList
#215 ParseStatementList
#217 ParserBase<PreParser>::ParseMemberExpression
#218 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#219 ParserBase<PreParser>::ParseLeftHandSideExpression
#220 ParserBase<PreParser>::ParsePostfixExpression
#221 ParserBase<PreParser>::ParseBinaryExpression
#222 ParserBase<PreParser>::ParseConditionalExpression
#223 ParserBase<PreParser>::ParseAssignmentExpression
#224 ParserBase<PreParser>::ParseVariableDeclarations
#225 ParseVariableStatement
#227 ParserBase<PreParser>::ParseStatementList
#228 ParseStatementList
#230 ParserBase<PreParser>::ParseMemberExpression
#231 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#232 ParserBase<PreParser>::ParseLeftHandSideExpression
#233 ParserBase<PreParser>::ParsePostfixExpression
#234 ParserBase<PreParser>::ParseBinaryExpression
#235 ParserBase<PreParser>::ParseConditionalExpression
#236 ParserBase<PreParser>::ParseAssignmentExpression
#237 ParserBase<PreParser>::ParseVariableDeclarations
#238 ParseVariableStatement
#240 ParserBase<PreParser>::ParseStatementList
#241 ParseStatementList
#243 ParserBase<PreParser>::ParseMemberExpression
#244 ParserBase<PreParser>::ParseMemberWithNewPrefixesExpression
#245 ParserBase<PreParser>::ParseLeftHandSideExpression
#246 ParserBase<PreParser>::ParsePostfixExpression
#247 ParserBase<PreParser>::ParseBinaryExpression
#248 ParserBase<PreParser>::ParseConditionalExpression
#249 ParserBase<PreParser>::ParseAssignmentExpression
#250 ParserBase<PreParser>::ParseArguments
#251 ParserBase<PreParser>::ParseLeftHandSideExpression
#252 ParserBase<PreParser>::ParsePostfixExpression
#253 ParserBase<PreParser>::ParseBinaryExpression
#254 ParserBase<PreParser>::ParseConditionalExpression
#255 ParserBase<PreParser>::ParseAssignmentExpression
#256 ParserBase<PreParser>::ParseAssignmentExpression
#257 ParserBase<PreParser>::ParseExpressionCoverGrammar
#258 ParserBase<PreParser>::ParseExpression
#259 ParserBase<PreParser>::ParseExpressionOrLabelledStatement
#260 ParserBase<PreParser>::ParseStatementList
#261 PreParser::ParseStatementListAndLogFunction
#262 PreParser::PreParseFunction
#263 Parser::SkipFunction
#264 Parser::ParseFunctionLiteral
#265 ParserBase<Parser>::ParseMemberExpression
#266 ParserBase<Parser>::ParseLeftHandSideExpression
#267 ParserBase<Parser>::ParsePostfixExpression
#268 ParserBase<Parser>::ParseBinaryExpression
#269 ParserBase<Parser>::ParseConditionalExpression
#270 ParserBase<Parser>::ParseAssignmentExpression
#271 ParserBase<Parser>::ParseArguments
#272 ParserBase<Parser>::ParseLeftHandSideExpression
#273 ParserBase<Parser>::ParsePostfixExpression
#274 ParserBase<Parser>::ParseBinaryExpression
#275 ParserBase<Parser>::ParseConditionalExpression
#276 ParserBase<Parser>::ParseAssignmentExpression
#277 ParserBase<Parser>::ParseExpressionCoverGrammar
#278 ParseExpression
#280 ParserBase<Parser>::ParseStatementList
#281 ParseStatementList
#283 Parser::ParseProgram

So, it is somewhat deep but not even close to the point where we'd overflow.

We seem to be inside many "loops" like
ParsePrimary-> ParseArrayLiteral -> ParseAssignmentExpression -> ParseConditionalExpression -> ParseBinaryExpression -> ParsePostfixExpression -> ParseLeftHandSideExpression -> ParseMemberWithNewPrefixes -> ParseMember -> ParsePrimary

so it's nested array literals.

However, if it's really some windows weirdness, these Linux investigations might not matter.

A runner up is that we were always somehow "close" to the stack limit and now some minor changes (such as using O3 instead of O2) pushed us beyond the limit.

Waiting to get a windows computer to investigate further.

Comment 27 by marja@chromium.org, Nov 16 2016

Going to run these experiments after getting a Windows computer:
1) Check if we're anywhere close to the stack limit when running w/ d8 and -O3.
2) Run with content-shell and crash if we reach the stack limit; get a stack trace from there and see where we are. Maybe something wonky is going on on the Chromium side so that V8 ends up getting not so much stack to begin with. (We set the stack limit during initialization, so whatever Chromium then has on the stack when calling into V8 are counted against the limit.)

Comment 28 by marja@chromium.org, Nov 17 2016

Oh noes, this doesn't repro on Windows with a self-built Chrome (or content shell) :/

Comment 29 by marja@chromium.org, Nov 17 2016

Couldn't repro on Windows w/ Chrome 55.0.2883.52 either. Maybe already fixed on trunk? But we should find out what the fix is and backmerge it if needed.

Comment 30 by marja@chromium.org, Nov 17 2016

... aaand couldn't repro on 54.0.2840.99 either. But otoh I'm now using a different Windows machine than when I was able to repro this, so, I'm starting to doubt that that's why I can't repro.

Kris, does this still repro for you in some setup?

Comment 31 by marja@chromium.org, Nov 18 2016

... another possibility is that the script in that link has been updated (maybe migrated to use Uglify 2.7, see comment 7) and that's why I cannot repro this any more :P

(I didn't save the file for which I was able to repro this.)

Comment 32 by marja@chromium.org, Nov 18 2016

Omg, I can repro it now. The reason I couldn't before was doing stupid stuff.
Components: Blink>JavaScript
It seems we see the same error in our project on Windows/Chrome 55. I am not 100% sure, starting from Chrome 54. I was able to create a minimal example demonstrating the issue:

https://jsfiddle.net/71hrzobq/

It does nothing in Chrome - shows 'Uncaught RangeError: Maximum call stack size exceeded'. On other browsers it works fine, both alert messages are shown.

We also found, that issue is somehow related to string size being generated. To reproduce this issue on some machines smaller string size is enough, some machines need more lines concatenated to string.


(Update: After all, I wasn't able to repro the orig. issue in a consistent manner; e.g., I got the error, but trying out a different chromium version and going back to the old version made it disappear; it was impossible to debug / bisect.)

The new example is essentially (quoted string length doesn't matter for stack consumption):

var t = "a" + "a" + "a" + ... ~8700 times.

But I'm not sure if it's the same or a different issue... a recursive descent parser inevitably runs out of stack if the construct to be parsed is deep enough. But the orig. issue seemed to be something more fishy (we shouldn't have been even close to running out of stack with that code!).
... aaand tested with Firefox; it handles an addition consisting of 512000 additions just fine (at that point I stopped experimenting since my text editor slowed down so badly) whereas Chrome doesn't handle even the 8700 

Maybe SpiderMonkey (Firefox) has a better parser shortcut for this case and doesn't even enter the recursive descent for each component (like we seem to do)!

I filed a separate bug about that: https://bugs.chromium.org/p/v8/issues/detail?id=5793
You started fixing this bug over two years ago. Are you still working on it? You can update the status to "archived", "wontfix", or "closed". You can remove yourself as owner and change status to "untriaged", but if this is still a real bug, please do not sit on it.

Sign in to add a comment