-------------------------------------------------------------- 這篇文章的小目標(biāo): 1. systrace是怎么抓出來的 2. 這些信息的來源是什么 ------------------------------------
[Android systrace系列] systrace入門第一式 介紹了用命令行抓取systrace的方法。 打開systrace.py的目錄,會發(fā)現(xiàn)一大堆python文件,讓人以為抓取systrace的流程很復(fù)雜。 其實(shí)不然,systrace是附屬于catapult這個項目(傳送門),是一個抓trace的框架,而且不僅僅為Andorid服務(wù)。
打開/catapult/systrace/systrace/tracing_agents,我們就能發(fā)現(xiàn)很多抓trace的agent,這是抓不同類型信息對應(yīng)的代碼邏輯。 抓Android默認(rèn)用到這三個agent,對應(yīng)三類信息: atrace_agent(atrace,負(fù)責(zé)收集用戶空間打印的systrace log和kernel ftrace事件) android_process_data_agent(ps命令,用來對應(yīng)進(jìn)程名與PID) android_cgroup_agent(cgroup中cpuset子系統(tǒng),市面銷售的機(jī)器不一定能抓到)
atrace抓取的信息是Android systrace中最核心的部分。 通過atrace_agent.py的函數(shù)StartAgentTracing和StopAgentTracing,我們終于知道了systrace的主要部分是通過atrace命令抓取的。 實(shí)質(zhì)上,只抓取atrace就可以生成systrace html文件了。 雖然使用systrace.py是抓取systrace最常規(guī)的方法,但如果要在測試腳本加入抓systrace的操作,我認(rèn)為atrace命令是最直接的方法,也可以節(jié)省測試腳本的運(yùn)行時間。 這也有助于了解systrace的細(xì)節(jié),衍生出更多技巧。
0. 執(zhí)行adb shell atrace --list_categories,選擇你需要的log類別 1. adb shell atrace --async_start -b 8192 gfx input view webview wm am sm audio video camera hal res dalvik rs bionic power pm ss database network sched freq idle disk sync memreclaim binder_driver binder_lock gfx ion 2. 重現(xiàn)問題,現(xiàn)象出現(xiàn)后,執(zhí)行 adb shell atrace --async_stop -z > a.out 3. 事后轉(zhuǎn)換成html文件,systrace.py --from-file a.out -o a.html
現(xiàn)在我們閱讀atrace的代碼,尋找更多細(xì)節(jié)。 代碼路徑://android/frameworks/native/cmds/atrace/atrace.cpp 這個數(shù)組,就是之前提到的systrace信息的兩大來源,用戶空間打印的systrace log和kernel ftrace事件。 用戶空間systrace log:ATRACE_TAG 開頭的 kernel ftrace:events開頭的 static const TracingCategory k_categories[] = { { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { { OPT, "events/mdss/enable" }, { OPT, "events/sde/enable" }, } }, { "input", "Input", ATRACE_TAG_INPUT, { } }, { "view", "View System", ATRACE_TAG_VIEW, { } }, { "webview", "WebView", ATRACE_TAG_WEBVIEW, { } }, { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } }, { "am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } }, { "sm", "Sync Manager", ATRACE_TAG_SYNC_MANAGER, { } }, { "audio", "Audio", ATRACE_TAG_AUDIO, { } }, { "video", "Video", ATRACE_TAG_VIDEO, { } }, { "camera", "Camera", ATRACE_TAG_CAMERA, { } }, { "hal", "Hardware Modules", ATRACE_TAG_HAL, { } }, { "res", "Resource Loading", ATRACE_TAG_RESOURCES, { } }, { "dalvik", "Dalvik VM", ATRACE_TAG_DALVIK, { } }, { "rs", "RenderScript", ATRACE_TAG_RS, { } }, { "bionic", "Bionic C Library", ATRACE_TAG_BIONIC, { } }, { "power", "Power Management", ATRACE_TAG_POWER, { } }, { "pm", "Package Manager", ATRACE_TAG_PACKAGE_MANAGER, { } }, { "ss", "System Server", ATRACE_TAG_SYSTEM_SERVER, { } }, { "database", "Database", ATRACE_TAG_DATABASE, { } }, { "network", "Network", ATRACE_TAG_NETWORK, { } }, { "adb", "ADB", ATRACE_TAG_ADB, { } }, { "vibrator", "Vibrator", ATRACE_TAG_VIBRATOR, { } }, { "aidl", "AIDL calls", ATRACE_TAG_AIDL, { } }, { k_coreServiceCategory, "Core services", 0, { } }, { k_pdxServiceCategory, "PDX services", 0, { } }, { "sched", "CPU Scheduling", 0, { { REQ, "events/sched/sched_switch/enable" }, { REQ, "events/sched/sched_wakeup/enable" }, { OPT, "events/sched/sched_waking/enable" }, { OPT, "events/sched/sched_blocked_reason/enable" }, { OPT, "events/sched/sched_cpu_hotplug/enable" }, { OPT, "events/sched/sched_pi_setprio/enable" }, { OPT, "events/cgroup/enable" }, } }, { "irq", "IRQ Events", 0, { { REQ, "events/irq/enable" }, { OPT, "events/ipi/enable" }, } }, { "irqoff", "IRQ-disabled code section tracing", 0, { { REQ, "events/preemptirq/irq_enable/enable" }, { REQ, "events/preemptirq/irq_disable/enable" }, } }, { "preemptoff", "Preempt-disabled code section tracing", 0, { { REQ, "events/preemptirq/preempt_enable/enable" }, { REQ, "events/preemptirq/preempt_disable/enable" }, } }, { "i2c", "I2C Events", 0, { { REQ, "events/i2c/enable" }, { REQ, "events/i2c/i2c_read/enable" }, { REQ, "events/i2c/i2c_write/enable" }, { REQ, "events/i2c/i2c_result/enable" }, { REQ, "events/i2c/i2c_reply/enable" }, { OPT, "events/i2c/smbus_read/enable" }, { OPT, "events/i2c/smbus_write/enable" }, { OPT, "events/i2c/smbus_result/enable" }, { OPT, "events/i2c/smbus_reply/enable" }, } }, { "freq", "CPU Frequency", 0, { { REQ, "events/power/cpu_frequency/enable" }, { OPT, "events/power/clock_set_rate/enable" }, { OPT, "events/power/clock_disable/enable" }, { OPT, "events/power/clock_enable/enable" }, { OPT, "events/clk/clk_set_rate/enable" }, { OPT, "events/clk/clk_disable/enable" }, { OPT, "events/clk/clk_enable/enable" }, { OPT, "events/power/cpu_frequency_limits/enable" }, } }, { "membus", "Memory Bus Utilization", 0, { { REQ, "events/memory_bus/enable" }, } }, { "idle", "CPU Idle", 0, { { REQ, "events/power/cpu_idle/enable" }, } }, { "disk", "Disk I/O", 0, { { OPT, "events/f2fs/f2fs_sync_file_enter/enable" }, { OPT, "events/f2fs/f2fs_sync_file_exit/enable" }, { OPT, "events/f2fs/f2fs_write_begin/enable" }, { OPT, "events/f2fs/f2fs_write_end/enable" }, { OPT, "events/ext4/ext4_da_write_begin/enable" }, { OPT, "events/ext4/ext4_da_write_end/enable" }, { OPT, "events/ext4/ext4_sync_file_enter/enable" }, { OPT, "events/ext4/ext4_sync_file_exit/enable" }, { REQ, "events/block/block_rq_issue/enable" }, { REQ, "events/block/block_rq_complete/enable" }, } }, { "mmc", "eMMC commands", 0, { { REQ, "events/mmc/enable" }, } }, { "load", "CPU Load", 0, { { REQ, "events/cpufreq_interactive/enable" }, } }, { "sync", "Synchronization", 0, { // before linux kernel 4.9 { OPT, "events/sync/enable" }, // starting in linux kernel 4.9 { OPT, "events/fence/enable" }, } }, { "workq", "Kernel Workqueues", 0, { { REQ, "events/workqueue/enable" }, } }, { "memreclaim", "Kernel Memory Reclaim", 0, { { REQ, "events/vmscan/mm_vmscan_direct_reclaim_begin/enable" }, { REQ, "events/vmscan/mm_vmscan_direct_reclaim_end/enable" }, { REQ, "events/vmscan/mm_vmscan_kswapd_wake/enable" }, { REQ, "events/vmscan/mm_vmscan_kswapd_sleep/enable" }, { OPT, "events/lowmemorykiller/enable" }, } }, { "regulators", "Voltage and Current Regulators", 0, { { REQ, "events/regulator/enable" }, } }, { "binder_driver", "Binder Kernel driver", 0, { { REQ, "events/binder/binder_transaction/enable" }, { REQ, "events/binder/binder_transaction_received/enable" }, { OPT, "events/binder/binder_set_priority/enable" }, } }, { "binder_lock", "Binder global lock trace", 0, { { OPT, "events/binder/binder_lock/enable" }, { OPT, "events/binder/binder_locked/enable" }, { OPT, "events/binder/binder_unlock/enable" }, } }, { "pagecache", "Page cache", 0, { { REQ, "events/filemap/enable" }, } }, };
各個ATRACE_TAG_XXX的功能是掩碼,在 //android/system/core/include/cutils/trace.h 的函數(shù) static inline void atrace_begin(uint64_t tag, const char* name) 中控制是否寫入相應(yīng)TAG的log。
systrace在各層的調(diào)用接口,以及最終systrace的log格式如下表: (看不清楚的可以右擊圖片,在新標(biāo)簽頁打開圖片)
跟蹤上表的代碼很容易會發(fā)現(xiàn),用戶空間的systrace log,最終通過libcutils的接口,寫入到 手機(jī)的 /sys/kernel/debug/tracing/trace_marker,就是寫入到kernel ftrace的buffer中。 用戶空間打印的systrace log 和 kernel ftrace事件在這里勝利會師了。
用純文本打開systrace html 文件,除了上述兩類log,開頭還有一大段Javascript。 通過Javascript的解析處理,呈現(xiàn)出systrace可視化的分析界面。
轉(zhuǎn)載請注明出處:https://www.cnblogs.com/zzcperf/p/14052681.html |
|