应用程序执行期间跟踪堆栈大小

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用程序执行期间跟踪堆栈大小相关的知识,希望对你有一定的参考价值。

我在嵌入式(PowerPC 32位)系统上运行应用程序,其中堆栈大小限制为64K。由于堆栈溢出,我偶尔会遇到一些崩溃。

我也可以为普通的Linux系统构建应用程序(代码中有一些小的改动),所以我可以在我的开发环境中运行仿真。

我想知道哪个是找到超出堆栈大小限制的方法的最佳方法,这是发生这种情况时的堆栈帧(为了执行一些代码重构)。

我已经尝试过Callgrind(Valgrind工具),但它似乎不是正确的工具。

我正在寻找一个工具而不是代码中的更改(因为它是一个200K LOC和100个文件项目)。

该应用程序完全用C ++ 03编写。

答案

虽然似乎应该有一个现有的工具,我会通过编写一个小宏并将其添加到可疑功能的顶部来接近它:

char *__stack_root__;

#define GUARD_SIZE (64 * 1024 - 1024)

#define STACK_ROOT 
    char __stack_frame__; 
    __stack_root__ = &__stack_frame__;

#define STACK_GUARD 
    char __stack_frame__; 
    if (abs(&__stack_frame__ - __stack_root__) > GUARD_SIZE) { 
        printf("stack is about to overflow in %s: at %d bytes
", __FUNCTION__, abs(&__stack_frame__ - __stack_root__)); 
    }

在这里如何使用它:

#include <stdio.h>
#include <stdlib.h>

void foo(int);

int main(int argc, char** argv) {
    STACK_ROOT;                    // this macro records the top of the bottom of the thread's stack
    foo(10000);
    return 0;
}

void foo(int x) {
    STACK_GUARD;                   // this macro checks if we're approaching the end of memory available for stack
    if (x > 0) {
        foo(x - 1);
    }
}

这里有几个笔记:

  • 此代码假定为单线程。如果你有多个线程,你需要跟踪每个线程一个__stack_frame__变量。为此使用线程本地存储
  • 使用abs()确保宏在PowerPC增加堆叠时都能正常工作(以及它可以:取决于你的设置)
  • 根据自己的喜好调整GUARD_SIZE,但要保持小于目标堆栈的最大大小

以上是关于应用程序执行期间跟踪堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

从堆栈跟踪中查找共享库中的源代码行

jstack简介

LinuxBPF学习笔记 - 堆栈跟踪[3]

LinuxBPF学习笔记 - 堆栈跟踪[3]

进程和线程和协程之间的关系

如何收集功能模块执行的详细堆栈跟踪?