获取win7当前使用的堆栈大小

Posted

技术标签:

【中文标题】获取win7当前使用的堆栈大小【英文标题】:Get current used stack size for win7 【发布时间】:2018-09-19 10:12:55 【问题描述】:

是否有用于 GetCurrentThreadStackLimits 的 windows7 函数,它似乎仅适用于 windows >= 8 ? [1] 和 - 如果不是 - 我如何在 win 7 上获得这些信息?

我需要找到当前线程使用的堆栈大小。 (usedstacksize != maximumstacksize)

谢谢!

PS:这是用于诊断目的。我们需要找到为 stm32 应用程序保留的堆栈大小,我只是想让 pc 模拟也能工作。

[1]:调用函数时程序编译,但在运行时会弹出一个消息框,提示“在 kernel32.dll 中找不到函数入口点”文档指出此函数需要 windows8: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadstacklimits

【问题讨论】:

这个问题有点不清楚,至少对我来说。如果你在win7中检查进程的堆栈大小@RbMm回答了它。如果你想写一个模拟器,为什么不创建一个大堆栈(比如说 2MB 或更大),并创建某种页面保护来检测堆栈溢出,如果你确实达到堆栈限制,要么静态地使其更大或动态执行(它会影响性能,但这是您对堆栈实现的选择)。 为了找到 stm32 上的最大堆栈大小,您必须计算 stm32 应用程序调用的最大嵌套函数数。如果计算中存在,则必须添加中断的函数调用(如计时器\看门狗)。 【参考方案1】:

我需要找到当前线程使用的堆栈大小。 (使用堆栈大小!= 最大堆栈大小)

在这种情况下,GetCurrentThreadStackLimits 对您来说是错误的函数,因为它返回 已分配 堆栈大小。所以 maximumstacksize 可能的堆栈大小。但通常大多数内存是保留的,但没有分配。如果你想准确使用堆栈大小 - 你需要从NT_TIB 阅读它

void GetCurrentThreadUsedStackLimits(PULONG_PTR LowLimit,  PULONG_PTR HighLimit )

    NT_TIB* tib = (NT_TIB*)NtCurrentTeb();
    *HighLimit = (ULONG_PTR)tib->StackBase;
    *LowLimit = (ULONG_PTR)tib->StackLimit;

HighLimit 将与返回 GetCurrentThreadStackLimits 相同,但 LowLimit 通常会有所不同 - GetCurrentThreadStackLimits 返回堆栈的分配基数(因此可能是最大大小,当 NT_TIB.StackLimit 当前分配堆栈时限制(可以向下增长)


如果您想实现GetCurrentThreadStackLimits 的功能(但请注意 - 它不会返回 最大 堆栈大小。您可以执行以下操作:

ULONG GetCurrentThreadStackLimits_old( _Out_ PULONG_PTR LowLimit, _Out_ PULONG_PTR HighLimit )

    static void (WINAPI* GetCurrentThreadStackLimits)(PULONG_PTR , PULONG_PTR);

    if (!GetCurrentThreadStackLimits)
    
        *(void**)&GetCurrentThreadStackLimits = GetProcAddress(GetModuleHandle(L"kernel32"), "GetCurrentThreadStackLimits");

        if (!GetCurrentThreadStackLimits)
        
            NT_TIB* tib = (NT_TIB*)NtCurrentTeb();
            *HighLimit = (ULONG_PTR)tib->StackBase;

            MEMORY_BASIC_INFORMATION mbi;
            if (VirtualQuery(tib->StackLimit, &mbi, sizeof(mbi)))
            
                *LowLimit = (ULONG_PTR)mbi.AllocationBase;
                return 0;
            

            return GetLastError();
        
    

    GetCurrentThreadStackLimits(LowLimit, HighLimit);
    return 0;

所以我们首先尝试从"kernel32" 获取GetCurrentThreadStackLimits 的地址。可能并在此处使用"api-ms-win-core-processthreads-l1-1-1" 而不是"kernel32"。如果我们得到系统提供的函数指针 - 使用它。 if no (win7 -) - 自己查询这个限制


【讨论】:

代码应该在STM32 架构上运行。这个提议的答案不承认这一点。 @IInspectable - 这与stm32 有什么关系?主要是我的代码有什么问题?具体什么不正确? @IInspectable: 该应用是为stm设计的,但我说的是在win32上运行的应用的pc模拟...... @charly_b - 我如何理解您需要 Windows 通用代码。我粘贴它 - 这将适用于每个窗口和平台。 @cha: “我只是想让电脑模拟也能工作” - 这不像你只是希望它运行在 PC 上。【参考方案2】:

我发现了一个非常简单的“快速而肮脏”的解决方案。 (这很明显)

它只是在函数中声明一个局部变量并获取该变量的地址:

uint GetCurrentStackAdress()

  uint aDummy;
  return reinterpret_cast<uint>(&aDummy);

我猜这应该适用于大多数系统,并且出于我的诊断目的,它已经够脏了 ;-)。

【讨论】:

如果这符合 OP 的要求,为什么要投反对票?如果您想投反对票,请对 问题 投反对票,因为它不够清晰。此外,此代码不适用于 64 位应用程序 - 返回 INT_PTR 或类似的。

以上是关于获取win7当前使用的堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

如何找出堆栈的开始和结束的地址?

如何在颤动中获取堆栈内容器的固有大小

如何在 Java 中获取当前堆栈跟踪?

如何在 Java 中获取当前堆栈跟踪?

如何知道.exe程序的堆栈大小限制?

获取对当前堆栈上的视图控制器的引用