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

在 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博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

制作一个动态库

1. 准备工作 # 目录结构 add.c div.c mult.c sub.c -> 算法的源文件, 函数声明在头文件 head.h # main.c中是对接口的测试程序, 制作库的时候不需要将 main.c 算进去 . ├── add.c ├── div.c ├── include │ └── head.h ├── main.c ├── mult.c └── s…

Day04-jenkins-docker

Day04-jenkins-docker 9. 案例06: 基于docker的案例实现静态代码9.1 整体流程9.2 步骤与环境1) 步骤2) 环境 9.3 详细步骤1&#xff09;代码准备2&#xff09;书写dockerfile3&#xff09;准备私有仓库4&#xff09;创建jenkins任务5&#xff09;web节点上启动对应的docker容器…

WPF真入门教程34--爆肝了【仓库管理系统】

1、项目介绍 本项目是一个基于C#WPF实现的仓库管理系统&#xff0c;系统规模较小&#xff0c;适合入门级的项目练练手&#xff0c;但项目还是具有较高的学习价值&#xff0c;它采用mvvmlight框架&#xff0c;EF框架&#xff0c;WPF前端等技术构成。对于学习来说&#xff0c;可…

Ubuntu设置nacos开机以单机模式自启动

首先&#xff0c;需要安装jdk Ubuntu 安装JDK 创建Systemd服务单元文件 sudo vim /etc/systemd/system/nacos.service按i进入编辑模式&#xff0c;写入下面信息 [Unit] Descriptionnacos server Afternetwork.target[Service] Typeforking Environment"JAVA_HOME/opt/j…

树莓派0 2W重启后突然没有声音

树莓派0 2W重启后突然没有声音。 最近在使用该板卡。重启后突然出现了显示器不能显示界面的情况&#xff0c;接着用putty的ssh方式连接该板卡&#xff0c;能连上。使用vnc方式连接该板卡&#xff0c;也能连上。后来通过修改/boot/config.txt文件&#xff0c;能在显示器上显示界…

AI大模型深度学习:理论与应用全方位解析

背景 在当前技术环境下&#xff0c;AI大模型学习不仅要求研究者具备深厚的数学基础和编程能力&#xff0c;还需要对特定领域的业务场景有深入的了解。通过不断优化模型结构和算法&#xff0c;AI大模型学习能够不断提升模型的准确性和效率&#xff0c;为人类生活和工作带来更多…

用一百场线下讲座科普充电桩 能效电气做到了

在新能源汽车产业蓬勃发展的今天,充电桩作为产业链的重要环节,其建设与发展成为推动行业进步的关键。在这一背景下,能效电气凭借其卓越的技术实力和前瞻性的市场布局,成为了新能源充电桩行业的佼佼者。 为了进一步推动新能源产业的发展,普及充电桩知识,能效电气精心策划并举办…

LangChain的基本构成、组件与典型场景

【图书推荐】《ChatGLM3大模型本地化部署、应用开发与微调》-CSDN博客 在人工智能的持续演进中&#xff0c;语言模型&#xff0c;尤其是大型语言模型&#xff08;LLM&#xff09;&#xff0c;例如备受瞩目的ChatGPT&#xff0c;已经稳固地占据了科技前沿的核心地位。这些模型不…

ChatGPT 论文助手:如何用 AI 技术加速学术写作过程

ChatGPT在论文写作中的应用 ChatGPT作为一个先进的语言模型&#xff0c;在学术论文创作领域提供显著帮助。它不仅提升学生与研究者的写作效率&#xff0c;还优化论文质量并引入创新观点。以下是ChatGPT在论文写作中的几种具体应用&#xff1a; 提升写作效率 生成写作构思&…

Mac密室逃脱游戏推荐:Escape Simulator for mac安装包

Escape Simulator 是一款逃生模拟游戏&#xff0c;玩家在游戏中需要寻找线索、解决谜题&#xff0c;以逃离各种房间或环境。这种类型的游戏通常设计有多个关卡或场景&#xff0c;每个场景都有不同的设计和难度。 在 Escape Simulator 中&#xff0c;玩家的目标通常是找到出口或…

