dumpstate log总结
dumpstate的結構
dumpState log在Android開發中是解決問題的重要途徑之一,dumpstate文件一般有幾十萬行的log,要從這么多log中找出想要的關鍵信息,如果不掌握一定的技巧,儼然大海撈針。先從總體上了解dumpstate的結構,以至于不會迷失在log海當中.
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程序,并將結果重定位到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提供給開發者的幫助了解系統運行狀態的利器。
從main函數看起:
1. 設置執行dumpstate這個命令的進程的一些屬性
??? 使它不會占用過多系統資源,即利用setpriority來告知內核它可以隨時被調度
??? 因為在手機系統信息,通過proc/self/oom_adj接口來告知內核(-17這是一個特殊的參數,詳見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權限,就可以從dalvik處獲得各種dalvik提供的trace信息
??? 利用了utils/中的dump_vm_traces函數,
???其中通過proc/[pid]/exe的link的程序如果是app_process,再找到對應pid下的cmdline過濾掉根 zygote,即得到所有由Android系統通過zygote所fork出來的所有的dalvik process(即各個APK)。
??? 從這里可以看出,所有的APK都是由app_process這個應用從跟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. 解析參數
??? 中間一個有一個關于使用socket的參數值得看一下
??? 它使用到了由init.rc中定義的專門給dumpstate使用的socket
??? service dumpstate /system/bin/dumpstate -s
??? socket dumpstate stream 0660 shell log
??? disabled
??? oneshot
??? 相關啟動各種系統service的init.rc的命令參見/init/readme.txt
4. 如果有root權限,拿到控制vibrator的權限和獲得kernel啟動的cmd參數
?? vibrator用來在dumpstate結束之后震動以提示用戶。這是一個在嵌入式設備中常用的提示技巧,有時候也會用簡單一個聲音提示。
?? kernel的啟動參數會在dump出來的信息中顯示。
5. 根據dumpstate的參數做一些簡單的準備,然后調用dumpstate()
?? 關鍵的dumpstate函數
?? 5.1 通過property_get獲得一些從kernel cmdline及vendor提供的property信息(參見default.prop, build.prop中的預設值)
?? 5.2 通過proc系統獲得各種內存管理系統提供的信息(如, /proc/meminfo, top等等),其中利用了android提供的一個procrank命令獲得制定進程的信息(參見我的另一篇文章,《Android性能分析工具之procrank》)
?? 5.3 dump logcat中的信息和一些網絡信息(netcfg, /proc/net/XXX下的內容)
?? 5.4 dump 一些dalvik收集的trace信息
?? 5.5 dump properties信息
?? 5.6 各種通過sysfs接口暴露出來的kernel信息
?? 5.7 vold, native packages, led燈等信息
?? 5.8 調用dumpsys,顯示dumpsys的信息
6. dumpstate()結束之后的一些后續處理(文件copy,壓縮等等)
Log工具
要打印一句log,通過這樣的方法,Log.i("csf", "log test");
Log源碼在android\frameworks\base\core\java\android\util\Log.java,看Log.i的實現
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層實現,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()函數中,這個函數在android\system\core\liblog\logd_write.c中
通過分析,總結出下面,具體請查看源碼
通過Log.d、Log.i、Log.v等輸出的log保存在/dev/log/main這個緩沖區中,一般app用這種方式打log
通過Rlog.d、Rlog.v、Rlog.i等輸出的log保存在/dev/log/radio這個緩沖區中,一般射頻、SIM、telephony模塊用這個比較多
通過Slog.d、Slog.v、Slog.i等輸出的log保存在/dev/log/system這個緩沖區中,很多framework的log都用Slog
通過EventLog.writeEvent輸出的log保存在/dev/log/events這個緩沖區中,一般用在framework模塊中
查看FrameWork所有service的信息,實際上運行的是dumpsys serviceName
比如:
dumpsys account列出所有賬戶
dumpsys activity activity的相關信息
dumpsys的代碼在android\frameworks\native\cmds\dumpsys\dumpsys.cpp
從源碼實現中看,是遍歷所有的service,然后調用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()函數
一些關鍵字
1、廣播相關信息
ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)
Registered Receivers 列出系統中所有動態注冊的廣播接收者ReceiverList,該結構包含一些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動態注冊了兩次,兩次注冊的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 列出位于后臺的歷史廣播
經常可以查看廣播從哪里發出。
2、虛擬機信息
Dalvik Thread
3、查看系統登錄了哪些賬號
DUMP OF SERVICE account:
屬于dumpstate的第四個階段的DumpsysAll中的dumpsys account
4、等待的intent的狀態
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、當前active狀態的service信息
ACTIVITY MANAGER SERVICES (dumpsys activity services)
上述4、5、6、7都是發生在dumpsys activity的過程中
8、查看CPU最近的使用情況
DUMP OF SERVICE cpuinfo:
9、查看系統上db的相關情況,app的數據庫最近的操作情況
DUMP OF SERVICE dbinfo
10、查看當前的notification,每個NotificationRecord記錄一個通知
DUMP OF SERVICE notification
11、查看某個包的信息,包名是AndroidManifest.xml中的包名
Package [com.samsung.android.email.provider]
這里也可以查看app的版本
12、查看是否發生了ANR
WINDOW MANAGER LAST ANR (dumpsys window lastanr)
13、查看data是否連接的信息
DUMP OF SERVICE connectivity
14、查看email service的相關信息
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的數量
16、查看手機芯片
Chip Name
17、手機使用的網絡
Network: China Telecom
18、Debug Level : 1
19、語言Current Lang Name : English (US)
20、查看是哪里啟動當前activity,可查看event log
如查到當前activity的event log:am_create_activity
可查看前面am_on_stop_called,am_destroy_activity,am_finish_activity,am_pause_activity,便可以推斷出是哪里啟動當前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
總結
以上是生活随笔為你收集整理的dumpstate log总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java计算机毕业设计高校多媒体设备运维
- 下一篇: 机器学习模型脆弱性和安全性的提议