估计线程堆栈大小

发布于 2024-12-14 22:59:23 字数 154 浏览 4 评论 0原文

我试图猜测在每个线程的基础上分配多少堆栈。 发现提示建议程序应在内存中写入已知模式(例如:0xEF),以获取堆栈的上限/下限。

有人可以提供快速的 C 程序来做到这一点吗?这真的是要走的路吗? 还有其他建议吗?

感谢您协助解决这个疑问。

Am trying to guess-timate how much stack to allocate on per thread basis.
Found hints that suggest program should scribble a known pattern (ex: 0xEF) in memory, to get upper/lower bounds of stack.

Can someone provide quick C program to do so? Is this truly the way to go?
Any other suggestions?

Thank you for assisting with this doubt.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深陷 2024-12-21 22:59:23

如果您完全控制您的程序(代码),那么尝试找到大小是无意义的,因为将是在您创建时告诉操作系统分配特定数量的堆栈大小的人使用 CreateThreadpthread_create 的线程。但是,如果您不这样做,根据您的操作系统,您可以调用 pthread_attr_getstack(在 unix 上)或 VirtualQuery(在 Windows 上),分配基于堆栈的变量,并计算堆栈基地址和变量位置之间的距离。

If you have complete control of your program( code ), it's a nonsense trying to find the size because you would be the one who's telling the OS to allocate the specific amount of stack size when you're creating a thread using CreateThread or pthread_create. However, if you don't, depending on your OS, you can either call pthread_attr_getstack (on unix) or VirtualQuery(on Windows), allocate a stack-based variable, and calculate the distance between the base address of the stack and the position of your variable.

上课铃就是安魂曲 2024-12-21 22:59:23

估计堆栈使用情况的另一种方法是读取每个函数中的堆栈指针值并更新最小和最大堆栈指针变量。在程序结束时,两个值之间的差异将为您提供估计值。

为了读取堆栈指针的值,您可以:

  • 实现汇编函数(对于 x86 CPU 执行 mov r/eax, r/esp + ret
  • )相同(当然,没有 ret),如果您的编译器支持,则使用内联汇编
  • 实现类似下面的内容(由于代码优化,这可能无法始终/在任何地方工作)

代码:

#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

// uintptr_t is an unsigned integer type from stdint.h
// that is capable of holding a pointer.
// If you don't have it in your compiler, use an
// equivalent, which may be size_t (stddef.h) or
// UINT_PTR (windows.h) or something else.
uintptr_t StackPointerMin = (uintptr_t)-1;
uintptr_t StackPointerMax = 0;

void UpdateStackUsageInner(int dummy, ...)
{
  va_list ap;
  volatile char* p;
  uintptr_t StackPointer;

  va_start(ap, dummy);
  p = va_arg(ap, volatile char*);
  StackPointer = (uintptr_t)p;

  if (StackPointer < StackPointerMin) StackPointerMin = StackPointer;
  if (StackPointer > StackPointerMax) StackPointerMax = StackPointer;

  va_end(ap);
}

void UpdateStackUsage()
{
  volatile char c = 'a';
  UpdateStackUsageInner(0, &c);
}

void DoSomething(void)
{
  char c[1024+1];
  UpdateStackUsage();
  memset(c, '*', sizeof(c));
  c[sizeof(c)-1] = '\0';
  printf("%s\n", c);
}

int main(void)
{
  UpdateStackUsage();
  DoSomething();
  printf("Approximate stack usage: %lu\n",
         (unsigned long)(StackPointerMax - StackPointerMin));
  return 0;
}

输出:

********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
****************************************************************
Approximate stack usage: 1040

我也知道某些编译器支持挂钩函数入口(并且可能退出),这可以简化任务,因为这样您就不需要将 UpdateStackUsage(); 插入到所有/许多函数中。 此处对此进行了讨论。

An alternative way to get an estimate of the stack usage is to read the stack pointer value in every function and update the minimum and maximum stack pointer variables. At the end of the program the difference between the two values will give you the estimate.

In order to read the value of the stack pointer you can:

  • Implement an assembly function (doing mov r/eax, r/esp + ret for the x86 CPU)
  • Do the same (w/o ret, of course) using inline assembly if supported by your compiler
  • Implement something like the below (which may not work always/everywhere due to code optimization)

Code:

#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

// uintptr_t is an unsigned integer type from stdint.h
// that is capable of holding a pointer.
// If you don't have it in your compiler, use an
// equivalent, which may be size_t (stddef.h) or
// UINT_PTR (windows.h) or something else.
uintptr_t StackPointerMin = (uintptr_t)-1;
uintptr_t StackPointerMax = 0;

void UpdateStackUsageInner(int dummy, ...)
{
  va_list ap;
  volatile char* p;
  uintptr_t StackPointer;

  va_start(ap, dummy);
  p = va_arg(ap, volatile char*);
  StackPointer = (uintptr_t)p;

  if (StackPointer < StackPointerMin) StackPointerMin = StackPointer;
  if (StackPointer > StackPointerMax) StackPointerMax = StackPointer;

  va_end(ap);
}

void UpdateStackUsage()
{
  volatile char c = 'a';
  UpdateStackUsageInner(0, &c);
}

void DoSomething(void)
{
  char c[1024+1];
  UpdateStackUsage();
  memset(c, '*', sizeof(c));
  c[sizeof(c)-1] = '\0';
  printf("%s\n", c);
}

int main(void)
{
  UpdateStackUsage();
  DoSomething();
  printf("Approximate stack usage: %lu\n",
         (unsigned long)(StackPointerMax - StackPointerMin));
  return 0;
}

Output:

********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
****************************************************************
Approximate stack usage: 1040

I also know that some compilers support hooking function entry (and probably exit), which can simplify the task because with that you won't need to insert UpdateStackUsage(); into all/many of your functions. That's been discussed here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文