Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Prefetch abort
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
SpiritDance
Непонятно поведение программы.
Через некоторое время работы (коннект по CSD и прогон данных туда/сюда) процессор вылетает в префетч, При этом в LR бешеный адрес начинающийся на 0xD8.

Вопрос. Я правильно понимаю что каким-то образом портится стек? Как это можно проверить и собственно как его можно попортить? Все указатели прна копирование информации при этом остаются целехонькими соответственно вроде не они.

Подскажите способ каким образом можно отловить момент ошибки а то я что-то не очень понимаю как это побороть?
aaarrr
Цитата(SpiritDance @ Jun 1 2009, 11:24) *
Подскажите способ каким образом можно отловить момент ошибки а то я что-то не очень понимаю как это побороть?

Для начала, крепко подумать, откуда на стеке может взяться "бешеный адрес начинающийся на 0xD8", иногда по числу удается понять, откуда оно пришло.

Еще можно порекомендовать посмотреть содержимое LR того режима, из которого влетели в аборт.
IgorMarx
А нескромный вопрос мона? Какая среда программирования? Какой язык программирования? Тут не боги заседают.

Если это IAR, то нужно сделать следующее:

1. в опциях линкера включить генерацию map файла;
2. посмотреть в этом файле, где лежит сегмент CSTACK;
3. Аккуратно протопать отладчиком, заходя в процедуры и наблюдая за стек пойнтером. Как только SP станет меньше, чем начало сегмента CSTACK, улыбайтесь .
Кстати, отладчик может предупреждать о переполнении стека. Нужно смотреть в окне отладочных сообщений.
aaarrr
Цитата(IgorMarx @ Jun 1 2009, 20:50) *
А нескромный вопрос мона? Какая среда программирования? Какой язык программирования? Тут не боги заседают.

Среда и язык программирования к проблеме и методам ее локализации не имеют ну ни малейшего отношения, уж поверьте.

Цитата(IgorMarx @ Jun 1 2009, 20:50) *
3. Аккуратно протопать отладчиком...

Да-да, отладчиком. Падает оно во время "коннекта по CSD", что несколько ограничивает использование этого инструмента, не находите?
xelax
Значение LR при perfetch слабо помогают, потомучто там в 99% случаев действительно дикие значения находятся.
LR помогает data abort отлавливать.
Пару месяцев назад я подобную тему поднимал в итоге пришёл к тому, что в handlere от perfetch вывожу через uart значение всех регистров и несколько десятков байт стека.
И по содержащимся там значениям, похожим на адреса, уже в рукопашную пытаюсь по дизасму находить похожие места.
Во всех случаях источником perfetchей было вызов функций по неинициализированным указателям.
aaarrr
Цитата(xelax @ Jun 2 2009, 10:02) *
Значение LR при perfetch слабо помогают, потомучто там в 99% случаев действительно дикие значения находятся.

LR_abt действительно слабо, а вот LR исходного режима - весьма сильно.
zltigo
Цитата(IgorMarx @ Jun 1 2009, 19:50) *
3. Аккуратно протопать отладчиком.....

Пока не надоест sad.gif
Цитата
Кстати, отладчик может предупреждать о переполнении стека. Нужно смотреть в окне отладочных сообщений.

Особенно "полезная" фича, если используется, несколько переключаемых стеков, например, в операционных системах.
Просто надо действительно смотреть при вылете регистры и стек (до сих пор мне 16 значений стека для разборок).
KAlex
Цитата(SpiritDance @ Jun 1 2009, 11:24) *
Вопрос. Я правильно понимаю что каким-то образом портится стек? Как это можно проверить и собственно как его можно попортить?

Была у меня похожая проблема, при использовании вложенных прерываний. Так же вылетало в неопределенный момент времени.
В стартапе в обработчике ошибочка была.
xelax
Цитата(aaarrr @ Jun 2 2009, 11:19) *
LR_abt действительно слабо, а вот LR исходного режима - весьма сильно.

Не согласен... Возможно иногда там и сохраняется, нормальный адрес возврата, но только если процессор не успел пробежаться по мусору или не встретил в этом мусоре ничего похожего на brunch. Когда процессор пошёл гулять по мусорным адресам из-за неинициализированного указателя, то первым гибнет корректное значение в LR регистре текущего режима.

