В работе использую 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).
Вместо флага в наверное лучше использовать сигнал, чтобы накладок небыло.
Ну и конечно при такой отладке размер стека нужно обозначать немного больше, чем реально выделено памяти.
Если кто-то знает другие методы, поделитесь.