Размер стека отслеживания во время выполнения приложения - PullRequest
0 голосов
/ 05 сентября 2018

Я запускаю приложение во встроенной (PowerPC 32-битной) системе, где ограничение размера стека составляет 64 КБ. Из-за переполнения стека возникают случайные сбои.

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

Мне было интересно, что является лучшим способом найти методы, которые превышают ограничение размера стека, и который является фреймом стека, когда это происходит (для выполнения некоторого рефакторинга кода).

Я уже пробовал Callgrind (инструмент Valgrind), но, похоже, это не тот инструмент.

Я ищу инструмент больше, чем изменения в коде (так как это проект 200K LOC и 100 файлов).

Приложение полностью написано на C ++ 03.

1 Ответ

0 голосов
/ 05 сентября 2018

Хотя кажется, что для этого должен существовать инструмент, я бы подошел к нему, написав небольшой макрос и добавив его в начало подозреваемых функций:

char *__stack_root__;

#define GUARD_SIZE (64 * 1024 - 1024)

#define STACK_ROOT \
    char __stack_frame__; \
    __stack_root__ = &__stack_frame__;

#define STACK_GUARD \
    char __stack_frame__; \
    if (abs(&__stack_frame__ - __stack_root__) > GUARD_SIZE) { \
        printf("stack is about to overflow in %s: at %d bytes\n", __FUNCTION__, abs(&__stack_frame__ - __stack_root__)); \
    }

А вот как это использовать:

#include <stdio.h>
#include <stdlib.h>

void foo(int);

int main(int argc, char** argv) {
    STACK_ROOT;                    // this macro records the top of the bottom of the thread's stack
    foo(10000);
    return 0;
}

void foo(int x) {
    STACK_GUARD;                   // this macro checks if we're approaching the end of memory available for stack
    if (x > 0) {
        foo(x - 1);
    }
}

пара замечаний здесь:

  • этот код предполагает один поток. Если у вас несколько потоков, вам нужно отслеживать отдельные переменные __stack_frame__, по одной на поток. Используйте локальное хранилище потока для этого
  • с использованием abs(), чтобы убедиться, что макрос работает как при увеличении стека PowerPC, так и при уменьшении (это может: зависит от ваших настроек)
  • настройте GUARD_SIZE по своему вкусу, но оставьте его меньше, чем максимальный размер вашего стека на цели
...