Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Отладка и выход за пределы массивов
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Neo_Matrix
Подскажите, есть ли способ под FreeRTOS понять есть ли выходы за предел массива. Хуки на недостаток хипа и стека работают нормально и очень помогают, когда нужно зажать стек задачи до минимума. Но как отладить выход за пределы массивов? Такая необходимость появилась, так как иногда устройства перезагружаются сами по себе(в обработчиках исключений стоит функция сброса, так как устройства должны максимально быть доступны). Есть подозрение на выход за пределы. Так как проект достаточно крупный около 300кб кода с оптимизацией, пересмотреть, а главное заметить ошибку очень сложно.
Кто, что может порекомендовать?
jcxz
Цитата(Neo_Matrix @ Apr 6 2018, 23:27) *
Подскажите, есть ли способ под FreeRTOS понять есть ли выходы за предел массива. Хуки на недостаток хипа и стека работают нормально и очень помогают, когда нужно зажать стек задачи до минимума. Но как отладить выход за пределы массивов?

А какое имеет отношение FreeRTOS или какая другая ОС к вашим массивам?
Читайте описание на используемый процессор.
Для Cortex-M - читать описание MPU.
kolobok0
Цитата(Neo_Matrix @ Apr 6 2018, 23:27) *
...Кто, что может порекомендовать?


Наберите людей на испытательный срок. С условием = найдут проблемы, бонусы.
А для программиста = обратная задача. Найдётся баг - из его зарплаты минусы.

Думаю проблемЫ найдутся быстро, тоннами и качественно.

Не технический путь, но профит будет 100%

удачи вам
(круглый)
ЗЫ
Если технически - наверное пытаться эмулировать работу логики. + изоляция памяти, с анализом на перезатирку. Но профит будет меньше чем в первом случае...
novikovfb
Для начала стоит перенести код в настольный ПК и погонять на модели под отладчиком, напихав туда проверок при каждом обращении к массивам. Ну и статические анализаторы типа CPP-Check или PVS-Studio помогают найти некоторые ошибки.
k155la3
1. Проработайте код аналитически, тк выход за границы массива "чем-то" - грубая ошибка, скорее всего программера а не компилятора или OS.
2. Используйте "на полную" возможности отладчика, например IAR. Настройте BP на стоп по изменению памяти (write).
Ставите такй BP на ячейку (адрес) за пределами массива и .... ждете sm.gif
3. Ну, можно "наложить" в памяти 2 массива. (&WorkArry[0] == &DbgArry[0])
Один - большой, отладочный, который перекрывает по размеру "проблемный".
Заполняете отладочный массив паттерном, напр. 0x55.
Второй массив - Ваш "проблемный". После сбоя смотрим паттерны в отладочном массиве выше последней ячейки "проблемного".

ps/ п.3.
При остановке в этой BP, через StackCall будет видно, кто там "порылся".
jcxz
Цитата(kolobok0 @ Apr 7 2018, 03:19) *
Наберите людей на испытательный срок. С условием = найдут проблемы, бонусы.
А для программиста = обратная задача. Найдётся баг - из его зарплаты минусы.
Думаю проблемЫ найдутся быстро, тоннами и качественно.

Вот именно! ... когда люди на испытательном сроке познакомятся с программистом делающим баги, я думаю они быстро найдут формулу взаимовыгодного сотрудничества: "утром баги, вечером бонусы" или "вечером баги, утром бонусы".
И все будут довольны: люди - бонусами, программист откатами от бонусов людей, а хозяин тоннами находимых и находимых багов... biggrin.gif biggrin.gif biggrin.gif biggrin.gif

Цитата(k155la3 @ Apr 7 2018, 12:14) *
Ставите такй BP на ячейку (адрес) за пределами массива и .... ждете sm.gif

На какую именно ячейку "за пределами"? Если к примеру массив == 10 байт, а размер памяти МК == 1<<32, то на какую из
(1<<32)-10 ячеек ставить? На все? Боюсь что жизни не хватит. laughing.gif

Цитата(k155la3 @ Apr 7 2018, 12:14) *
При остановке в этой BP, через StackCall будет видно, кто там "порылся".

char m[10];
int i = char[20]; //однако проблема!

И как же именно будет видно "через StackCall" или через некие "паттерны" кто порылся в вышеприведённом фрагменте кода??? wacko.gif
k155la3
Цитата(jcxz @ Apr 7 2018, 22:08) *
. . .
(1) На какую именно ячейку "за пределами"? Если к примеру массив == 10 байт, а размер памяти МК == 1<<32, то на какую из
. . .
(2) . . И как же именно будет видно "через StackCall" или через некие "паттерны" кто порылся в вышеприведённом фрагменте кода???

1 - понятно, что если вылет идет с "фонарным" индексом то это не вариант.
Если же это примитивный "зашкал" по sprintf - то вполне. (кто не пользуется snprintf)

2. Это не мое "изобретение", метода исползуется для контроля использования стека в scmRTOS.
Для чтения за пределами массива - никак. Разве что знать, что считывается определенный адрес и BP поставить на него. Смотреть стек вызовов.
Для чтения более целесообразно смотреть что попадает в [] а не вылавливать последствия. С указателем сложнее.
Код
//    Target-specific configuration macros
//
#ifdef scmRTOS_USER_DEFINED_STACK_PATTERN
#define scmRTOS_STACK_PATTERN scmRTOS_USER_DEFINED_STACK_PATTERN
#else
#define scmRTOS_STACK_PATTERN 0x55aaU
#endif
jcxz
Цитата(k155la3 @ Apr 7 2018, 22:49) *
2. Это не мое "изобретение", метода исползуется для контроля использования стека в scmRTOS.

