emberjs / ember.js

Ember.js - A JavaScript framework for creating ambitious web applications
https://emberjs.com
MIT License
22.47k stars 4.21k forks source link

Uncaught TypeError: Cannot read property 'syscall' of null #16503

Closed nullrocket closed 6 years ago

nullrocket commented 6 years ago

I have been banging my head against this every time I try to update from 3.0.0 to any >= 3.1 version beta or final.
It happens after transitioning in and out of a particular route exactly 3 times. Unfortunately I'm unable to create a reproduction except in this application and the stacktrace doesn't point to anything I can dig into. Any idea where I can start looking?


AppendOpcodes.prototype.evaluate = function evaluate(vm$$1, opcode, type) {
            var operation = this.evaluateOpcode[type];
             if (operation.syscall) {  // here is where it errors.  type argument is 0
                operation.evaluate(vm$$1, opcode);
            } else {
                operation.evaluate(vm$$1.inner, opcode);
            }
        };
Turbo87 commented 6 years ago

we are seeing similar issues in our Sentry logs after upgrading to Ember 3.1 πŸ€”

the stacktraces are not giving any hints unfortunately. this is one example from Safari:

TypeError: null is not an object (evaluating 'n.syscall')
  at evaluate(@glimmer/runtime.js:29:1)
  at evaluateSyscall(@glimmer/runtime.js:3310:1)
  at evaluateInner(@glimmer/runtime.js:3286:1)
  at evaluateOuter(@glimmer/runtime.js:3278:1)
  at next(@glimmer/runtime.js:4865:1)
  at execute(@glimmer/runtime.js:4850:1)
  at handleException(@glimmer/runtime.js:4363:1)
  at handleException(@glimmer/runtime.js:4532:1)
  at throw(@glimmer/runtime.js:4272:1)
  at evaluate(@glimmer/runtime.js:1105:1)
  at execute(@glimmer/runtime.js:4259:1)
  at methodName(@glimmer/runtime.js:4558:1)
  at runInTransaction(ember-metal.js:1152:1)
  at _renderRoots(ember-glimmer.js:4496:1)
  at _renderRootsTransaction(ember-glimmer.js:4529:1)
  at call(ember-glimmer.js:4572:1)
  at invoke(backburner.js:227:1)
  at flush(backburner.js:134:1)
  at flush(backburner.js:290:1)
  at end(backburner.js:423:1)
  at run(backburner.js:800:1)

and another from Chrome:

TypeError: Cannot read property 'syscall' of null
  at evaluate(@glimmer/runtime.js:29:1)
  at evaluateSyscall(@glimmer/runtime.js:3310:1)
  at evaluateInner(@glimmer/runtime.js:3286:1)
  at evaluateOuter(@glimmer/runtime.js:3278:1)
  at next(@glimmer/runtime.js:4865:1)
  at execute(@glimmer/runtime.js:4850:1)
  at insert(@glimmer/runtime.js:4404:1)
  at nextInsert(@glimmer/reference.js:609:1)
  at nextAppend(@glimmer/reference.js:572:1)
  at sync(@glimmer/reference.js:530:1)
  at evaluate(@glimmer/runtime.js:4492:1)
  at execute(@glimmer/runtime.js:4259:1)
  at rerender(@glimmer/runtime.js:4558:1)
  at methodName(ember-glimmer.js:4230:1)
  at runInTransaction(ember-metal.js:1152:1)
  at _renderRoots(ember-glimmer.js:4496:1)
  at _renderRootsTransaction(ember-glimmer.js:4529:1)
  at call(ember-glimmer.js:4572:1)
  at invoke(backburner.js:227:1)
  at flush(backburner.js:134:1)
  at flush(backburner.js:290:1)
  at end(backburner.js:423:1)
  at _run(backburner.js:800:1)
  at _join(backburner.js:782:1)
  at apply(backburner.js:492:1)
  at apply(ember-metal.js:420:1)
  at callback(ember-glimmer.js:854:1)
  at flaggedInstrument(ember-metal.js:3877:1)
  at HTMLButtonElement.<anonymous>(ember-glimmer.js:853:1)
pieter-v commented 6 years ago

Similar here. I did some debugging, and this is what I found so far: If the error happens, then WriteOnlyProgram.opcode receives an offset that is larger than WriteOnlyProgram.heap.heap.length and the size of the heap is always 0x100000

