Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work around the memmove bug on Samsung device #4402

Merged
merged 18 commits into from
Apr 7, 2017
Merged

Conversation

beeender
Copy link
Contributor

@beeender beeender commented Mar 30, 2017

Fix #3651

@Zhuinden
Copy link
Contributor

If this works.... Celebration 😄

@nhachicha
Copy link
Collaborator

is this function hooking? we used similar approach in ReactNative https://github.com/realm/realm-js/blob/master/src/android/jsc_override.cpp#L60-L126

Copy link
Contributor

@cmelchior cmelchior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments, but would rather have someone from #core reviewing this.

return (*s_wrap_memmove_ptr)(dest, src, n);
}

static void check_memmove()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this test come from anywhere? Then a link to that would be nice

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -57,6 +59,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_SharedRealm_nativeInit(JNIEnv* env
{
TR_ENTER()

hack_init();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be called in JNI_OnLoad or something? There is no guarantee that this code is the first native code being called?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UH, yes, JNI_OnLoad() would be a better place! But first need to make this patch work ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using __attribute__((constructor)); is also an option, if I remember it runs when the .so is loaded https://github.com/realm/realm-js/blob/master/src/android/jsc_override.cpp#L38

Copy link
Contributor Author

@beeender beeender Apr 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__attribute__((constructor)); looks much better, but it seems to be a gcc extension, i am not quite sure if clang support it. I will check and replace the JNI_onLoad() if it supported by clang as well.

@beeender
Copy link
Contributor Author

@nhachicha no, the code you posted is really hacky 😁 It modifies the machine code in RAM during run time. This will just link to our wrapped version function during the linking time.

s = (uint8_t*)src;
while (count--)
*tmp++ = *s++;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitespace is weird here

There was a bug for memmove on some Samsung devices. The functions
returns "dest + n" instead of "dest".
This has been identified earlier by QT. See:
https://bugreports.qt.io/browse/QTBUG-34984
The relevant android bug:
https://code.google.com/p/android/issues/detail?id=81692

This fix try to test if the device have this issue first, if yes, switch
to a own implementation of memmove.

This fix works for most cases, but since the memmove bug existing in the
system, there would be other lib/system call the buggy version of
memmove which could still corrupt the memory -- which means there are
still some possibilities that app gets crashed on those devices.

The more hacky way is hooking into the process's code space and modify
the function point to our own implementation which could solve the
problem for other lib/system calls. But there is a risk that google
might reject the apk for play store.
namespace realm {
namespace jni_util {

void* my_bcopy(void *, const void *, std::size_t);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my_bcopy sounds strange... just __bcopy? Also, no need to have this in an independent header since it is not supposed to be used for any other places, just extern it from the hack.cpp?

@kneth
Copy link
Member

kneth commented Apr 1, 2017

@beeender I have asked our ops team for legal advice since we are including 3rd party code. Please do not merge before we have a clear understanding of the legal implications.

@Zhuinden
Copy link
Contributor

Zhuinden commented Apr 4, 2017

@kneth any luck? This fix is super-duper important

@cmelchior
Copy link
Contributor

@Zhuinden We just pinged our legal.
We want this released just as much as you 😄

@dalinaum
Copy link
Contributor

dalinaum commented Apr 4, 2017

Sumsung? Samsung? It seems a typo on this PR's title and commit logs.

s_wrap_memcpy_ptr = &hacked_memmove;
}
else {
Log::i("memmove is not broken on this device - lucky you.");
Copy link
Contributor

@dalinaum dalinaum Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be logged? So many users would be lucky.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this shouldn't be logged :)

@Zhuinden
Copy link
Contributor

Zhuinden commented Apr 5, 2017

Shame that 3.1.0 did not have this, hoping for 3.1.1 😄

@cmelchior
Copy link
Contributor

Yes, we wil make a patch release with this as soon as legal gives a 👍

@beeender beeender changed the title Work around the memmove bug on sumsung device Work around the memmove bug on Samsung device Apr 5, 2017
@beeender
Copy link
Contributor Author

beeender commented Apr 5, 2017

need to benchmark with/without wrap memcpy

@beeender
Copy link
Contributor Author

beeender commented Apr 5, 2017

Wrap both memmove and memcpy:
with_memcpy_0

wrap only memmove
without_memcpy_1

no noticeable performance difference.

@Zhuinden
Copy link
Contributor

Zhuinden commented Apr 7, 2017

Switching to DRY libc11's implementations

I guess the legal team said you need one with a bit more permissive license

Copy link
Contributor

@cmelchior cmelchior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only nitpicking comments 👍

// See https://github.com/realm/realm-java/issues/3651#issuecomment-290290228
// There is a bug in memmove for some Samsung devices which will return "dest-n" instead of dest.
// The bug was originally found by QT, see https://bugreports.qt.io/browse/QTBUG-34984 .
// To work around it, we use linker's wrap feature to use a pure C implementation of memmove if the device has the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has this

size_t len = strlen(array);
void* ptr = __real_memmove(array + 1, array, len - 1);
if (ptr != array + 1 || strncmp(array, "FFooba", len) != 0) {
Log::e("memmove is broken on this device. Switching to the builtin implementation.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builtin reads wrong to me here. What about Switching to a version provided by Realm ?

@beeender beeender merged commit 6ad1e13 into releases Apr 7, 2017
@beeender beeender removed the S:Review label Apr 7, 2017
@beeender beeender deleted the mc/bug/hack-memmove branch April 7, 2017 11:28
bdash added a commit to realm/realm-object-store that referenced this pull request Jun 26, 2017
The underlying issue turned out to be a bug in `memmove` on some Android
devices. It was addressed via realm/realm-java#4402.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants