I'm programming in C in Visual Studio 2005. I have a multi-threaded program, but that's not especially important here.
How can I determine (approximately) how much stack space my threads use?
The technique I was planning to use is setting the stack memory to some predetermined value, say 0xDEADBEEF, running the program for a long time, pausing the program, and investigating the stack.
How do I read and write stack memory with Visual Studio?
EDIT: See, for example, "How to determine maximum stack usage." That question talks about an embedded system, but here I'm trying to determine the answer on a regular PC.
The stack doesn't work the way you expect it too. The stack is a linear sequence of pages, the last (top) one of which is marked with a page guard bit. When this page is touched, the guard bit is removed, and the page can be used. For further growth, a new guard page is allocated.
Hence, the answer you want is where the gaurd page is allocated. But the technique you propose would touch the page in question, and as a result it would invalidate the very thing you're trying to measure.
The non-invasive way to determine if a (stack) page has the guard bit is via
VirtualQuery()
.You can make use of information in the Win32 Thread Information Block
When you want in a thread to find out how much stack space it uses you can do something like this:
Windows does not commit the stack memory immediately; instead, it reserves the address space for it, and commits it page-by-page when it is accessed. Read this page for more info.
As a result, stack address space consists of three contiguous regions:
This allows us to construct a function that obtains stack size (with page size granularity):
One thing to consider:
CreateThread
allows to specify initial stack commit size (viadwStackSize
parameter, whenSTACK_SIZE_PARAM_IS_A_RESERVATION
flag is not set). If this parameter is nonzero, our function will return correct value only when stack usage becomes greater thandwStackSize
value.You can use GetThreadContext() function to determine thread's current stack pointer. Then use VirtualQuery() to find stack base for this pointer. Substracting those two pointers will give you stack size for given thread.