IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> CallStack获取函数堆栈 -> 正文阅读

[移动开发]CallStack获取函数堆栈

之前总看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;
}

编译

在这里插入图片描述

在这里插入图片描述

运行

在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:46:00  更:2021-07-29 11:48:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 17:58:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码