测量Linux多线程应用程序的堆栈使用情况

时间:2021-11-21 00:33:46

I'm developing a multi-threaded app for a Linux embedded platform.

我正在为Linux嵌入式平台开发一个多线程应用程序。

At the moment I'm setting the stack size for each thread (via pthread_set_attr) to a fairly large default value. I would like to fine tune that value for each thread to something smaller to reduce my application's memory usage. I could go through the trial and error route of setting each thread's stack size to progressively smaller values until the program crashed, but the application uses ~15 threads each with completely different functionality/attributes so that approach would be extremely time consuming.

目前我正在将每个线程的堆栈大小(通过pthread_set_attr)设置为相当大的默认值。我想将每个线程的值调整为更小的值以减少应用程序的内存使用量。我可以通过试验和错误路径将每个线程的堆栈大小设置为逐渐变小的值,直到程序崩溃,但应用程序使用~15个线程,每个线程具有完全不同的功能/属性,因此这种方法非常耗时。

I would much rather prefer being able to directly measure each thread's stack usage. Is there some utility people can recommend to do this? (For example, I come from a vxWorks background and using the 'ti' command from the vxWorks shell directly gives stats on the stack usage as well as other useful info on the task status.)

我更愿意能够直接测量每个线程的堆栈使用情况。是否有人可以推荐这样做的实用程序? (例如,我来自vxWorks背景,并使用vxWorks shell中的'ti'命令直接给出有关堆栈使用情况的统计信息以及有关任务状态的其他有用信息。)

Thanks

3 个解决方案

#1


3  

I do not know any good tools but as last resort you could include some code in your application to check it, similar to the following:

我不知道任何好工具,但作为最后的手段,您可以在应用程序中包含一些代码来检查它,类似于以下内容:

__thread void* stack_start;
__thread long stack_max_size = 0L;

void check_stack_size() {
  // address of 'nowhere' approximates end of stack
  char nowhere;
  void* stack_end = (void*)&nowhere;
  // may want to double check stack grows downward on your platform
  long stack_size = (long)stack_start - (long)stack_end;
  // update max_stack_size for this thread
  if (stack_size > stack_max_size)
    stack_max_size = stack_size;
}

The check_stack_size() function would have to be called in some of the functions that are most deeply nested.

必须在一些嵌套最深的函数中调用check_stack_size()函数。

Then as last statement in the thread you could output stack_max_size to somewhere.

然后作为线程中的最后一个语句,您可以将stack_max_size输出到某个地方。

The stack_start variable would have to be initialized at start of your thread:

必须在线程开始时初始化stack_start变量:

void thread_proc() {
  char nowhere;
  stack_start = (void*)&nowhere;
  // do stuff including calls to check_stack_size()
  // in deeply nested functions
  // output stack_max_size here
}

#2


2  

Referencing Tobi's answer: You can use pthread_attr_getstackaddr to get the base of the stack at any time, if setting a variable at thread initialization is difficult. You can then get the address of an automatic variable in your own function to determine how deep the stack is at that moment.

引用Tobi的答案:如果在线程初始化时设置变量很困难,可以随时使用pthread_attr_getstackaddr来获取堆栈的基础。然后,您可以在自己的函数中获取自动变量的地址,以确定此时堆栈的深度。

#3


2  

Here are two tools that measure (native pthreads) stack usage in Linux applications:

以下是在Linux应用程序中测量(本机pthreads)堆栈使用情况的两个工具:

Valgrind

Usage:

valgrind --tool=drd --show-stack-usage=yes PROG

Valgrind is a stable and powerful tool, useful not only for measuring stack usage. It may not support all embedded CPU models though.

Valgrind是一款稳定而强大的工具,不仅可用于测量堆栈使用情况。但它可能不支持所有嵌入式CPU型号。

Stackusage

Usage:

stackusage PROG

Stackusage is a light-weight tool specifically designed for measuring thread stack usage which should be portable for most embedded Linux platforms equipped with glibc. It is likely not as well-tested or mature as Valgrind/drd at this point.

Stackusage是一款专为测量线程堆栈使用而设计的轻量级工具,对于大多数配备glibc的嵌入式Linux平台而言,它应该是可移植的。在这一点上,它可能没有像Valgrind / drd那样经过充分测试或成熟。

Full disclosure: I'm the author of Stackusage.

完全披露:我是Stackusage的作者。

#1


3  

I do not know any good tools but as last resort you could include some code in your application to check it, similar to the following:

我不知道任何好工具,但作为最后的手段,您可以在应用程序中包含一些代码来检查它,类似于以下内容:

__thread void* stack_start;
__thread long stack_max_size = 0L;

void check_stack_size() {
  // address of 'nowhere' approximates end of stack
  char nowhere;
  void* stack_end = (void*)&nowhere;
  // may want to double check stack grows downward on your platform
  long stack_size = (long)stack_start - (long)stack_end;
  // update max_stack_size for this thread
  if (stack_size > stack_max_size)
    stack_max_size = stack_size;
}

The check_stack_size() function would have to be called in some of the functions that are most deeply nested.

必须在一些嵌套最深的函数中调用check_stack_size()函数。

Then as last statement in the thread you could output stack_max_size to somewhere.

然后作为线程中的最后一个语句,您可以将stack_max_size输出到某个地方。

The stack_start variable would have to be initialized at start of your thread:

必须在线程开始时初始化stack_start变量:

void thread_proc() {
  char nowhere;
  stack_start = (void*)&nowhere;
  // do stuff including calls to check_stack_size()
  // in deeply nested functions
  // output stack_max_size here
}

#2


2  

Referencing Tobi's answer: You can use pthread_attr_getstackaddr to get the base of the stack at any time, if setting a variable at thread initialization is difficult. You can then get the address of an automatic variable in your own function to determine how deep the stack is at that moment.

引用Tobi的答案:如果在线程初始化时设置变量很困难,可以随时使用pthread_attr_getstackaddr来获取堆栈的基础。然后,您可以在自己的函数中获取自动变量的地址,以确定此时堆栈的深度。

#3


2  

Here are two tools that measure (native pthreads) stack usage in Linux applications:

以下是在Linux应用程序中测量(本机pthreads)堆栈使用情况的两个工具:

Valgrind

Usage:

valgrind --tool=drd --show-stack-usage=yes PROG

Valgrind is a stable and powerful tool, useful not only for measuring stack usage. It may not support all embedded CPU models though.

Valgrind是一款稳定而强大的工具,不仅可用于测量堆栈使用情况。但它可能不支持所有嵌入式CPU型号。

Stackusage

Usage:

stackusage PROG

Stackusage is a light-weight tool specifically designed for measuring thread stack usage which should be portable for most embedded Linux platforms equipped with glibc. It is likely not as well-tested or mature as Valgrind/drd at this point.

Stackusage是一款专为测量线程堆栈使用而设计的轻量级工具,对于大多数配备glibc的嵌入式Linux平台而言,它应该是可移植的。在这一点上,它可能没有像Valgrind / drd那样经过充分测试或成熟。

Full disclosure: I'm the author of Stackusage.

完全披露:我是Stackusage的作者。