1. Java層如何列印調用棧?
在最佳化Android啟動過程時,同事給出一種列印出調用棧的函數。分享一下
java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();
StackTraceElement[] ste = ts.get(Thread.currentThread());
for (StackTraceElement s : ste) {
android.util.Slog.e("SS ", s.toString()); //這個是android內建的,如果沒有,用其他的列印函數一樣
}
為了列印出在android啟動時,Zygote啟動的所有java應用。在
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {
//debug add
java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();
StackTraceElement[] ste = ts.get(Thread.currentThread());
for (StackTraceElement s : ste) {
android.util.Slog.e("SS ", s.toString());
}
}
就可以在終端中使用命令logcat來查看列印出的調用棧了。
2. C/C++層如何列印調用棧?
Java可以方便的列印函數的調用棧。C/C++也可以。
為了顯示在vm/Misc.cpp中誰調用了函數dvmAllocRegion,在這個函數中加入下面紅色代碼:
#include <utils/CallStack.h>
...
void *dvmAllocRegion(size_t byteCount, int prot, const char *name)
{
...
#ifdef _ARM_
LOGW("name=%s", name);
android::CallStack stack;
stack.update(1, 100);
stack.dump("");
#endif
...
}
在vm/Dvm.mk中,加入:
LOCAL_CFLAGS += -D_ARM_
LOCAL_SHARED_LIBRARIES += libutils
"mmm dalvik" 得到libdvm.so。然後
adb root
adb remount
adb push libdvm.so /system/lib
adb reboot
系統重啟後,新的libdvm.so就投入使用了。