Перейти к содержанию
    

IAR CSTACK RSTACK - измерение глубины стека

Привет!

 

По идеям документа с сайта IAR

https://www.iar.com/support/resources/artic...em-reliability/

хочу напрямую смотреть использование стека в процессе выполнения программы

 

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

С data stack (CSTACK) все вроде должно получиться без проблем, а вот как получить указатель на текущий RSTACK?

 

C data stack идея такова -

char *highStack, *lowStack; 
int main(int argc, char *argv[])
{
highStack = (char *)&argc; 
// ... 
printf("Current stack usage: %d\n", highStack - lowStack); 
}

void sampling_timer_interrupt_handler(void) 
{ 
char* currentStack; 
int a; 
currentStack = (char *)&a; 
if (currentStack < lowStack) lowStack = currentStack; 
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

+1 Тем более, что этот метод не является в прямом смысле "мгновенным", т. к. не позволяет уличить момент порчи стека, а в случае с AVR и никакой другой метод этого не позволит - AVR ядро не содержит таких аппаратных возможностей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Идея в том, чтобы через таймерное прерывание...

 

обычно привязывают к коду или потоку при выполнении которого портится стэк.

Либо как тут уже прозвучало выше - иметь аппаратные механизмы отслеживающие выход стэка за тот объём, что ему отведён.

Либо ставят анализатор на переключении контекста (в случае ОС).

 

Как превентивная мера - можно замерять сколько осталось(используется) по глубине стэк. И при изменении данного показателя производит запись

для дальнейшего анализа и разбора.

 

(круглый)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Ок, спасибо.

А есть пример как заполнить стеки константами, и получить указатель на начало в программе на рабочем девайсе (не в эмуляторе)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А есть пример как заполнить...

Как и любой массив памяти.

получить указатель на начало в программе на рабочем девайсе (не в эмуляторе)?

Поскольку стеки УСТАНАВЛИВАЮТСЯ при инициализации, а не назначаются господом богом, то "узнать" на самом деле означает посмотреть в программе где они устанавливаются (очевидно в cstartup). и/bли посмотреть имена сегментов в конфигурации линкера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С data stack (CSTACK) все вроде должно получиться без проблем, а вот как получить указатель на текущий RSTACK?

 

Так программно доступный регистр SP и есть указатель на RSTACK.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Друзья, если у кого то есть рабочий код на С по заполнению стека при стартапе - буду признателен.

 

Пока нашел только это на ASM

http://caxapa.ru/301695.html?todo=full

 

PS: zltigo прошу не утруждать себя ответами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока нашел только это на ASM

Неправда. Там описан и абсолютно правильный путь и для IAR + Си. Только, как писал - "посмотреть имена сегментов в конфигурации линкера" таки придется.

Надо только думать, а не просто вопрошать "дайте рабочий код"

PS: zltigo прошу не утруждать себя ответами.

Без проблем.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему у них там (у IAR) стек расположен не вверху памяти? А вверху памяти расположена куча? Непонятно что-то.

 

 

mastering_stack_heap_1.jpg

post-90364-1461001949_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему у них там (у IAR) стек расположен не вверху памяти?

А потому, что по барабану как, это раз. И IAR тут ни причем - дело хозяйское - как прикажете линкеру, так и будет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А потому, что по барабану как, это раз. И IAR тут ни причем - дело хозяйское - как прикажете линкеру, так и будет.

Еще вот как раз недавнюю тему почитал. Да - оказывается и так делают. Теперь надо бы переварить это... Посмотреть бы еще примеры под это дело (arm gcc).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хочу напрямую смотреть использование стека в процессе выполнения программы

Вам правильно посоветовали использовать предварительное заполнение области стека константой с дальнейшим анализом содержимого оной.

Этот метод даст максимально точный результат. Хотя и не 100%.

А насколько точный результат глубины заполнения стека Вы хотите получить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так программно доступный регистр SP и есть указатель на RSTACK.

 

Спасибо, все оказывается просто :)

 

 

Вам правильно посоветовали использовать предварительное заполнение области стека константой с дальнейшим анализом содержимого оной.

Этот метод даст максимально точный результат. Хотя и не 100%.

А насколько точный результат глубины заполнения стека Вы хотите получить?

 

Большой точности не надо, просто приблизительная оценка на реальной работе системы.

 

Способ с заполнением хорош, только вот примера на С рабочего нет. В примере по ссылке, про который я писал имена сегментов выставлены правильные, в map файле они так и называются CSTACK и RSTACK но пример нерабочий.

 

char __low_level_init()
{
    #pragma segment="CSTACK"
    char* p = (char*)__segment_begin("CSTACK");
    size_t len = (size_t)__segment_end("CSTACK") - (size_t)__segment_begin("CSTACK");
    
    while( len-- )
        *p++ = 'C';
    
    p = (char*)__segment_begin("RSTACK");
    len = (size_t)__segment_end("RSTACK") - (size_t)__segment_begin("RSTACK");
    
    while( len-- )
        *p++ = 'R';

    return 1;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

return 1;

Смотреть на "1". И думать что происходит при возврате 1 функцией __low_level_init

 

P.S.

Mty вышенаписаное читать не надо. Это только для тех, кому интересно, как это может не работать.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...