Android 开发中 C++ 和Java 日志调试

news2024/9/22 21:31:11

在 C++ 中添加堆栈日志

先在 Android.bp 中 添加 ‘libutilscallstack’

 shared_libs:[
    "liblog",
 "	libutilscallstack"
 ]

在想要打印堆栈的代码中添加

#include <utils/CallStack.h>
using android::CallStack;

// 在函数中添加
int VisualizerLib_Create{
 CallStack stack(TAG);
 stack.update(); 
}

最后日志示例:
image.png

通过 堆栈日志,可以分析函数的调用路径。在代码跳转中了解整个调用逻辑。

系统库的源码位置

代码路径:android\system\core\libutils\include\utils\CallStack.h

// Collect/print the call stack (function, file, line) traces for a single thread.
class CallStack {
public:
    // Create an empty call stack. No-op.
    CallStack();
    // Create a callstack with the current thread's stack trace.
    // Immediately dump it to logcat using the given logtag.
    CallStack(const char* logtag, int32_t ignoreDepth = 1);
    ~CallStack();

    // Reset the stack frames (same as creating an empty call stack).
    void clear() { mFrameLines.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 = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);

    // Dump a stack trace to the log using the supplied logtag.
    void log(const char* logtag,
             android_LogPriority priority = ANDROID_LOG_DEBUG,
             const char* prefix = nullptr) const;

    // Dump a stack trace to the specified file descriptor.
    void dump(int fd, int indent = 0, const char* prefix = nullptr) const;

    // Return a string (possibly very long) containing the complete stack trace.
    String8 toString(const char* prefix = nullptr) const;

    // Dump a serialized representation of the stack trace to the specified printer.
    void print(Printer& printer) const;

    // Get the count of stack frames that are in this call stack.
    size_t size() const { return mFrameLines.size(); 
                        }

在 C++ 中打开日志开关

#define LOG_NDEBUG 0

这里针对的是 所有 ALOGV 的日志开关,调试时需要打开上面的 define

如果只是针对联调日志,只想添加部分日志, 则加上 ALOGD 或 ALOGW 的日志

在 java 中添加日志

import android.util.Log;

//
Exception e = new Exception("This is a log");
e.printStackTrace();

//
Thread.currentThread().getStackTrace();

//
Log.e(TAG , Log.getStackTraceString(new Throwable()));

打印日志示例:

06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): java.lang.Throwable
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.setSpeakerphoneOn(CallAudioRouteStateMachine.java:1655)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.reinitialize(CallAudioRouteStateMachine.java:1898)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.access 2200 ( C a l l A u d i o R o u t e S t a t e M a c h i n e . j a v a : 73 ) 06 − 0416 : 19 : 29.648 D / C a l l A u d i o R o u t e S t a t e M a c h i n e ( 1070 ) : a t c o m . a n d r o i d . s e r v e r . t e l e c o m . C a l l A u d i o R o u t e S t a t e M a c h i n e 2200(CallAudioRouteStateMachine.java:73) 06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine 2200(CallAudioRouteStateMachine.java:73)060416:19:29.648D/CallAudioRouteStateMachine(1070):atcom.android.server.telecom.CallAudioRouteStateMachineActiveSpeakerRoute.processMessage(CallAudioRouteStateMachine.java:1223)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.internal.util.StateMachine S m H a n d l e r . p r o c e s s M s g ( S t a t e M a c h i n e . j a v a : 993 ) 06 − 0416 : 19 : 29.648 D / C a l l A u d i o R o u t e S t a t e M a c h i n e ( 1070 ) : a t c o m . a n d r o i d . i n t e r n a l . u t i l . S t a t e M a c h i n e SmHandler.processMsg(StateMachine.java:993) 06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.internal.util.StateMachine SmHandler.processMsg(StateMachine.java:993)060416:19:29.648D/CallAudioRouteStateMachine(1070):atcom.android.internal.util.StateMachineSmHandler.handleMessage(StateMachine.java:810)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Handler.dispatchMessage(Handler.java:106)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Looper.loopOnce(Looper.java:201)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Looper.loop(Looper.java:288)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.HandlerThread.run(HandlerThread.java:67)

附件: C++的宏定义打印格式

# 打印 bool 类型
bool doProcess = !mEffectCallback->isOffloadOrMmap() && !mEffectCallback->isOffloadOrDirect();

