简体   繁体   English

使用C ++,如何在msvc X64中获取堆栈指针的值

[英]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? 使用C ++,在X64上的msvc ++中,获取堆栈指针或对堆栈指针的最大值进行粗略估计的最快方法是什么?

I'm going to use it to write this INLINE function: 我将使用它来编写此INLINE函数:

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. 64位堆栈似乎是一个相对较低的虚拟地址。 Our allocator uses a predefined virtual base address (16GB right now). 我们的分配器使用预定义的虚拟基地址(现在为16GB)。 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. 该方法可能会意外地假设使用malloc或:: new分配的任何东西都在堆栈上,这不会是世界末日,因为我们不应该使用它们。 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). 编辑我应该补充一点,我们不使用std库(部分是因为代码太旧了,部分是因为我们的应用程序处于极端情况并且性能如此重要)。 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. 我们的代码都是64位。 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. 我们使用的是Microsoft Visual Studio 2013,即vc ++2012。我们在服务器2008上运行。有一天我们将升级到服务器2012,而在Visual Studio 2015发布时将升级到服务器。

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. 然后,我很难找到有关在Windows上运行的vc ++应用程序的常规内存布局(堆栈在哪里,堆栈在哪里等)的文档。

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". 首先,“知道是否需要释放”应该用std::shared_ptrstd::unique_ptr ,而不是通过“检查它是否在堆栈中”来解决。 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. std::vector中间释放几乎是一件非常糟糕的事情-但我保证地址不在堆栈中。

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). 至于“堆栈位于何处”则完全基于运行时环境(OS和编译器的组合等)。 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). 当然,线程堆栈的位置还完全取决于提供线程(以及堆栈分配)的OS和运行时库。

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. 但是,它并不能保证每次甚至在大多数时间都能正常工作-根据实际的操作系统和编译器选择,结果可能会有很大的不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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