之前总看Android的源码感觉CallStack做的很不错,现在终于用户三方库libunwind做出了自己的CallStack,虽然代码不多,但也是自己写的

上代码

/*************************************************************************> File Name: callstack.h> Author: hsz> Mail:> Created Time: Tue 27 Jul 2021 06:02:23 PM CST************************************************************************/#ifndef __ALIAS_CALLSTACK_H__
#define __ALIAS_CALLSTACK_H__
#include <log/log.h>          // 自己写的log
#include <stdio.h>
#include <vector>
#include <utils/string8.h>        // 仿照Android String8,添加了移动构造和移动赋值namespace Alias {class CallStack {public:CallStack();CallStack(const char* logtag, int32_t ignoreDepth = 1);~CallStack();void clear() { mStackFrame.clear(); }// Immediately collect the stack traces for the specified thread.// The default is to dump the stack of the current call.void update(int32_t ignoreDepth = 2);void log(const char* logtag,LogLeval::Leval leval = LogLeval::DEBUG) const;// Return a string (possibly very long) containing the complete stack trace.String8 toString() const;// Get the count of stack frames that are in this call stack.size_t size() const { return mStackFrame.size(); }private:std::vector<String8>    mStackFrame;uint32_t                mSkip;
};
} // namespace Alias#endif // __ALIAS_CALLSTACK_H__
/*************************************************************************> File Name: callstack.cpp> Author: hsz> Mail:> Created Time: Tue 27 Jul 2021 06:02:27 PM CST************************************************************************/#define UNW_LOCAL_ONLY
#include "callstack.h"
#include <cxxabi.h>
#include <libunwind.h>
#include <stdlib.h>namespace Alias {CallStack::CallStack()
{}CallStack::CallStack(const char* logtag, int32_t ignoreDepth)
{this->update(ignoreDepth + 1);this->log(logtag);
}CallStack::~CallStack()
{}void CallStack::update(int32_t ignoreDepth)
{mSkip = ignoreDepth;unw_cursor_t cursor;unw_context_t context;unw_getcontext(&context);unw_init_local(&cursor, &context);while (unw_step(&cursor) > 0){unw_word_t offset, funcPointer;unw_get_reg(&cursor, UNW_REG_IP, &funcPointer);if (funcPointer == 0) {break;}char sym[256];if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {char *nameptr = sym;int status = -1;char *demangled = abi::__cxa_demangle(sym, nullptr, nullptr, &status);if (status == 0) {nameptr = demangled;}mStackFrame.push_back(std::move(String8::format("-0x%012x: (%s + %p)", funcPointer, nameptr, offset)));std::free(demangled);} else {mStackFrame.push_back(std::move(String8::format("(unable to obtain symbol name for this frame)")));}}
}void CallStack::log(const char* logtag, LogLeval::Leval leval) const
{for (size_t i = 0; i < mStackFrame.size() - mSkip; ++i) {log_write(leval, logtag, "%s\n", mStackFrame[i].c_str());}
}String8 CallStack::toString() const
{String8 str;for (size_t i = 0; i < mStackFrame.size(); ++i) {str += mStackFrame[i];str += "\n";}return std::move(str);
}} // namespace Alias

·测试代码

#include <utils/callstack.h>
#include <utils/thread.h>namespace ns
{template <typename T, typename U>void func(T t, U u){Alias::CallStack cs;cs.update();Alias::String8 str = cs.toString();printf("%s\n\n\n", str.c_str());cs.log("DEBUG");}
}template <typename T>
struct Len
{public:void len(){Alias::String8 s;ns::func(t, s);}
private:T t;
};int thread(void *arg)
{Len<int> l;l.len();return 0;
}int main()
{Len<int> l;l.len();Alias::Thread th("Thread", thread);th.run();sleep(2);return 0;
}

编译

运行