ALOGD("doProcess: %s", doProcess ? "true" : "false"); //true:0 False:1

 ALOGW%s mEffects[%zu] name %s", __func__, i, mEffects[i]->desc().name);
//W/AudioFlinger::EffectChain(  862): process_l  mEffects[0] name Visualizer

// 测试某个函数的方法打印
ALOGD("----------%s---------",__func__);

%d输出int型。
%zu输出size_t型。size_t在库中定义为unsigned int。
一个是整型,一个是无符号整型(无法打印负数)。
补充:如果%zu不能使用,可以用%u取代。%zu,%u不能输出负数。

%@     对象
%d, %i 整数
%u     无符整形
%f     浮点/双字
%x, %X  16进制整数
%x     --- 一般的16进制的打印
%2x   --- 要求打印2个16进制位,不够2个位的时候使用空格填充
%02x --- 要打印2个16进制位,不够2个位的时候使用0填充
%o     八进制整数
%zu    size_t
%p     指针
%e     浮点/双字 (科学计算)
%g     浮点/双字
%s     C 字符串
%.*s   Pascal字符串
%c     字符
%C     unichar
%lld   64位长整数(long long)
%llu   无符64位长整数
%Lf    64位双字

其他 格式的,请参考:

C语言中printf打印形式(%02X, %2X, %-2X, %.nf, %m.nf, %e, %m.ne, %2d, %-2d, %02d, %.2d)_printf %.2x-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1907782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

20240708 每日AI必读资讯

&#x1f916;破解ChatGPT惊人耗电&#xff01;DeepMind新算法训练提效13倍&#xff0c;能耗暴降10倍 - 谷歌DeepMind研究团队提出了一种加快AI训练的新方法——多模态对比学习与联合示例选择&#xff08;JEST&#xff09;&#xff0c;大大减少了所需的计算资源和时间。 - JE…

python基础篇(9):模块

1 模块简介 Python 模块(Module)&#xff0c;是一个 Python 文件&#xff0c;以 .py 结尾. 模块能定义函数&#xff0c;类和变量&#xff0c;模块里也能包含可执行的代码. 模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现…

实在智能荣获WAIC 2024机器之心重量级奖项——AI隐形冠军TOP 10!

近日&#xff0c;世界人工智能大会&#xff08;WAIC 2024&#xff09;如火如荼召开&#xff0c;自2018年首届举办以来&#xff0c;WAIC已成为全球AI领域最具影响力的国际盛会之一。本届WAIC再度集聚了来自世界各地的政府代表、顶尖科学家、行业领袖和创新企业等&#xff0c;共同…

Redis存储原理与数据模型

Redis存储结构 存储转换 redis-value编码 string int&#xff1a;字符串长度小于等于20切能转成整数raw&#xff1a;字符串长度大于44embstr&#xff1a;字符串长度小于等于44 list quicklist&#xff08;双向链表&#xff09;ziplist&#xff08;压缩链表&#xff09; hash …

7.8作业

一、思维导图 二、 1】按值修改 2】按值查找&#xff0c;返回当前节点的地址 &#xff08;先不考虑重复&#xff0c;如果有重复&#xff0c;返回第一个&#xff09; 3】反转 4】销毁链表 //按值修改 int value_change(linklistptr H,datatype e,int value) {if(HNULL||empty(H…

自动化测试及生成测试报告

Linux安装Selenium进行自动化测试 首先需要安装python、Chrome&ChromeDirver ChromeDriver与Chrome对应版本 #查看chrome版本google-chrome --version或者在浏览器搜索chrome://version/ChromeDriver下载地址这里下载114版本 wget https://chromedriver.storage.googleap…

数据库图形化管理界面应用 Navicat Premium 使用教程

经同学介绍的一个把数据库可视化的软件Navicat Premium&#xff0c;很好用&#xff0c;在这里分享一下&#xff0c;需要的同学可以去了解看看 一&#xff1a;下载并解压 链接&#xff1a;https://pan.baidu.com/s/1ZcDH6m7EAurAp_QmXWx81A 提取码&#xff1a;e5f6 解压到合…

Windows下载、配置Java JDK开发环境的方法

本文介绍在Windows电脑中&#xff0c;安装JDK&#xff08;Java Development Kit&#xff09;&#xff0c;也就是Java开发工具包的详细方法。 JDK是Java软件开发的基础&#xff0c;由Oracle公司提供&#xff0c;用于构建在Java平台上运行的应用程序与组件等&#xff1b;其已经包…

