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

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

Это труднее обнаружить, так как он не указан в трассировке, и ошибка не возникает в конкретной модели, которая использует такое настраиваемое поле.

Но попробуйте добавить auto_now_add=True в поле Time в вашей модели

.
33
задан Paul Hargreaves 10 September 2008 в 12:15
поделиться

7 ответов

У Raymond Chen ( Старая Новая Вещь ) есть хороший ответ на этот вид вопроса:

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

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

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

, Что точно Вы пытаетесь сделать?

6
ответ дан 27 November 2019 в 18:11
поделиться

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

size_t top_of_stack;

void Main()
{
  int x=0;
  top_of_stack = (size_t) &x;

  do_something_very_recursive(....)
}

size_t SizeOfStack()
{
  int x=0;
  return top_of_stack - (size_t) &x;
} 

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

14
ответ дан 27 November 2019 в 18:11
поделиться

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

9
ответ дан 27 November 2019 в 18:11
поделиться

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

3
ответ дан 27 November 2019 в 18:11
поделиться

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

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


typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_OPTIONAL_HEADER {
    ...
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    ...
}

существует простой способ получить эти значения: использование GetModuleHandle (ПУСТОЙ УКАЗАТЕЛЬ) даст Вам imagebase (дескриптор) Вашего модуля, адрес, где Вы найдете структуру IMAGE_DOS_HEADER, которая поможет Вам найти структуру IMAGE_NT_HEADERS (imagebase+IMAGE_DOS_HEADER.e_lfanew)-> IMAGE_NT_HEADERS и там Вы найдете те поля: SizeOfStackReserve и SizeOfStackCommit.

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

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

2
ответ дан 27 November 2019 в 18:11
поделиться

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

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

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

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

3
ответ дан 27 November 2019 в 18:11
поделиться

На Linux Вы назвали бы getrusage и проверили бы ru_isrss участника rusage возвращенной структуры (интегральный неразделенный размер стека).

От сайта MINGW и его отслеживания сайта SourceForge патчей, я вижу, что в мае 2008 было некоторое исправление, сделанное вокруг getrusage, и похоже, что это обычно поддерживалось долгое время. Необходимо проверить тщательно на любые протесты с точки зрения того, сколько из типичной функциональности Linux поддерживается MinGW.

2
ответ дан 27 November 2019 в 18:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: