[BUG] BufferExtensions.ToBytes() methods crash on Android ARMv7 with Unity IL2CPP
See original GitHub issueVersion v5.0.8
Describe the bug
Unity app with LiteDB assembly compiled to C++ with Unity’s IL2CPP would crash with signal 7 (SIGBUS), code 1 (BUS_ADRALN)
(Memory misalignment) on Android’s ARMv7 ABI.
This bug is due to the memory alignment requirement of ARM gets violated by methods in BufferExtensions
, for instance ToBytes(this Int64 value, byte[] array, int startIndex
:
/// <summary>
/// Copy Int64 bytes direct into buffer
/// </summary>
public static unsafe void ToBytes(this Int64 value, byte[] array, int startIndex)
{
fixed (byte* ptr = &array[startIndex])
{
*(Int64*)ptr = value;
}
}
This would cause a memory misalignment on 32-bit architecture. Similarly for ToBytes(this UInt64 value, byte[] array, int startIndex
and ToBytes(this Double value, byte[] array, int startIndex
as well.
One workaround is to simply rewrite the methods in a safe way:
/// <summary>
/// Copy Int64 bytes direct into buffer
/// </summary>
public static void ToBytes(this Int64 value, byte[] array, int startIndex)
{
var bytes = BitConverter.GetBytes(value);
for (var i = 0; i < bytes.Length; i++)
{
array[startIndex + i] = bytes[i];
}
}
But this would obviously degrade the performance.
It should be noted that the crash only happens when Unity IL2CPP’s C++ Compiler Configuration is set to Release
, which probably makes sense as the release configuration may have disallowed unaligned access using a flag like GCC’s no-unaligned-access
.
Code to Reproduce
public class Test : MonoBehaviour
{
void Start()
{
var db = new LiteDatabase(
new ConnectionString
{
Filename = Path.Combine(Application.persistentDataPath, "test.db")
}
);
var col = db.GetCollection<TestFloatDocument>("Float");
for (var i = 0; i < 100; i++)
{
Debug.LogWarning($"Before insert {i}");
col.Insert(new TestFloatDocument());
Debug.LogWarning($"After insert {i}");
}
db.Dispose();
}
}
[Serializable]
public class TestFloatDocument
{
public float Value { get; set; }
}
For your convenience, I have attached a minimal project created with Unity 2019.4.3f1 - you should be able to simply open this project, click File -> Build, then Build And Run, which will build and install the APK on your Android device. After that is done, you should see the game crashes right after the Unity logo.
Logcat stacktrace:
2020-07-19 23:49:55.178 23529-23571/? W/Unity: Before insert 0
UnityEngine.Logger:Log(LogType, Object)
Test:Start()
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 35)
2020-07-19 23:49:55.209 23529-23571/? E/CRASH: pid: 23529, tid: 23571, name: UnityMain >>> litedb.armv7.test <<<
2020-07-19 23:49:55.448 23529-23571/? E/AndroidRuntime: FATAL EXCEPTION: UnityMain
Process: litedb.armv7.test, PID: 23529
java.lang.Error: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Version '2019.4.3f1 (f880dceab6fe)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'armeabi-v7a'
Build fingerprint: 'HUAWEI/ELE-AL00/HWELE:10/HUAWEIELE-AL00/10.1.0.160C00:user/release-keys'
Revision: '0'
ABI: 'arm'
Timestamp: 2020-07-19 23:49:55-0400
pid: 23529, tid: 23571, name: UnityMain >>> litedb.armv7.test <<<
uid: 10286
signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xab909052
r0 ab909042 r1 00000000 r2 ab905000 r3 00004042
r4 00004042 r5 ab905000 r6 00000000 r7 00000000
r8 00000000 r9 00000001 r10 bad8aa5c r11 bad8aa20
ip b93aac7c sp bad8aa10 lr b8c05b60 pc b8c05b44
backtrace:
#00 pc 0034eb44 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#01 pc 0034eb5c /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#02 pc 006eb2a4 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#03 pc 0044ba38 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#04 pc 0035c6d8 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#05 pc 0035ccc8 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#06 pc 0034a6c0 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#07 pc 00275638 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#08 pc 0028ce04 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#09 pc 00296edc /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#10 pc 0075d7d4 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#11 pc 004c2f00 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#12 pc 006da82c /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#13 pc 00896b5c /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#14 pc 001653a0 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#15 pc 001d7554 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libil2cpp.so (BuildId: 31835bce2e513191371aab359af65bdbde84f116)
#16 pc 00122dcd /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libunity.so (BuildId: 88df2eb5154cb72586988f4f5599151757e4b6a2)
#17 pc 0012b1bb /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libunity.so (BuildId: 88df2eb5154cb72586988f4f5599151757e4b6a2)
#18 pc 001310e7 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libunity.so (BuildId: 88df2eb5154cb72586988f4f5599151757e4b6a2)
#19 pc 001311b7 /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libunity.so (BuildId: 88df2eb5154cb72586988f4f5599151757e4b6a2)
#20 pc 0013051f /data/app/litedb.armv7.test-KMTJ11TGX3-ugBuvBbOavA==/lib/arm/libunity.so (BuildId: 88df2eb5154cb72586988f4f5599151757e4b6a2)
Issue Analytics
- State:
- Created 3 years ago
- Comments:7
Top GitHub Comments
@tomandr I’ll try to reproduce it in the following days.
I continue to see this bug every so often through crash reports.
Native Crash - BufferExtensions_ToBytes_m57828C95884C6B9FF457C57C567129717B67856C
There was also this in the logs from OdinSerializer: OdinSerializer detected Android architecture ‘armv8l’ for determining unaligned read/write capabilities. Unaligned read/write support: all=False, float=True
Hopefully this helps track down the issue.
cpu: ARMv7 VFPv3 NEON device_model: samsung/SM-A015M/a01q os: Android OS 10 / API-29 (QP1A.190711.020/A015MUBU4AUD9) sdk_ver: 2020.3.25f1 log_messages: OdinSerializer detected Android architecture ‘armv8l’ for determining unaligned read/write capabilities. Unaligned read/write support: all=False, float=True
Stack trace:
(I didn’t include the filename or line numbers because its compiled via il2cpp and won’t be useful.)