pieter-v commented 6 years ago

Moreover, heap.offset is also larger than heap.heap.length

pieter-v commented 6 years ago

If I look at the implementation of the class Heap, I notice that the buffer uses a TypedArray

this.heap = new Uint16Array(0x100000);

If something is pushed on the heap, then there is no size checking:

  push(item: number): void {
    this.heap[this.offset++] = item;
  }

This is a problem with TypedArray as they don't expand if needed as regular arrays does.

A simple test

let heap = new Uint16Array(2);
heap.length;

produces 2

heap[3]=1;
heap.length;

produces 2

rwjblue commented 6 years ago

@pieter-v - I agree, that seems likely to be the issue. Thank you for digging! Can you report the specific issue to glimmer-vm (so we can coordinate solving over there)?

@krisselden / @chadhietala / @wycats / @tomdale - how should we address expanding the heap when it’s reached it’s max capacity?

urbany commented 6 years ago

Hi all, thanks for the quick work on this! Any hot fix I can apply while it's not properly fixed?

Turbo87 commented 6 years ago

@urbany as far as I know the best option for now is to stay on Ember 3.0 until this is resolved

urbany commented 6 years ago

I shouldn't have run the es5-getter-ember-codemod before some propper testing, eheh. Thanks!

nullrocket commented 6 years ago

Maybe next time around I won't wait a month to report, I was pretty determined it was something in one of our components though.

I have a question that will probably just highlight the fact that I know nothing of the glimmer-vm internals. Is this heap growing constantly between transitioning in and out of this route a sign of anything else that I should be looking to mitigate in general?

krisselden commented 6 years ago

@nullrocket my concern is something is regenerating opcodes that should be using what is already compiled. Specifically if it is alway pushComponentDefinition wondering if it is always seeing a new definition for something it should see an existing definition for.

This still smells off for me.

krisselden commented 6 years ago

@rwjblue I'm not sure we should close this. You may have address the crash, I'm not confident this has been fully root caused. I'm wondering if there is some idiom people do that messes up the caching that is not covered in the test suite.

nullrocket commented 6 years ago

