systrace/perfetto第三方app的Trace.beginSection方法无效问题和TAG开放剖析

news2024/9/22 1:21:21

背景

针对程序如何在自己的代码中加入相关的trace方法和TAG来方便在systrace/perfetto中进行查看,下面这篇文章已经进行了详细的讲解:
systrace/perfetto中需要actrace打tag相关方法-车载车机framework系统开发实战

有针对native的c++代码,也有系统app的java代码,但是缺少了普通第三方app如何打印trace,有学员朋友在第三方app尝试打印trace时候发现了一些问题,那就是使用perfetto抓取的trace死活没有自己打印的trace,马哥这边经过验证也确实有存在相关的问题,下面针对第三方app没办法打印trace问题来进行详细的分析。

问题复现过程

第三应用一般只能使用如下类:
frameworks/base/core/java/android/os/Trace.java
在这里插入图片描述
这里可以看到Trace总共才可以使用上面几个公开方法,其他方法和变量第三方应用均不可以使用,当然也可以使用反射的方式。
正常代码中如果加入trace一般使用如下方式:
void beginSection( String sectionName);//sectionName代表打印trace的名字,一般可以写成当前方法等
void endSection();//trace代表结束,与上面方法成对出现

打印如下:
在这里插入图片描述
运行抓取:
使用写好perfetto脚本抓取

sh capture.sh

capture.sh源码如下:

#!/system/bin/sh
~/aosp/external/perfetto/tools/record_android_trace -o $(date +%Y%m%d_%H%M%S)_trace_file.perfetto-trace -t 5s -b 32mb sched freq idle am wm power gfx view binder_driver hal dalvik camera input res memory gfx view wm ss video camera hal res sync idle binder_driver binder_lock ss

上面就是使用aosp源码的record_android_trace工具抓取的,大家自己改成自己合适路径。

结果如下:
在这里插入图片描述
发现完全没有"MainActivity onclick"这里trace。

原因分析

   public static void beginSection(@NonNull String sectionName) {
        android.util.Log.i("beginSection","beginSection isTagEnabled " + isTagEnabled(TRACE_TAG_APP));
        if (isTagEnabled(TRACE_TAG_APP)) {//关键的使用APP的TAG判断
            if (sectionName.length() > MAX_SECTION_NAME_LEN) {
                throw new IllegalArgumentException("sectionName is too long");
            }
            nativeTraceBegin(TRACE_TAG_APP, sectionName);
        }
    }

这里可以看到也加入了相关的打印看看isTagEnabled(TRACE_TAG_APP)是否使能了,结果如下:

在这里插入图片描述可以看出isTagEnabled(TRACE_TAG_APP)为false是导致没办法查看trace的关键,看看isTagEnabled源码:

public static boolean isTagEnabled(long traceTag) {
    long tags = nativeGetEnabledTags();
    return (tags & traceTag) != 0;
}

这里是native方法会调用到jni的cpp文件
在这里插入图片描述

最后调用到这里
system/core/libcutils/trace-dev.inc

uint64_t atrace_get_enabled_tags()
{
    atrace_init();
    return atrace_enabled_tags;
}

void atrace_init() {
#if defined(__BIONIC__)
    uint32_t seq_no = __system_property_serial(atrace_property_info);  // Acquire semantics.
#else
    uint32_t seq_no = 0;
#endif
    uint32_t prev_seq_no = atomic_load_explicit(&last_sequence_number, memory_order_relaxed);
    if (CC_UNLIKELY(seq_no != prev_seq_no)) {
        atrace_seq_number_changed(prev_seq_no, seq_no);
    }
}

会调用到atrace_seq_number_changed方法中
system/core/libcutils/trace-dev.cpp

