dumpstate log总结
dumpstate的結(jié)構(gòu)
dumpState log在Android開發(fā)中是解決問題的重要途徑之一,dumpstate文件一般有幾十萬行的log,要從這么多l(xiāng)og中找出想要的關(guān)鍵信息,如果不掌握一定的技巧,儼然大海撈針。先從總體上了解dumpstate的結(jié)構(gòu),以至于不會迷失在log海當(dāng)中.
dumpstate解析
對于三星型號,電話盤輸入*#9900#進入以下界面
這個界面的代碼在android\vendor\samsung\packages\apps\MSP\FactoryTest\ServiceModeApp\src\com\sec\android\app\servicemodeapp\app\SysDump.java
這里只分析點擊第三項RUN DUMPSTATE/LOGCAT為例,實際運行的主要代碼是
Runtime.getRuntime().exec("bugreport >/data/log/dumpstate_sysdump_time.log");
這里運行了bugreport程序,并將結(jié)果重定位到log文件中,這個log文件就是我們所說的dumpstate log了
bugreport的代碼位于android\frameworks\native\cmds\bugreport\Bugreport.c
dumpstate的代碼位于android\frameworks\native\cmds\dumpstate\Dumpstate.c
在bugreport中,先啟動dumpstate的service
dumpstate類似于dumpsys都是android提供給開發(fā)者的幫助了解系統(tǒng)運行狀態(tài)的利器。
從main函數(shù)看起:
1. 設(shè)置執(zhí)行dumpstate這個命令的進程的一些屬性
??? 使它不會占用過多系統(tǒng)資源,即利用setpriority來告知內(nèi)核它可以隨時被調(diào)度
??? 因為在手機系統(tǒng)信息,通過proc/self/oom_adj接口來告知內(nèi)核(-17這是一個特殊的參數(shù),詳見man proc),在尋找可以被kill掉的進程時,忽略該進程。
??? /* set as high priority, and protect from OOM killer */????????????????????????????????????????????????????????????????????????????????????? ?
??? setpriority(PRIO_PROCESS, 0, -20);?????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
??? FILE *oom_adj = fopen("/proc/self/oom_adj", "w");??????????????????????????????????????????????????????????????????????????????????????????? ?
??? if (oom_adj) {?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
??????? fputs("-17", oom_adj);?????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
??????? fclose(oom_adj);???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?
??? }
2. 如果有root權(quán)限,就可以從dalvik處獲得各種dalvik提供的trace信息
??? 利用了utils/中的dump_vm_traces函數(shù),
???其中通過proc/[pid]/exe的link的程序如果是app_process,再找到對應(yīng)pid下的cmdline過濾掉根 zygote,即得到所有由Android系統(tǒng)通過zygote所fork出來的所有的dalvik process(即各個APK)。
??? 從這里可以看出,所有的APK都是由app_process這個應(yīng)用從跟zygote所fork出來。
??? 例如,
??? #ps
??? ...
??? app_67??? 9986? 172?? 99464? 21012 ffffffff afd0c75c S com.keramidas.TitaniumBackup
??? app_80??? 9995? 172?? 116304 32656 ffffffff afd0c75c S com.hiapk.marketpho
??? ...
?
??? # ls -l /proc/9986/exe
??? lrwxrwxrwx??? 1 app_67?? app_67?????????? 0 Oct 19 15:12 /proc/9986/exe -> /system/bin/app_process
??? # cat /proc/9986/cmdline
??? com.keramidas.TitaniumBackup#
3. 解析參數(shù)
??? 中間一個有一個關(guān)于使用socket的參數(shù)值得看一下
??? 它使用到了由init.rc中定義的專門給dumpstate使用的socket
??? service dumpstate /system/bin/dumpstate -s
??? socket dumpstate stream 0660 shell log
??? disabled
??? oneshot
??? 相關(guān)啟動各種系統(tǒng)service的init.rc的命令參見/init/readme.txt
4. 如果有root權(quán)限,拿到控制vibrator的權(quán)限和獲得kernel啟動的cmd參數(shù)
?? vibrator用來在dumpstate結(jié)束之后震動以提示用戶。這是一個在嵌入式設(shè)備中常用的提示技巧,有時候也會用簡單一個聲音提示。
?? kernel的啟動參數(shù)會在dump出來的信息中顯示。
5. 根據(jù)dumpstate的參數(shù)做一些簡單的準(zhǔn)備,然后調(diào)用dumpstate()
?? 關(guān)鍵的dumpstate函數(shù)
?? 5.1 通過property_get獲得一些從kernel cmdline及vendor提供的property信息(參見default.prop, build.prop中的預(yù)設(shè)值)
?? 5.2 通過proc系統(tǒng)獲得各種內(nèi)存管理系統(tǒng)提供的信息(如, /proc/meminfo, top等等),其中利用了android提供的一個procrank命令獲得制定進程的信息(參見我的另一篇文章,《Android性能分析工具之procrank》)
?? 5.3 dump logcat中的信息和一些網(wǎng)絡(luò)信息(netcfg, /proc/net/XXX下的內(nèi)容)
?? 5.4 dump 一些dalvik收集的trace信息
?? 5.5 dump properties信息
?? 5.6 各種通過sysfs接口暴露出來的kernel信息
?? 5.7 vold, native packages, led燈等信息
?? 5.8 調(diào)用dumpsys,顯示dumpsys的信息
6. dumpstate()結(jié)束之后的一些后續(xù)處理(文件copy,壓縮等等)
Log工具
要打印一句log,通過這樣的方法,Log.i("csf", "log test");
Log源碼在android\frameworks\base\core\java\android\util\Log.java,看Log.i的實現(xiàn)
public static int i(String tag, String msg) {
? ? ? ? return println_native(LOG_ID_MAIN, INFO, tag, msg);
? ? }
打印堆棧Log的方式
android.util.Log.d(TAG,"nnn"+android.util.Log.getStackTraceString(new Throwable()));?
在native層實現(xiàn),android\frameworks\base\core\jni\android_util_Log.cpp
static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,
? ? ? ? jint bufID, jint priority, jstring tagObj, jstring msgObj)
{
? ? const char* tag = NULL;
? ? const char* msg = NULL;
?
? ? if (msgObj == NULL) {
? ? ? ? jniThrowNullPointerException(env, "println needs a message");
? ? ? ? return -1;
? ? }
?
? ? if (bufID < 0 || bufID >= LOG_ID_MAX) {
? ? ? ? jniThrowNullPointerException(env, "bad bufID");
? ? ? ? return -1;
? ? }
?
? ? if (tagObj != NULL)
? ? ? ? tag = env->GetStringUTFChars(tagObj, NULL);
? ? msg = env->GetStringUTFChars(msgObj, NULL);
?
? ? int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
?
? ? if (tag != NULL)
? ? ? ? env->ReleaseStringUTFChars(tagObj, tag);
? ? env->ReleaseStringUTFChars(msgObj, msg);
?
? ? return res;
}
真面目還藏在__android_log_buf_write()函數(shù)中,這個函數(shù)在android\system\core\liblog\logd_write.c中
通過分析,總結(jié)出下面,具體請查看源碼
通過Log.d、Log.i、Log.v等輸出的log保存在/dev/log/main這個緩沖區(qū)中,一般app用這種方式打log
通過Rlog.d、Rlog.v、Rlog.i等輸出的log保存在/dev/log/radio這個緩沖區(qū)中,一般射頻、SIM、telephony模塊用這個比較多
通過Slog.d、Slog.v、Slog.i等輸出的log保存在/dev/log/system這個緩沖區(qū)中,很多framework的log都用Slog
通過EventLog.writeEvent輸出的log保存在/dev/log/events這個緩沖區(qū)中,一般用在framework模塊中
查看FrameWork所有service的信息,實際上運行的是dumpsys serviceName
比如:
dumpsys account列出所有賬戶
dumpsys activity activity的相關(guān)信息
dumpsys的代碼在android\frameworks\native\cmds\dumpsys\dumpsys.cpp
從源碼實現(xiàn)中看,是遍歷所有的service,然后調(diào)用service->dump()方法,比如查看EmailService的棧
EmailContent$Account.dumpAccountInfo(Context) line: 7597
EmailSyncServiceLogger.dumpAllAccountInfo(Context, PrintWriter) line: 768
EmailService.dump(FileDescriptor, PrintWriter, String[]) line: 395
ActivityThread.handleDumpService(ActivityThread$DumpComponentInfo) line: 3655
dumpsys activity all -> 所有task和task上activity,activity的view Hierachy
dumpsys activity service all ->所有app service的信息
具體參考源碼dumpstate.cpp的dumpsys_other()函數(shù)
一些關(guān)鍵字
1、廣播相關(guān)信息
ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)
Registered Receivers 列出系統(tǒng)中所有動態(tài)注冊的廣播接收者ReceiverList,該結(jié)構(gòu)包含一些Intent filter,比如下面的log
?ReceiverList{27d9778 18700 system/1000/u0 local:com.android.server.AlarmManagerService$UninstallReceiver@86fd5ea,7c790db}
? ? app=18700:system/1000 pid=18700 uid=1000 user=0
? ? Filter #0: BroadcastFilter{2703e51}
? ? ? Action: "android.intent.action.PACKAGE_REMOVED"
? ? ? Action: "android.intent.action.PACKAGE_RESTARTED"
? ? ? Action: "android.intent.action.PACKAGE_DATA_CLEARED"
? ? ? Action: "android.intent.action.QUERY_PACKAGE_RESTART"
? ? ? Scheme: "package"
? ? ? AutoVerify=false
? ? Filter #1: BroadcastFilter{6d66b6}
? ? ? Action: "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE"
? ? ? Action: "android.intent.action.USER_STOPPED"
? ? ? Action: "android.intent.action.UID_REMOVED"
? ? ? AutoVerify=false
存在Filter #0 和 Filter #1,說明UninstallReceiver這個receiver動態(tài)注冊了兩次,兩次注冊的filter分別有所不同,過濾的action有所不同,查看AlaramManagerService.java的源碼后也確實如此
public UninstallReceiver() {
? ? ? ? ? ? IntentFilter filter = new IntentFilter();
? ? ? ? ? ? filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
? ? ? ? ? ? filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
? ? ? ? ? ? filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
? ? ? ? ? ? filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
? ? ? ? ? ? filter.addDataScheme("package");
? ? ? ? ? ? getContext().registerReceiver(this, filter);
? ? ? ? ? ? ?// Register for events related to sdcard installation.
? ? ? ? ? ? IntentFilter sdFilter = new IntentFilter();
? ? ? ? ? ? sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
? ? ? ? ? ? sdFilter.addAction(Intent.ACTION_USER_STOPPED);
? ? ? ? ? ? sdFilter.addAction(Intent.ACTION_UID_REMOVED);
? ? ? ? ? ? getContext().registerReceiver(this, sdFilter);
? ? ? ? }
Historical Broadcast foreground 列出位于前臺的歷史廣播
Historical Broadcast background 列出位于后臺的歷史廣播
經(jīng)常可以查看廣播從哪里發(fā)出。
2、虛擬機信息
Dalvik Thread
3、查看系統(tǒng)登錄了哪些賬號
DUMP OF SERVICE account:
屬于dumpstate的第四個階段的DumpsysAll中的dumpsys account
4、等待的intent的狀態(tài)
ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)
5、所有所有注冊的broadcastReceiver及其filter、action的信息
ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)
6、顯示所有content providers信息
ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)
7、當(dāng)前active狀態(tài)的service信息
ACTIVITY MANAGER SERVICES (dumpsys activity services)
上述4、5、6、7都是發(fā)生在dumpsys activity的過程中
8、查看CPU最近的使用情況
DUMP OF SERVICE cpuinfo:
9、查看系統(tǒng)上db的相關(guān)情況,app的數(shù)據(jù)庫最近的操作情況
DUMP OF SERVICE dbinfo
10、查看當(dāng)前的notification,每個NotificationRecord記錄一個通知
DUMP OF SERVICE notification
11、查看某個包的信息,包名是AndroidManifest.xml中的包名
Package [com.samsung.android.email.provider]
這里也可以查看app的版本
12、查看是否發(fā)生了ANR
WINDOW MANAGER LAST ANR (dumpsys window lastanr)
13、查看data是否連接的信息
DUMP OF SERVICE connectivity
14、查看email service的相關(guān)信息
SERVICE com.samsung.android.email.provider/com.samsung.android.email.sync.service.EmailService
SERVICE com.samsung.android.email.provider/com.samsung.android.email.sync.exchange.ExchangeService
15、查看Email是否收到新郵件,更新badge
11-16 14:50:54.314: D/BadgeCache(12920): 1. updateBadgeCounts: com.samsung.android.email.provider = 2,2表示badge的數(shù)量
16、查看手機芯片
Chip Name
17、手機使用的網(wǎng)絡(luò)
Network: China Telecom
18、Debug Level : 1
19、語言Current Lang Name : English (US)
20、查看是哪里啟動當(dāng)前activity,可查看event log
如查到當(dāng)前activity的event log:am_create_activity
可查看前面am_on_stop_called,am_destroy_activity,am_finish_activity,am_pause_activity,便可以推斷出是哪里啟動當(dāng)前activity
21、查看每個進程的流量消耗
------ QTAGUID STATS INFO (/proc/net/xt_qtaguid/stats) ------
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
總結(jié)
以上是生活随笔為你收集整理的dumpstate log总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java计算机毕业设计高校多媒体设备运维
- 下一篇: Linux常用命令,个人学习笔记