1

We all know that stack is growing downward, so it's really a straightforward assumption that if we find the address of the last declared variable, we will get out the smallest address in stack, so we could just assume that this address will be our residual available stack.

And i did it, and i got just humongous address {0x000000dc9354f540} = {947364623680} we know that stack growing downward and we know that we can't go lower than 0. so a bit of math:

947364623680 / (1024*1024*1024) = 882.302060425

--> Do they imply that i have 882Gb of stack on my machine?!

I test it and obviously get the stack overflow exception after allocating additional 2mb on stack:

uint8 array[1024*1024*2] = {};

And there my question come WTF is this, and how can i get my actual stack size?

Mohammad Kanan
  • 4,452
  • 10
  • 23
  • 47
  • 5
    See https://stackoverflow.com/questions/22801666/memory-layout-of-stack-and-heap-in-user-space – Barmar Feb 23 '18 at 20:14
  • Also see https://stackoverflow.com/questions/1740888/determining-stack-space-with-visual-studio – user4581301 Feb 23 '18 at 20:18
  • @Barmar, this do not answer my question at all, I'm informed about what stack layout is. I don't understand why do i have such a strange pointer. – stronk_kisik Feb 23 '18 at 20:21
  • @user4581301 thx, but I was thinking about something inbox solution) – stronk_kisik Feb 23 '18 at 20:23
  • Inbox as in something like a pre-existing `GetStackSize` function? – user4581301 Feb 23 '18 at 20:25
  • @user4581301, yeah something like that, earlier when i need certain amount of stack space i just requested it directly from compiler. And i was always thinking that i can get my stack space with the way i describe in my question, or reading esp variable and this is why i was confused. – stronk_kisik Feb 23 '18 at 20:30

3 Answers3

4

Since you question has a tag "visual-studio-debugging" I assume you use windows.

First you should get the current stack pointer. Either get an address of a local dummy variable (like you did now), or by raw asm read esp/rsp, or get an address of a local dummy variable (like you did now), or get CPU register via Win32 API call to GetThreadContext).

Now, in order to find out the available stack size you may use VirtualQuery to see the starting address of this virtual memory region (aka allocation base address). Basically subtracting those pointers would give you the remaining stack size (precision up to the size of the current stack frame).

Long time ago I've written an article about this subject, including querying the currently allocated/reserved stack size. You can find out more info there if you want:

Do they imply that i have 882Gb of stack on my machine?!

It has nothing to do with the "stack on your machine". It's about virtual address space, which has nothing to do with the physical storage (RAM + page files) available in the system.

Mohammad Kanan
  • 4,452
  • 10
  • 23
  • 47
valdo
  • 12,632
  • 2
  • 37
  • 67
2

Another approach to get an approximate value of the stack space left at any given point in a win32 application would be something like the following function. It uses structured exception handling to catch the stack overflow exception.

Note: @valdo's solution is the correct solution. I'm posting this answer because it's kind of an interesting way to solve it. It's going to be very slow because it's runtime is linear (in terms of stack size), as opposed to constant runtime of @valdo's solution.

static uint64_t GetAvailableStackSpace()
{
    volatile uint8_t var;
    volatile uint8_t* addr = &var;
    volatile uint8_t sink;

    auto filter = [](unsigned int code) -> int
    {
        return (code == EXCEPTION_STACK_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
    };

    __try
    {
        while (true)
        {
            addr = addr - 1024;
            sink = *addr;
        }
    }
    __except (filter(GetExceptionCode()))
    {
        return (&var - addr);
    }

    return 0;
}
Shivanshu Goyal
  • 1,374
  • 2
  • 16
  • 22
1

This is an implementation of the VirtualQuery technique mentioned by @valdo. This function returns an approximate number of bytes of stack available. I tested this on Windows x64.

static uint64_t GetAvailableStackSpace()
{
    volatile uint8_t var;
    MEMORY_BASIC_INFORMATION mbi;

    auto virtualQuerySuccess = VirtualQuery((LPCVOID)&var, &mbi, sizeof(mbi));

    if (!virtualQuerySuccess)
    {
        return 0;
    }

    return &var - mbi.AllocationBase;
}
Shivanshu Goyal
  • 1,374
  • 2
  • 16
  • 22