realm-java: Unrecoverable error. Permission denied in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp

Goal

Sharing a crash log (as reported by Crashlytics) on specific devices.

Expected Results

To verify if my current API usage is correct and hopefully find a resolution.

Actual Results

Fatal Exception: io.realm.exceptions.RealmError: Unrecoverable error. Permission denied in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 92 at io.realm.internal.SharedRealm.nativeGetSharedRealm(SharedRealm.java) at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:205) at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:182) at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:124) at io.realm.Realm.getInstance(Realm.java:227) at com.project.base.BaseRealm.(BaseRealm.java) at com.project.helpers.RepoImpl.(RepoImpl.java) at com.project.MainActivity.initialiseHelpers(MainActivity.java:272) at com.project.MainActivity.onCreate(MainActivity.java:162) at android.app.ActivityThread.handleCreateService(ActivityThread.java:2937) at android.app.ActivityThread.access$1900(ActivityThread.java:174) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5752) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(NativeStart.java)

Code:

public class BaseRealm {
    private RealmConfiguration config = new RealmConfiguration.Builder().build();
    protected Realm mRealm = Realm.getInstance(config);
}
public class RepoImpl extends BaseRealm implements RepoInterface {
    @Override
    public void add(String item) {
        MyPOJO data = new MyPOJO();
        data.setItem(item);
        data.setTimestamp(System.currentTimeMillis());
        mRealm.beginTransaction();
        mRealm.copyToRealmOrUpdate(data);
        mRealm.commitTransaction();
    }
    @Override
    public int getResultCount() {
        return mRealm.where(MyPOJO.class).findAllSorted("timestamp", Sort.DESCENDING).size();
    }
    @Override
    public MyPOJO getItemObjectByIndex(int index) {
        try {
            return mRealm.where(MyPOJO.class).findAllSorted("timestamp", Sort.DESCENDING).get(index);
        } catch (Exception e) {
            return null;
        }
    }
    @Override
    public void remove(int position) {
        mRealm.beginTransaction();
        mRealm.where(MyPOJO.class).findAllSorted("timestamp", Sort.DESCENDING).deleteFromRealm(position);
        mRealm.commitTransaction();
    }
    @Override
    public void closeRealm() {
        mRealm.close();
    }
    @Override
    public Realm getRealm() {
        return mRealm;
    }
    @Override
    public void clearRealm() {
        getRealm().beginTransaction();
        getRealm().deleteAll();
        getRealm().commitTransaction();
    }

The RepoImpl instance is being created from two separate classes and the realm instance is being closed only when onDestroy() is triggered in each of the classes. clearRealm() is currently never called.

Realm version(s): 2.2.1

Android Studio version: 2.2.3

Which Android version and device: Samsung SM-A500F (Android 6.0) and Lenovo S1a40 (Android 4.4.4)

It’s seemingly working well on other devices.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 104 (54 by maintainers)

Most upvoted comments

First, thanks a lot for leading us to reproduce this annoy issue! @alexandrosla ! We can reproduce this issues with tow huawei phones, P8 Lite and Hornor 7.

I think it is definitely a bug with those Huawei device.

TL;DL:

Huawei has a feature to do factory restore without erase all apps’ internal data. But the feature has a bug which is not always reproducible that after reboot and install the apk again, the uid for a fifo file has not been set to the newly installed app’s uid. It leads to a EACCES when opening the fifo file.

The problem

First please notice that we are using mkfifo calls to create fifo on the internal storage for internal usage – mostly to handle inter-process/thread accessing.

I have successfully to reproduce this issue with our test case. Thus I can attach a native debugger:

screenshot from 2017-07-07 17-52-06

The above snap shot is the stat() call results on two files, one is a normal Realm file(stat_buf_1), the other is a fifo file(stat_buf). They are both on the internal storage. The snapshot was taken after factory reset, when the crash happens. As you can see, the uid of the normal Realm file has been changed to the newly installed apk’s uid, 10093. But the uid of the fifo file stays as the old value 10083. And since Realm is running in the process with the new uid 10093 in this case, try to open() the fifo file will generate an EACCES error.

To confirm this behaviour, i created a test project which can be found on https://github.com/beeender/HuaweiFifoTest What does it do:

  1. create a normal file if it doesn’t exist and try to open it for read
  2. create a fifo file if it doesn’t exist and try to open it for read
  3. print information on the phone screen. Not surprisingly it can reproduce this behaviour by reset factory without clearing internal data.

before factory reset: before_reset

after factory reset: after_reset

As you can see, the normal file’s uid changed to 10093 which is the new uid of the apk, but the fifo’s uid stays with the old value 10094.

Then magic happens

  • After a few tries without tweaking my project, the issue suddenly disappeared. I didn’t do factory reset or clear apk data, just try to get more information on the fifo. The fifo’s uid magically changed to the normal value 10093 and the issue gets fixed.
  • Then I tried to follow the reproduce steps, the issue cannot be produced anymore (in 3 tries).

So … Huawei made a wonderful feature, and it works if you try hard 😦

When would user see this crash?

