我是靠谱客的博主 端庄猫咪,最近开发中收集的这篇文章主要介绍C++打印调用栈,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

C/C++打印runtime的调用栈

方案1: bombela/backward-cpp

这是在github上找到的一个很好的方案,可以实现异常捕捉以及runtime的stack展示,我做了一个更好一点的封装,只需要include头文件就可以了。
具体的链接参见这里
需要注意的是,最好在编译的时候,使用debug模式,同时需要链接到系统的dl和bfd两个库。

一个简单的例子:

step1: 安装依赖:
apt-get install binutils-dev
step2: 编译源码:
make && ./backtrace_benchmark
step3: 结果展示
Registering backtrace service successful
=========== show_stack_snapshot_at_runtime===========
Stack trace (most recent call last):
#7    Object "", at 0xffffffffffffffff, in
#6    Object "backtrace_benchmark", at 0x5568e64a38d9, in _start
#5    Source "/build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c", line 310, in __libc_start_main
#4    Source "example/backward_test.cc", line 18, in main
         15: }; // namespace
         16: int main(void)
         17: {
      >  18:     show_stack_snapshot_at_runtime();
         19:     show_exception();
         20:     return 0;
         21: }
#3    Source "example/backward_test.cc", line 8, in (anonymous namespace)::show_stack_snapshot_at_runtime()
          5:     void show_stack_snapshot_at_runtime()
          6:     {
          7:         std::cout << "=========== show_stack_snapshot_at_runtime===========" << std::endl;
      >   8:         newplan_toolkit::BackTraceService::show_stack_snapshot();
          9:     }
         10:     void show_exception()
         11:     {
#2    Source "example/../backtrace_service.h", line 23, in newplan_toolkit::BackTraceService::show_stack_snapshot()
         20:         static void show_stack_snapshot()
         21:         {
         22:             backward::StackTrace st;
      >  23:             st.load_here(128);
         24:             backward::Printer p;
         25:             p.print(st);
         26:         }
#1    Source "example/../3rd_party/backward/backward.hpp", line 869, in backward::StackTraceImpl<backward::system_tag::linux_tag>::load_here(unsigned long, void*, void*)
        866:       return 0;
        867:     }
        868:     _stacktrace.resize(depth);
      > 869:     size_t trace_cnt = details::unwind(callback(*this), depth);
        870:     _stacktrace.resize(trace_cnt);
        871:     skip_n_firsts(0);
        872:     return size();
#0    Source "example/../3rd_party/backward/backward.hpp", line 851, in unsigned long backward::details::unwind<backward::StackTraceImpl<backward::system_tag::linux_tag>::callback>(backward::StackTraceImpl<backward::system_tag::linux_tag>::callback, unsigned long)
        849: template <typename F> size_t unwind(F f, size_t depth) {
        850:   Unwinder<F> unwinder;
      > 851:   return unwinder(f, depth);
        852: }
        853:
        854: } // namespace details
===========show_exception===========
terminate called after throwing an instance of 'char const*'
Stack trace (most recent call last):
#11   Object "", at 0xffffffffffffffff, in
#10   Object "backtrace_benchmark", at 0x5568e64a38d9, in _start
#9    Source "/build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c", line 310, in __libc_start_main [0x7ff391249bf6]
#8    Source "example/backward_test.cc", line 19, in main [0x5568e64a3a7b]
         16: int main(void)
         17: {
         18:     show_stack_snapshot_at_runtime();
      >  19:     show_exception();
         20:     return 0;
         21: }
#7    Source "example/backward_test.cc", line 13, in (anonymous namespace)::show_exception() [0x5568e64a3a6a]
         10:     void show_exception()
         11:     {
         12:         std::cout << "===========show_exception===========" << std::endl;
      >  13:         newplan_toolkit::execption_test();
         14:     }
         15: }; // namespace
         16: int main(void)
#6    Source "example/../backtrace_service.h", line 73, in newplan_toolkit::execption_test(int, int) [0x5568e64a39f5]
         70:     {
         71:         if (b == 0)
         72:         {
      >  73:             throw "Division by zero condition!";
         74:         }
         75:         while (1)
         76:             a = a + 2; // normally, the process would stuck here until a signal ctrl+c
#5    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7ff3918c3d53, in __cxa_throw
#4    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7ff3918c3b20, in std::terminate()
#3    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7ff3918c3ae5, in std::rethrow_exception(std::__exception_ptr::exception_ptr)
#2    Object "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7ff3918bd956, in
#1    Source "/build/glibc-S9d2JN/glibc-2.27/stdlib/abort.c", line 79, in __GI_abort [0x7ff391268920]
#0    Source "/build/glibc-S9d2JN/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c", line 51, in __GI_raise [0x7ff391266fb7]
Aborted (Signal sent by tkill() 32001 1001)
fish: Job 1, './backtrace_benchmark' terminated by signal SIGABRT (Abort)

方案2: boost::stacktrace::stacktrace

一个简单的例子:

安装依赖

sudo apt-get install libboost-stacktrace-dev

源码boost_stacktrace.cpp

#include <iostream>

#define BOOST_STACKTRACE_USE_ADDR2LINE
#include <boost/stacktrace.hpp>

void my_func_2(void) {
    std::cout << boost::stacktrace::stacktrace() << std::endl;
}

void my_func_1(double f) {
    (void)f;
    my_func_2();
}

void my_func_1(int i) {
    (void)i;
    my_func_2();
}

int main(int argc, char **argv) {
    long long unsigned int n;
    if (argc > 1) {
        n = strtoul(argv[1], NULL, 0);
    } else {
        n = 1;
    }
    for (long long unsigned int i = 0; i < n; ++i) {
        my_func_1(1);   // line 28
        my_func_1(2.0); // line 29
    }
}

编译

g++ -fno-pie -ggdb3 -O0 -no-pie -o boost_stacktrace.out -std=c++11 
  -Wall -Wextra -pedantic-errors boost_stacktrace.cpp -ldl

运行

./boost_stacktrace.out
结果如下:

 0# my_func_2() at /usr/include/boost/stacktrace/stacktrace.hpp:129
 1# my_func_1(int) at /root/example/boost_strace.cc:18
 2# main at /root/example/boost_strace.cc:29 (discriminator 2)
 3# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
 4# _start in ./boost_stacktrace.out

 0# my_func_2() at /usr/include/boost/stacktrace/stacktrace.hpp:129
 1# my_func_1(double) at /root/example/boost_strace.cc:13
 2# main at /root/example/boost_strace.cc:27 (discriminator 2)
 3# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
 4# _start in ./boost_stacktrace.out

参考资料

https://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c
https://github.com/bombela/backward-cpp

最后

以上就是端庄猫咪为你收集整理的C++打印调用栈的全部内容,希望文章能够帮你解决C++打印调用栈所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部