По крайней мере мне ниразу не удавалось из LR исходного режима вытянуть полезной информации при perfetch abort, всегда там был мусор.
Другоe дело data abort smile.gif
aaarrr
Цитата(xelax @ Jun 2 2009, 15:01) *
Не согласен... Возможно иногда там и сохраняется, нормальный адрес возврата, но только если процессор не успел пробежаться по мусору или не встретил в этом мусоре ничего похожего на brunch. Когда процессор пошёл гулять по мусорным адресам из-за неинициализированного указателя, то первым гибнет корректное значение в LR регистре текущего режима.

Совершенно неубедительно. Во-первых, обычно процессор влетает в prefetch abort или undefined instruction на первой же инструкции после ошибочного перехода. Во-вторых, LR, естественно, не "гибнет первым делом", т.к. для этого нужно или выполнить инструкцию с Rd=LR, или же выполнить инструкцию BL.
defunct
Цитата(xelax @ Jun 2 2009, 14:01) *
По крайней мере мне ниразу не удавалось из LR исходного режима вытянуть полезной информации при perfetch abort, всегда там был мусор.

Вообще-то если проблема с перетиранием стека (то о чем Вы предположили в самом начале). То вылет по логике вещей должен произойти на выходе из функции сразу после выполнения
LDMIA !R13, {PC}... И LR должен быть целым
xelax
Цитата(aaarrr @ Jun 2 2009, 15:19) *
Совершенно неубедительно. Во-первых, обычно процессор влетает в prefetch abort или undefined instruction на первой же инструкции после ошибочного перехода. Во-вторых, LR, естественно, не "гибнет первым делом", т.к. для этого нужно или выполнить инструкцию с Rd=LR, или же выполнить инструкцию BL.

laughing.gif однако же там мусор. Perfech abort не той системы наверное.
А вообще не понятно о чём спор. Это вещь сугубо вероятностная.
aaarrr
Цитата(xelax @ Jun 2 2009, 18:43) *
А вообще не понятно о чём спор. Это вещь сугубо вероятностная.

Несомненно, только вот вероятность Вы оценили как-то странно - "первым гибнет корректное значение в LR регистре текущего режима". Это не так.
SpiritDance
Цитата(aaarrr @ Jun 1 2009, 11:41) *
Для начала, крепко подумать, откуда на стеке может взяться "бешеный адрес начинающийся на 0xD8", иногда по числу удается понять, откуда оно пришло.


Там на самом деле разный мусор. Число каждый раз непонятное, ни очем не говорящее.


Цитата(aaarrr @ Jun 1 2009, 11:41) *
Еще можно порекомендовать посмотреть содержимое LR того режима, из которого влетели в аборт.

Смотрел. Влетаю явно из систем-режима, но в данном регистре вообще был нечетный адрес.

Проблема была хитрой. Парсер от процессора ловил некоторую сигнатуру в данных и принимал ее за команду и... всё.

Но она была явно не одна.

Сейчас наблюдаю вылет по данным.

Проблема в том что без отключенной оптимизации код вместе с сегментом констант и инициализированных данных не влезает в процессор. Соответственно под отладчиком посмотреть не получается - информация для него отсутсвует и он кажет хрень.

Закомментировал некоторое количество кода и запустил без оптимизатора (none и low) - сбоев нет. Включаю оптимизатор и сбоит, причем точку вылета поймать пока не удается - в отладчике опять охинея, плюс он подвисает в самый неудачный момент. Программа без операционки, но с кучей конечных автоматов. Хорошо хоть проблема стабильно проявляется.

Уарты все заняты и в консольку я выбросить ничего не могу, есть только вариант с USB. Однако непонятно как написав обработчик dataabort дотянутся до регистров system.

Чтобы сделать такого чтоб добраться до истока проблемы? Мозг уже сломал.

Цитата(IgorMarx @ Jun 1 2009, 20:50) *
А нескромный вопрос мона? Какая среда программирования? Какой язык программирования? Тут не боги заседают.

Не знаю чем поможет такое уточнение. Проц sams256 + IAR4.41A.

Цитата(IgorMarx @ Jun 1 2009, 20:50) *
Кстати, отладчик может предупреждать о переполнении стека. Нужно смотреть в окне отладочных сообщений.

