perfetto抓取与导入
https://developer.android.com/tools/perfetto?hl=zh-cn
常用方法
抓取(分解步骤)
- adb 连接设备,adb shell 进入 shell环境执行下面命令;
- -t表示抓几秒的;
- o表示抓完输出到哪儿;
- 后面的tag表示抓取哪些信息
perfetto -o /data/misc/perfetto-traces/111.perfetto-trace -t 60s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
- 导出perfetto,到本地
adb pull /data/misc/perfetto-traces/111.perfetto-trace .
- 浏览器打开网址,并导入文件
https://ui.perfetto.dev/
google脚本工具(合并)
google提供了原生工具给我们使用,方法如下
首先也是需要adb连接设备
// 进入源码路径
cd /src/aosp/aosp13_r6/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 gfx view binder_driver hal dalvik camera input res memory gfx view wm am ss video camera hal res sync idle binder_driver binder_lock ss
- -b为文件大小限制
- -t为时间间隔
抓取后会自己打开google chrome网址
perfetto分析
线程状态
- running:运行态
-
runnable:待调度(点击可查看被唤醒时的waker process 、thread)
-
Uninterruptible Sleep:不可中断休眠(IO或者非IO)
计数值
异步执行块
跨进程调用跟踪
binder transact:同步调用,调用端
binder reply:同步调用,接收端
binder transaction async:异步调用,调用端
binder recv async:异步调用,接收端
如何自己加tag(cpp)
条件:
-
需要在mk/bp文件引入系统lib
"libutils",
-
需要引入头文件
#include <utils/Trace.h>
-
引入
#undef ATRACE_TAG
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
相关代码原理:
#ifndef ANDROID_TRACE_H
#define ANDROID_TRACE_H
#if defined(_WIN32)
#define ATRACE_NAME(...)
#define ATRACE_CALL()
#else // !_WIN32
#include <stdint.h>
#include <cutils/trace.h>
// See <cutils/trace.h> for more ATRACE_* macros.
// ATRACE_NAME traces from its location until the end of its enclosing scope.
#define _PASTE(x, y) x ## y
#define PASTE(x, y) _PASTE(x,y)
#define ATRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(ATRACE_TAG, name)
// ATRACE_CALL is an ATRACE_NAME that uses the current function name.
#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
namespace android {
class ScopedTrace {
public:
inline ScopedTrace(uint64_t tag, const char* name) : mTag(tag) {
atrace_begin(mTag, name);
}
inline ~ScopedTrace() {
atrace_end(mTag);
}
private:
uint64_t mTag;
};
} // namespace android
#endif // _WIN32
#endif // ANDROID_TRACE_H
使用 ATRACE_CALL();
在当前作用域的开始和结束处,以函数名为name,增加trace
ATRACE_NAME(“NAME”)
在当前作用域的开始和结束处,以参数为name,增加trace
ATRACE_BEGIN() + ATRACE_END()
使用这两个宏,或者函数,直接在期望进行trace的函数前后进行处理。
/**
* Trace the beginning of a context. name is used to identify the context.
* This is often used to time function execution.
*/
#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name)
static inline void atrace_begin(uint64_t tag, const char* name)
{
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
void atrace_begin_body(const char*);
atrace_begin_body(name);
}
}
/**
* Trace the end of a context.
* This should match up (and occur after) a corresponding ATRACE_BEGIN.
*/
#define ATRACE_END() atrace_end(ATRACE_TAG)
static inline void atrace_end(uint64_t tag)
{
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
void atrace_end_body();
atrace_end_body();
}
}
ATRACE_INT()
打印数值
ATRACE_FORMAT
- 需要额外
#include <gui/TraceUtils.h>
本质上与ATRACE_NAME()一样;
相当于自己拼接了一个string,并传递给ATRACE_NAME
从源码也能看出来
#define ATRACE_FORMAT(fmt, ...) \
TraceUtils::TraceEnder __traceEnder = \
(TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), TraceUtils::TraceEnder())
#define ATRACE_FORMAT_BEGIN(fmt, ...) TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__)
namespace android {
class TraceUtils {
public:
class TraceEnder {
public:
~TraceEnder() { ATRACE_END(); }
};
static void atraceFormatBegin(const char* fmt, ...) {
if (CC_LIKELY(!ATRACE_ENABLED())) return;
const int BUFFER_SIZE = 256;
va_list ap;
char buf[BUFFER_SIZE];
va_start(ap, fmt);
vsnprintf(buf, BUFFER_SIZE, fmt, ap);
va_end(ap);
ATRACE_BEGIN(buf);
}
}; // class TraceUtils
} /* namespace android */
如何自己加tag(JAVA)
原理上和cpp一样,都是通过native调用下去
实验
JAVA
todo
CPP