реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Странная генерация исключения Misaligned (ARM9)
Harvester
сообщение Sep 4 2015, 20:28
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Добрый день.
Процессор 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. Но если дело в этом, то почему не возникает исключения во время работы функции (при обращении к этому массиву)? Больше ничего криминального не вижу.
Подскажите пожалуйста, что может быть причиной такого поведения - уже всю голову сломал.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 4 2015, 21:33
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

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

Похоже, Вы просто проблемы работы отладчика наблюдаете. При очевидной причине и месте возникновении исключения. Так зачем голову ломать?
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 5 2015, 05:32
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



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

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

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

Важное дополнение - в первом сообщении была ошибка. Еще раз внимательно проверил: pSubsTable при вызове выровнен на границу двойного слова (r3 = 01064484). Теперь я вообще ничего не понимаю crying.gif


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 5 2015, 06:31
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

Тогда это больше похоже на повреждение стека в процессе выполнения функции с перетиранием адреса возврата.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 5 2015, 14:05
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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

Напишите нормальный обработчик исключения с выводом в лог (UART) содержимого регистров в момент исключения. Какой смысл гадать на кофейной гуще если у Вас при исключении девайс перегружается и информация о причине теряется?
Исключение может быть вообще не в этой функции возникает. Также - в случае невыровненной записи, в некоторых случаях, я думаю, исключение может генериться не сразу, а через неск. команд из-за буферизации записи.
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Sep 6 2015, 03:50
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



В случае, когда сходу ничего не понятно, совет простой: последовательно комментировать операции, которые могут как-то влиять на работу. Я бы начал с последовательного комментирования операций записей. Если не помогает, тогда начал бы комментировать операции чтения. Как только после очередной закоментированной строчки ошибка пропадает, необходимо "помедетировать" над этой строчкой. Не помогла "медитация", комментируем что-нибудь еще и так до полного просветления :-)


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 7 2015, 09:08
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Всем спасибо за советы. Дело действительно оказалось не в функции, а в той самой команде, следующей за вызовом функции.
Код
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, которые читают/пишут значение побайтно.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01378 секунд с 7
ELECTRONIX ©2004-2016