Оценка размера стека потока - PullRequest
0 голосов
/ 10 ноября 2011

Пытаюсь угадать, сколько стека выделить для каждого потока. Найденные подсказки, которые предполагают, что программа должна набросать известный образец (например: 0xEF) в памяти, чтобы получить верхние / нижние границы стека.

Может ли кто-нибудь предоставить быструю программу на С для этого? Это действительно путь? Любые другие предложения?

Спасибо за помощь в этом сомнении.

Ответы [ 2 ]

1 голос
/ 11 ноября 2011

Если у вас есть полный контроль над вашей программой (кодом), бессмысленно пытаться найти размер, потому что you будет тем, кто говорит ОС выделять конкретную величину размера стека, когда вы ' Создайте поток, используя CreateThread или pthread_create. Однако, если вы этого не сделаете, в зависимости от вашей ОС, вы можете либо вызвать pthread_attr_getstack (в Unix) или VirtualQuery (в Windows), выделить переменную на основе стека и вычислить расстояние между базовым адресом стек и позиция вашей переменной.

0 голосов
/ 11 ноября 2011

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

Чтобы прочитать значение указателя стека, вы можете:

  • Реализовать функцию сборки(делает mov r/eax, r/esp + ret для процессора x86)
  • Сделайте то же самое (без повторов, конечно), используя встроенную сборку, если поддерживается вашим компилятором
  • Реализуйте что-то вродениже (который может работать не всегда / везде из-за оптимизации кода)

Код:

#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

// uintptr_t is an unsigned integer type from stdint.h
// that is capable of holding a pointer.
// If you don't have it in your compiler, use an
// equivalent, which may be size_t (stddef.h) or
// UINT_PTR (windows.h) or something else.
uintptr_t StackPointerMin = (uintptr_t)-1;
uintptr_t StackPointerMax = 0;

void UpdateStackUsageInner(int dummy, ...)
{
  va_list ap;
  volatile char* p;
  uintptr_t StackPointer;

  va_start(ap, dummy);
  p = va_arg(ap, volatile char*);
  StackPointer = (uintptr_t)p;

  if (StackPointer < StackPointerMin) StackPointerMin = StackPointer;
  if (StackPointer > StackPointerMax) StackPointerMax = StackPointer;

  va_end(ap);
}

void UpdateStackUsage()
{
  volatile char c = 'a';
  UpdateStackUsageInner(0, &c);
}

void DoSomething(void)
{
  char c[1024+1];
  UpdateStackUsage();
  memset(c, '*', sizeof(c));
  c[sizeof(c)-1] = '\0';
  printf("%s\n", c);
}

int main(void)
{
  UpdateStackUsage();
  DoSomething();
  printf("Approximate stack usage: %lu\n",
         (unsigned long)(StackPointerMax - StackPointerMin));
  return 0;
}

Вывод:

********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
****************************************************************
Approximate stack usage: 1040

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

...