static void atrace_seq_number_changed(uint32_t prev_seq_no, uint32_t seq_no) {
    if (!atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
        return;
    }

    // Someone raced us.
    if (!atomic_compare_exchange_strong(&last_sequence_number, &prev_seq_no, seq_no)) {
        return;
    }

    if (CC_UNLIKELY(prev_seq_no == kSeqNoNotInit)) {
#if defined(__BIONIC__)
        const prop_info* new_pi = __system_property_find("debug.atrace.tags.enableflags");
        if (new_pi) atrace_property_info = new_pi;
#endif
        pthread_once(&atrace_once_control, atrace_init_once);
    }

    atrace_update_tags();
}

这里用调用到了atrace_update_tags
system/core/libcutils/trace-dev.inc

void atrace_update_tags()
{
    uint64_t tags;
    if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
        tags = atrace_get_property();
        pthread_mutex_lock(&atrace_tags_mutex);
        atrace_enabled_tags = tags;
        pthread_mutex_unlock(&atrace_tags_mutex);
    } else {
        // Tracing is disabled for this process, so we simply don't
        // initialize the tags.
        pthread_mutex_lock(&atrace_tags_mutex);
        atrace_enabled_tags = ATRACE_TAG_NOT_READY;
        pthread_mutex_unlock(&atrace_tags_mutex);
    }
}

最后到了

void atrace_update_tags()
{
    uint64_t tags;
    if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
        tags = atrace_get_property();
        pthread_mutex_lock(&atrace_tags_mutex);
        atrace_enabled_tags = tags;
        pthread_mutex_unlock(&atrace_tags_mutex);
    } else {
        // Tracing is disabled for this process, so we simply don't
        // initialize the tags.
        pthread_mutex_lock(&atrace_tags_mutex);
        atrace_enabled_tags = ATRACE_TAG_NOT_READY;
        pthread_mutex_unlock(&atrace_tags_mutex);
    }
}

再调用到atrace_get_property方法

static uint64_t atrace_get_property()
{
    char value[PROPERTY_VALUE_MAX];
    char *endptr;
    uint64_t tags;

    property_get("debug.atrace.tags.enableflags", value, "0");//属性中获取这些设置的tag
    errno = 0;
    tags = strtoull(value, &endptr, 0);
    if (value[0] == '\0' || *endptr != '\0') {
        ALOGE("Error parsing trace property: Not a number: %s", value);
        return 0;
    } else if (errno == ERANGE || tags == ULLONG_MAX) {
        ALOGE("Error parsing trace property: Number too large: %s", value);
        return 0;
    }

    // Only set the "app" tag if this process was selected for app-level debug
    // tracing.
    if (atrace_is_app_tracing_enabled()) { //注意这里针对tag_app的是单独设置的哈
        tags |= ATRACE_TAG_APP;
    } else {
        tags &= ~ATRACE_TAG_APP;
    }

    return (tags | ATRACE_TAG_ALWAYS) & ATRACE_TAG_VALID_MASK;
}

上面可以看出tag最后其实有2个部分:普通tag,ATRACE_TAG_APP。

既可以看出ATRACE_TAG_APP和其他如下TAG不同:

 sched freq idle am wm power gfx view binder_driver hal dalvik camera input res

下面分别分析一下普通tag和ATRACE_TAG_APP是如何进行设置的,这里为了简单方便拿atrace代码来分析。
1 普通tag
上面代码看出主要是"debug.atrace.tags.enableflags"属性获取值,那么可以把这里作为切入点反推
在这里插入图片描述
使用这个属性的只有setTagsProperty方法
在这里插入图片描述
那么看看setTagsProperty是在哪调用的

在这里插入图片描述
这里核心变量g_categoryEnables和k_categories就是常见携带的参数映射表进行匹配,然后设置相关tags这个整型变量
在这里插入图片描述g_categoryEnables是哪里设置呢?
在下面的setCategoryEnable方法设置
在这里插入图片描述setCategoryEnable是靠atrace传递来的相关tag参数解析调用
在这里插入图片描述

