简体   繁体   中英

Using c++, how do I get the value of the stack pointer in msvc X64

Using c++, what is the fastest way to get either the stack pointer or a rough estimate of the maximum value of the stack pointer in msvc++ on X64?

I'm going to use it to write this INLINE function:

static __forceinline bool IsOnStack(const void *p) {
    return UINT_PTR(p) < __ESP;
}

I could use it as a macro if that is better

#define ISONSTACK(a)

thanks!

EDIT

I need to know if something is on the stack so other code won't free it. Suffice it to say its a legacy implementation of smart pointers that I am making faster. All I have to work with is the address of the object the smart pointer is referring to. I am making a change so a smart pointer can refer to an item on the stack, which will eliminate superflous heap allocations. The 64 bit stack appears to be a relatively low virtual address. Our allocator uses a predefined virtual base address (16GB right now). I could just assume anything below that is on the stack. This method might accidentally assume anything allocated with malloc or ::new was on the stack, which wouldn't be the end of the world, since we aren't supposed to ever use those. I thought I'd see if there was a better way to get an idea where the stack was. Performance is more important than accuracy as long as we don't get false negatives.

EDIT

I know we are currently only assigning smart pointers to allocated memory because we only use 2 ways to set smart pointers:

new(spFoo) CFoo();  // uses an overridden new to do this

or

spFoo = spOtherFoo;  

I am thinking of adding:

CFoo Foo();
spFoo = &Foo;

EDIT I should add that we do not use std libraries (partly because the code is so old and partly because our application is an edge case and performance is so important). I don't want to make this a debate about standard libraries, which we all agree are awesome. I don't have that with this application. Our code only runs on internal servers. Our code is all 64 bit. Sometimes we use threads, but that is rare. Portability is not an issue. We use microsoft visual studio 2013, which is vc++ 2012. We run on server 2008. We will be upgrading to server 2012 some day, and visual studio 2015 when it comes out.

This started out with the usual gripe about inline assembly not being available. Then I was having a hard time finding documentation about the general memory layout (where the stack goes, where the heap goes, etc) of a vc++ app running on windows.

Ok, so this will get longer than a "comments" worth.

First of all "knowing if you need to free or not" should probably be solved with std::shared_ptr or std::unique_ptr , not by "checking if it's on the stack or not". What about:

void Function(int *p)
{
    if (!isOnStack(p)) delete p;
}


std::vector<int> v;

... fill stuff into v ... 
Function(&v[14]); 

Freeing in the middle of the std::vector is almost certainly a very bad thing - but I guarantee the address is not on the stack.

static int x;
Function(&x); 

no better there - it will also cause bad free.

As to "where the stack is located" is entirely based on the runtime environment (combination of OS and compiler, etc). It may be a high address. It may be a high address in the "main" thread, and a lower address in a secondary thread - but you don't REALLY want this to only work in the "main" thread, do you?

The location of thread's stacks is of course ALSO entirely dependent on the OS and runtime library that provides the thread (and the stack allocation).

You MAY be able to do something like:

uintptr_t sp_base;

bool isInStack(void *p)
{
    int x;
    uintptr_t sp_top = (uintptr_t)(&x);
    // Assumes stack grows towards 0.
    return (p > sp_top) && (p < sp_base);
}

int main()
{
    int x;
    sp_base = (uintptr_t)(&x); 
    ... 
}

But it far from guaranteed to work every time, or even most of the time - depending on the actual OS and compiler choice, the result may vary quite wildly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM