使用方法

目标进程需要打开调试开关,android:debuggable=true

adb shell am profile start com.tencent.mm /data/local/tmp/1.trace
adb shell am profile stop com.tencent.mm
adb pull /data/local/tmp/1.trace
~/adt-2014/sdk/tools/traceview 1.trace

文件格式

http://androidxref.com/6.0.1_r10/xref/art/runtime/trace.h

enum TracingMode {
  kTracingInactive,
  kMethodTracingActive,
  kSampleProfilingActive,
};
// File format:
//     header
//     record 0
//     record 1
//     ...
//
// Header format:
//     u4  magic ('SLOW')
//     u2  version
//     u2  offset to data
//     u8  start date/time in usec
//     u2  record size in bytes (version >= 2 only)
//     ... padding to 32 bytes
//
// Record format v1:
//     u1  thread ID
//     u4  method ID | method action
//     u4  time delta since start, in usec
//
// Record format v2:
//     u2  thread ID
//     u4  method ID | method action
//     u4  time delta since start, in usec
//
// Record format v3:
//     u2  thread ID
//     u4  method ID | method action
//     u4  time delta since start, in usec
//     u4  wall time since start, in usec (when clock == "dual" only)
//
// 32 bits of microseconds is 70 minutes.
//
// All values are stored in little-endian order.
enum TraceAction {
    kTraceMethodEnter = 0x00,       // method entry
    kTraceMethodExit = 0x01,        // method exit
    kTraceUnroll = 0x02,            // method exited by exception unrolling
    // 0x03 currently unused
    kTraceMethodActionMask = 0x03,  // two bits
};

原理解析

Android 6.0.1 - 服务进程 http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java#19543

public boolean profileControl(
    String process,
    int userId,
    boolean start,
    ProfilerInfo profilerInfo,
    int profileType
    ) throws RemoteException{
    // ...
    ProcessRecord proc = null;
    if (process != null){
        proc = findProcessLocked(process,userId,"profileControl");
    }
    // ...
    if (start){
        // ...
        proc.thread.profileControl(start,profilerInfo,profileType);
    }
    // ...

}
  • 目标进程 http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/app/ActivityThread.java#914
public void proilerControl(boolean start,ProfilerInfo profilerInfo, int profileType) {
    sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
}

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/app/ActivityThread.java#handleProfilerControl

final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType){
    if (start){
        mProfiler.startProfiling();
    }else{
        mProfiler.stopProfiling();
    }
}

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/app/ActivityThread.java#startProfiling http://androidxref.com/6.0.1_r10/xref/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java

public void startProfiling(){
    VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
        8 * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
}
  • Native

http://androidxref.com/6.0.1_r10/xref/art/runtime/native/dalvik_system_VMDebug.cc#116

static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename,
    jint bufferSize, jint flags,
    jboolean samplingEnabled, jint intervalUs){

    }
Grape

Grape

Graduated in Computer Science and Engineering, but currently working with GNU/Linux infrastructure and in the spare time I'm an Open Source programmer (Python and C), a drawer and author in the YINGJUE Blog.


Comments