  1. If the user has the apk installed and executed, then he/she does a factory restore without clearing the internal storage, and install the apk again. There is a chance (I would say not 100%), he could see this crash.
  2. Maybe, just maybe, if he/she got a ROM update, he might be able to see it. THIS IS JUST MY GUESS! MAYBE THERE IS NO PROBLEM WITH ROM UPDATE AT ALL

Solution

I would say it is quite difficult to workaround this from Realm side. Since the fifo’s uid is different from the process Realm lives in, Realm cannot chown or delete it. The best think i can think about is try to check the fifo uid by stat() when issue happens, then throw an special exception like InconsistentUIDDetectedException for app to catch. The app could catch it and pop up user that he/she needs to clear the app’s data storage to continue use the apk because there is a bug on the phone.

So anyone who is seeing this crash, would above solution be acceptable for you? or Do you have any better ideas to solve this?

@beeender I tested it and its working, I went to first realm call happen in the app and catch the exception on catch I call clearApplicationUserData() this is the best workaround for now and the crashes went down to 0 on fabric crash reports. 😄

@beeender Yes in Application.onCreate()

edit reproduce : I just find out, that this crash appears only, when you:

  1. Have once clean installed the app, in order to run realm.init(this) at Application.OnCreate()
  2. don’t un-install the app (continue to the next step)
  3. perform “factory reset” without “wiping data” (don’t check wipe data option)
  4. install the application again (adb or apk install)
  5. app should crash in the first Realm.getDefaultInstance();

As I have understood, remaining files when you don’t wipe your data, cause this issue. If you had select to wipe data along with factory reset, or haven’t install the app before the reset, then application won’t crash.

In the same way, I have managed to reproduce this issue, in one of realm examples (IntroExample):

E/REALM_JNI: jni: ThrowingException 5, Permission denied in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 238, . io.realm.examples.intro E/REALM_JNI: Exception has been thrown: Unrecoverable error. Permission denied in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 238

Hi

I have a similar crash on 4.3.2 but with a sligh different name. It’s same issue here ?

BTW: This realm instance was created at when Application onCrate method is called and never close in the whole lifecycle of the app.

Not sure this is relevant or not.

Fatal Exception: io.realm.exceptions.RealmError: Unrecoverable error. Permission denied in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
       at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Unknown Source)
       at io.realm.internal.OsSharedRealm.<init>(Unknown Source:184)
       at io.realm.internal.OsSharedRealm.getInstance(Unknown Source:254)
       at io.realm.internal.OsSharedRealm.getInstance(Unknown Source:244)
       at io.realm.RealmCache.doCreateRealmOrGetFromCache(Unknown Source:319)
       at io.realm.RealmCache.createRealmOrGetFromCache(Unknown Source:282)
       at io.realm.Realm.getDefaultInstance(Unknown Source:332)

Guys, I have set this code,

How i’m calling realm screen shot 2017-12-20 at 3 04 48 pm

If the exception has Permission denied message, i will clear all data. screen shot 2017-12-20 at 2 59 25 pm

Android has clear data method after kit-kat, but if the version code less than 19, i have to delete the data manually. screen shot 2017-12-20 at 3 04 13 pm

@beeender Very nice! 😃

I think your approach would be very useful, it is much better to inform the user about a clean install, instead of a non functional/crashing app.

Hello, same issue here!

device: Huawei ALE-L21 android: 6 reproduce: In my case, this issue faced every time, after a “factory reset” of the phone, and then installing the application. After that, if you clean install the application, there is no crash.

issue: io.realm.exceptions.RealmError: Unrecoverable error. Permission denied in /Users/cm/Realm/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 238 at io.realm.internal.SharedRealm.nativeGetSharedRealm(Native Method) at io.realm.internal.SharedRealm.<init>(SharedRealm.java:192) at io.realm.Realm.getDefaultInstance(Realm.java:273)

@beeender According to the data we have it seems that it is as you say

@deathstroke007 I wish I had anything to tell you.

I actually don’t even know why this issue is closed. I believe it is the most severe issue, and should be utmost priority, but it’s kinda been happening for… a while now.

@Zhuinden @cmelchior So, is there any workaround for this or the issue gets resolved in 5.8.0? This error has been reported once since I upload my application on play store which is around 2 months back. My daily active user is around 50 - 80 right now. I am initializing the Realm in Application’s oncreate like this -

Realm.init(App.this);
                RealmConfiguration config = new RealmConfiguration.Builder()
                        .encryptionKey(REALM_KEY.getBytes())
                        .schemaVersion(0)
                        .deleteRealmIfMigrationNeeded()
                        .build();
                Realm.setDefaultConfiguration(config);
                Realm.getInstance(config);

And using getDefaultInstance() wherever i need it throughout the application.

Do I need to change anything? I am not able to reproduce it.

The Device was OnePlus 3T - 8.0.0

@tamtom I don’t think that will work. When realm file created, there are some other files will be created as well, eg.:

test.realm 
test.realm.management/.test.realm.xxx.cv
//...

When the problem happens, you can delete test.realm. But those .cv files belong to another uid which you don’t even have permission to delete it.

@kneth only in wild 😦

@sabergeek it has less bugs than 2.2.1, and I do not know of any new bugs that were introduced.