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)
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:
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, theuid
of the normal Realm file has been changed to the newly installed apk’s uid, 10093. But theuid
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 toopen()
the fifo file will generate anEACCES
error.To confirm this behaviour, i created a test project which can be found on https://github.com/beeender/HuaweiFifoTest What does it do:
before factory reset:
after factory 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
So … Huawei made a wonderful feature, and it works if you try hard 😦
When would user see this crash?
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 likeInconsistentUIDDetectedException
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:
realm.init(this)
atApplication.OnCreate()
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.
Guys, I have set this code,
How i’m calling realm
If the exception has Permission denied message, i will clear all data.
Android has clear data method after kit-kat, but if the version code less than 19, i have to delete the data manually.
@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 -
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.:
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.