Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странная генерация исключения Misaligned (ARM9)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Harvester
Добрый день.
Процессор ARM926, отладчик - китайский T32.
В процессе портирования кода опять столкнулся с исключением Misaligned. Нашел функцию, ПОСЛЕ возврата из которой возникает упомянутое исключение. Обращаю внимание - именно после возврата. Причем если поставить точку останова на команду, следующую за командой вызова функции, то выполнение программы на ней останавливается как бы без генерации исключения, однако при последующем запуске (RUN или STEP) отладчик пишет "Emulator running", а устройство перезапускается (штатное поведение при фатальной ошибке в рабочем режиме). Т.е. исключение генерируется, но почему-то отладчик его не отслеживает, а, наоборот, "теряет" устройство. То же самое происходит если дойти до этой команды пошагово (при этом неважно, есть там точка останова или нет).
А вот если поставить точку останова на 2-ю команду после команды вызова функции, то до нее программа не доходит, а вылетает в обработчик фатальных ошибок.
Стек в порядке. На всякий случай код функции:
Код
void MainCipherStepWithOptimization (
  PULONG pN,                  // r0 = 01AF4054
  PUCHAR pKey,                // r1 = 01AF408C
  PUCHAR keyIndexes,          // r2 = 00F44E20
  PULONG pSubstTable,         // r3 = 00CA2027
  unsigned char itCounter
)
{
    ULONG Temp, Idx;
    PULONG pKeyItem = (PULONG)pKey;
    int i;

    for (i = 0; i < itCounter; i++)
    {
        Idx = *pN + pKeyItem[keyIndexes[i]];

        Temp = pSubstTable[((Idx >> 0)  & 0x000000FFUL)        ]
             | pSubstTable[((Idx >> 8)  & 0x000000FFUL) + 0x100]
             | pSubstTable[((Idx >> 16) & 0x000000FFUL) + 0x200]
             | pSubstTable[((Idx >> 24) & 0x000000FFUL) + 0x300];

        Temp ^= *(pN + 1);
      
        *(pN + 1) = *pN;
        *pN = Temp;
    }
    Temp = *pN;
    *pN = *(pN + 1);
    *(pN + 1) = Temp;
}

Единственная зацепка - нечетное значение указателя на массив long-ов pSubsTable. Но если дело в этом, то почему не возникает исключения во время работы функции (при обращении к этому массиву)? Больше ничего криминального не вижу.
Подскажите пожалуйста, что может быть причиной такого поведения - уже всю голову сломал.
aaarrr
Цитата(Harvester @ Sep 4 2015, 23:28) *
Единственная зацепка - нечетное значение указателя на массив long-ов pSubsTable. Но если дело в этом, то почему не возникает исключения во время работы функции (при обращении к этому массиву)?

Т.е. отладчик свободно в пошаговом режиме проходит обращения к pSubsTable? Просто исключить в функции обращение к pSubsTable не пробовали?

Похоже, Вы просто проблемы работы отладчика наблюдаете. При очевидной причине и месте возникновении исключения. Так зачем голову ломать?
Harvester
Цитата(aaarrr @ Sep 5 2015, 00:33) *
Т.е. отладчик свободно в пошаговом режиме проходит обращения к pSubsTable? Просто исключить в функции обращение к pSubsTable не пробовали?

Похоже, Вы просто проблемы работы отладчика наблюдаете. При очевидной причине и месте возникновении исключения. Так зачем голову ломать?

Обращения к pSubsTable проходят свободно в любом режиме, как в пошаговом, так и в обычном. При запуске без отладчика исключение тоже генерируется - устройство перезагружается. В общем, как-то не похоже на глюки отладчика.
Попробовал убрать обращение к pSubsTable - поведение не изменилось.

Важное дополнение - в первом сообщении была ошибка. Еще раз внимательно проверил: pSubsTable при вызове выровнен на границу двойного слова (r3 = 01064484). Теперь я вообще ничего не понимаю crying.gif
aaarrr
Цитата(Harvester @ Sep 5 2015, 08:32) *
Важное дополнение - в первом сообщении была ошибка. Еще раз внимательно проверил: pSubsTable при вызове выровнен на границу двойного слова (r3 = 01064484). Теперь я вообще ничего не понимаю crying.gif

Тогда это больше похоже на повреждение стека в процессе выполнения функции с перетиранием адреса возврата.
jcxz
Цитата(Harvester @ Sep 5 2015, 11:32) *
Обращения к pSubsTable проходят свободно в любом режиме, как в пошаговом, так и в обычном. При запуске без отладчика исключение тоже генерируется - устройство перезагружается. В общем, как-то не похоже на глюки отладчика.
Попробовал убрать обращение к pSubsTable - поведение не изменилось.
Важное дополнение - в первом сообщении была ошибка. Еще раз внимательно проверил: pSubsTable при вызове выровнен на границу двойного слова (r3 = 01064484). Теперь я вообще ничего не понимаю crying.gif

Напишите нормальный обработчик исключения с выводом в лог (UART) содержимого регистров в момент исключения. Какой смысл гадать на кофейной гуще если у Вас при исключении девайс перегружается и информация о причине теряется?
Исключение может быть вообще не в этой функции возникает. Также - в случае невыровненной записи, в некоторых случаях, я думаю, исключение может генериться не сразу, а через неск. команд из-за буферизации записи.
ArtDenis
В случае, когда сходу ничего не понятно, совет простой: последовательно комментировать операции, которые могут как-то влиять на работу. Я бы начал с последовательного комментирования операций записей. Если не помогает, тогда начал бы комментировать операции чтения. Как только после очередной закоментированной строчки ошибка пропадает, необходимо "помедетировать" над этой строчкой. Не помогла "медитация", комментируем что-нибудь еще и так до полного просветления :-)
Harvester
Всем спасибо за советы. Дело действительно оказалось не в функции, а в той самой команде, следующей за вызовом функции.
Код
void Gost_EncryptCFB_(PGOST28147_CTX pX)
{
    ULONG *pLB = (ULONG *)pX->pd.prData;
    ...
    MainCipherStepWithOptimization(...);
            *(pLB + 0) ^= pX->N[0];
            *(pLB + 1) ^= pX->N[1];
    ...

Указатель на char явно приводится к указателю на long. Поскольку исходный указатель не выровнен, то при обращении к новому указателю (компилятор использует команды LD/ST) возникает исключение. Чтобы этого избежать надо добавить атрибут packed:
Код
__packed ULONG *pLB = (__packed ULONG *)pX->pd.prData;

В этом случае компилятор подставляет библиотечные функции __rt_uread4/__rt_write4, которые читают/пишут значение побайтно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.