Springboot+Vue3开发学习笔记《1》

SpringbootVue3开发学习笔记《1》 博主正在学习SpringbootVue3开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。 一、前置条件 博主所用版本&#xff1a; IDEA需要破解&#xff0c;破解工具链接容易挂&#xff0c;关注私聊我单发。 Spring Boot是Spring提…

Zabbix 配置WEB监控

Zabbix WEB监控介绍 在Zabbix中配置Web监控&#xff0c;可以监控网站的可用性和响应时间。Zabbix提供了内置的Web监控功能&#xff0c;通过配置Web场景&#xff08;Web Scenario&#xff09;&#xff0c;可以监控HTTP/HTTPS协议下的Web服务。 通过Zabbix的WEB监控可以监控网站…

深入解析RocketMQ的存储设计艺术(二)

1. 零拷贝与MMAP 1.1 什么是零拷贝? 零拷贝(英语: Zero-copy) 技术是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。这种技术通常用于通过网络传输文件时节省CPU周期和内存带宽。 ➢零拷贝技术可以减少数据拷贝和共享总线操作的次数,消除传输数据…

MySQL关于日志15个讲解

​​​​​​ 1. redo log是什么? 为什么需要redo log&#xff1f; redo log 是什么呢? redo log 是重做日志。 它记录了数据页上的改动。 它指事务中修改了的数据&#xff0c;将会备份存储。 发生数据库服务器宕机、或者脏页未写入磁盘&#xff0c;可以通过redo log恢复…

【web APIs】快速上手Day04(Dom节点)

目录 Web APIs - 第4天日期对象实例化方法案例-页面显示时间时间的另外一个写法 时间戳三种方式获取时间戳案例-毕业倒计时效果 节点操作DOM节点查找节点父节点查找案例-关闭广告子节点查找兄弟关系查找 增加节点创建节点追加节点案例-学成在线案例渲染克隆节点 删除节点 M端事…

零基础入门 Ai 数据挖掘竞赛-速通 Baseline-1

#AI夏令营 #Datawhale #夏令营 本项目为Datawhale 2024 年 AI 夏令营赛事&#xff0c;零基础入门 AI 数据挖掘竞赛-速通学习手册配套的代码项目。 项目链接&#xff1a;https://aistudio.baidu.com/bd-cpu-02/user/2961857/8113198/home#codelab 任务目标 根据给的test&…

JS基础与Chrome介绍

导言 在Web开发中后端负责程序架构和数据管理&#xff0c;前端负责页面展示和用户交互&#xff1b;在这种前后端分离的开发方式中&#xff0c;以接口为标准来进行联调整合&#xff0c;为了保证接口在调用时数据的安全性&#xff0c;也为了防止请求参数被篡改&#xff0c;大多数…

NFT音乐版权系统的主要功能

NFT音乐版权系统是指利用区块链技术和NFT技术来管理和交易音乐版权的系统。该系统的主要功能包括以下几个方面。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 音乐版权确权 NFT音乐版权系统可以为音乐作品的版权提供独特的标识和…

如何将 Apifox 的自动化测试与 Jenkins 集成?

CI/CD &#xff08;持续集成/持续交付&#xff09; 在 API 测试 中的主要目的是为了自动化 API 的验证流程&#xff0c;确保 API 发布到生产环境前的可用性。通过持续集成&#xff0c;我们可以在 API 定义变更时自动执行功能测试&#xff0c;以及时发现潜在问题。 Apifox 支持…

ETL数据集成丨使用ETLCloud实现MySQL与Greenplum数据同步

我们在进行数据集成时&#xff0c;MySQL和Greenplum是比较常见的两个数据库&#xff0c;我们可以通过ETLCloud数据集成平台&#xff0c;可以快速实现MySQL数据库与数仓数据库&#xff08;Greenplum&#xff09;的数据同步。 MySQL数据库&#xff1a; 优点&#xff1a; 轻量级…