CnosDB:深入理解时序数据修复函数

CnosDB是一个专注于时序数据处理的数据库。CnosDB针对时序数据的特点设计并实现了三个强大的数据修复函数&#xff1a; timestamp_repair – 对时间戳列进行有效修复&#xff0c;支持插入、删除、不变等操作。value_repair – 对值列进行智能修复&#xff0c;根据时间戳间隔和…

Django 新增数据 save()方法

1&#xff0c;添加模型 Test/app11/models.py from django.db import modelsclass Book(models.Model):title models.CharField(max_length100)author models.CharField(max_length100)publication_date models.DateField()price models.DecimalField(max_digits5, decim…

数据分析与挖掘实战案例-电商产品评论数据情感分析

数据分析与挖掘实战案例-电商产品评论数据情感分析 文章目录 数据分析与挖掘实战案例-电商产品评论数据情感分析1. 背景与挖掘目标2. 分析方法与过程2.1 评论预处理1. 评论去重2. 数据清洗 2.2 评论分词1. 分词、词性标注、去除停用词2. 提取含名词的评论3. 绘制词云查看分词效…

OS-HACKNOS-2.1

确定靶机IP地址 扫描靶机开放端口信息 目录扫描 访问后发现个邮箱地址 尝试爆破二级目录 确定为wordpress站 利用wpscan进行漏洞扫描 #扫描所有插件 wpscan --url http://192.168.0.2/tsweb -e ap 发现存在漏洞插件 cat /usr/share/exploitdb/exploits/php/webapps/46537.txt…

用例导图CMind

突然有一些觉悟&#xff0c;程序猿不能只会吭哧吭哧的低头做事&#xff0c;应该学会怎么去展示自己&#xff0c;怎么去宣传自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;这两天一直在整理自己的作品&#xff0c;也为接下来的找工作多做点准备。接下来…

Tomcat的负载均衡、动静分离

一、如何tomcat和nginx负载均衡及动静分离&#xff1a;2台tomcat&#xff0c;3台nginx来实现 1.首先设置tomcat1和tomcat2服务器 关闭两台tomcat的防火墙及安全机制&#xff1a;systemctl stop filwalld setenforce 0 进入tomcat目录的webapps中&#xff0c;创建test 2.配…

Sprint Boot 2 核心功能(一)

核心功能 1、配置文件 application.properties 同基础入门篇的application.properties用法一样 Spring Boot 2 入门基础 application.yaml&#xff08;或application.yml&#xff09; 基本语法 key: value&#xff1b;kv之间有空格大小写敏感使用缩进表示层级关系缩进不允…

数学系C++ 继承派生多态 (十四十三)

— 继承 可以使得派生类具有父类的各种属性和功能&#xff0c;而不需要再次编写相同的代码。 类的继承&#xff1a;派生类继承了父类的特性&#xff08;数据和函数&#xff09; ► 继承是可传递的&#xff1a;从父类继承的特性可以传递给新的子类 ► 继承方式&#xff1a;规…

Unity Text Mesh Pro 中英文混编自动换行问题

问题描述 使用TextMeshPro 输入中英文时&#xff0c;在一行内 输入中英文&#xff0c;当英文部分超过第一行剩余位置时&#xff0c;整个英文部分都会自动换行 问题截图&#xff1a; 期待截图&#xff1a; 问题说明 因为 TextMeshPro识别中文后会带换行符。 解决方案 修改…

YOLOv5改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制【全网独家】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a; 《YOLOv5入门 改…

比赛获奖的武林秘籍:04 电子类比赛嵌入式开发快速必看的上手指南

比赛获奖的武林秘籍&#xff1a;04 电子类比赛嵌入式开发快速必看的上手指南 摘要 本文主要介绍了电子类比赛中负责嵌入式开发同学的上手比赛的步骤、开发项目的流程和具体需要学习的内容&#xff0c;并结合自身比赛经历给出了相关建议。 正文 如何开始上手做自己第一个项目…

H5使用支付宝支付

详情可参考支付宝开发文档&#xff1a;支付宝开发文档 前端把购买信息通过请求接口告诉后端&#xff0c;接口返回含有支付相关信息字符串string&#xff0c;前端插入html中调用 例&#xff1a;form < form name "punchout_form" method "post" act…