Существует API-нитей, чтобы определить, где находится стек:
#include <pthread.h>
void PrintStackInfo (void)
{ pthread_attr_t Attributes;
void *StackAddress;
int StackSize;
// Get the pthread attributes
memset (&Attributes, 0, sizeof (Attributes));
pthread_getattr_np (pthread_self(), &Attributes);
// From the attributes, get the stack info
pthread_attr_getstack (&Attributes, &StackAddress, &StackSize);
// Done with the attributes
pthread_attr_destroy (&Attributes);
printf ("Stack top: %p\n", StackAddress);
printf ("Stack size: %u bytes\n", StackSize);
printf ("Stack bottom: %p\n", StackAddress + StackSize);
}
На i386, стек начинается в нижней части и растет по направлению к вершине.
Итак, вы знаете, что у вас есть ($ ESP - StackAddress) байты.
В моей системе у меня есть обертка вокруг pthread_create(), поэтому каждый поток начинается с моей частной функции. В этой функции я нахожу стек, как описано выше, затем нахожу неиспользованную часть, затем инициализирую эту память с помощью отличительного шаблона (или «Паттона», как сказал бы мой тесть Сомервилл, родившийся в Массачусетском море).
Затем, когда я хочу знать, сколько из стека было использовано, я начинаю вверху и выполняю поиск в нижней части для первого значения, которое не соответствует моему шаблону.
Что относительно сегмента кучи? Я слышал, что сегменты стека и кучи растут напротив друг друга? Будет ли это влиять на эффективный размер стека? Поправьте меня, если я ошибаюсь. –
для вашей проблемы вы можете относиться к ней как к ортогональному .. свободный магазин или куча - это не пространство стека, а «растущая противоположность» - не лучший способ подумать об этом. в точке распределения кучи (новые типы) размер стека, вероятно, будет кратковременно/временно затронут, но это не проблема, с которой вы сталкиваетесь. –
Это не так просто, как «они растут напротив друг друга» , glibc может просто использовать mmap() для запроса дополнительной области виртуальной памяти, и теоретически может жить в любом месте в адресном пространстве виртуальной памяти, поэтому malloc() не обязательно будет использовать пространство, которое будет использоваться стеком. Метод выделения, используемый glibc для malloc(), может варьироваться в зависимости от многих факторов (например, он может использовать sbrk(), или он может использовать mmap()). – ehabkost