@krisselden I do have a component that has the following template in the route that causes the error, perhaps the component helper is related to the problem, I will dig a bit deeper. This fix did help but I've opened another issue that seems to be related to continually growing opcodes. https://github.com/emberjs/ember.js/issues/16532


    {{#each items as |item|}}
        {{component itemComponent options=args }}
    {{/each}}
nullrocket commented 6 years ago

Edited I have a reproduction now, I am pretty sure it is related to usage of the {{component}} helper in an {{each}} block After reading @willviles comment I went back and simplified my reproduction some more, it doesn't take a {{component}} or {{each}} to reproduce as I initially thought. I removed the each and just pasted in a large number of components to simulate the number being rendered in the each I had previously set up.

The reproduction transitions between two routes with this template in each route, after some number of transitions it will throw the error. Currently it throws the error I'm experiencing in https://github.com/emberjs/ember.js/issues/16532 but if you switch ember-source to 3.1.0 you can duplicate this error

{{my-component text=item}}
{{my-component text=item}}
... about 600 more 

https://github.com/nullrocket/glimmer-crash

willviles commented 6 years ago

I'm experiencing the same issue since upgrading to Ember 3.1.1.

In my app, it occurs after transitioning between two 'tab' states multiple times (between 5-10 transitions) and errors on a tab's child component scheduling a function using Ember runloop's next. The child component is not being rendered using the component helper.

I can prevent the error by using once instead, but this is not a solution as it locks up the thread quite perceptibly.

rwjblue commented 6 years ago

@krisselden - Agreed, reopened. :smiley:

@nullrocket / @willviles - Can you test with the latest release build to confirm it is working?

The following will get you the current tarball URL:

npm install -g ember-source-channel-url
ember-source-channel-url release

Then you can update your package.json to have:

  β€œember-source”: β€œ<URL printed above>”,
willviles commented 6 years ago

@rwjblue - I can confirm the issue has been resolved in my app! Thank you!

urbany commented 6 years ago

@rwjblue I also confirm that ember-source-channel-url release version fixed it for my app. Thanks!

rwjblue commented 6 years ago

Awesome, thank you for testing! I’ll try to take some time today and poke at things with @krisselden to try and see if we have another underlying issue before releasing 3.1.1. Will try to update here to let y’all know...

nullrocket commented 6 years ago

@rwjblue it does fix this error, 3.2.0-beta.2 also fixed it, but it doesn't fix https://github.com/emberjs/ember.js/issues/16532 I can still reproduce that one with the same reproduction app, they seem related.

urbany commented 6 years ago

I tested the project linked in #16532 with the latest ember release right now

ember-source-channel-url release
The URL for the latest tarball from ember-source's release channel is:
https://s3.amazonaws.com/builds.emberjs.com/release/shas/4cb565e3924363b165736cbaff8e4ee5d29218d7.tgz

And the problem reported in #16532 still occurs Uncaught Error: Operand over 16-bits. Got 65536. This probably means this bug is not correctly fixed, right?

rwjblue commented 6 years ago

FYI - This issue is still an ongoing problem, but we need a reproduction (like we had https://github.com/nullrocket/glimmer-crash for https://github.com/emberjs/ember.js/issues/16532). I believe that https://github.com/emberjs/ember.js/issues/16503#issuecomment-381842386 roughly describes the issue.

@nullrocket - Do you have a minute to try the technique you did in glimmer-crash repo (bouncing back and forth between routes) but with {{#each and {{component (like you mentioned in https://github.com/emberjs/ember.js/issues/16503#issuecomment-381842386)? If you use 3.1.0 for the demo, we should be able to reproduce the specific error for this issue (which led to us ensuring the heap can grow).

FWIW - The fix we landed in https://github.com/emberjs/ember.js/pull/16527 and https://github.com/glimmerjs/glimmer-vm/pull/798 was still needed, we just want to avoid needing to grow the heap needlessly (in this case there appears to be a leak)...

nullrocket commented 6 years ago

@rwjblue I pushed two branches to the repo

https://github.com/nullrocket/glimmer-crash/tree/each-component-3-1-0 This is the original setup with {{#each and {{component using 3.1.0

https://github.com/nullrocket/glimmer-crash/tree/each-component-source-release This is the original setup with {{#each and {{component but using ember-source-channel-url release I do see the heap continually growing here, it takes a while so I upped the number of {{#each}} iterations and the number of route changes to speed up the growth, after about 5 minutes it grows significantly.

rwjblue commented 6 years ago

Awesome, thank you very much @nullrocket!

rwjblue commented 6 years ago

I tested https://github.com/nullrocket/glimmer-crash/compare/each-component-3-1-0 with the changes from https://github.com/emberjs/ember.js/pull/16558 linked locally, and after running through all 200 iterations there is no heap growth.

rwjblue commented 6 years ago

Closing this issue as the underlying bug has been fixed (and confirmed with the demo repos provided). The fix for this has been pulled into release (for 3.1.x release) and beta (for 3.2.0-beta.x release). The latest builds (in 10-15 minutes) to the release, beta, and canary channels should include the fix (you can get the latest tarball URL via ember-source-channel-url).

If additional issues crop up, we should report as a new issue with a reproduction.

Turbo87 commented 6 years ago

@rwjblue unfortunately I don't have a reproduction yet, but I'm seeing a similar error with v3.1.2. According to the Sentry traces there was also a previous error thrown that might have caused the Glimmer VM to throw up later. The previous errors seems to be that during factoryManager.create(); the create() method "is not a function" πŸ€”

kjf commented 6 years ago

We're experiencing the same issue with 3.1.2.

runtime.js:43 Uncaught TypeError: Cannot read property 'syscall' of null
    at AppendOpcodes.evaluate (runtime.js:43)
    at LowLevelVM.evaluateSyscall (runtime.js:3249)
    at LowLevelVM.evaluateInner (runtime.js:3225)
    at LowLevelVM.evaluateOuter (runtime.js:3217)
    at VM.next (runtime.js:4800)
    at VM.execute (runtime.js:4785)
    at TryOpcode.handleException (runtime.js:4298)
    at UpdatingVMFrame.handleException (runtime.js:4464)
    at UpdatingVM._throw [as throw] (runtime.js:4205)
    at Assert.evaluate (runtime.js:1098)
evaluate @ runtime.js:43
evaluateSyscall @ runtime.js:3249
evaluateInner @ runtime.js:3225
evaluateOuter @ runtime.js:3217
next @ runtime.js:4800
execute @ runtime.js:4785
handleException @ runtime.js:4298
handleException @ runtime.js:4464
_throw @ runtime.js:4205
evaluate @ runtime.js:1098
execute @ runtime.js:4192
rerender @ runtime.js:4491
_this27.render @ ember-glimmer.js:4559
runInTransaction @ ember-metal.js:1231
_renderRoots @ ember-glimmer.js:4820
_renderRootsTransaction @ ember-glimmer.js:4852
_revalidate @ ember-glimmer.js:4892
invoke @ backburner.js:205
flush @ backburner.js:125
flush @ backburner.js:278
end @ backburner.js:410
_run @ backburner.js:760
_join @ backburner.js:736
join @ backburner.js:477
run.join @ ember-metal.js:456
hash.success @ rest.js:1329
fire @ jquery.js:3268
fireWith @ jquery.js:3398
done @ jquery.js:9305
(anonymous) @ jquery.js:9548
load (async)
send @ jquery.js:9567
ajax @ jquery.js:9206
_ajaxRequest @ rest.js:983
Promise @ rest.js:1341
initializePromise @ rsvp.js:397
Promise @ rsvp.js:877
_makeRequest @ rest.js:1325
query @ rest.js:497
_query @ -private.js:8910
_query @ -private.js:11106
query @ -private.js:11093
_loadTemplates @ index.js:124
model @ index.js:119
deserialize @ route.js:951
applyHook @ router.js:211
runSharedModelHook @ router.js:662
getModel @ router.js:896
tryCatcher @ rsvp.js:200
invokeCallback @ rsvp.js:372
publish @ rsvp.js:358
(anonymous) @ rsvp.js:14
invoke @ backburner.js:205
flush @ backburner.js:125
flush @ backburner.js:278
end @ backburner.js:410
Backburner._boundAutorunEnd @ backburner.js:372
setTimeout (async)
Backburner.platform.next @ backburner.js:360
_ensureInstance @ backburner.js:884
schedule @ backburner.js:499
(anonymous) @ rsvp.js:13
then @ rsvp.js:435
resolve @ router.js:254
Transition @ router.js:421
getTransitionByIntent @ router.js:1505
transitionByIntent @ router.js:1289
doTransition @ router.js:1917
handleURL @ router.js:1320
_doURLTransition @ router.js:256
handleURL @ router.js:253
(anonymous) @ router.js:163
_popstateHandler @ history_location.js:238
kjf commented 6 years ago

I can produce it reliably here. Our app is behind some auth at the min but I can share some credentials with anyone who is able to take a look.

joshuataylor commented 6 years ago

Also seeing this still on 3.1.2

TypeError: Cannot read property 'syscall' of null
  at evaluate(@glimmer/runtime.js:29:1)
  at evaluateSyscall(@glimmer/runtime.js:3310:1)
  at evaluateInner(@glimmer/runtime.js:3286:1)
  at evaluateOuter(@glimmer/runtime.js:3278:1)
  at next(@glimmer/runtime.js:4865:1)
  at execute(@glimmer/runtime.js:4850:1)
  at insert(@glimmer/runtime.js:4404:1)
  at nextInsert(@glimmer/reference.js:609:1)
  at nextAppend(@glimmer/reference.js:572:1)
  at sync(@glimmer/reference.js:530:1)
  at evaluate(@glimmer/runtime.js:4492:1)
  at execute(@glimmer/runtime.js:4259:1)
  at rerender(@glimmer/runtime.js:4558:1)
  at methodName(ember-glimmer.js:4230:1)
  at runInTransaction(ember-metal.js:1152:1)
  at _renderRoots(ember-glimmer.js:4496:1)
  at _renderRootsTransaction(ember-glimmer.js:4529:1)
  at call(ember-glimmer.js:4572:1)
  at invoke(backburner.js:227:1)
  at flush(backburner.js:134:1)
  at flush(backburner.js:290:1)
  at end(backburner.js:423:1)
  at _run(backburner.js:800:1)
  at _join(backburner.js:782:1)
  at apply(backburner.js:492:1)
  at apply(ember-metal.js:420:1)
  at callback(ember-glimmer.js:854:1)
  at flaggedInstrument(ember-metal.js:3877:1)
  at apply(ember-glimmer.js:853:1)
  at invokeAction(addon-tree-output/ember-invoke-action/index.js:43:1)
  at _click(addon-tree-output/ember-one-way-controls/components/one-way-checkbox.js:39:1)
  at apply(addon-tree-output/ember-one-way-controls/components/one-way-checkbox.js:25:1)
  at HTMLInputElement.i(vendor/raven.js:443:1)
sethphillips commented 6 years ago

I'm still seeing this on 3.1.2 as well, though less often than 3.1.0

rwjblue commented 6 years ago

Please open a new issue with as much info as you can! As you can see from the back and forth here it will almost certainly take a reproduction for us to be able to track it down, so the sooner we gather enough info for one the faster we can fix...

sammynave commented 6 years ago

Not sure if this is helpful but Uncaught TypeError: Cannot read property 'syscall' of null is an error I encountered when I had I forgotten to import { computed } from '@ember/object'; in a component. I'm running 3.1.1 Β―\_(ツ)_/Β―

nullrocket commented 6 years ago

I'm still seeing it in production logs occasionally but it isn't the same cause as this issue as far as I can tell, it is something similar to what @sammynave said, not imports in our case although I have seen it there but unrelated/uncaught exceptions, once corrected it fixes it, this error makes it hard/impossible to trace where the issue is though, I've just gotten good at guessing.

sethphillips commented 6 years ago

i never see this in development, only in production builds.

tomdale commented 6 years ago

The root issue is caused by the program counter being set to an invalid offset in the heap. If it tries to invoke an opcode at that offset and there's nothing there, you will get the above Cannot read property 'syscall' of null error because it can't find an opcode object.

I suspect what's happening is that an exception is getting thrown somewhere during render that we're not catching and cleaning up appropriately. We can add better logging to track it down but that may not help if people are only seeing this in production where logging and assertions would be stripped. I would expect though that Ember would re-throw the error, so the initial error should be visible in logs as well.

The VM itself doesn't try to catch exceptions, although maybe we should start doing so to try to be more aggressive about cleaning up the state of the VM.

Turbo87 commented 6 years ago

I suspect what's happening is that an exception is getting thrown somewhere during render that we're not catching and cleaning up appropriately.

I can definitely confirm that suspicion. Every instance of the syscall error that I see in our sentry logs has some other error in the log before it. As mentioned in https://github.com/emberjs/ember.js/issues/16503#issuecomment-387330295, a lot of the times factoryManager.create() seems to be involved in the original error, but according to Sentry that was apparently already an issue before we upgraded to Ember 3.0/3.1.

joshuataylor commented 6 years ago

Not having an error surface would be a very valid cause of this issue, especially as we can't seem to spot this on development, but getting constant reports on sentry and user reports of app issues.

What can I do to help debug?

tylerturdenpants commented 6 years ago

I can get this to occur in 3.2 while developing. I would love to help. Please let me know how I can do that.

Turbo87 commented 6 years ago

@tylerturdenpants can you reproduce it in a fresh ember new app? if so a reproduction repo would be awesome

alexparker commented 6 years ago

I just got this as well, as soon as I thought I had finished upgrading to 3.2. Dont have a reproducable repo yet tho

iorlas commented 5 years ago

We have encountered such error on 3.5. Any ideas?

sethbrasile commented 4 years ago

Apologies if I'm incorrect here, but I may have a minimal reproduction of this issue that works in dev?

I have a full app that tends to throw this syscall error and then render the entire app 3 times in a row any time I hit a compilation error.

I was able to reproduce the issue that I'm experiencing just by generating a new app with 3.15.1, then creating an index template containing a nonsense component name (to create a compilation error).

ember-cli: 3.15.1
node: 10.18.0
os: darwin x64

Reproduction repo is here: https://github.com/sethbrasile/possible-ember-issue-reproduction-16503

shama commented 2 years ago

We ran into this with Ember 3.12 when trying to convert a pod component to a co-located:

It works as a Pod Component:

app/
β”œβ”€ pods/
β”‚  β”œβ”€ budget-available-number/
β”‚  β”‚  β”œβ”€ component.ts
β”‚  β”‚  β”œβ”€ template.hbs

But not as a co-located component, errors with Cannot read property 'syscall' of null:

app/
β”œβ”€ components/
β”‚  β”œβ”€ budget-available-number/
β”‚  β”‚  β”œβ”€ index.ts
β”‚  β”‚  β”œβ”€ index.hbs

Even with deleting everything in the component and template to simplify it, the syscall error still occurs. But trying this on our Ember upgrade to 3.19 PR, we don't get an error.