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

 
 
> GCC и переполнение стека в многопоточных приложениях
Puzan
сообщение Sep 5 2007, 14:53
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 30
Регистрация: 16-12-05
Пользователь №: 12 295



В работе использую GCC. Искал метод определения размера стека для потока в многопоточном приложении. Собственно ничего толкового не нашел, по этому пришлось придумывать самому. Вот решил поделиться.

Первоначально хотел написать анализатор стека, но не стал этого делать, потому что некогда (может потом сделаю). По этому пошел другим путем.
В GCC есть опция -finstrument-functions, по которой компилятор вставляет в начало каждой функции вызов void __cyg_profile_func_enter( void*, void* ), а в конец вызов void __cyg_profile_func_exit( void*, void* ). Определяем эти функции и контролируем в них регистр sp. Вот примерно так:

Код
void __attribute__((no_instrument_function)) __cyg_profile_func_enter (void *this_fn, void *call_site) {
    register UINT32 sp asm("r13");
    register UINT32 cpsr asm("r2");
    asm(    "mrs        r2,cpsr" :: );
    if( (cpsr & 0x1F) == 0x1F )        // находимся в SYSMODE?
        if( cur_thd->sp_min > sp ) {
            cur_thd->sp_min = sp;
            cur_thd->sp_change = TRUE;
        }
}


где cur_thd - указатель на текущий поток,
cur_thd->sp_min - минимальное значение SP (глубина стека, стек растет вниз),
cur_thd->sp_change - флаг изменения cur_thd->sp_min.

Поясню: я использую свою ОС, по этому определил в структуре потока необходимые мне поля. Если не хочется лезть в исходники ОС, можно определить отдельно для каждого потока sp_min и пр.
У меня все потоки (и только потоки) выполняются в SYSMODE.
Атрибут __attribute__((no_instrument_function)) используется для того, чтобы функции не контролировали сами себя. Так же можно определить функции, которые никогда не вызываются из потоков (не используют потоковый стек), например обработчики прерываний, или ядерные функции.

Далее, добавил поток, в котором по sp_change контролирую выход за границу стека, а за одно и максимальный размер стека для потока (чтобы зря не тратить память) и вывожу это все в консоль (через UART).
Вместо флага в наверное лучше использовать сигнал, чтобы накладок небыло.

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

Если кто-то знает другие методы, поделитесь.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 21:37
Рейтинг@Mail.ru


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