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

Issue 252492 link

Starred by 15 users

Issue metadata

Status: Fixed
Owner:
Closed: Nov 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Web Workers's stack size is smaller than the intended size

Reported by matthewc...@gmail.com, Jun 20 2013

Issue description

UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22

Steps to reproduce the problem:
1. Download xsltproc.html and xsltproc.js from https://github.com/mcasperson/xsltproc.js/tree/e54bc9bbbf11d88e892ceb453d8a41bf577cf384
2. Run xsltproc.html in Chrome
3. The first run will succeed (without web workers), and the second (using web workers) will fail with a "Uncaught RangeError: Maximum call stack size exceeded" exception

What is the expected behavior?
Both calls should result in the XML being transformed (and this is the case in Firefox).

What went wrong?
"Uncaught RangeError: Maximum call stack size exceeded" exception in webworkers

Did this work before? N/A 

Chrome version: 25.0.1364.160  Channel: stable
OS Version: Kubuntu 13.04
 
Error also occures in Chrome Version 29.0.1541.2 dev
Cc: rponnada@chromium.org
Labels: Needs-Feedback
Could you please screen-cast of the issue will help in triage further. 
Open the page at https://googledrive.com/host/0B6cpJDiEKC62RU1rU1d4OFhselU/xsltproc.html and you can see the issue for yourself.

The code works in Windows Chrome 28.0.1500.71 m, but fails in Ubuntu 13.04 Chromium 28.0.1500.52 and Ubuntu 13.04 Chrome  29.0.1547.18 dev.
Confirming that this is still an error in Chrome 30.0.1599.101 under Fedora 19 x64.

Comment 5 by Deleted ...@, Dec 2 2013

Hello, I made a fiddle that I think exposes this, or a related/similar, issue:

http://jsfiddle.net/3wrju/17/

For us the problem surfaced originally while using crypto-js inside a worker (see the links below with other people having similar problems). So we made this fiddle and discovered that in at least one chrome build the web workers have a very small limit for the argument length of Function.apply. In particular, Chrome Version 31.0.1650.57 on Fedora  64bit exhibits the problem with workers throwing RangeError at 31774, but the same version using on OS X 10.9 both worker and window invocations fail at a much bigger limit (~127800). This is the limit that I also find on version 27.0.1453.116 on Windows 8 65 bit.

possibly same issue:
http://code.google.com/p/crypto-js/issues/detail?id=90
http://code.google.com/p/crypto-js/issues/detail?id=68

Perhaps this is a problem with the Linux builds then?

Here are some other related issues: 

https://bugs.webkit.org/show_bug.cgi?id=80797

And here is a bug in crypto-js that was fixed apparently in reference to the aforementioned webkit issue.

http://code.google.com/p/crypto-js/issues/detail?id=37

Comment 6 Deleted

As it turns out there is a command line switch that can work around the issue:

chrome --js-flags="--stack-size 2048"

Tweaking the stack size fixes the issue I reported.

Comment 8 by Deleted ...@, Feb 25 2014

As far as crypto-js is concerned, I have a small patch that sidesteps/fixes the issue for web workers.  I hope this is merged into upstream crypto-js ASAP.

Instead of using a '[].push.apply()' call, I used the simpler '[].concat()' function which doesn't hit this limit anymore (see last comment):

https://code.google.com/p/crypto-js/issues/detail?id=68

I guess in web worker code avoid things that cause tons of function calls at once/recursion.

Comment 9 by rob@robwu.nl, Mar 24 2014

Labels: -Needs-Feedback Cr-Blink Cr-Blink-Workers
Status: Untriaged
Summary: Web Workers's maximum argument count of function.apply is lower than main scripts (was: "Maximum call stack size exceeded" with emenscript and web workers)
Comment 5 provided a dynamic test case that shows the core of the issue: http://jsfiddle.net/3wrju/17/

The problem is basically that the following script works in non-worker scripts:

var list = new Array(1e5);
<function>.apply(null, list)