И что? "Метод" не даёт никакой гарантии. Подумайте, что будет при вызове функции:
Код
void func() {
int m[100];
...
}
если вызов происходит вблизи границы стека. Да и не про стек вопрос автора.

Цитата(k155la3 @ Apr 7 2018, 22:49) *
Для чтения за пределами массива - никак.

Как. Если знать какой CPU у автора. Для Cortex-M я уже написал выше как. Для CPU с MMU - ещё лучше. И чтение и произвольная запись. Именно - произвольная, а не только в следующий адрес после массива.
Neo_Matrix
Спасибо всем за ответы. Их действительно много и они вполне перекрывают вопрос. Думаю лучший способ настроить MPU(cortex m4) + в некоторых местах сделаю массивы на длину +1 элемент и поставлю туда брейкпоинт на запись и чтение. Вариант с перекрытием массивов очень сложен, так как кода много и проблемный массив неизвестен. Аналитически код был просмотрен уже неоднократно, был найден один ляп с приведением типов, но это не изменило ситуацию в корне. Так же интересует, в случае фриртоса и выделения памяти в хипе, если будет затерт конец массива выделенной памяти, будет ли вызван ассерт во время фрии, или в конце нет данных маллока для отслеживания окончания массива(используется heap4.c + его модификация под CCM память)? Вариант с испытательным сроком очень оригинален. Всем спасибо sm.gif
HardEgor
Цитата(Neo_Matrix @ Apr 7 2018, 03:27) *
Так как проект достаточно крупный около 300кб кода с оптимизацией, пересмотреть, а главное заметить ошибку очень сложно.
Кто, что может порекомендовать?

Анализаторами кода пользовались? PVS-studio писали что адаптировались под Keil/IAR, только у меня руки не дошли проверить.
kolobok0
Цитата(Neo_Matrix @ Apr 8 2018, 01:57) *
Спасибо всем за ответы. ...


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

Но имхо - проблема не в коде, а в организации...

удачи вам
(круглый)
k155la3
Цитата(jcxz @ Apr 7 2018, 23:23) *
И что? "Метод" не даёт никакой гарантии. Подумайте, что будет при вызове функции:
Код
void func() {
int m[100];
...
}
если вызов происходит вблизи границы стека. Да и не про стек вопрос автора.
. . .

А какие могут быть гарантии при отладке каким-либо одним методом ?
Смею предположить, что затрется адрес возврата или контекст. Вообще - что угодно.

Код
void func()
{
static int m[100];
...
}

Если характер сбоя изменился или он вообще перестал проявляться - некорректная работа с этим массивом.
Цитата(Neo_Matrix @ Apr 8 2018, 01:57) *
Спасибо всем за ответы. Их действительно много и они вполне перекрывают вопрос. Думаю лучший способ настроить MPU(cortex m4) + в некоторых местах
. . .
Если RAM позволяет, попробуйте массив(ы) которые "под подозрением" объявить как static.
Kabdim
Цитата(jcxz @ Apr 7 2018, 23:23) *
И что? "Метод" не даёт никакой гарантии. Подумайте, что будет при вызове функции:

Гарантий нет, но в жизни это самый быстрый и действенный способ.
Neo_Matrix
Всем спасибо. Ошибка найдена. Функции strncmp при определенных стечениях обстоятельств передавался NULL вместо валидного указателя.
jcxz
Цитата(Neo_Matrix @ Apr 10 2018, 15:11) *
Всем спасибо. Ошибка найдена. Функции strncmp при определенных стечениях обстоятельств передавался NULL вместо валидного указателя.

Вообще в нормально построенной программе на Cortex-M все области вне регионов ОЗУ обычно запрещаются для доступа по записи, а все регионы где вообще нет никакой памяти запрещаются для любого типа доступа. Для этого и предназначен MPU. Если-б у Вас программа была построена так, то скорей всего ошибка нашлась бы при первом же её проявлении.
megajohn
Цитата(Neo_Matrix @ Apr 10 2018, 15:11) *
Всем спасибо. Ошибка найдена. Функции strncmp при определенных стечениях обстоятельств передавался NULL вместо валидного указателя.


на будущее: если юзаете IAR, то там там появилось C-RUN Runtime Checking
( сам не юзал )
haker_fox
QUOTE (jcxz @ Apr 10 2018, 20:26) *
Вообще в нормально построенной программе на Cortex-M все области вне регионов ОЗУ обычно запрещаются для доступа по записи

А как разрешить запись в разрешённые регионы?
Neo_Matrix
Использую Keil.
В комплекте с FREERTOS есть демка, показывающая, как это делать. Сам не использую.
jcxz
Цитата(haker_fox @ Apr 10 2018, 17:51) *
А как разрешить запись в разрешённые регионы?

Начать с открытия мануала на ядро Cortex-M и изучения регистра конфигурации MPU.
А чтение мануала вслух - услуга платная. laughing.gif
haker_fox
QUOTE (jcxz @ Apr 11 2018, 14:24) *
А чтение мануала вслух - услуга платная. laughing.gif

Ну вот, а мне так нравится когда мне всё рассказывают rolleyes.gif Мануалы читать - это так скучно biggrin.gif biggrin.gif biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.