Android NDK: доступ к элементу структуры C ++, вызывает SIGBUS (сигнал SIGBUS: неправильное выравнивание)

Я портирую библиотеку C ++ на Android (Android Studio 2.3.1 / NDK 25); библиотека безупречно работает на UWP (VS2017 VC 1.41 — ARM & Win32) пользовательская плата ARM7 (GCC 4.8).

При отладке на Android Studio я получаю «SIGBUS (сигнал SIGBUS: неправильное выравнивание)» во время присваивания члену структуры.
Вот структура (мне нужно, чтобы она была выровнена на 64 бита):

typedef unsigned int        _t_u32;         // 32-bit unsigned
typedef unsigned long long  _t_u64;         // 64-bit unsigned

typedef struct __attribute__((aligned(8)))
{
_t_u32      crc32;
_t_u64      counter;

} t_security;

Теперь вот фрагмент кода:

void prepareBuffer(_t_u8 cmd, _t_u8 *buffer, _t_u32 buffferLen)
{
t_security *secPtr = ((t_security *)(buffer + sizeof(_t_u8)));

secPtr->crc32 = 0;
secPtr->counter= 0; << when this is being executed, on Android Studio-only, I get *"SIGBUS (signal SIGBUS: illegal alignment)"*
...
...
}

Из отладочных часов Android Studio:

sizeof(t_security) = {unsigned int} 16
&secPtr = {t_security * | 0xdc98eb41} 0xdc98eb41
&secPtr->crc32 = {_t_u32 * | 0xdc98eb41} 0xdc98eb41
&secPtr->counter = {_t_u64 * | 0xdc98eb49} 0xdc98eb49

Из отладочных часов Visual Studio (платформа ARM):

sizeof(t_security)  16  unsigned int
secPtr  0x00afe2e5 {crc32=3435973836 ...}   t_security *
&secPtr->crc32  0x00afe2e5 {3435973836} unsigned int *
&secPtr->counter    0x00afe2ed {14757395258967641292}   unsigned __int64 *

Я полагаю, что это связано с выравниванием упаковки / элемента … но, как вы можете заметить, упаковка выглядит согласованной на двух платформах … только на Android Studio-only, я получаю «SIGBUS (сигнал SIGBUS: неправильное выравнивание)».

Может кто-нибудь, пожалуйста, помогите мне понять, что происходит?
Может быть, мне не хватает переключателя компилятора? Вот конфигурация Gradle ndk:

android.ndk {
moduleName = "NativeLib"
// add compilation flags
cppFlags.add("-DANDROID")
cppFlags.add("-frtti")
cppFlags.add("-std=c++14")
cppFlags.add("-fexceptions")

// include headers
cppFlags.add("-I${file("native-src")}".toString())

ldLibs.addAll("android", "dl", "log", "z", "atomic")

stl = "c++_static"  // LLVM compiler
}
android.buildTypes {
all {
// To solve struct packing issues, setting abiFilters to package only 32-bit architectures:
ndk.with {
abiFilters.add("armeabi")
abiFilters.add("armeabi-v7a")
abiFilters.add("mips")
abiFilters.add("x86")
}
}
debug {
ndk.with {
cppFlags.add("-DDEBUG")
CFlags.add("-DDEBUG")
}
}
}

Большое спасибо!

1

Решение

У меня была точно такая же проблема.

В вашем фрагменте кода, secPtr не выровнен, потому что это указывает на buffer смещено на 1 (sizeof(_t_u8)байт. (при условии, что buffer выравнивается адрес)

Все 4-байтовые адреса памяти должны заканчиваться на «0», «4», «8» или «C». поскольку secPtr заканчивается на «5», он не выровнен.

Процессоры ARM поддерживают доступ к памяти без выравнивания. Поэтому secPtr->crc32 = 0; законно, но secPtr->counter= 0; не является.

Попробуйте удалить 1-байтовое смещение в secPtr как-нибудь и посмотрим, исчезнет ли проблема.

Также проверьте эту страницу для подробной информации: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector