为什么使用systrace
- 能够捕获一段时间内Android系统的运行状态,生成html图
- 分析Android系统/应用的显示、绘制等性能问题
如何抓取systrace
- Android Studio(Tools->Android->Android Device Monitor)
- 使用sdk/platform-tools/systrace中的systrace.py
- adb shell下使用atrace
- 直接使用Ftrace
在代码中添加trace
Java代码中添加
- 使用beginSection API
注意,使用此方法只有在应用的debuggable为true,并且在抓取systrace的时候选定该进程才有效。
Trace.beginSection("traceName");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
Trace.endSection();
- 反射使用traceBegin API
public class TraceUtil {
private static final String LOG_TAG = TraceUtil.class.getSimpleName();
private static final String TRACE_MARKER_PATH = "/sys/kernel/debug/tracing/trace_marker";
// Using VIEW option, also using others, but APP
private static final long TRACE_TAG_VIEW = 1L << 3;
public static void begin(String methodName) {
Log.i(LOG_TAG, "Trace being...");
try {
Method traceBegin = Trace.class.getDeclaredMethod("traceBegin", long.class, String.class);
traceBegin.invoke(Trace.class, TRACE_TAG_VIEW, methodName);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void end() {
Log.i(LOG_TAG, "Trace end...");
try {
Method traceEnd = Trace.class.getDeclaredMethod("traceEnd", long.class);
traceEnd.invoke(Trace.class, TRACE_TAG_VIEW);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void traceMarkerBegin(String methodName) {
Log.i(LOG_TAG, "traceMarkerBegin");
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));
try {
fileOutputStream.write(("B|" + Process.myPid() + "|" + "wlb").getBytes());
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// No Need Close
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void traceMarkerEnd() {
Log.i(LOG_TAG, "traceMarkerEnd");
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File(TRACE_MARKER_PATH));
try {
fileOutputStream.write(("E").getBytes());
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// No Need Close
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
TraceUtil.begin("wlb");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
TraceUtil.end();
- 直接写trace_marker
TraceUtil.traceMarkerBegin("traceName");
registerReceiver(ContextReceiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
TraceUtil.traceMarkerEnd();
Native代码中添加
- 使用NDK提供的API
typedef void (*func_p)(void);
static void trace_func(void)
{
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Test Native Trace");
}
static void test_native_trace(func_p)
{
if (ATrace_isEnabled()) {
ATrace_beginSection("traceName");
func_p();
ATrace_endSection();
}
}
- 直接写trace_marker
static inline void begin_trace(int fd)
{
char buf[MAX_BUFF_SIZE];
int len = snprintf(buf, MAX_BUFF_SIZE, "B|%d|%s", getpid(), "traceName");
if (fd > 0)
write(fd, buf, len);
}
static inline void end_trace(int fd)
{
if (fd > 0)
write(fd, "E", 1);
}
// Note: Not close trace_marker fd
static void test_trace_marker(func_p)
{
const char *trace_marker_path = "/sys/kernel/debug/tracing/trace_marker";
int tm_fd = open(trace_marker_path, O_WRONLY);
if (tm_fd < 0) {
return;
}
begin_trace(tm_fd);
func_p();
end_trace(tm_fd);
}
systrace的工作原理
使能systrace workflow
j3y17qltecmcc:/sys/kernel/debug/tracing # ls
README kprobe_events trace
available_events kprobe_profile trace_clock
available_tracers options trace_marker
buffer_size_kb per_cpu trace_options
buffer_total_size_kb printk_formats trace_pipe
cpu_freq_switch_profile_enabled saved_cmdlines tracing_cpumask
current_tracer saved_cmdlines_size tracing_max_latency
events saved_tgids tracing_on
free_buffer set_event tracing_thresh
instances snapshot
- trace
- trace_marker
- buffer_size_kb
- tracing_on
细节参考
/android/kernel/Documentation/trace/
下Ftrace文档