Fix JSC DebugHeap Crash #109
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fix a crash in the JSC DebugHeap when using tools like ASAN by adding an implementation of posix_memalign() and not patching the DebugHeap::memalign() method.
Previously JSC's debug heap would crash when activated by using tools like ASAN. This was due to a call to posix_memalign() being patched out during the build process which caused DebugHeap::memalign() to unconditionally call BCRASH(). The call to posix_memalign() was originally patched out because it is not offered in Android API <= 16 and jsc-android targets API >= 16. This change replaces the original patch with one that adds an implementation of posix_memalign() borrowed from the Android Support Library source.
Because Android API version 16 doesn't include posix_memalign(), the call to it gets patched out to work around the compilation error it causes. This is done by jsc_fix_build_error_memalign.patch. DebugHeap::memalign() becomes:
The DebugHeap isn't typically enabled. But it can be. The decision is made by Environment::computeIsDebugHeapEnabled():
isSanitizerEnabled() is the particular check giving me problems (though the other checks may also be of concern in other scenarios). This method searches the current process for the ASAN and TSAN init methods:
The decision made by Environment::computeIsDebugHeapEnabled() is cached by the Environment object and exposed outward via Environment::isDebugHeapEnabled(). This method is then referenced in several places by Webkit's custom allocator, bmalloc. Here it's used in the bmalloc Heap constructor to decide whether to allocate a DebugHeap object:
When the ASAN wrap.sh, included with the Android NDK, is used:
libclang_rt.asan-arm-android.so is loaded before JSC and so the symbol __asan_init exists when the sanitizer check is performed. The decision to enable the debug heap is made and JSC crashes with a SIGILL when DebugHeap::memalign() is called and invokes BCRASH().
This patch avoids the crash by not patching the DebugHeap::memalign() method and instead adding an implementation for posix_memalign(), taken from the Android Support Library source. https://android.googlesource.com/platform/ndk/+/c066f37aeadeb8a8b21468ad8c82f4469fb5a70d/sources/android/support/src/posix_memalign.cpp
Test Plan
Ran the modified build of JSC on an x86 simulator and a real Pixel 2 (armeabi-v7a) with and without ASAN enabled in my own C++ code. Observed that JSC did not crash in any of these cases.
What's required for testing (prerequisites)?
A local build of JSC with the included modifications and a RN project modified to to use the wrap.sh feature to LD_PRELOAD the ASAN library.
https://developer.android.com/ndk/guides/wrap-script
https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid
What are the steps to reproduce (after prerequisites)?
Run the application using a publicly released build of jsc-android on a device with the appropriate wrap.sh and ASAN .so included and observe the crash. Then switch to use the local JSC build with this patch and observe that it does not crash.
Compatibility
Checklist
README.mdCHANGELOG.mdexample/App.js)