Угу. Это если ему будет угодно то да, покажет. Ну если конечно не зависнет.
aaarrr
Цитата(SpiritDance @ Jun 3 2009, 14:08) *
Проблема в том что без отключенной оптимизации код вместе с сегментом констант и инициализированных данных не влезает в процессор

И не надо ее отключать.

Цитата(SpiritDance @ Jun 3 2009, 14:08) *
Однако непонятно как написав обработчик dataabort дотянутся до регистров system.

Просто переключиться в режим System.

Цитата(SpiritDance @ Jun 3 2009, 14:08) *
Чтобы сделать такого чтоб добраться до истока проблемы? Мозг уже сломал.

Выкинуть отладчик, добавить нормальные обработчики abort'ов, и исследовать их вывод.
SpiritDance
Цитата(aaarrr @ Jun 3 2009, 14:19) *
Просто переключиться в режим System.


Туплю.
zltigo
Цитата(SpiritDance @ Jun 3 2009, 13:08) *
Сейчас наблюдаю...

Как Вам уже рекомендовали, сделайте нормальный обработчик исключений. У меня, например, выдат такую информацию:
Код
Abort:[D] PC:00006774 Op:E18060B1 CPSR:200000DF
   LR:00015D44 SP:40004C74
SP[0]:DEADBEEF->400024B8->400024B8->0001F4AC->
SP[4]:00000004->00000000->4000015C->0000BF24
Test:00000000
R0:00000000 R1:00000000 R2:00000003 R3:D0120F12  R4:40001D94  R5:400024B8
R6:0000CA02 R7:40000060 R8:00000004 R9:00000002 R10:40000010 R11:00000001
R12:000000C0

Еще ни разу не довелось не найти по ней причину. Адрес известен, функция по map файлу. Место по листингу, если оптимизация сильно мешает понять - отключается на конкретных местах, если функция не виноватая, типа "memcpy", то в Вашем распоряжении LR и стек для поиска первоисточника
SpiritDance
Цитата(zltigo @ Jun 3 2009, 19:03) *
Как Вам уже рекомендовали, сделайте нормальный обработчик исключений. У меня, например, выдат такую информацию:


Я безусловно приму рекомендации, просто не уверен что uSB у меня по прерываниям нормально сработает, а выдавать больше некуда. Надо думать а время заставляет прыгать и я боюсь напортачить.

Проблему решил. одна функция портила индексную пременную и при пробеге массива случался аборот. как оно работало при отключенном оптимизаторе сказать затруднительно.

Всем спасибо за соболезнования.
smile3046.gif
Shaienn
Добрый день. Поднимаю тему из-за непонимания.

Все таки, каким образом портится стек?
Ведь с ними работаю не я, а компилятор. Я же просто пишу функции в текстовом виде и обращаюсь к ним тоже в текстовом виде, а все адреса переходов и запоминание и восстановление регистров делает компилятор...

Написал программу, в которой появился Prefetch abort. Появляется он после следующей строки:

Код
0x00101224  E8BD47F0  LDMIA     R13!,{R4-R10,R14}


То есть, после восстановления регистров...
Но восстанавливается что-то странное. Значение R14 - 0x48d9055d, и, конечно, по этому адресу ничего нет...

Программа построена так:

3 юнита:
Процесс 1 (АЦП).с
Процесс 2 (LCD).с
Объединяющий процесс.с

Из объединяющего процесса запускаю Процесс 1, там по прерываниям опрашивается диапазон значений, после выставляется флаг окончания работы. Объединяющий процесс, среагировав на этот флаг, запускает отображение на LCD - Процесс 2. Заметил особенность - если Процесс 2 запускать из Процесса 1, то ошибки не возникает и все работает как надо.

Научите, как такие вещи лечить? Ну нашел я команду, после которой сбой возникает, но что делать дальше? И как таки эти ошибки возникают?

Спасибо.
aaarrr
Цитата(Shaienn @ Jun 14 2010, 16:08) *
Ведь с ними работаю не я, а компилятор.

Ну, это не совсем так. Компилятор, например, не следит за границами стека, если его не попросить.

Цитата(Shaienn @ Jun 14 2010, 16:08) *
Ну нашел я команду, после которой сбой возникает, но что делать дальше?

Сначала посмотрите, где в этот момент находится SP.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.