realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.62k stars 558 forks source link

Xcode pauses inside JavaScriptCore when using the Chrome debugger #1095

Closed compojoom closed 2 years ago

compojoom commented 6 years ago

I'm experimenting with realm and react native. I have the following RN code:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

var Realm = require('realm');

// Define your models and their properties
class Car {}
Car.schema = {
    name: 'Car',
    properties: {
        make:  'string',
        model: 'string',
        miles: 'int',
    }
};
class Person {}
Person.schema = {
    name: 'Person',
    properties: {
        name:    {type: 'string'},
        cars:    {type: 'list', objectType: 'Car'},
        picture: {type: 'data', optional: true}, // optional property
        birthday: {type: 'date'}
    }
};

Realm.Sync.User.login('http://localhost:9080', 'dd', 'xxxx', (error, user) => { console.log(error, user) });

export default class realmDBtest extends Component {

    constructor(props) {
        super(props);

        let user = Realm.Sync.User.current;

        this.realm = new Realm({
            schema: [Car, Person],
            sync: {
                user: user,
                url: 'realm://localhost:9080/~/cars',
            },
        });

        this.realm.addListener('change', () => {
            this.forceUpdate()
        });
    }

  render() {
      let cars = this.realm.objects('Car').filtered('miles > 1000');

      var carsOutput = cars.map(el => {
        return (
            <View>
              <Text>{el.make} - {el.model} - {el.miles}</Text>
            </View>
        )
      });

      return (
      <View style={styles.container}>
          {carsOutput}
          <Text onPress={() => {
              this.realm.write(() => {
                  let myCar = this.realm.create('Car', {
                      make: 'Honda',
                      model: 'Civic',
                      miles: 2000,
                  });
                  myCar.miles += 20; // Update a property value
              });
            }
          }>Add car </Text>

        <Text onPress={() => {
            console.log(this.realm.syncSession);
            }}>log session</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('realmDBtest', () => realmDBtest);

When I use the app for no apparent reason the app stalls and xcode is showing the following:

JavaScriptCore`JSC::Heap::releaseAccessSlow:
    0x108b62110 <+0>:   pushq  %rbp
    0x108b62111 <+1>:   movq   %rsp, %rbp
    0x108b62114 <+4>:   pushq  %r14
    0x108b62116 <+6>:   pushq  %rbx
    0x108b62117 <+7>:   movq   %rdi, %r14
    0x108b6211a <+10>:  movl   0x488(%r14), %eax
    0x108b62121 <+17>:  testb  $0x4, %al
    0x108b62123 <+19>:  je     0x108b62182               ; <+114>
    0x108b62125 <+21>:  leaq   0x488(%r14), %rbx
    0x108b6212c <+28>:  nopl   (%rax)
    0x108b62130 <+32>:  testb  $0x2, %al
    0x108b62132 <+34>:  jne    0x108b62194               ; <+132>
    0x108b62134 <+36>:  movl   %eax, %ecx
    0x108b62136 <+38>:  testb  $0x10, %al
    0x108b62138 <+40>:  jne    0x108b62150               ; <+64>
    0x108b6213a <+42>:  testb  $0x1, %al
    0x108b6213c <+44>:  jne    0x108b62170               ; <+96>
    0x108b6213e <+46>:  andl   $-0x5, %ecx
    0x108b62141 <+49>:  lock   
    0x108b62142 <+50>:  cmpxchgl %ecx, (%rbx)
    0x108b62145 <+53>:  jne    0x108b6217c               ; <+108>
    0x108b62147 <+55>:  jmp    0x108b62183               ; <+115>
    0x108b62149 <+57>:  nopl   (%rax)
    0x108b62150 <+64>:  andl   $-0x11, %ecx
    0x108b62153 <+67>:  lock   
    0x108b62154 <+68>:  cmpxchgl %ecx, (%rbx)
    0x108b62157 <+71>:  jne    0x108b6217c               ; <+108>
    0x108b62159 <+73>:  movq   %r14, %rdi
    0x108b6215c <+76>:  callq  0x108b621a0               ; JSC::Heap::finalize()
    0x108b62161 <+81>:  movq   %rbx, %rdi
    0x108b62164 <+84>:  callq  0x108fa08a0               ; WTF::ParkingLot::unparkAll(void const*)
    0x108b62169 <+89>:  jmp    0x108b6217c               ; <+108>
    0x108b6216b <+91>:  nopl   (%rax,%rax)
    0x108b62170 <+96>:  andl   $-0x7, %ecx
    0x108b62173 <+99>:  orl    $0x2, %ecx
    0x108b62176 <+102>: lock   
    0x108b62177 <+103>: cmpxchgl %ecx, (%rbx)
    0x108b6217a <+106>: je     0x108b62188               ; <+120>
    0x108b6217c <+108>: movl   (%rbx), %eax
    0x108b6217e <+110>: testb  $0x4, %al
    0x108b62180 <+112>: jne    0x108b62130               ; <+32>
    0x108b62182 <+114>: int3   
->  **0x108b62183 <+115>: popq   %rbx**
    0x108b62184 <+116>: popq   %r14
    0x108b62186 <+118>: popq   %rbp
    0x108b62187 <+119>: retq   
    0x108b62188 <+120>: movq   %rbx, %rdi
    0x108b6218b <+123>: popq   %rbx
    0x108b6218c <+124>: popq   %r14
    0x108b6218e <+126>: popq   %rbp
    0x108b6218f <+127>: jmp    0x108fa08a0               ; WTF::ParkingLot::unparkAll(void const*)
    0x108b62194 <+132>: int3   
    0x108b62195 <+133>: nopw   %cs:(%rax,%rax)I can continue with the program execution and the app doesn't crash, but it's extremely annoying and I wonder what all this means and would it affect an app in production?

Also what I noticed is that my app doesn't update when I do an update on the remote Database. Basically my change event is not triggered, but if I relaunch the app - I have the correct data.

compojoom commented 6 years ago

I decided to have a look at the terminal window and there seems to be an error that might be related to the above:

2017-06-25T11:06:18.777Z - info: sync-server: HTTP Connection[80]: Connection from 127.0.0.1:64680
2017-06-25T11:06:18.778Z - info: sync-server: HTTP Connection[80]: Received: Sync HTTP request(protocol_version=18)
2017-06-25T11:06:18.778Z - info: sync-server: Sync Connection[80]: Session[1]: Session initiated (session_ident=1).
2017-06-25T11:06:18.778Z - info: sync-server: Sync Connection[80]: Session[1]: Received: BIND(server_path=/1d83a32b834a1fcd91d396b044ecce9b/cars, signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==', need_file_ident_pair=0)
2017-06-25T11:06:18.780Z - error: sync-server: Sync Connection[80]: Session[1]: Token expired (signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:18.780Z - error: sync-server: Sync Connection[80]: Session[1]: Token expired (message_type='bind', signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:18.780Z - info: sync-server: Sync Connection[80]: Session[1]: Session terminated (session_ident=1).
2017-06-25T11:06:18.780Z - info: sync-server: Sync Connection[80]: Sending: ERROR(error_code=202, message_size=20, try_again=0, session_ident=1)
2017-06-25T11:06:18.780Z - info: sync-server: Sync Connection[80]: Connection closed by client: End of input
2017-06-25T11:06:36.533Z - info: sync-server: HTTP Connection[81]: Connection from 127.0.0.1:64754
2017-06-25T11:06:36.534Z - info: sync-server: HTTP Connection[81]: Received: Sync HTTP request(protocol_version=18)
2017-06-25T11:06:36.534Z - info: sync-server: Sync Connection[81]: Session[1]: Session initiated (session_ident=1).
2017-06-25T11:06:36.534Z - info: sync-server: Sync Connection[81]: Session[1]: Received: BIND(server_path=/1d83a32b834a1fcd91d396b044ecce9b/cars, signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==', need_file_ident_pair=0)
2017-06-25T11:06:36.536Z - error: sync-server: Sync Connection[81]: Session[1]: Token expired (signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:36.536Z - error: sync-server: Sync Connection[81]: Session[1]: Token expired (message_type='bind', signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:36.536Z - info: sync-server: Sync Connection[81]: Session[1]: Session terminated (session_ident=1).
2017-06-25T11:06:36.536Z - info: sync-server: Sync Connection[81]: Sending: ERROR(error_code=202, message_size=20, try_again=0, session_ident=1)
2017-06-25T11:06:36.536Z - info: sync-server: Sync Connection[81]: Connection closed by client: End of input
2017-06-25T11:06:56.017Z - info: sync-server: HTTP Connection[82]: Connection from 127.0.0.1:64820
2017-06-25T11:06:56.017Z - info: sync-server: HTTP Connection[82]: Received: Sync HTTP request(protocol_version=18)
2017-06-25T11:06:56.018Z - info: sync-server: Sync Connection[82]: Session[1]: Session initiated (session_ident=1).
2017-06-25T11:06:56.019Z - info: sync-server: Sync Connection[82]: Session[1]: Received: BIND(server_path=/1d83a32b834a1fcd91d396b044ecce9b/cars, signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==', need_file_ident_pair=0)
2017-06-25T11:06:56.020Z - error: sync-server: Sync Connection[82]: Session[1]: Token expired (signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:56.020Z - error: sync-server: Sync Connection[82]: Session[1]: Token expired (message_type='bind', signed_user_token='...zoZfIG1aliCBULC/xBp13MstN7zA==').
2017-06-25T11:06:56.020Z - info: sync-server: Sync Connection[82]: Session[1]: Session terminated (session_ident=1).
2017-06-25T11:06:56.025Z - info: sync-server: Sync Connection[82]: Sending: ERROR(error_code=202, message_size=20, try_again=0, session_ident=1)
2017-06-25T11:06:56.025Z - info: sync-server: Sync Connection[82]: Connection closed by client: End of input
ianpward commented 6 years ago

@compojoom This is with a local Realm Object Server? How did you set up the User accounts? that error indicates your login is failing, looking at the code, this: Realm.Sync.User.login('http://localhost:9080', 'danield', 'xxxx', (error, user) => { console.log(error, user) });

Is suspect - if you are using username/password a username must be in email format.

compojoom commented 6 years ago

Thanks for the reply @ianpward I downloaded the MacOS platform and started the object server. There I created a user for the tasks demo. That's the username and pass. The demo tasks didn't enforce an email for the username?

compojoom commented 6 years ago

I don't know why this is set to "waiting for user", but since you guys are waiting on me here I am :)

I'm no longer login with username & password but with an access_token. I've written an authenticator for auth0: https://www.npmjs.com/package/realm-auth0-authenticator

Despite that I see the same behavior in the app. As I said the app is not crashing, but it pauses its execution at the above code lines and waits for me to hit the continue program execution button in xCode.

I have the feeling that the app only does this when the server isn't able to authenticate the user. For example - if I send an expired token to the server and the server returns an error then most of the time the app stalls. If I always send a valid access_token, then everything seems fine.

fealebenpae commented 6 years ago

When the program pauses can you take a detailed backtrace of the application? I guess you can expand all the threads in the Xcode Debug Navigator and take a screenshot? I'm afraid that the disassembly you've provided is really not helpful.

compojoom commented 6 years ago

Like this?

grafik
fealebenpae commented 6 years ago

Could you also expand Thread 194 - the React Native JS execution thread?

compojoom commented 6 years ago

there we go again.

grafik grafik grafik grafik
fealebenpae commented 6 years ago

Thanks. Can you disable remote JS debugging and see what happens?

compojoom commented 6 years ago

Yep, disabling JS debugging seems to resolve the issue. I started the same dummy project yesterday evening, disabled remote JS debugging. Made several refreshes of the app and let it run over the night - no hanging.

fealebenpae commented 6 years ago

Sigh. This seems to be yet another issue related to the React Native debugger :/

fealebenpae commented 6 years ago

Out of curiosity, does this also happen when using remote debugging but with a different iOS version?

compojoom commented 6 years ago

@fealebenpae - interesting. I'm working now already an hour with iOS 9.3 simulator and I haven't stumbled on the issue. How did you come with this idea?

fealebenpae commented 6 years ago

Welp, different iOS versions have different JavaScriptCore versions so if debugging is doing something to upset one version of JavaScriptCore, another version might be more forgiving.

jeremyong commented 6 years ago

I'm seeing this as well. Makes debugging a realm-enabled app very difficult

sampurcell93 commented 6 years ago

Would just like to confirm that switching to a simulator running iOS 9.3 does indeed get rid of the problem for me, too.

ghost commented 6 years ago

Same issue here

yamazaki-sensei commented 6 years ago

Same issue here

ghost commented 6 years ago

Any updates on this? Almost impossible to debug as it stops every time i run it after 20-30 secs. That's my window for debugging at the moment lol

sampurcell93 commented 6 years ago

@danieldelouya If you can, debugging in iOS 9.3 does fix this (for me). If not, sorry :(

ghost commented 6 years ago

@sampurcell93 Might have to do that then. Hope they fix it for > 9.3 soon

jeremyong commented 6 years ago

What alternatives are people using? This situation is so awful I'm considering migrating the organization to something else in the meantime. I can't understand how this project can be under active development while debugging is nigh impossible.

ghost commented 6 years ago

@jeremyong I agree it's super irritating, but it literally takes 30 seconds to open Xcode and run your app via an iOS 9.3 simulator, which indeed works flawlessly. Hope they fix the issue soon for newer iOS versions though :)

jeremyong commented 6 years ago

And what do you do if you want to test newer device compatibility or introduce features that require ios 10 and 11...

robhogan commented 6 years ago

Agreed on the latter point, although for release testing and for testing device/OS compatibility you should never really be using remote JS debugging anyway, since the javascript environment isn't real-world.

The greater issue for me is that disabling the debugger or using an older iOS might only hide the problem. The crash appears to be telling us we're trying to release memory that isn't ours. A different JS environment might not be smart enough to detect/prevent that - it doesn't mean that the bug doesn't exist.

bkniffler commented 6 years ago

I cant believe this bug is opened for over 11 months and uncommented for 6 months. I’ve just now been bitten by it. Any news?

scottwio commented 5 years ago

This is slightly crazy. The Realm team have built out a whole react-native version of there product and it's basically unusable with the main developer tool. I get it we shouldn't be using chrome debugger but the reality is that this is what is used by the community. Reverting to 9.3 is not really an option either as that version of iOS is so old now.

If any product owner, product managers see this your investment in react-native support is being completely wasted while this bug exists.

bmunkholm commented 5 years ago

@scottwio We are fully aware of the unfortunate issue and are really sorry about the implications. This issue https://github.com/realm/realm-js/issues/491 is related and the options we have for resolving it has been outlined there (specifically here: https://github.com/realm/realm-js/issues/491#issuecomment-350718316). TL;DR; We are hoping latest developments from ReactNative can help resolve this.

scottwio commented 5 years ago

@bmunkholm thanks for the response. Reading through this thread it seemed like the issue was just being ignored but I can now see you are fully on top of it. Such a shame though I was looking to use Realm for a project this means it's not really an option unless we write some sort of native bridging code ):

bmunkholm commented 5 years ago

@scottwio Fully understand. We do however have many users that are happily getting around this - perhaps debugging in different ways or not experiencing this as badly as others.

scottwio commented 5 years ago

Currently, the debugger will crash the app after a couple of reloads, so it's not even like you can just make do with the slower debugging. Chrome debugger doesn't seem to be an option at all. If it was just slow I could live with it but the app crashing after a couple of reloads is the main blocker.

esutton commented 5 years ago

@scottwio Sadly, I had to largely abandon Chrome debugging.

When developing new features for my app, I must add (and then remember to remove) many console.log statements, then use adb logcat or xcode to develop and debug. It is a significant hit on efficient development.

A single package ( realm ) prevents efficient Chrome debugging of anything.

nabeelItilite commented 4 years ago

getting same issue. any workaround ?

compojoom commented 3 years ago

Ok, 4 years after posting this I'm reinvestigating if realm could be a good fit for another app. Originally when I stumbled on this bug we switched over to firestore...

Is this still a bug in Realm? I see the issue is in the backlog, but are there any plans to resolve it? Or is it already resolved?

bmunkholm commented 3 years ago

@compojoom If this was only a bug, it would have been fixed. Unfortunately, it's an architectural consequence. Debugging with Safari however works reasonable well. Please see the issue I referred to above: https://github.com/realm/realm-js/issues/1095#issuecomment-402134399. That said, we expect all this is fixed when we support Hermes.

sync-by-unito[bot] commented 2 years ago

➤ Brian Munkholm commented:

Closing as this is resolved with Hermes support.