2 单独的ATRACE_TAG_APP
识别是否有-a参数然后进行获取参数赋值g_debugAppCmdLine
在这里插入图片描述
在上面提到的setUpUserspaceTracing方法中调用了setAppCmdlineProperty
在这里插入图片描述看看setAppCmdlineProperty实现
在这里插入图片描述在这里插入图片描述
看得出来本质也是调用了属性设置而已。
然后在
system/core/libcutils/trace-dev.inc
会进行属性获取,并且与当前进程名字进行比较决定是否开启app的trace。
在这里插入图片描述在这里插入图片描述最后在atrace_get_property时候会进行ATRACE_TAG_APP的或操作
在这里插入图片描述

配置不一样,不是和他们一起,需要单独设置,具体如何设置呢?

如何开放ATRACE_TAG_APP

如何设置可以看看perfetto和atrace命令的help:
在这里插入图片描述

在这里插入图片描述
这里要加入-a方式
在这里插入图片描述执行结果如下:

包名为com.example.injectmotion

sh capture.sh com.example.injectmotion

抓取trace后看到结果如下:
在这里插入图片描述

更多framework详细代码和资料参考如下链接

hal+perfetto+surfaceflinger

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615

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

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

相关文章

Java面试题总结-基础和框架-面试题一

1、TCP和UDP tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输,而 udp 则常被用于让广播和细节控制交给应用的通信传输。 两者的区别大致如下: tcp 面向连接,udp 面向非连接即发送数据前不需要建立链接;tcp …

MQ-135空气质量传感器(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 mq135.h文件 mq135.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 MQ-135空气质量传感器属于MQ系列气体传感器,广泛用于检测有害气体、新鲜空气中的烟…

Vmware 傻瓜式安装( Linux 网络操作系统 01)

一、下载VMware虚拟机安装包 虚拟机下载链接:https://share.weiyun.com/4haPul0y ​ 二、安装 点击安装文件 ​ 点击下一步,勾选“我接受...条款",继续点击下一步 修改更改安装位置,尽量不要安装到系统C盘: …

爆刷!LLM入门必备吴恩达新书-《面向开发者的LLM入门课程》

吴恩达联合OpenAI推出LLM现象级课程!|||绝了||重磅首发🔥 1、LLM入门必看课程-吴恩达373 PDF||!适用于所有具备基础 Python 能力,想要入门 LLM 的学习者 2、由吴恩达老师与 OpenAI 联合推出的官方教程,面向入门 LLM 的开发者&…

[Linux入门]---进程替换

文章目录 1.进程替换原理2.进程替换函数2.1execl函数2.2execlp函数2.3execv函数2.4execvp函数2.5execle函数2.6execve函数2.7跨语言调用程序 3.总结 1.进程替换原理 一个程序替换的函数&#xff1a; #include <unistd.h> int execl(const char *path, const char *arg,…

Linux下的系统接口(实时更新)

文件操作 open pathname:路径 flags&#xff1a;文件的打开方式 mode&#xff1a;文件的权限 返回值 打开成功返回值该文件的文件描述符&#xff0c;打开失败返回-1。 write fd : 文件描述符 buf : 指向用于存储写入数据的缓冲区的指针 count : 写入字节的最大个数 返回…

7系列FPGA HR/HP I/O区别

HR High Range I/O with support for I/O voltage from 1.2V to 3.3V. HP High Performance I/O with support for I/O voltage from 1.2V to 1.8V. UG865&#xff1a;Zynq-7000 All Programmable SoC Packaging and Pinout

Jmeter之beanshell使用

beanshell&#xff1a;和setup类似&#xff0c;登录前需要做的工作&#xff0c;是一种java源代码解释器&#xff0c;具有脚本语言的特性 使用beanshell可以使jmeter实现更多的业务需求 beanshell常用语法 vars.get() 从jmeter中获得变量 vars.put() 把数据保存为jmeter的变量…

Access用了20年杀死VF,等来的却是:国产新型软件反杀

现如今&#xff0c;使用Access数据库的人可能不多了。 Access数据库 在早些年的时候&#xff0c;微软旗下有两个广为人知的桌面数据库开发工具。 一款是自家研发的Microsoft ACCESS&#xff0c;它依托Windows操作系统&#xff0c;并内嵌于Microsoft Office之中&#xff0c;深受…

2024下《系统规划与管理师》50个高频考点汇总!背就有效

今年高项仅考上半年一次&#xff0c;下半年考的高级科目只有系规难度相对较低&#xff0c;系规需要学习的内容比高项少很多&#xff0c;高项第四版教程731页&#xff0c;系规只有328页&#xff0c;少了一半多。并且系规IT内容会更少&#xff0c;考试内容大多在书上&#xff0c;…

接口幂等的方案

一、什么是幂等 幂等指多次操作产生的影响只会跟一次执行的结果相同&#xff0c;通俗的说&#xff1a;某个行为重复的执行&#xff0c;最终获取的结果是相同的。 二、什么是接口幂等 同一个接口&#xff0c;对于同一个请求&#xff0c;不管调用多少次&#xff0c;产生的最终…

除了C盘其它盘都不见了?专业数据恢复策略解析

在数字时代&#xff0c;数据几乎成为了我们生活与工作的核心。然而&#xff0c;当电脑突然遭遇“除了C盘其它盘都不见了”的困境时&#xff0c;无疑是对我们数据安全的一次重大挑战。面对这样的紧急情况&#xff0c;如何迅速、有效地恢复丢失的数据&#xff0c;成为了许多用户迫…

苹果被删视频怎么恢复?分享4个靠谱的方法

平时过年过节的时候&#xff0c;亲戚家的小孩总会拿你的手机乱点一通&#xff0c;有时可能会不小心点进手机相册里面&#xff0c;误删了相册里的视频。如果苹果用户遇到这种情况&#xff0c;那该如何恢复苹果被删视频呢&#xff1f;不要慌张&#xff0c;既然你点开了这篇文章&a…

cv::convexityDefects()详解

参考链接:详解OpenCV的函数convexHull()和函数convexityDefects(),并利用它们)做凸包(凸壳)检测及凸包(凸壳)的缺陷检测-CSDN博客 void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); 三个参数说明如下&#xff1a; contou…

