Подтвердить что ты не робот

Что означает эта ошибка: `somefile.c: 200: ошибка: размер кадра 1032 байта больше 1024 байта`?

Во время make я вижу ошибку в строках:

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];
    ...

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

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

4b9b3361

Ответ 1

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

Ответ 2

Вот эта документация 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

Ответ 3

-Wframe-larger-than

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

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

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

main.c

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

и:

$ gcc -std=c99 -O0 -Wframe-larger-than=1 main.c
main.c: In function ‘main:
main.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 main.c
# No warning.

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

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

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

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

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

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

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