Как узнать размер стека c
Перейти к содержимому

Как узнать размер стека c

Получить размер стека и установить размер стека атрибута потока в C

,
pthread_attr_getstacksize ():
Используется для получения размера стека потоков. Атрибут stacksize дает минимальный размер стека, выделенный стеку потоков. При успешном запуске это дает 0, иначе дает любое значение.

Первый аргумент — принимает атрибут pthread.
Второй аргумент — принимает переменную и дает размер атрибута потока.

pthread_attr_setstacksize ():
Используется для установки размера стека новых потоков. Атрибут stacksize дает минимальный размер стека, выделенный стеку потоков. При успешном запуске он дает 0 в противном случае, если ошибка дает какое-либо значение.

Первый аргумент — принимает атрибут pthread.
Второй аргумент — принимает размер нового стека (в байтах)

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

// for принимает размер стека потоков

// он получает размер стека потоков и дает

// значение в переменной stksize

// выводим текущий размер стека потоков

printf ( «Current stack size — > %d\n» , stksize);

// затем устанавливаем размер стека новых потоков

// выводим новый размер стека

printf ( «New stack size-> %d\n» , stksize);

Для компиляции используйте gcc имя_программы.c -lpthread

Эта статья предоставлена Devanshu Agarwal . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Как узнать размер стека?

Можно ли из проги на С++ узнать размер стека? Просто нужно реализовать рекурсивные вычисления, и узнать насколько глубоко может зайти рекурсивная функция.

Как узнать размер стека?

Re: Как узнать размер стека?

Re: Как узнать размер стека?

Если более точно, то около min(getrlimit(RLIMIT_STACK)+getrlimit(RLIMIT_DATA), getrlimit(RLIMIT_AS)).

Реально чуть меньше, т.к. часть памяти уже занята.

Re: Re: Как узнать размер стека?

Правда, для нитевого стека это всё не годится.
В этом случае можно поковырять как-нибудь так:

register unsigned long esp asm("esp");
И далее ковырять /proc/self/maps на предмет размера карты.

Правда, это не переносимо 🙁

Может кто-нибудь получше что предложит в этом случае .

Re: Re: Re: Как узнать размер стека?

Хотя вот для POSIX Threads есть pthread_attr_getstacksize/pthread_attr_setstacksize.

По-моему, эти pthread_attr_getstacksize/setstacksize возвращают не совсем то. Как узнать attr для треда?

Для библиотеки GNU C: #include <sys/resource.h>

Размер общей памяти, использованной текущим процессом под стек
находится в элементе long ru_isrss структуры rusage,
заполняемой ф-ей int getrusage(int who, struct rusage* res);
где who = RUSAGE_SELF

Мягкий/жесткий предел размера стека
находится в элементе rlim_t rlim_cur/rlim_max структуры rlimit,
заполняемой ф-ей int getrlimit(int what, struct rlimit* res);
где what = RLIMIT_STACK

Re: Re:

>По-моему, эти pthread_attr_getstacksize/setstacksize возвращают не совсем то. Как узнать attr для треда? Почему не то? По-моему как раз то.

Атрибут для нити ты сам создаешь pthread_attr_init (post factum не знаю). После этого ты можешь вытянуть либо default stack size через getstacksize или установить свой через setstacksize.

Проверка доступного размера стека в C

Я использую MinGW с GCC 3.4.5 (mingw-special vista r3).

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

Если нет, то какими еще способами вы могли бы обойти проблему потенциальной нехватки места в стеке?

Я понятия не имею, с какого размера стека я начну, поэтому мне нужно будет определить это также программно.

9 ответов

У Раймонда Чена (The Old New Thing) есть хороший ответ на такой вопрос:

Если вам нужно спросить, вы, вероятно, делаете что-то не так.

Вот некоторые подробности Win32 о распределении стека: MSDN.

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

Что именно ты пытаешься сделать?

Функция getrusage дает вам текущее использование. (см. man getrusage ).

getrlimit в Linux поможет получить размер стека с помощью параметра RLIMIT_STACK .

Взгляните на man getrlimit . Эту же информацию можно получить из строки размера стека ulimit -s или ulimit -a . Также обратите внимание на функцию setrlimit , которая позволяет устанавливать ограничения. Но, как упоминалось в других ответах, если вам нужно настроить стек, возможно, вам следует пересмотреть свой дизайн. Если вам нужен большой массив, почему бы не взять память из кучи?

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

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

Проверьте, поддерживает ли ваш компилятор stackavail ()

Предполагая, что вы знаете размер полного стека, вы, вероятно, могли бы добавить какой-нибудь ассемблерный код для чтения ESP.
Если вы прочитаете ESP и сохраните его в стороне в основной функции, вы можете сравнить текущий ESP с ESP, который у вас есть в main, и увидеть, насколько изменился ESP. Это даст вам представление о том, сколько стека вы используете.

Это проблема, от которой я отказался. При помощи множества взломов и (в основном) молитв вы можете получить решение, которое будет работать в данный момент на данной машине. Но в целом, похоже, нет достойного способа сделать это.

Вам нужно будет получить позицию и размер стека вне вашей программы (в Linux вы можете получить это из /proc/<pid>/maps ). В своей программе вы должны каким-то образом проверить, где вы находитесь в стеке. Использование локальных переменных возможно, но нет реальной гарантии, что они действительно находятся в стеке. Вы также можете попытаться получить значение из регистра указателя стека с помощью некоторой сборки.

Итак, теперь у вас есть местоположение стека, его размер и текущее положение, и вы предполагаете, что знаете, в каком направлении растет стек. Когда вы переходите в режим переполнения стека? Лучше не делать это ближе к концу, потому что ваша оценка (то есть адрес локальной переменной или значение из указателя стека), вероятно, слишком оптимистична; не редкость адресация памяти за пределами указателя стека. Кроме того, вы не имеете ни малейшего представления о том, сколько места в стеке требуется той или иной функции (и функциям, которые она вызывает). Так что в конце вам придется оставить немного места.

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

Возможно, это поможет только для платформы Windows:

В заголовке PE (IMAGE_NT_HEADERS) вашего exe есть такие записи, как:

Есть простой способ получить эти значения: использование GetModuleHandle (NULL) предоставит вам базу изображений (дескриптор) вашего модуля, адрес, по которому вы найдете структуру IMAGE_DOS_HEADER, которая поможет вам найти структуру IMAGE_NT_HEADERS (imagebase + IMAGE_DOS_HEADER. e_lfanew) -> IMAGE_NT_HEADERS, и там вы найдете эти поля: SizeOfStackReserve и SizeOfStackCommit .

Максимальный объем пространства, который ОС будет выделять для вашего стека, равен SizeOfStackReserve.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *