Что означает эта ошибка: `somefile.c: 200: ошибка: размер кадра 1032 байта превышает 1024 байта`? - PullRequest
27 голосов
/ 16 марта 2010

Во время сборки я вижу ошибку в следующем виде:

cc1: warnings being treated as errors
somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes

Номер строки указывает на закрывающую скобку функции c, которая имеет такую ​​подпись:

void trace(SomeEnum1 p1, SomeEnum2 p2, char* format, ...) {
    char strBuffer[1024];
    ...

Функция выводит некоторые данные в буфер.

Кто-нибудь знает, что вообще означает этот тип ошибки?

Ответы [ 3 ]

34 голосов
/ 16 марта 2010

Я предполагаю, что в этой подпрограмме есть какой-то большой буфер, который выделен стеком; это может привести к тому, что размер стека этой функции превысит 1024 байта, что, по-видимому, является неким ограничением, применяемым компилятором для архитектуры, на которой вы строите. Возможные решения включают передачу флага компилятора для ослабления предупреждения, расширения верхнего предела размера стека или динамического выделения буфера.

13 голосов
/ 16 марта 2010

Вот документация GCC, ссылающаяся на это предупреждение:

STACK_CHECK_MAX_FRAME_SIZE

Максимальный размер кадра стека в байтах. GNU CC сгенерирует тестовые инструкции в неконечных функциях, чтобы обеспечить доступность как минимум такого количества байтов стека. Если кадр стека больше этого размера, проверка стека не будет надежной, и GNU CC выдаст предупреждение. Значение по умолчанию выбрано так, что GNU CC генерирует только одну инструкцию в большинстве систем. Обычно вы не должны изменять значение по умолчанию этого макроса.

С http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_17.html#SEC214

6 голосов

-Wframe-larger-than

Предупреждение генерируется -Wframe-larger-than. man gcc из GCC 7 говорит:

Предупреждать, если размер функционального кадра больше, чем длина байта. Вычисления, сделанные для определения размера кадра стека, являются приблизительными и не являются консервативными. фактические требования могут быть несколько выше, чем len, даже если вы не получили предупреждение. Кроме того, любое пространство, выделенное через "alloca", массивы переменной длины, или связанные конструкции не включены компилятором при определении того, следует ли выдавать предупреждение.

Минимальный пример

int main(void) {
    char s[1024];
    return 0;
}

и

$ gcc -std=c99 -O0 -Wframe-larger-than=1 a.c
a.c: In function ‘main’:
a.c:4:1: warning: the frame size of 1040 bytes is larger than 1 bytes [-Wframe-larger-than=]
 }
 ^
$ gcc -std=c99 -O0 -Wframe-larger-than=2048 a.c
# No warning.

Почему это существует

Операционные системы должны ограничивать размер стека, иначе он будет расти, пока не достигнет кучи / mmap s, и все будет непредсказуемо сломаться.

Linux отправляет сигнал, если программа пытается выйти за пределы этого максимального размера стека.

-Wframe-larger-than= - это способ предотвратить переполнение стека, сохраняя локальные переменные функции (которые помещаются в стек) небольшими.

Однако нет гарантии времени компиляции, поскольку проблема, вероятно, возникает при вызове рекурсивных функций, и все сводится к тому, сколько раз она повторяется.

Решение состоит в том, чтобы выделить память с malloc вместо использования больших массивов в качестве локальных переменных. Это заканчивается использованием mmap памяти.

Ключевое различие между стеком и malloc памятью состоит в том, что стек должен быть смежным, что просто приводит к большой эффективности упаковки памяти, тогда как malloc требует сложной эвристики. Смотри также:

...