But fails in worker scripts with "Uncaught RangeError: Maximum call stack size exceeded".

This issue still exists in 35.0.1863.0.
Please see #367176

Peersm is doing very exactly what is explained in this thread: decrypt/hash inside a worker using String.fromCharCode.apply(null,Uint8Array)

The chunks passed to apply are 65 KB length, which seems little but the same issue occurs.

Right now we have implemented a workaround, which is cutting the 65 kB blocks into 16 kB blocks before passing them to apply.

But we can not reproduce the problem on our confs so we don't know if the workaround is working.

We can provide more details and the worker code if needed.
The workaround is working so this bug should be confirmed, it occurs with chunk size as small as 65 kB.
I have similar issues with my flash shared object editor (http://apps.coursevector/minerva/). If you open a large SOL file, and go to save it, internally a web worker coverts all the data into a an Int8Array and then calls Array.apply([], arrReturn). But in one instance a user has an arrReturn (Int8Array) of a size of 33,906 integers which returns this error as well. It works fine in x32 and on firefox or any other browser. But x64 chrome dies. Just another vote to increase this limit and fix this bug!

Comment 13 by van...@gmail.com, Nov 24 2014

--stack-size option doesn't seem to affect web workers
[Automated message] This issue does not seem to be a V8 issue. The label Cr-Blink-JavaScript will be removed next week. The label Cr-Blink will be added instead. If you think that this issue is correctly labeled as a V8 issue please contact hablich@.
Labels: NotV8
[Automated message] This issue does not seem to be a V8 issue. The label Cr-Blink-JavaScript is removed. The label Cr-Blink is added instead. If you think that this issue was correctly labeled as a V8 issue please contact hablich@.

Comment 16 by tkent@chromium.org, Jul 15 2015

Labels: -Cr-Content-JavaScript -Cr-Blink
Labels: -OS-Linux -Pri-2 OS-All Pri-3
Status: Available (was: Untriaged)
The link in comment #5 and comment #9 is a good repro and indeed Chrome 53.0.2785.8 still exhibits the problem on Linux and Windows.

Firefox 47 does not have have this issue.
I think my problem may be related to this but reproduced in a different way. Loading a js file containing the following function definition inside a web/service worker will also result in "Uncaught RangeError: Maximum call stack size exceeded". without any code being executed.
Firefox does not seem to have problems with it.

function nOa() {
        EE.call(this);
        this.kLa = this.F2a = this.cD = this.idb = this.dSa = this.N2a = this.O8a = this.$6a = this.g0a = this.TLa = this.RLa = this.$9a = this.d$a = this.h$a = this.T1a = this.l2a = this.V_a = this.S$a = this.jgb = this.yeb = this.IRa = this.LIa = this.gSa = this.R8a = this.w1a = this.XIa = this.IKa = this.FKa = this.DW = this.xA = this.K3a = this.bdb = this.Eeb = this.ieb = this.M6a = this.H6a = this.LRa = this.Sab = this.zu = this.m0a = this.z0a = this.cUa = this.QQ = this.meb = this.Ldb = this.Oeb = this.leb = this.qeb = this.Jdb = this.YPa = this.bQa = this.kOa = this.vdb = this.iKa = this.z1a = this.iOa = this.Qeb = this.Qbb = this.RKa = this.sgb = this.A7a = this.O3a = this.WSa = this.VXa = this.XT = this.ZRa = this.lYa = this.Hgb = this.MNa = this.rt = this.Dfb = this.gLa = this.TT = this.ndb = this.ddb = this.RPa = this.qPa = this.m$a = this.Bbb = this.Wcb = this.XP = this.ON = this.kc = this.eUa = this.hUa = this.PRa = this.ISa = this.xSa = this.bW = this.I_ = this.U3a = this.AMa = this.yX = this.GXa = this.zq = this.EVa = this.ml = this.QWa = this.OWa = this.MWa = this.KWa = this.IT = this.HT = this.CMa = this.Gab = this.K2a = this.R0a = this.NC = this.hXa = this.KXa = this.H2a = this.iSa = this.hMa = this.d5a = this.r6a = this.$3a = this.Y3a = this.b4a = this.L8a = this.sPa = this.I3a = this.K9a = this.i_a = this.i0a = this.SRa = this.mcb = this.v6a = this.t6a = this.h6a = this.f6a = this.c6a = this.Z5a = this.X5a = this.R5a = this.P5a = this.N5a = this.L5a = this.J5a = this.n5a = this.r5a = this.p5a = this.V4a = this.T4a = this.R4a = this.P4a = this.j4a = this.h4a = this.W3a = this.Pab = this.H9a = this.cLa = this.ehb = this.kdb = this.W2a = this.d0a = this.$_a = this.o_a = this.iYa = this.TOa = this.oOa = this.Tfb = this.m2a = this.R2a = this.J6a = this.p1a = this.qXa = this.Eab = this.z2a = this.PXa = this.VQa = this.R9a = this.k_ = this.sbb = this.lQa = this.Y9a = this.B9a = this.h9a = this.GVa = this.EP = this.VOa = this.cPa = this.ZKa = this.VKa = this.OIa = this.eza = this.Vbb = this.a8a = this.o0a = this.yhb = this.Sya = this.F_ = this.Nya = this.$cb = this.b_ = this.r9a = this.T5a = this.QW = this.V5a = this.a6a = this.p6a = this.n6a = this.l6a = this.j6a = this.F5a = this.D5a = this.B5a = this.z5a = this.x5a = this.v5a = this.t5a = this.l5a = this.h5a = this.j5a = this.f5a = this.$4a = this.X4a = this.x4a = this.vra = this.ura = this.f4a = this.sJa = this.x3a = this.o_ = this.SXa = this.O2a = this.UIa = this.RT = this.GRa = this.Wgb = this.$fb = this.ed = this.ocb = this.kcb = this.ubb = this.$ab = this.Tab = this.Kab = this.Iab = this.Cab = this.U$a = this.c9a = this.B8a = this.x8a = this.z6a = this.G3a = this.w3a = this.t3a = this.B2a = this.q2a = this.R1a = this.J1a = this.y1a = this.n1a = this.V0a = this.z_a = this.x_a = this.v_a = this.RXa = this.IXa = this.jXa = this.YVa = this.SVa = this.QVa = this.OVa = this.MVa = this.KVa = this.aTa = this.BSa = this.nSa = this.URa = this.WRa = this.NRa = this.rRa = this.hRa = this.fRa = this.cRa = this.XQa = this.vPa = this.OOa = this.MOa = this.aLa = this.XKa = this.TKa = this.MKa = this.qJa = this.oJa = this.SIa = this.QIa = this.x6a = this.H5a = this.b5a = this.N4a = this.F4a = this.H4a = this.J4a = this.D4a = this.B4a = this.L4a = this.z4a = this.v4a = this.t4a = this.r4a = this.p4a = this.n4a = this.l4a = this.d4a = this.DSa = this.Vqa = this.Fra = this.NXa = this.W9a = this.$Pa = this.tPa = this.OPa = this.RO = this.Ueb = this.WUa = this.UUa = this.QUa = this.IQ = this.Teb = this.dfb = this.cfb = this.ffb = this.Zeb = this.afb = this.P7a = this.O7a = this.q7a = this.s7a = this.o7a = this.Rgb = this.Q6a = this.lRa = this.kRa = this.$Qa = this.vQa = this.DQa = this.tQa = this.rQa = this.nQa = this.MJa = this.$Ja = this.bKa = this.OJa = this.WJa = this.UJa = this.YJa = this.SJa = this.QJa = this.Phb = this.$gb = this.beb = this.Zdb = this.Rdb = this.Tdb = this.b7a = this.W6a = this.S6a = this.U2a = this.Y2a = this.o2a = this.B0a = this.HNa = this.X_ = this.Meb = this.L1a = this.P1a = this.N1a = this.H1a = this.rVa = this.kVa = this.qVa = this.vVa = this.INa = this.d7a = this.Y0a = this.w0a = this.P0a = this.M9a = this.g7a = this.mX = this.i7a = this.m7a = this.k7a = this.oXa = this.iX = this.u2a = this.y6a = this.YMa = this.xNa = this.QMa = this.FNa = this.mO = this.tNa = this.DNa = this.fNa = this.SMa = this.hNa = this.dNa = this.$Ma = this.MMa = this.bNa = this.UMa = this.Cy = this.KMa = this.jNa = this.OMa = this.zNa = this.nNa = this.lNa = this.BNa = this.rNa = this.vNa = this.oLa = this.XN = this.rLa = this.sLa = this.JC = null ;
        this.Rc = C();
        this.U6a = this.Y6a = this.F1a = this.xPa = this.yVa = this.BVa = this.uVa = this.xdb = this.Y8a = this.v8a = this.mOa = this.d1a = this.ZSa = this.g2a = this.pgb = this.bhb = this.b1a = this.$0a = this.n8a = this.uSa = this.qSa = this.aVa = this.yRa = this.APa = this.fQa = this.KNa = this.pNa = this.WMa = this.uLa = this.mLa = this.qLa = null ;
        this.Rn = C();
        this.Zgb = this.Nfb = this.Web = this.SUa = this.P_a = this.eJa = this.YUa = this.jJa = this.cJa = this.xQa = this.zQa = this.BQa = this.pQa = this.FQa = this.iLa = this.Pgb = this.Agb = this.deb = this.feb = this.aeb = this.Wdb = null ;
        this.Ay = C();
        this.jh = C();
        this.lKa = null ;
        this.kh = C();
        this.mh = C();
        this.gYa = null ;
        this.rMa = C()
}

Comment 19 Deleted

I don't really know what I'm talking about, but this[1] looks to me like the stack size of workers is 500KB, and overrides the --stack-size flag. the main thread's stack size is V8's default of 894KB.

[1] https://chromium.googlesource.com/chromium/blink/+/986a9000e9cb2b032274412356dc9720e96a2584/Source/bindings/core/v8/V8Initializer.cpp#469

Comment 21 by marsh...@mroch.com, Oct 10 2016

See also a few lines down from there: https://chromium.googlesource.com/chromium/blink/+/986a9000e9cb2b032274412356dc9720e96a2584/Source/bindings/core/v8/V8Initializer.cpp#483

Dividing by the pointer size means that the stack is 500KB/8 = 62.5KB. That seems like a bug, compared to the main thread's 894KB.

Comment 22 by n...@fb.com, Nov 3 2016

Labels: DevRel-Facebook
Cc: jochen@chromium.org
Owner: haraken@chromium.org
Cc: haraken@chromium.org
Owner: nhiroki@chromium.org
nhiroki@: Is there any reason we want to limit the worker stack size to 500 KB?

This patch set the limit:
https://webkit.googlesource.com/WebKit/+/85ac4cf1c68530e5cc3144a83c7eee4c10915d9f

"This is because V8's default stack limit is 512K on ia32 or 1M on x64, but the worker process runs workers on a thread with the OS X default stack size--512K. Because there are already some C++ frames on the stack when V8 establishes its 512K default stack limit, and V8 doesn't precisely enforce the stack limit, runaway recursion in V8 workers overflows the OS stack and segfaults, killing the worker process."

We already stopped supporting 32-bit Chrome for MacOSX, so we can simply raise the limit?
https://gsuiteupdates.googleblog.com/2014/09/google-chrome-64-bit-for-mac-and-windows.html
nhiroki@: check out https://chromium.googlesource.com/v8/v8.git/+/5.6.204/src/execution.cc#401

I think this is where V8 gets its stack limit. It's interesting to me that V8 sets its limit to `GetCurrentStackPosition() - kLimitSize`, but the worker sets it to `&here - kWorkerMaxStackSize / sizeof(uint32_t*)`.

GetCurrentStackPosition() is equivalent to &here, and kLimitSize and kWorkerMaxStackSize are both in KB. so why does the worker divide by sizeof(uint32_t*)?

FWIW, when I take the script I was trying to run in a worker, and run it in Node with --stack-size=500, it works. but it overflows with --stack-size=63 (500/8). That makes me think that 500KB would be adequate and the sizeof(uint32_t*) is the issue.

But I really have little idea what I'm talking about :)
Labels: -NotV8 -Pri-3 Pri-2
Status: Started (was: Available)
marshall@: Thank you for the information. That's really helpful to understand the current behavior. I'll take a closer look...
As marshall@ pointed out, the calculation looks wrong.

The formula for main thread is:
  GetCurrentStackPosition() - kLimitSize
This can be represented as
  <uintptr_t> - <uintptr_t>

On the other hand, the formula for worker thread is:
  const int kWorkerMaxStackSize;
  uint32_t here;
  reinterpret_cast<uintptr_t>(&here - kWorkerMaxStackSize / sizeof(uint32_t*))
This can be represented as:
  reinterpret_cast<uintptr_t>(<uint32_t*> - <int> / <size_t>)

The correct formula for worker thread would be:
  reinterpret_cast<uintptr_t>(&here) - kWorkerMaxStackSize;
WIP CL: https://codereview.chromium.org/2498943002/

I'll investigate the behavior on MacOSX regarding to c#26 and then ask owners to review it.
According to Mac OS X threadng programming guide[1], default stack size for secondary threads would still be 512 KB. When a renderer starts a new thread[2], it changes stack size for the thread to max(default value, PTHREAD_STACK_MIN, getrlimit()), that is, stack size can be 512KB for worker threads.

[1] https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW7
[2] https://chromium.googlesource.com/chromium/src/+/23c669b5b4cf228dab6da2cc47293b4650a7b923/base/threading/platform_thread_mac.mm#214
Based on c#31, I plan to fix the wrong formula and keep the limit for workers as is for now. If you think worker's stack size should be the same with the main thread, please let me know.

Comment 33 by marsh...@mroch.com, Nov 15 2016

Not sure if you mean me, or haraken@ (#25). Keeping the 500KB limit but fixing the unnecessary division sounds smart. 500KB should be enough for me (famous last words, right?)
marshal@, thank you for the reply. I meant to ask you all who read this issue :)
On second thoughts, the division itself was not wrong. This was correct if the denominator was sizeof(uint32_t).

Uploaded a CL: https://codereview.chromium.org/2506583002/
Project Member

Comment 36 by bugdroid1@chromium.org, Nov 15 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7d9e75c30702cd9e0e206ebac8906b56389565dc

commit 7d9e75c30702cd9e0e206ebac8906b56389565dc
Author: nhiroki <nhiroki@chromium.org>
Date: Tue Nov 15 22:12:25 2016

Worker: Fix wrong stack size calculation

Before this CL, stack size for worker threads is unexpectedly lowered than the
intended size (500KB) because a denominator sizeof(uint32_t*) in the calculation
is not correct. This should have been sizeof(uint32_t). This CL fixes it.

BUG= 252492 

Review-Url: https://codereview.chromium.org/2506583002
Cr-Commit-Position: refs/heads/master@{#432267}

[modify] https://crrev.com/7d9e75c30702cd9e0e206ebac8906b56389565dc/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp

Summary: Web Workers's stack size is smaller than the intended size (was: Web Workers's maximum argument count of function.apply is lower than main scripts)
Labels: M-56
Status: Fixed (was: Started)
Still encountering this issue on "Version 68.0.3440.106 (Official Build) (64-bit)"

["arrReturn bytelength: 68.359375kb"]
00:27:00.049 SOLWriterWorker.js:118 Uncaught RangeError: Maximum call stack size exceeded at onmessage (SOLWriterWorker.js:118)

If i manipulate my array to be less than 65kb, it works fine, if i push it past that limit, I get this error again.

Sign in to add a comment