Java ArrayList扩容机制 (源码解读)

结论&#xff1a;初始长度为10&#xff0c;若所需长度小于1.5倍原长度&#xff0c;则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义 1&#xff1a;数组默认长度 2:这是一个共享的空数组实例&#xff0c;用于明确创建长度为0时的ArrayList &#xff…

钙粘蛋白CDH:肿瘤靶点研究新秀

前 言&#xff1a; 钙粘蛋白是钙依赖性细胞间粘附的重要介质&#xff0c;属于跨膜糖蛋白。钙粘蛋白在组织稳态中起重要作用&#xff0c;促进组织发育、突触粘附和上皮屏障功能。钙粘蛋白功能改变与癌症进展、血管疾病和其他病理学有关。目前多种钙粘蛋白有望成为治疗靶点&…

英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大?

环境&#xff1a; 英伟达A100显卡 问题描述&#xff1a; 英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大&#xff1f; 定制版 原本 解决方案&#xff1a; NVIDIA A100显卡的定制版和原版之间的主要区别通常在于它们的设计、用途、性能以及价格。以下是一些…

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前&#xff0c;许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流&#xff0c;但其费用昂贵。鉴于此&#xff0c;众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台&#xff0c;但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境…

“数据守护,商业共赢” — 华企盾招商会议圆满落幕

在数字化浪潮席卷全球的今天&#xff0c;数据安全已成为企业可持续发展的基石。为了共同探讨数据防护的新策略&#xff0c;推动行业生态的健康发展&#xff0c;我司于2024年9月6日成功举办了一场以“数据守护&#xff0c;商业共赢”为主题的招商会议。此次会议汇聚了来自各行各…

本地私有化RAG知识库搭建—基于Ollama+AnythingLLM保姆级教程

一、关于RAG 1.1 简介 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;是一种结合了信息检索和语言模型的技术&#xff0c;它通过从大规模的知识库中检索相关信息&#xff0c;并利用这些信息来指导语言模型生成更准确和深入的答案。这种…