📜  打印堆栈 c++ (1)

📅  最后修改于: 2023-12-03 15:10:01.870000             🧑  作者: Mango

打印堆栈 C++

在编写C++程序时,了解当前执行路径的堆栈信息是非常有用的。在调试程序时,我们经常需要查看函数调用堆栈信息。

本篇文章将介绍如何在C++代码中打印出堆栈信息。

解决方案

我们可以使用标准C++库中的<execinfo.h>头文件中提供的函数来实现打印堆栈信息的功能。

以下是一个简单的实现:

#include <iostream>
#include <execinfo.h>

#define MAX_BACKTRACE_DEPTH 50

void printStackTrace() {
    void* buffer[MAX_BACKTRACE_DEPTH];
    int num_stack_frames = backtrace(buffer, MAX_BACKTRACE_DEPTH);
    char** stack_frames = backtrace_symbols(buffer, num_stack_frames);

    for (int i = 0; i < num_stack_frames; ++i) {
        std::cout << stack_frames[i] << std::endl;
    }

    free(stack_frames);
}

在上面的代码中,我们使用了backtrace()backtrace_symbols()函数来获取堆栈信息。首先,我们定义了一个指针数组buffer来保存堆栈帧的地址。接着,我们调用backtrace()函数来获取当前调用堆栈帧的地址列表,并将它们存储在buffer数组中。我们还定义了一个名为MAX_BACKTRACE_DEPTH的常量来限制堆栈帧的数量。

接下来,我们调用backtrace_symbols()函数将地址转换为可读字符串数组stack_frames。最后,我们遍历stack_frames并打印每个堆栈帧的字符串表示形式。

使用示例

以下是一个使用示例:

void func3() {
    printStackTrace();
}

void func2() {
    func3();
}

void func1() {
    func2();
}

int main() {
    func1();
    return 0;
}

在上面的示例中,我们定义了三个函数func1()func2()func3(),它们各自调用下一个函数。在最后,我们在main()函数中调用func1()

当运行程序时,它将打印以反向顺序列出的函数调用堆栈帧的列表。我们可以看到,打印出了每个函数的名称和偏移地址:

./backtrace-example(printStackTrace+0x28) [0x5628f3c3ac9e]
./backtrace-example(func3()+0x9) [0x5628f3c3ace5]
./backtrace-example(func2()+0x9) [0x5628f3c3ad30]
./backtrace-example(func1()+0x9) [0x5628f3c3ad7b]
./backtrace-example(main+0xf) [0x5628f3c3ad9e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1) [0x7fd35c13b1c1]
./backtrace-example(_start+0x2a) [0x5628f3c3aa2a]

如上所述,我们通过这种方式可以在程序运行时打印出当前调用堆栈的信息,而无需依赖外部的调试工具。

总结:本篇文章我们介绍了如何使用标准C++库中的<execinfo.h>头文件中提供的函数来实现打印堆栈信息的功能,并提供了一个简单的示例,希望能够帮助到大家。