CallStack获取函数堆栈相关推荐

  1. 【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )

    文章目录 一.进程注入原理 二.远程调用流程 ( 获取 so 动态库地址 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 ) 一.进程注入原理 调试进程 At ...

  2. ebp 函数堆栈esp_对于ESP、EBP寄存器的理解

    esp是栈指针,是cpu机制决定的,push.pop指令会自动调整esp的值: ebp只是存取某时刻的esp,这个时刻就是进入一个函数内后,cpu会将esp的值赋给ebp,此时就可以通过ebp对栈进行 ...

  3. C/C++中手动获取调用堆栈【转】

    转自:http://blog.csdn.net/kevinlynx/article/details/39269507 版权声明:本文为博主原创文章,未经博主允许不得转载. 当我们的程序core掉之后, ...

  4. 使用dbghelp获取调用堆栈--release下的调试方法学

    Author : Kevin Lynx 当软件作为release模式被发布给用户时,当程序崩溃时我们很难去查找原因.常见的手法是输出LOG文件,根据LOG文件分析 程序崩溃时的运行情况.我们可以通过S ...

  5. 如何在Matlab中获取函数参数的数目?

    本图文详细介绍了Matlab中获取函数参数数目的方法.

  6. Java获取异常堆栈信息

    Java获取异常堆栈信息 参考文章: (1)Java获取异常堆栈信息 (2)https://www.cnblogs.com/zhi-leaf/p/6288769.html 备忘一下.

  7. 在C语言中以编程的方式获取函数名

    在C语言中以编程的方式获取函数名 仅仅为了获取函数名,就在函数体中嵌入硬编码的字符串,这种方法单调乏味还易导致错误,不如看一下怎样使用新的C99特性,在程序运行时获取函数名吧. 对象反射库.调试工具及 ...

  8. 水滴石穿之IFRANME加载完成判断、获取函数的动态参数信息

    1.判断IFRAME是否加载完成 由于页面过程中,需要对IFRAME中的页面进行控制!但是由于IFRAME页面是其他人完成的,只是知道它的一些变量!页面结构如下: <mw:SplitterPan ...

  9. 获取成员函数地址及获取函数地址

     首先我们定义一个类Ctest,类里面包含三个不同形式的成员函数,静态成员函数statFunc().动态成员函数dynFunc()和虚拟函数virtFunc().在main函数中我们利用cout标 ...

  10. linux函数地址获取函数名,函数名/函数地址/函数指针

    函数指针:1.指针变量 2.指针变量指向函数 这正如用指针变量可指向整型变量.字符型.数组一样. 在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址. 可利用该指针变量调用函数, ...

最新文章

  1. 每个程序员都必须知道的 8 种数据结构
  2. python3 判断字符串是否包含指定字符
  3. 蓝桥杯--2013--黄金连分数(大数)
  4. win10 电脑 .Net framework3.5 组件无法安装0x800f801f
  5. tensorboard出现OSError: [Errno 22] Invalid argument问题解决
  6. python学习笔记(四):函数
  7. 算法 - 普里姆算法(修路问题求解)
  8. mysql 5.7 数据库备份_MySQL5.7.20数据库备份与恢复
  9. Magento用的哪个php框架,初识magento框架代码目录
  10. AS3 XML全部用法
  11. 程序员面试金典——9.1上楼梯
  12. 深入了解 HTML 5
  13. svn取消文件夹图标_SVN文件夹或文件不显示图标解决方法
  14. ArcMap坐标系转换
  15. python中一元二次方程的判别式_一元二次方程根的判别式知识点
  16. Codeforces Round #707 (Div. 2)
  17. 计算机网络拓扑星型结构应用,浅谈计算机网络拓扑结构及其应用.doc
  18. MAE 代码实战详解
  19. 集团公司申请企业邮箱有哪些注意事项?
  20. Frps一键安装脚本,带Frpc Windows便捷启动脚本

热门文章

  1. 照片尺寸及像素对应表
  2. RRT算法及其部分改进算法介绍
  3. 从支付架构到风控报警,支付系统的设计如何环环相扣?
  4. 雨课堂计算机基础与应用大一,雨课堂试卷批量导入Word模板.doc
  5. 一般纳税人与小规模纳税人有什么区别
  6. 小规模45万免税,免的是增值税,没有企业所得税!
  7. 二阶无源低通滤波器幅频特性曲线_几种无源滤波器的电路及频响特性对比
  8. 德标螺纹规格对照表_德标等螺纹对照表.doc
  9. 一键GHOST v2019.08.12优盘教程
  10. 多种文件上传绕过手法