Я работаю над проектом, который переносится на ARM7 (изначально был на x86). Он работает на QNX. У нас было несколько проблем с выравниванием памяти (ошибка SIGBUS) из-за чтения/записи со смещенными указателями. Я исправил большинство проблем с выравниванием, просто заменив приведение и назначение указателя на memcpy, но эту проблему я не могу решить таким образом.
Существует общий пул памяти между процессами, который инициализируется следующим образом:
int m_nSharedMemory = shm_open(EVENT_LIST_NAME, O_RDWR | O_CREAT, 0777);
ftruncate(m_nSharedMemory, nSize)
unsigned char* m_pMemory = (unsigned char*) mmap(0, nSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_nSharedMemory, 0);
Предполагается, что память используется следующим образом: в начале адресного пространства есть Header
, а затем массив Event
. Таким образом, nSize = sizeof(Header) + MAX_EVENTS * sizeof(Event)
.
m_pHeader = (Header*)m_pMemory;
m_pEvents = (Event*)(m_pMemory + sizeof(Header));
И Header
, и Event
являются структурами с примитивными типами. Насколько мне известно, эта память не выровнена, поэтому выполнение m_pEvents[0].m_SomeField == 3
или m_pHeader->m_SomeField = 1
потенциально может вызвать ошибку SIGBUS. Такого рода инструкции повсюду, поэтому замена каждой из них на memcpy будет настоящей проблемой, я надеюсь, что смогу обойтись чем-то другим.
Я нашел posix_memalign
, который, по моему мнению, может заменить либо shm_open
, либо mmap
, еще не уверен, что именно, но это тоже не решает проблему. Во-первых, я все еще получаю предупреждение. Даже игнорируя предупреждение, я мог бы убедиться, что память выровнена по sizeof(Header)
, но m_pEvents
не будет выровнена.
Есть ли способ предотвратить ошибку SIGBUS без внесения серьезных изменений в эту схему? Сейчас компилятор ругается из-за "cast from 'unsigned char*' to 'Header*' increases required alignment of target type"
(такое же предупреждение есть для Event
), но программа не падает, чего я действительно не могу объяснить.
Итак, два вопроса: 1) Почему не вылетает? 2) Как мне убедиться, что этого никогда не произойдет, в идеале, обеспечив выравнивание памяти и подавление предупреждения
Header
на 32/64 бита или добавьте дополнение кnSize
и выровняйтеm_pEvents
.(m_pMemory + sizeof(Header) + 7) & ~7
Вы должны прочитатьFSR
(регистр статуса ошибки), чтобы посмотрите, не является ли это проблемой выравнивания или разрешения. - person artless noise   schedule 29.05.2017PLT_ARM7LE
, не уверен, что это отвечает на вопрос. Что я хочу сделать, так это предотвратить сбои SIGBUS, работает ли код или нет, это проблема для другого дня. - person freejuices   schedule 29.05.2017m_pEvents
. Все еще не получил тот дляHeader
. Что вы имеете в виду, чтобы изменить его, чтобы выровнять его до 32/64?Header
запустится везде, где mmap решит выровнять m_pMemroy. Может быть, я должен добавить, чтоnSize = sizeof(Header) + MAX_EVENTS * sizeof(Event)
- person freejuices   schedule 29.05.2017