My Win32 C++ application acts as an RPC server - it has a set of functions for processing requests and RPC runtime creates a separate thread and invokes one of my functions in that thread.
In my function I have an std::auto_ptr which is used to control a heap-allocated char[] array of size known at compile time. It accidentially works when compiled with VC++ but it's undefined behaviour according to C++ standard and I'd like to get rid of it.
I have two options: std::vector or a stack-allocated array. Since I have no idea why there's a heap-allocated array I would like to consider replacing it with a stack-allocated one. The array is 10k elements and I can hypothetically face a stack overflow if the RPC runtime spawns a thread with a very small stack.
I would like to detect how much stack space is typilcally allocated to the thread and how much of it is available to my function (its callees certainly consume some of allocated space). How could I do that?
You can check how much stack space you are really using by checking how far %esp is from the upper limit of the stack area on smaps (as the stack grows down).
For calculating (and therefore optimizing) the required stack memory size, the following methods may be used: • Static analysis (using call tree analysis) is performed at build time (by a linker for example). Dynamic analysis (using stack watermarking) is performed at run-time (in a debug session for example).
Stack size is 8.192MB of memory.
I don't know of any way of figuring out the stack size directly using the API if you don't have access to the CreateThread
call or, if it's the main thread, looking into the EXE's default thread size in the PE header.
In your situation, I would allocate on the heap to be safe, even though a 10K array of small data is unlikely to max out the stack in non-recursive scenarios.
However, you can probe for the stack limit, if done carefully. The stack gets committed in 4K pages as you touch them (via guard pages) until you hit the limit, whereupon Windows will throw a stack overflow exception. There is still one page of stack left when the exception gets dispatched, so that the exception dispatching logic itself (including filter functions) can execute - but Windows throws the exception because it couldn't allocate another guard page. That means that the next stack overflow, or probe, will not result in a stack overflow exception, but an access violation. So to make probing work reliably (and in particular, repeatably) you need to decommit the memory allocated by the probing and reinstate a guard page.
This article on KB describes how to decommit stack memory and reinstate the guard page. It probes using recursion and 10,000-byte increments; the compiler by default implements its own stack probing for stack allocations of locals >4KB, so that the stack growth mechanism works correctly.
In windows, the default stack size is 1MB, so you are unlikely to stack overflow with only a 10k array. That said, I think that allocating so much memory on the stack is a bad practice, and you should try to favour allocating it dynamically, if you can. There is also the Scoped Array which is well defined for automatically managing arrays - unlike the vector
class, it is non-copyable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With