1fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis/* 2fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * Copyright (C) 2012 The Android Open Source Project 3fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * 4fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 5fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * you may not use this file except in compliance with the License. 6fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * You may obtain a copy of the License at 7fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * 8fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 9fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * 10fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * Unless required by applicable law or agreed to in writing, software 11fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 12fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * See the License for the specific language governing permissions and 14fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis * limitations under the License. 15fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis */ 16fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 172cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence#define LOG_TAG "atrace" 1840b26b4fc597f105823bc1e2a640e4df8baea243John Reck 19fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <errno.h> 20fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <fcntl.h> 214edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling#include <getopt.h> 2292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <inttypes.h> 23fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <signal.h> 24fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <stdarg.h> 25fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <stdbool.h> 26fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <stdio.h> 27fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <stdlib.h> 283da5d235dab9469ccec567c4ebbb5206f4558a18Elliott Hughes#include <string.h> 29fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis#include <time.h> 30d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen#include <unistd.h> 317b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis#include <zlib.h> 32fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 33ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson#include <fstream> 34a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes#include <memory> 35a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes 366eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis#include <binder/IBinder.h> 376eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis#include <binder/IServiceManager.h> 386eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis#include <binder/Parcel.h> 396eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 40ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen#include <android/hidl/manager/1.0/IServiceManager.h> 41ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen#include <hidl/ServiceManagement.h> 426eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 43a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka#include <pdx/default_transport/service_utility.h> 446eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis#include <utils/String8.h> 45469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck#include <utils/Timers.h> 4646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda#include <utils/Tokenizer.h> 476eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis#include <utils/Trace.h> 48d8419c29e3a32cf9eebed8ef7f34e27fa756b17eStephane Gasparini#include <android-base/file.h> 495fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes#include <android-base/macros.h> 505fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes#include <android-base/properties.h> 515fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes#include <android-base/stringprintf.h> 526eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 536eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisusing namespace android; 54a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabakausing pdx::default_transport::ServiceUtility; 556eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 56ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenenusing std::string; 57ac9453d82e9077a8b02afa4e26ef9ff1f47b4ee9Jeff Brown 584144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv#define MAX_SYS_FILES 10 596eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 606eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisconst char* k_traceTagsProperty = "debug.atrace.tags.enableflags"; 6165ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jacksonconst char* k_userInitiatedTraceProperty = "debug.atrace.user_initiated"; 624144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv 634144eff1e261f6462be3753fc9543d82f9a4fd96sergeyvconst char* k_traceAppsNumberProperty = "debug.atrace.app_number"; 644144eff1e261f6462be3753fc9543d82f9a4fd96sergeyvconst char* k_traceAppsPropertyTemplate = "debug.atrace.app_%d"; 65db40415e05e39c1f4faa62735f435b031e53af7csergeyvconst char* k_coreServiceCategory = "core_services"; 66a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabakaconst char* k_pdxServiceCategory = "pdx"; 67db40415e05e39c1f4faa62735f435b031e53af7csergeyvconst char* k_coreServicesProp = "ro.atrace.core.services"; 686eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 696eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennistypedef enum { OPT, REQ } requiredness ; 706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 716eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstruct TracingCategory { 726eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // The name identifying the category. 736eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* name; 746eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 756eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // A longer description of the category. 766eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* longname; 776eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 786eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // The userland tracing tags that the category enables. 796eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis uint64_t tags; 806eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 816eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // The fname==NULL terminated list of /sys/ files that the category 826eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // enables. 836eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis struct { 846eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // Whether the file must be writable in order to enable the tracing 856eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // category. 866eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis requiredness required; 876eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 886eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // The path to the enable file. 896eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* path; 906eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } sysfiles[MAX_SYS_FILES]; 916eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis}; 926eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 936eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis/* Tracing categories */ 946eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic const TracingCategory k_categories[] = { 95732a29a4a6f07958bd15e01c5ec1fdab53243374John Reck { "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { 96732a29a4a6f07958bd15e01c5ec1fdab53243374John Reck { OPT, "events/mdss/enable" }, 97e2c104625d60ee2be3d727f7074fe649c3fed377Wei Wang { OPT, "events/sde/enable" }, 98732a29a4a6f07958bd15e01c5ec1fdab53243374John Reck } }, 99b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "input", "Input", ATRACE_TAG_INPUT, { } }, 100b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "view", "View System", ATRACE_TAG_VIEW, { } }, 101b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "webview", "WebView", ATRACE_TAG_WEBVIEW, { } }, 102b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "wm", "Window Manager", ATRACE_TAG_WINDOW_MANAGER, { } }, 103b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } }, 10470ec2941530766bdca09ef2983a3ff794c028ee6Patrick Auchter { "sm", "Sync Manager", ATRACE_TAG_SYNC_MANAGER, { } }, 105b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "audio", "Audio", ATRACE_TAG_AUDIO, { } }, 106b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "video", "Video", ATRACE_TAG_VIDEO, { } }, 107b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "camera", "Camera", ATRACE_TAG_CAMERA, { } }, 108b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "hal", "Hardware Modules", ATRACE_TAG_HAL, { } }, 1099380d78c98d8b8fbce9ade5881fab7134fadc015Dianne Hackborn { "res", "Resource Loading", ATRACE_TAG_RESOURCES, { } }, 110eff2e8d2374692213204468433e3d96e7472ea02Jamie Gennis { "dalvik", "Dalvik VM", ATRACE_TAG_DALVIK, { } }, 111f0f2841d95a26247dfa0b31a6bfa8b010fe89aa2Tim Murray { "rs", "RenderScript", ATRACE_TAG_RS, { } }, 112750aa9743c0c4c592213fbb39b8d328bd0075fd6Brigid Smith { "bionic", "Bionic C Library", ATRACE_TAG_BIONIC, { } }, 1133200b0bf507936ecf43784191880e4e91c54568cJeff Brown { "power", "Power Management", ATRACE_TAG_POWER, { } }, 11401e111b5a02440c0684494e9286709285e20097fTodd Kennedy { "pm", "Package Manager", ATRACE_TAG_PACKAGE_MANAGER, { } }, 1157cc4977ccd98a4ee557c8382bbc705eef702bdb6Yasuhiro Matsuda { "ss", "System Server", ATRACE_TAG_SYSTEM_SERVER, { } }, 116bbd7d991db7cdb0f09a765d23e32c7441eb0393fGreg Hackmann { "database", "Database", ATRACE_TAG_DATABASE, { } }, 1170f97c1d775dd95fab5142d7aae6d34b80b4c2312Felipe Leme { "network", "Network", ATRACE_TAG_NETWORK, { } }, 118468b4cb566fd81d7181764d3f7121125c7db3b24Josh Gao { "adb", "ADB", ATRACE_TAG_ADB, { } }, 11947791e972a0127399808e429361e99c8a3a50c38Martijn Coenen { "vibrator", "Vibrator", ATRACE_TAG_VIBRATOR, { } }, 12047791e972a0127399808e429361e99c8a3a50c38Martijn Coenen { "aidl", "AIDL calls", ATRACE_TAG_AIDL, { } }, 121db40415e05e39c1f4faa62735f435b031e53af7csergeyv { k_coreServiceCategory, "Core services", 0, { } }, 122a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka { k_pdxServiceCategory, "PDX services", 0, { } }, 123b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "sched", "CPU Scheduling", 0, { 1242cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/sched/sched_switch/enable" }, 1252cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/sched/sched_wakeup/enable" }, 126ee593e27cf607ab4603f65e89a7a366c5f154942Joel Fernandes { OPT, "events/sched/sched_waking/enable" }, 1272cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/sched/sched_blocked_reason/enable" }, 1282cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/sched/sched_cpu_hotplug/enable" }, 129ca49dfccbadab5ac57d4f8bb31b2a6a0a51c0fb2Wei Wang { OPT, "events/sched/sched_pi_setprio/enable" }, 1304dfca7c9d7decf492b244cd031d98c30c6a592ebJoel Fernandes { OPT, "events/cgroup/enable" }, 1316eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 132f440d398faad3bafe2e7f365c62163aca45e36a3Dan Willemsen { "irq", "IRQ Events", 0, { 1332cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/irq/enable" }, 1342cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/ipi/enable" }, 135f440d398faad3bafe2e7f365c62163aca45e36a3Dan Willemsen } }, 1360ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { "irqoff", "IRQ-disabled code section tracing", 0, { 1370ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { REQ, "events/preemptirq/irq_enable/enable" }, 1380ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { REQ, "events/preemptirq/irq_disable/enable" }, 1390ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes } }, 1400ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { "preemptoff", "Preempt-disabled code section tracing", 0, { 1410ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { REQ, "events/preemptirq/preempt_enable/enable" }, 1420ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes { REQ, "events/preemptirq/preempt_disable/enable" }, 1430ad0f3059ffca0c6e1de680ca7e68d5150b8b14fJoel Fernandes } }, 14443fb6787bcb749c6d848235e82fa17a002379bbfMichael Wright { "i2c", "I2C Events", 0, { 1452cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/i2c/enable" }, 1462cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/i2c/i2c_read/enable" }, 1472cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/i2c/i2c_write/enable" }, 1482cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/i2c/i2c_result/enable" }, 1492cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/i2c/i2c_reply/enable" }, 1502cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/i2c/smbus_read/enable" }, 1512cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/i2c/smbus_write/enable" }, 1522cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/i2c/smbus_result/enable" }, 1532cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/i2c/smbus_reply/enable" }, 15443fb6787bcb749c6d848235e82fa17a002379bbfMichael Wright } }, 155b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "freq", "CPU Frequency", 0, { 1562cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/power/cpu_frequency/enable" }, 1572cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/power/clock_set_rate/enable" }, 158afc2f970e479dca5f9676474879b0b8d4beac82aKevin DuBois { OPT, "events/power/clock_disable/enable" }, 159afc2f970e479dca5f9676474879b0b8d4beac82aKevin DuBois { OPT, "events/power/clock_enable/enable" }, 160391efc2e4a00e6e408d5a21c138ef8bcba90eb90Wei Wang { OPT, "events/clk/clk_set_rate/enable" }, 161391efc2e4a00e6e408d5a21c138ef8bcba90eb90Wei Wang { OPT, "events/clk/clk_disable/enable" }, 162391efc2e4a00e6e408d5a21c138ef8bcba90eb90Wei Wang { OPT, "events/clk/clk_enable/enable" }, 1632cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/power/cpu_frequency_limits/enable" }, 1646eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 165b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "membus", "Memory Bus Utilization", 0, { 1662cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/memory_bus/enable" }, 1676eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 168b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "idle", "CPU Idle", 0, { 1692cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/power/cpu_idle/enable" }, 1706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 171b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "disk", "Disk I/O", 0, { 1722cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/f2fs/f2fs_sync_file_enter/enable" }, 1732cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/f2fs/f2fs_sync_file_exit/enable" }, 1742cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/f2fs/f2fs_write_begin/enable" }, 1752cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/f2fs/f2fs_write_end/enable" }, 1762cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/ext4/ext4_da_write_begin/enable" }, 1772cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/ext4/ext4_da_write_end/enable" }, 1782cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/ext4/ext4_sync_file_enter/enable" }, 1792cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { OPT, "events/ext4/ext4_sync_file_exit/enable" }, 1802cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/block/block_rq_issue/enable" }, 1812cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/block/block_rq_complete/enable" }, 1826eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 183d3fa5616160c53d5bec8cd91d65f3732413c1a56Ken Sumrall { "mmc", "eMMC commands", 0, { 1842cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/mmc/enable" }, 185d3fa5616160c53d5bec8cd91d65f3732413c1a56Ken Sumrall } }, 186b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "load", "CPU Load", 0, { 1872cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/cpufreq_interactive/enable" }, 1886eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 189b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "sync", "Synchronization", 0, { 190ae001a33fbfeb30f91ab33e675de7c3efa49111cJesse Hall // before linux kernel 4.9 191ae001a33fbfeb30f91ab33e675de7c3efa49111cJesse Hall { OPT, "events/sync/enable" }, 192ae001a33fbfeb30f91ab33e675de7c3efa49111cJesse Hall // starting in linux kernel 4.9 193ae001a33fbfeb30f91ab33e675de7c3efa49111cJesse Hall { OPT, "events/fence/enable" }, 1946eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 195b2a89e3155969e5bc9653966069d6dbabdd3f623Jamie Gennis { "workq", "Kernel Workqueues", 0, { 1962cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/workqueue/enable" }, 1976eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } }, 198580407f1075fe97d7466724f71cc03816b7404feColin Cross { "memreclaim", "Kernel Memory Reclaim", 0, { 1992cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/vmscan/mm_vmscan_direct_reclaim_begin/enable" }, 2002cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/vmscan/mm_vmscan_direct_reclaim_end/enable" }, 2012cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/vmscan/mm_vmscan_kswapd_wake/enable" }, 2022cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/vmscan/mm_vmscan_kswapd_sleep/enable" }, 203f1f62e3b73fa5b84a552332beeacce874fd9429cMarc Hittinger { REQ, "events/lowmemorykiller/enable" }, 204580407f1075fe97d7466724f71cc03816b7404feColin Cross } }, 205c2c6ecd1195481f5813a721a7d20a73c0795c135Aaron Schulman { "regulators", "Voltage and Current Regulators", 0, { 2062cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/regulator/enable" }, 207c2c6ecd1195481f5813a721a7d20a73c0795c135Aaron Schulman } }, 208ae473363270724550699a7fd9c110a839f79964cScott Bauer { "binder_driver", "Binder Kernel driver", 0, { 2092cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/binder/binder_transaction/enable" }, 2102cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/binder/binder_transaction_received/enable" }, 2117f3d7a2234d7fedc1333152a0567dec74d82ee9cMartijn Coenen { OPT, "events/binder/binder_set_priority/enable" }, 212ae473363270724550699a7fd9c110a839f79964cScott Bauer } }, 213ae473363270724550699a7fd9c110a839f79964cScott Bauer { "binder_lock", "Binder global lock trace", 0, { 214eb8acbf4af7f1ad7ae94337dc3e0d6a38eab4178Howard Chen { OPT, "events/binder/binder_lock/enable" }, 215eb8acbf4af7f1ad7ae94337dc3e0d6a38eab4178Howard Chen { OPT, "events/binder/binder_locked/enable" }, 216eb8acbf4af7f1ad7ae94337dc3e0d6a38eab4178Howard Chen { OPT, "events/binder/binder_unlock/enable" }, 217ae473363270724550699a7fd9c110a839f79964cScott Bauer } }, 2187048161951761cd5fe0109c34204ba8229f9eddfMartijn Coenen { "pagecache", "Page cache", 0, { 2192cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence { REQ, "events/filemap/enable" }, 2207048161951761cd5fe0109c34204ba8229f9eddfMartijn Coenen } }, 2216eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis}; 2226eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 223fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis/* Command line options */ 224fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic int g_traceDurationSeconds = 5; 225fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic bool g_traceOverwrite = false; 226cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennisstatic int g_traceBufferSizeKB = 2048; 2277b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennisstatic bool g_compress = false; 22831be80f02cddda55e75614884038fa4645b694cdGlenn Kastenstatic bool g_nohup = false; 22931be80f02cddda55e75614884038fa4645b694cdGlenn Kastenstatic int g_initialSleepSecs = 0; 23046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsudastatic const char* g_categoriesFile = NULL; 231e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* g_kernelTraceFuncs = NULL; 232f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennisstatic const char* g_debugAppCmdLine = ""; 23340b26b4fc597f105823bc1e2a640e4df8baea243John Reckstatic const char* g_outputFile = nullptr; 234fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 235fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis/* Global state */ 236a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabakastatic bool g_tracePdx = false; 237fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic bool g_traceAborted = false; 2385fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughesstatic bool g_categoryEnables[arraysize(k_categories)] = {}; 2392cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrencestatic std::string g_traceFolder; 240fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 241fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis/* Sys file paths */ 242fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic const char* k_traceClockPath = 2432cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "trace_clock"; 244fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 245cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennisstatic const char* k_traceBufferSizePath = 2462cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "buffer_size_kb"; 247cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 248734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh#if 0 249734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh// TODO: Re-enable after stabilization 250ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandesstatic const char* k_traceCmdlineSizePath = 251ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes "saved_cmdlines_size"; 252734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh#endif 253ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes 254fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic const char* k_tracingOverwriteEnablePath = 2552cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/overwrite"; 256fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 257e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_currentTracerPath = 2582cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "current_tracer"; 259e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 260e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_printTgidPath = 2612cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/print-tgid"; 262e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 263e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_funcgraphAbsTimePath = 2642cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/funcgraph-abstime"; 265e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 266e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_funcgraphCpuPath = 2672cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/funcgraph-cpu"; 268e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 269e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_funcgraphProcPath = 2702cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/funcgraph-proc"; 271e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 272e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_funcgraphFlatPath = 2732cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "options/funcgraph-flat"; 274e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 275e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic const char* k_ftraceFilterPath = 2762cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "set_ftrace_filter"; 277e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 278fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic const char* k_tracingOnPath = 2792cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "tracing_on"; 280fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 281fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic const char* k_tracePath = 2822cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "trace"; 283fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 284d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenenstatic const char* k_traceStreamPath = 2852cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "trace_pipe"; 286d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen 287469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reckstatic const char* k_traceMarkerPath = 2882cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence "trace_marker"; 289469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck 290e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennis// Check whether a file exists. 291e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennisstatic bool fileExists(const char* filename) { 2922cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence return access((g_traceFolder + filename).c_str(), F_OK) != -1; 293e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennis} 294e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennis 2956eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Check whether a file is writable. 2966eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool fileIsWritable(const char* filename) { 2972cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence return access((g_traceFolder + filename).c_str(), W_OK) != -1; 2986eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 2996eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 300e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Truncate a file. 301e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool truncateFile(const char* path) 302fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 30343122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis // This uses creat rather than truncate because some of the debug kernel 30443122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis // device nodes (e.g. k_ftraceFilterPath) currently aren't changed by 30543122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis // calls to truncate, but they are cleared by calls to creat. 3062cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence int traceFD = creat((g_traceFolder + path).c_str(), 0); 30743122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis if (traceFD == -1) { 3082cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence fprintf(stderr, "error truncating %s: %s (%d)\n", (g_traceFolder + path).c_str(), 30943122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis strerror(errno), errno); 310e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return false; 311e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 312e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 31343122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis close(traceFD); 31443122e7e672eb170334a4467dd41cf4bd545bae5Jamie Gennis 315e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return true; 316e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 317e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 318e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool _writeStr(const char* filename, const char* str, int flags) 319e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 3202cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence std::string fullFilename = g_traceFolder + filename; 3212cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence int fd = open(fullFilename.c_str(), flags); 322fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (fd == -1) { 3232cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence fprintf(stderr, "error opening %s: %s (%d)\n", fullFilename.c_str(), 324fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis strerror(errno), errno); 325fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return false; 326fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 327fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 328fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis bool ok = true; 329fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis ssize_t len = strlen(str); 330fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (write(fd, str, len) != len) { 3312cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence fprintf(stderr, "error writing to %s: %s (%d)\n", fullFilename.c_str(), 332fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis strerror(errno), errno); 333fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis ok = false; 334fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 335fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 336fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis close(fd); 337fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 338fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return ok; 339fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 340fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 341e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Write a string to a file, returning true if the write was successful. 342e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool writeStr(const char* filename, const char* str) 343e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 344e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return _writeStr(filename, str, O_WRONLY); 345e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 346e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 347e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Append a string to a file, returning true if the write was successful. 348e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool appendStr(const char* filename, const char* str) 349e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 350e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return _writeStr(filename, str, O_APPEND|O_WRONLY); 351e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 352e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 353469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reckstatic void writeClockSyncMarker() 354469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck{ 355469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck char buffer[128]; 3560bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen int len = 0; 3572cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence int fd = open((g_traceFolder + k_traceMarkerPath).c_str(), O_WRONLY); 3580bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen if (fd == -1) { 3590bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen fprintf(stderr, "error opening %s: %s (%d)\n", k_traceMarkerPath, 3600bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen strerror(errno), errno); 3610bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen return; 3620bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen } 363469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck float now_in_seconds = systemTime(CLOCK_MONOTONIC) / 1000000000.0f; 3640bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen 3650bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen len = snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds); 3660bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen if (write(fd, buffer, len) != len) { 3670bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno); 3680bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen } 3690bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen 3700bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen int64_t realtime_in_ms = systemTime(CLOCK_REALTIME) / 1000000; 3710bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen len = snprintf(buffer, 128, "trace_event_clock_sync: realtime_ts=%" PRId64 "\n", realtime_in_ms); 3720bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen if (write(fd, buffer, len) != len) { 3730bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno); 3740bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen } 3750bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen 3760bcd97a7485d971c5276e19b1a6c2672539dc38dMartijn Coenen close(fd); 377469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck} 378469a194051f1657b3f77ff2f5d84a60f7521fabaJohn Reck 3796eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Enable or disable a kernel option by writing a "1" or a "0" into a /sys 3806eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// file. 381fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic bool setKernelOptionEnable(const char* filename, bool enable) 382fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 383fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return writeStr(filename, enable ? "1" : "0"); 384fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 385fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 3866eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Check whether the category is supported on the device with the current 3876eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// rootness. A category is supported only if all its required /sys/ files are 3886eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// writable and if enabling the category will enable one or more tracing tags 3896eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// or /sys/ files. 3906eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool isCategorySupported(const TracingCategory& category) 3913169533f1d11c4a7aa0cd6fa2aa04fc810db0de6Jamie Gennis{ 392db40415e05e39c1f4faa62735f435b031e53af7csergeyv if (strcmp(category.name, k_coreServiceCategory) == 0) { 3935fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes return !android::base::GetProperty(k_coreServicesProp, "").empty(); 394db40415e05e39c1f4faa62735f435b031e53af7csergeyv } 395db40415e05e39c1f4faa62735f435b031e53af7csergeyv 396a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka if (strcmp(category.name, k_pdxServiceCategory) == 0) { 397a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka return true; 398a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka } 399a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka 4006eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool ok = category.tags != 0; 4016eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (int i = 0; i < MAX_SYS_FILES; i++) { 4026eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* path = category.sysfiles[i].path; 4036eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool req = category.sysfiles[i].required == REQ; 4046eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (path != NULL) { 4056eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (req) { 4066eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (!fileIsWritable(path)) { 4076eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return false; 4086eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else { 4096eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok = true; 4106eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 4116eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else { 412eb8acbf4af7f1ad7ae94337dc3e0d6a38eab4178Howard Chen ok = true; 4136eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 4146eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 415e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennis } 416e8744fd4dce2881c83d69c084b6937d0397ace05Jamie Gennis return ok; 417cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis} 418cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 4196eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Check whether the category would be supported on the device if the user 4206eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// were root. This function assumes that root is able to write to any file 4216eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// that exists. It performs the same logic as isCategorySupported, but it 422b5c95475996c59bacb0ee760f11bf792f71e0c77Fabien Sanglard// uses file existence rather than writability in the /sys/ file checks. 4236eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool isCategorySupportedForRoot(const TracingCategory& category) 4249ba4baf178bb9dad3912403bfd9aee07c14da33aErik Gilling{ 4256eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool ok = category.tags != 0; 4266eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (int i = 0; i < MAX_SYS_FILES; i++) { 4276eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* path = category.sysfiles[i].path; 4286eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool req = category.sysfiles[i].required == REQ; 4296eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (path != NULL) { 4306eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (req) { 4316eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (!fileExists(path)) { 4326eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return false; 4336eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else { 4346eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok = true; 4356eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 4366eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else { 4376eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok |= fileExists(path); 4386eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 4396eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 4409ba4baf178bb9dad3912403bfd9aee07c14da33aErik Gilling } 4419ba4baf178bb9dad3912403bfd9aee07c14da33aErik Gilling return ok; 4429ba4baf178bb9dad3912403bfd9aee07c14da33aErik Gilling} 4439ba4baf178bb9dad3912403bfd9aee07c14da33aErik Gilling 4446eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Enable or disable overwriting of the kernel trace buffers. Disabling this 4456eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// will cause tracing to stop once the trace buffers have filled up. 4466eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool setTraceOverwriteEnable(bool enable) 447ac9453d82e9077a8b02afa4e26ef9ff1f47b4ee9Jeff Brown{ 4486eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return setKernelOptionEnable(k_tracingOverwriteEnablePath, enable); 449ac9453d82e9077a8b02afa4e26ef9ff1f47b4ee9Jeff Brown} 450ac9453d82e9077a8b02afa4e26ef9ff1f47b4ee9Jeff Brown 45165ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson// Set the user initiated trace property 45265ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jacksonstatic bool setUserInitiatedTraceProperty(bool enable) 45365ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson{ 45465ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson if (!android::base::SetProperty(k_userInitiatedTraceProperty, enable ? "1" : "")) { 45565ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson fprintf(stderr, "error setting user initiated strace system property\n"); 45665ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson return false; 45765ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson } 45865ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson return true; 45965ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson} 46065ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson 461fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis// Enable or disable kernel tracing. 462fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic bool setTracingEnabled(bool enable) 463fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 464fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return setKernelOptionEnable(k_tracingOnPath, enable); 465fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 466fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 467fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis// Clear the contents of the kernel trace. 468fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisstatic bool clearTrace() 469fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 470e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return truncateFile(k_tracePath); 471fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 472fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 473cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis// Set the size of the kernel's trace buffer in kilobytes. 474cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennisstatic bool setTraceBufferSizeKB(int size) 475cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis{ 476cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis char str[32] = "1"; 477cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis if (size < 1) { 478cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis size = 1; 479cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis } 480cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis snprintf(str, 32, "%d", size); 481cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis return writeStr(k_traceBufferSizePath, str); 482cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis} 483cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 484734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh#if 0 485734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh// TODO: Re-enable after stabilization 486ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes// Set the default size of cmdline hashtable 487ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandesstatic bool setCmdlineSize() 488ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes{ 489ce964f2e6088761f3e2b22535010872327eff264Joel Fernandes if (fileExists(k_traceCmdlineSizePath)) { 490ce964f2e6088761f3e2b22535010872327eff264Joel Fernandes return writeStr(k_traceCmdlineSizePath, "8192"); 491ce964f2e6088761f3e2b22535010872327eff264Joel Fernandes } 492ce964f2e6088761f3e2b22535010872327eff264Joel Fernandes return true; 493ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes} 494734e378a7387b2d51f40f4e4cba8887703bd1839Chih-Hung Hsieh#endif 495ed80bd04cc3bf80082b1d733ef06d90a29c6270aJoel Fernandes 496ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson// Set the clock to the best available option while tracing. Use 'boot' if it's 497ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson// available; otherwise, use 'mono'. If neither are available use 'global'. 498b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749Colin Cross// Any write to the trace_clock sysfs file will reset the buffer, so only 499b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749Colin Cross// update it if the requested value is not the current value. 500ea826794184be368f65f099ceac4fc31234700f6Carmen Jacksonstatic bool setClock() 501fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 502ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson std::ifstream clockFile((g_traceFolder + k_traceClockPath).c_str(), O_RDONLY); 503ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson std::string clockStr((std::istreambuf_iterator<char>(clockFile)), 504ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson std::istreambuf_iterator<char>()); 505ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson 506ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson std::string newClock; 507ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson if (clockStr.find("boot") != std::string::npos) { 508ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson newClock = "boot"; 509ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson } else if (clockStr.find("mono") != std::string::npos) { 510ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson newClock = "mono"; 511ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson } else { 512ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson newClock = "global"; 513ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson } 514b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749Colin Cross 515cb057c2e6bf23b43df49282c0db26b663e4535f7Chih-Hung Hsieh size_t begin = clockStr.find('[') + 1; 516cb057c2e6bf23b43df49282c0db26b663e4535f7Chih-Hung Hsieh size_t end = clockStr.find(']'); 517ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson if (newClock.compare(0, std::string::npos, clockStr, begin, end-begin) == 0) { 518b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749Colin Cross return true; 519b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749Colin Cross } 520ea826794184be368f65f099ceac4fc31234700f6Carmen Jackson return writeStr(k_traceClockPath, newClock.c_str()); 521fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 522fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 523e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool setPrintTgidEnableIfPresent(bool enable) 524e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 525e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis if (fileExists(k_printTgidPath)) { 526e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return setKernelOptionEnable(k_printTgidPath, enable); 527e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 528e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return true; 529e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 530e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 5316eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Poke all the binder-enabled processes in the system to get them to re-read 5326eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// their system properties. 5336eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool pokeBinderServices() 5346eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis{ 5356eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis sp<IServiceManager> sm = defaultServiceManager(); 5366eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis Vector<String16> services = sm->listServices(); 5376eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (size_t i = 0; i < services.size(); i++) { 5386eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis sp<IBinder> obj = sm->checkService(services[i]); 5396eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (obj != NULL) { 5406eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis Parcel data; 5416eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (obj->transact(IBinder::SYSPROPS_TRANSACTION, data, 5426eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis NULL, 0) != OK) { 5436eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (false) { 5446eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // XXX: For some reason this fails on tablets trying to 5456eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // poke the "phone" service. It's not clear whether some 5466eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // are expected to fail. 5476eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis String8 svc(services[i]); 5486eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "error poking binder service %s\n", 5496eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis svc.string()); 5506eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return false; 5516eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 5526eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 5536eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 5546eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 5556eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return true; 5566eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 5576eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 558ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen// Poke all the HAL processes in the system to get them to re-read 559ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen// their system properties. 560ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenenstatic void pokeHalServices() 561ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen{ 562f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen using ::android::hidl::base::V1_0::IBase; 563ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen using ::android::hidl::manager::V1_0::IServiceManager; 564ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen using ::android::hardware::hidl_string; 565f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen using ::android::hardware::Return; 566ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen 567ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen sp<IServiceManager> sm = ::android::hardware::defaultServiceManager(); 568a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland 569a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland if (sm == nullptr) { 570a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland fprintf(stderr, "failed to get IServiceManager to poke hal services\n"); 571a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland return; 572a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland } 573a42866b4cb9218cc80b8217ff9ad6458c3c4864eSteven Moreland 5748cf4ed19624a7ca1dd2d8d5b0dee15ca2bcdba04Yifan Hong auto listRet = sm->list([&](const auto &interfaces) { 575ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen for (size_t i = 0; i < interfaces.size(); i++) { 576ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen string fqInstanceName = interfaces[i]; 577cb057c2e6bf23b43df49282c0db26b663e4535f7Chih-Hung Hsieh string::size_type n = fqInstanceName.find('/'); 578ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen if (n == std::string::npos || interfaces[i].size() == n+1) 579ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen continue; 580ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen hidl_string fqInterfaceName = fqInstanceName.substr(0, n); 581ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen hidl_string instanceName = fqInstanceName.substr(n+1, std::string::npos); 582f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen Return<sp<IBase>> interfaceRet = sm->get(fqInterfaceName, instanceName); 583f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen if (!interfaceRet.isOk()) { 5841e4a7fbdd392cb5af35bca169d90b35850a9e9f4Martijn Coenen // ignore 585f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen continue; 586f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen } 5877320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson 588f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen sp<IBase> interface = interfaceRet; 5897320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson if (interface == nullptr) { 5907320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson // ignore 5917320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson continue; 5927320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson } 5937320612aeb8674a63106299f2cba5d23df1ca03bCarmen Jackson 594f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen auto notifyRet = interface->notifySyspropsChanged(); 595f6ac84820198b66b687738cb5ec32b19e74fef2aMartijn Coenen if (!notifyRet.isOk()) { 5961e4a7fbdd392cb5af35bca169d90b35850a9e9f4Martijn Coenen // ignore 5978cf4ed19624a7ca1dd2d8d5b0dee15ca2bcdba04Yifan Hong } 598ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen } 599ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen }); 6008cf4ed19624a7ca1dd2d8d5b0dee15ca2bcdba04Yifan Hong if (!listRet.isOk()) { 60164d54eb0465c7c372ea1b57a9fa4984be0cd79f8Martijn Coenen // TODO(b/34242478) fix this when we determine the correct ACL 60264d54eb0465c7c372ea1b57a9fa4984be0cd79f8Martijn Coenen //fprintf(stderr, "failed to list services: %s\n", listRet.description().c_str()); 6038cf4ed19624a7ca1dd2d8d5b0dee15ca2bcdba04Yifan Hong } 604ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen} 605ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen 6066eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Set the trace tags that userland tracing uses, and poke the running 6076eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// processes to pick up the new value. 6086eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool setTagsProperty(uint64_t tags) 6096eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis{ 6105fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes std::string value = android::base::StringPrintf("%#" PRIx64, tags); 6115fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes if (!android::base::SetProperty(k_traceTagsProperty, value)) { 6126eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "error setting trace tags system property\n"); 6136eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return false; 6146eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 615f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis return true; 616f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis} 617f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis 6184144eff1e261f6462be3753fc9543d82f9a4fd96sergeyvstatic void clearAppProperties() 6194144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv{ 6205fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes if (!android::base::SetProperty(k_traceAppsNumberProperty, "")) { 6214144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv fprintf(stderr, "failed to clear system property: %s", 6224144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv k_traceAppsNumberProperty); 6234144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv } 6244144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv} 6254144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv 626f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis// Set the system property that indicates which apps should perform 627f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis// application-level tracing. 62809a7987fb59ed6843d51acf0161d66ed3eb2252fDan Austinstatic bool setAppCmdlineProperty(char* cmdline) 629f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis{ 6304144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv int i = 0; 63109a7987fb59ed6843d51acf0161d66ed3eb2252fDan Austin char* start = cmdline; 6324144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv while (start != NULL) { 6334144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv char* end = strchr(start, ','); 6344144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv if (end != NULL) { 6354144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv *end = '\0'; 6364144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv end++; 6374144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv } 6385fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes std::string key = android::base::StringPrintf(k_traceAppsPropertyTemplate, i); 6395fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes if (!android::base::SetProperty(key, start)) { 6405fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes fprintf(stderr, "error setting trace app %d property to %s\n", i, key.c_str()); 6414144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv clearAppProperties(); 6424144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv return false; 6434144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv } 6444144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv start = end; 6454144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv i++; 6464144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv } 6474144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv 6485fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes std::string value = android::base::StringPrintf("%d", i); 6495fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes if (!android::base::SetProperty(k_traceAppsNumberProperty, value)) { 6505fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes fprintf(stderr, "error setting trace app number property to %s\n", value.c_str()); 6514144eff1e261f6462be3753fc9543d82f9a4fd96sergeyv clearAppProperties(); 652f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis return false; 653f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis } 654f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis return true; 6556eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 6566eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 6576eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Disable all /sys/ enable files. 6586eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic bool disableKernelTraceEvents() { 6596eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool ok = true; 6605fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 6616eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const TracingCategory &c = k_categories[i]; 6626eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (int j = 0; j < MAX_SYS_FILES; j++) { 6636eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* path = c.sysfiles[j].path; 6646eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (path != NULL && fileIsWritable(path)) { 6656eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok &= setKernelOptionEnable(path, false); 6666eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 6676eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 6686eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 6696eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis return ok; 6706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 6716eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 672e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Verify that the comma separated list of functions are being traced by the 673e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// kernel. 674e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool verifyKernelTraceFuncs(const char* funcs) 675e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 676d8419c29e3a32cf9eebed8ef7f34e27fa756b17eStephane Gasparini std::string buf; 6772cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence if (!android::base::ReadFileToString(g_traceFolder + k_ftraceFilterPath, &buf)) { 678d8419c29e3a32cf9eebed8ef7f34e27fa756b17eStephane Gasparini fprintf(stderr, "error opening %s: %s (%d)\n", k_ftraceFilterPath, 679e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis strerror(errno), errno); 680d8419c29e3a32cf9eebed8ef7f34e27fa756b17eStephane Gasparini return false; 681e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 682e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 683d8419c29e3a32cf9eebed8ef7f34e27fa756b17eStephane Gasparini String8 funcList = String8::format("\n%s",buf.c_str()); 684e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 685e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis // Make sure that every function listed in funcs is in the list we just 686a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot // read from the kernel, except for wildcard inputs. 687e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis bool ok = true; 688e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis char* myFuncs = strdup(funcs); 689e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis char* func = strtok(myFuncs, ","); 690e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis while (func) { 691a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot if (!strchr(func, '*')) { 692a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot String8 fancyFunc = String8::format("\n%s\n", func); 693a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot bool found = funcList.find(fancyFunc.string(), 0) >= 0; 694a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot if (!found || func[0] == '\0') { 695a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot fprintf(stderr, "error: \"%s\" is not a valid kernel function " 696a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot "to trace.\n", func); 697a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot ok = false; 698a2c228770ea1cadc1d06406baad899b8c500389aThomas Buhot } 699e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 700e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis func = strtok(NULL, ","); 701e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 702e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis free(myFuncs); 703e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return ok; 704e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 705e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 706e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Set the comma separated list of functions that the kernel is to trace. 707e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool setKernelTraceFuncs(const char* funcs) 708e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 709e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis bool ok = true; 710e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 711e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis if (funcs == NULL || funcs[0] == '\0') { 712e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis // Disable kernel function tracing. 7136f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis if (fileIsWritable(k_currentTracerPath)) { 7146f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis ok &= writeStr(k_currentTracerPath, "nop"); 7156f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis } 7166f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis if (fileIsWritable(k_ftraceFilterPath)) { 717e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= truncateFile(k_ftraceFilterPath); 718e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 719e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } else { 720e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis // Enable kernel function tracing. 721e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= writeStr(k_currentTracerPath, "function_graph"); 722e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= setKernelOptionEnable(k_funcgraphAbsTimePath, true); 723e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= setKernelOptionEnable(k_funcgraphCpuPath, true); 724e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= setKernelOptionEnable(k_funcgraphProcPath, true); 725e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= setKernelOptionEnable(k_funcgraphFlatPath, true); 726e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 727e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis // Set the requested filter functions. 728e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= truncateFile(k_ftraceFilterPath); 729e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis char* myFuncs = strdup(funcs); 730e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis char* func = strtok(myFuncs, ","); 731e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis while (func) { 732e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= appendStr(k_ftraceFilterPath, func); 733e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis func = strtok(NULL, ","); 734e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 735e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis free(myFuncs); 736e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 737e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis // Verify that the set functions are being traced. 738e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis if (ok) { 739e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis ok &= verifyKernelTraceFuncs(funcs); 740e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 741e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis } 742e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 743e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return ok; 744e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 745e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 74646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsudastatic bool setCategoryEnable(const char* name, bool enable) 74746c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda{ 7485fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 74946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda const TracingCategory& c = k_categories[i]; 75046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (strcmp(name, c.name) == 0) { 75146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (isCategorySupported(c)) { 75246c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda g_categoryEnables[i] = enable; 75346c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return true; 75446c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } else { 75546c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (isCategorySupportedForRoot(c)) { 75646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda fprintf(stderr, "error: category \"%s\" requires root " 75746c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda "privileges.\n", name); 75846c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } else { 75946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda fprintf(stderr, "error: category \"%s\" is not supported " 76046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda "on this device.\n", name); 76146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 76246c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return false; 76346c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 76446c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 76546c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 76646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda fprintf(stderr, "error: unknown tracing category \"%s\"\n", name); 76746c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return false; 76846c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda} 76946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda 77046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsudastatic bool setCategoriesEnableFromFile(const char* categories_file) 77146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda{ 77246c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (!categories_file) { 77346c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return true; 77446c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 77546c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda Tokenizer* tokenizer = NULL; 77646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (Tokenizer::open(String8(categories_file), &tokenizer) != NO_ERROR) { 77746c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return false; 77846c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 77946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda bool ok = true; 78046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda while (!tokenizer->isEol()) { 78146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda String8 token = tokenizer->nextToken(" "); 78246c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda if (token.isEmpty()) { 78346c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda tokenizer->skipDelimiters(" "); 78446c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda continue; 78546c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 78646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda ok &= setCategoryEnable(token.string(), true); 78746c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda } 78846c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda delete tokenizer; 78946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda return ok; 79046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda} 79146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda 792550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearmanstatic bool setUpUserspaceTracing() 793fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 794fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis bool ok = true; 795fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 7966eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // Set up the tags property. 7976eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis uint64_t tags = 0; 7985fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 7996eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (g_categoryEnables[i]) { 8006eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const TracingCategory &c = k_categories[i]; 8016eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis tags |= c.tags; 8026eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8036eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8046eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok &= setTagsProperty(tags); 805db40415e05e39c1f4faa62735f435b031e53af7csergeyv 806db40415e05e39c1f4faa62735f435b031e53af7csergeyv bool coreServicesTagEnabled = false; 8075fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 808db40415e05e39c1f4faa62735f435b031e53af7csergeyv if (strcmp(k_categories[i].name, k_coreServiceCategory) == 0) { 809db40415e05e39c1f4faa62735f435b031e53af7csergeyv coreServicesTagEnabled = g_categoryEnables[i]; 810db40415e05e39c1f4faa62735f435b031e53af7csergeyv } 811a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka 812a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka // Set whether to poke PDX services in this session. 813a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka if (strcmp(k_categories[i].name, k_pdxServiceCategory) == 0) { 814a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka g_tracePdx = g_categoryEnables[i]; 815a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka } 816db40415e05e39c1f4faa62735f435b031e53af7csergeyv } 817db40415e05e39c1f4faa62735f435b031e53af7csergeyv 818db40415e05e39c1f4faa62735f435b031e53af7csergeyv std::string packageList(g_debugAppCmdLine); 819db40415e05e39c1f4faa62735f435b031e53af7csergeyv if (coreServicesTagEnabled) { 820db40415e05e39c1f4faa62735f435b031e53af7csergeyv if (!packageList.empty()) { 821db40415e05e39c1f4faa62735f435b031e53af7csergeyv packageList += ","; 822db40415e05e39c1f4faa62735f435b031e53af7csergeyv } 8235fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes packageList += android::base::GetProperty(k_coreServicesProp, ""); 824db40415e05e39c1f4faa62735f435b031e53af7csergeyv } 82509a7987fb59ed6843d51acf0161d66ed3eb2252fDan Austin ok &= setAppCmdlineProperty(&packageList[0]); 826f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis ok &= pokeBinderServices(); 827ee9b97e85d153309cd6d076c54eefef991ac846dMartijn Coenen pokeHalServices(); 8286eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 829a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka if (g_tracePdx) { 830a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka ok &= ServiceUtility::PokeServices(); 831a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka } 832a6c0a721bd442f15d70a50815ef78a6c8ac6b1c9Corey Tabaka 833550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman return ok; 834550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman} 835550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 836550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearmanstatic void cleanUpUserspaceTracing() 837550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman{ 838550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman setTagsProperty(0); 839550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman clearAppProperties(); 840550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman pokeBinderServices(); 841550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 842550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (g_tracePdx) { 843550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ServiceUtility::PokeServices(); 844550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } 845550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman} 846550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 847550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 848550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman// Set all the kernel tracing settings to the desired state for this trace 849550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman// capture. 850550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearmanstatic bool setUpKernelTracing() 851550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman{ 852550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman bool ok = true; 853550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 85465ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson ok &= setUserInitiatedTraceProperty(true); 85565ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson 856550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman // Set up the tracing options. 857550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setCategoriesEnableFromFile(g_categoriesFile); 858550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setTraceOverwriteEnable(g_traceOverwrite); 859550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setTraceBufferSizeKB(g_traceBufferSizeKB); 860550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman // TODO: Re-enable after stabilization 861550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman //ok &= setCmdlineSize(); 862550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setClock(); 863550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setPrintTgidEnableIfPresent(true); 864550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setKernelTraceFuncs(g_kernelTraceFuncs); 865550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 8666eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // Disable all the sysfs enables. This is done as a separate loop from 8676eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // the enables to allow the same enable to exist in multiple categories. 8686eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok &= disableKernelTraceEvents(); 8696eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 8706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // Enable all the sysfs enables that are in an enabled category. 8715fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 8726eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (g_categoryEnables[i]) { 8736eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const TracingCategory &c = k_categories[i]; 8746eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (int j = 0; j < MAX_SYS_FILES; j++) { 8756eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const char* path = c.sysfiles[j].path; 8766eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis bool required = c.sysfiles[j].required == REQ; 8776eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (path != NULL) { 8786eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (fileIsWritable(path)) { 8796eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok &= setKernelOptionEnable(path, true); 8806eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else if (required) { 8816eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "error writing file %s\n", path); 8826eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ok = false; 8836eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8846eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8856eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8866eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 8874b23eefd72501b358c61fb1a7096a2a94e5ea351Jamie Gennis } 8884b23eefd72501b358c61fb1a7096a2a94e5ea351Jamie Gennis 889fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return ok; 890fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 891fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 892e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Reset all the kernel tracing settings to their default state. 893550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearmanstatic void cleanUpKernelTracing() 894fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 8956eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis // Disable all tracing that we're able to. 8966eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis disableKernelTraceEvents(); 8976eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 898fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // Set the options back to their defaults. 899fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis setTraceOverwriteEnable(true); 900e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis setTraceBufferSizeKB(1); 901e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis setPrintTgidEnableIfPresent(false); 902e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis setKernelTraceFuncs(NULL); 90365ecfbba620e4710331b26db4ebf087ca6d92a2bCarmen Jackson setUserInitiatedTraceProperty(false); 904e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 905e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 906e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Enable tracing in the kernel. 907e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic bool startTrace() 908e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 909e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis return setTracingEnabled(true); 910e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis} 911cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 912e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis// Disable tracing in the kernel. 913e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennisstatic void stopTrace() 914e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis{ 915e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis setTracingEnabled(false); 916fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 917fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 918d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen// Read data from the tracing pipe and forward to stdout 919d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenenstatic void streamTrace() 920d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen{ 921d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen char trace_data[4096]; 9222cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence int traceFD = open((g_traceFolder + k_traceStreamPath).c_str(), O_RDWR); 923d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen if (traceFD == -1) { 924d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen fprintf(stderr, "error opening %s: %s (%d)\n", k_traceStreamPath, 925d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen strerror(errno), errno); 926d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen return; 927d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 928d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen while (!g_traceAborted) { 929d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen ssize_t bytes_read = read(traceFD, trace_data, 4096); 930d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen if (bytes_read > 0) { 931d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen write(STDOUT_FILENO, trace_data, bytes_read); 932d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen fflush(stdout); 933d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } else { 934d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen if (!g_traceAborted) { 935d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen fprintf(stderr, "read returned %zd bytes err %d (%s)\n", 936d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen bytes_read, errno, strerror(errno)); 937d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 938d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen break; 939d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 940d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 941d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen} 942d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen 943fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis// Read the current kernel trace and write it to stdout. 94440b26b4fc597f105823bc1e2a640e4df8baea243John Reckstatic void dumpTrace(int outFd) 945fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 9466c8ac921ead0771b36281763d3724d67c9146c62John Reck ALOGI("Dumping trace"); 9472cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence int traceFD = open((g_traceFolder + k_tracePath).c_str(), O_RDWR); 948fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (traceFD == -1) { 949fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis fprintf(stderr, "error opening %s: %s (%d)\n", k_tracePath, 950fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis strerror(errno), errno); 951fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return; 952fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 953fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 9547b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (g_compress) { 9557b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis z_stream zs; 9563da5d235dab9469ccec567c4ebbb5206f4558a18Elliott Hughes memset(&zs, 0, sizeof(zs)); 957a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes 958a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes int result = deflateInit(&zs, Z_DEFAULT_COMPRESSION); 9597b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (result != Z_OK) { 9607b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error initializing zlib: %d\n", result); 9617b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis close(traceFD); 9627b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis return; 9637b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 9647b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 965a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes constexpr size_t bufSize = 64*1024; 966a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes std::unique_ptr<uint8_t> in(new uint8_t[bufSize]); 967a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes std::unique_ptr<uint8_t> out(new uint8_t[bufSize]); 968a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes if (!in || !out) { 969a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes fprintf(stderr, "couldn't allocate buffers\n"); 970a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes close(traceFD); 971a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes return; 972a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes } 973a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes 974a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes int flush = Z_NO_FLUSH; 9757b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 976a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes zs.next_out = reinterpret_cast<Bytef*>(out.get()); 9777b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis zs.avail_out = bufSize; 9787b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 9797b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis do { 9807b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 9817b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (zs.avail_in == 0) { 9827b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis // More input is needed. 983a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes result = read(traceFD, in.get(), bufSize); 9847b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (result < 0) { 9857b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error reading trace: %s (%d)\n", 9867b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis strerror(errno), errno); 9877b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis result = Z_STREAM_END; 9887b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis break; 9897b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } else if (result == 0) { 9907b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis flush = Z_FINISH; 9917b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } else { 992a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes zs.next_in = reinterpret_cast<Bytef*>(in.get()); 9937b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis zs.avail_in = result; 9947b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 9957b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 9967b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 9977b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (zs.avail_out == 0) { 9987b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis // Need to write the output. 999b59e2961471db9ede954a3d843e0bb545bb290faElliott Hughes result = write(outFd, out.get(), bufSize); 10007b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if ((size_t)result < bufSize) { 10017b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error writing deflated trace: %s (%d)\n", 10027b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis strerror(errno), errno); 10037b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis result = Z_STREAM_END; // skip deflate error message 10047b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis zs.avail_out = bufSize; // skip the final write 10057b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis break; 10067b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 1007a252f4db5df0a3802b471680bb32f2cbbd21c548Elliott Hughes zs.next_out = reinterpret_cast<Bytef*>(out.get()); 10087b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis zs.avail_out = bufSize; 10097b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 10107b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 10117b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } while ((result = deflate(&zs, flush)) == Z_OK); 10127b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 10137b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (result != Z_STREAM_END) { 10147b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error deflating trace: %s\n", zs.msg); 10157b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 10167b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 10177b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (zs.avail_out < bufSize) { 10187b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis size_t bytes = bufSize - zs.avail_out; 1019b59e2961471db9ede954a3d843e0bb545bb290faElliott Hughes result = write(outFd, out.get(), bytes); 10207b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if ((size_t)result < bytes) { 10217b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error writing deflated trace: %s (%d)\n", 10227b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis strerror(errno), errno); 10237b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 10247b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 10257b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 10267b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis result = deflateEnd(&zs); 10277b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis if (result != Z_OK) { 10287b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis fprintf(stderr, "error cleaning up zlib: %d\n", result); 10297b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 10307b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } else { 1031d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao char buf[4096]; 1032d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao ssize_t rc; 1033d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao while ((rc = TEMP_FAILURE_RETRY(read(traceFD, buf, sizeof(buf)))) > 0) { 1034d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao if (!android::base::WriteFully(outFd, buf, rc)) { 1035d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao fprintf(stderr, "error writing trace: %s\n", strerror(errno)); 1036d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao break; 1037d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao } 1038d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao } 1039d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao if (rc == -1) { 1040d3d36e71f274a1f6df1eb77db5a6abfb12035c75Josh Gao fprintf(stderr, "error dumping trace: %s\n", strerror(errno)); 10417b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis } 1042fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1043fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1044fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis close(traceFD); 1045fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 1046fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 104792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatic void handleSignal(int /*signo*/) 1048fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 104931be80f02cddda55e75614884038fa4645b694cdGlenn Kasten if (!g_nohup) { 105031be80f02cddda55e75614884038fa4645b694cdGlenn Kasten g_traceAborted = true; 105131be80f02cddda55e75614884038fa4645b694cdGlenn Kasten } 1052fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 1053fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 10546eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic void registerSigHandler() 10556eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis{ 1056fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis struct sigaction sa; 1057fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sigemptyset(&sa.sa_mask); 1058fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sa.sa_flags = 0; 1059fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sa.sa_handler = handleSignal; 1060fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sigaction(SIGHUP, &sa, NULL); 1061fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sigaction(SIGINT, &sa, NULL); 1062fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sigaction(SIGQUIT, &sa, NULL); 1063fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis sigaction(SIGTERM, &sa, NULL); 1064fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 1065fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 10666eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic void listSupportedCategories() 10676eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis{ 10685fd6ff6b7670cce9ed17e06764db59d44ba15575Elliott Hughes for (size_t i = 0; i < arraysize(k_categories); i++) { 10696eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis const TracingCategory& c = k_categories[i]; 10706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (isCategorySupported(c)) { 10716eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis printf(" %10s - %s\n", c.name, c.longname); 10726eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 10736eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 10746eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 10756eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 10766eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis// Print the command usage help to stderr. 10776eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennisstatic void showHelp(const char *cmd) 10786eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis{ 10796eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "usage: %s [options] [categories...]\n", cmd); 10806eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "options include:\n" 1081f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis " -a appname enable app-level tracing for a comma " 1082519a0790d7039ee9ed52ae057de30db0fddaee59Daniel Colascione "separated list of cmdlines; * is a wildcard matching any process\n" 10836eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " -b N use a trace buffer size of N KB\n" 10846eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " -c trace into a circular buffer\n" 108546c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda " -f filename use the categories written in a file as space-separated\n" 108646c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda " values in a line\n" 1087e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis " -k fname,... trace the listed kernel functions\n" 10886eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " -n ignore signals\n" 10896eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " -s N sleep for N seconds before tracing [default 0]\n" 1090b5c95475996c59bacb0ee760f11bf792f71e0c77Fabien Sanglard " -t N trace for N seconds [default 5]\n" 10916eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " -z compress the trace dump\n" 1092b5c95475996c59bacb0ee760f11bf792f71e0c77Fabien Sanglard " --async_start start circular trace and return immediately\n" 10936eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " --async_dump dump the current contents of circular trace buffer\n" 10946eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " --async_stop stop tracing and dump the current contents of circular\n" 10956eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis " trace buffer\n" 1096d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen " --stream stream trace to stdout as it enters the trace buffer\n" 1097d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen " Note: this can take significant CPU time, and is best\n" 1098d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen " used for measuring things that are not affected by\n" 1099d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen " CPU performance, like pagecache usage.\n" 110092573f1ba0d5360d7bfa8ab8935118db7a251f62Jamie Gennis " --list_categories\n" 110192573f1ba0d5360d7bfa8ab8935118db7a251f62Jamie Gennis " list the available tracing categories\n" 110240b26b4fc597f105823bc1e2a640e4df8baea243John Reck " -o filename write the trace to the specified file instead\n" 110340b26b4fc597f105823bc1e2a640e4df8baea243John Reck " of stdout.\n" 11046eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis ); 11056eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis} 11066eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis 11072cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrencebool findTraceFiles() 11082cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence{ 11092cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence static const std::string debugfs_path = "/sys/kernel/debug/tracing/"; 11102cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence static const std::string tracefs_path = "/sys/kernel/tracing/"; 11112cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence static const std::string trace_file = "trace_marker"; 11122cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 11132cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence bool tracefs = access((tracefs_path + trace_file).c_str(), F_OK) != -1; 11142cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence bool debugfs = access((debugfs_path + trace_file).c_str(), F_OK) != -1; 11152cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 11162cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence if (!tracefs && !debugfs) { 11172cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence fprintf(stderr, "Error: Did not find trace folder\n"); 11182cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence return false; 11192cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence } 11202cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 11212cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence if (tracefs) { 11222cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence g_traceFolder = tracefs_path; 11232cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence } else { 11242cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence g_traceFolder = debugfs_path; 11252cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence } 11262cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 11272cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence return true; 11282cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence} 11292cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 1130fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennisint main(int argc, char **argv) 1131fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis{ 11324edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling bool async = false; 11334edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling bool traceStart = true; 11344edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling bool traceStop = true; 11354edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling bool traceDump = true; 1136d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen bool traceStream = false; 1137550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman bool onlyUserspace = false; 11384b23eefd72501b358c61fb1a7096a2a94e5ea351Jamie Gennis 1139fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (argc == 2 && 0 == strcmp(argv[1], "--help")) { 1140fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis showHelp(argv[0]); 1141fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis exit(0); 1142fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1143fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 11442cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence if (!findTraceFiles()) { 11452cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence fprintf(stderr, "No trace folder found\n"); 11462cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence exit(-1); 11472cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence } 11482cd93cc4ce68da81815351db75cbda4b357e6753Paul Lawrence 1149fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis for (;;) { 1150fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis int ret; 11514edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling int option_index = 0; 11524edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling static struct option long_options[] = { 1153550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"async_start", no_argument, 0, 0 }, 1154550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"async_stop", no_argument, 0, 0 }, 1155550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"async_dump", no_argument, 0, 0 }, 1156550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"only_userspace", no_argument, 0, 0 }, 1157550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"list_categories", no_argument, 0, 0 }, 1158550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman {"stream", no_argument, 0, 0 }, 1159550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman { 0, 0, 0, 0 } 11604edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling }; 1161fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 116240b26b4fc597f105823bc1e2a640e4df8baea243John Reck ret = getopt_long(argc, argv, "a:b:cf:k:ns:t:zo:", 11634edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling long_options, &option_index); 1164fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1165fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (ret < 0) { 11666eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis for (int i = optind; i < argc; i++) { 11676eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis if (!setCategoryEnable(argv[i], true)) { 11686eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis fprintf(stderr, "error enabling tracing category \"%s\"\n", argv[i]); 11696eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis exit(1); 11706eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 11716eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } 1172fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis break; 1173fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1174fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1175fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis switch(ret) { 1176f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis case 'a': 1177f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis g_debugAppCmdLine = optarg; 1178f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis break; 1179f7f29c8f9d56dc908e501ae789e418a9974b6bceJamie Gennis 1180cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis case 'b': 1181cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis g_traceBufferSizeKB = atoi(optarg); 1182cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis break; 1183cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 1184fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis case 'c': 1185fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis g_traceOverwrite = true; 1186fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis break; 1187fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 118846c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda case 'f': 118946c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda g_categoriesFile = optarg; 119046c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda break; 119146c51fb1adf8bc011b7d5b1c98a89303acb8c57bYasuhiro Matsuda 1192e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis case 'k': 1193e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis g_kernelTraceFuncs = optarg; 11946f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis break; 1195e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis 119631be80f02cddda55e75614884038fa4645b694cdGlenn Kasten case 'n': 119731be80f02cddda55e75614884038fa4645b694cdGlenn Kasten g_nohup = true; 11986f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis break; 119931be80f02cddda55e75614884038fa4645b694cdGlenn Kasten 1200fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis case 's': 120131be80f02cddda55e75614884038fa4645b694cdGlenn Kasten g_initialSleepSecs = atoi(optarg); 120231be80f02cddda55e75614884038fa4645b694cdGlenn Kasten break; 120331be80f02cddda55e75614884038fa4645b694cdGlenn Kasten 1204fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis case 't': 1205fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis g_traceDurationSeconds = atoi(optarg); 1206fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis break; 1207fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 12087b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis case 'z': 12097b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis g_compress = true; 12107b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis break; 12117b5170b249c1d312cfe3b5658b6c140b2a48226fJamie Gennis 121240b26b4fc597f105823bc1e2a640e4df8baea243John Reck case 'o': 121340b26b4fc597f105823bc1e2a640e4df8baea243John Reck g_outputFile = optarg; 121440b26b4fc597f105823bc1e2a640e4df8baea243John Reck break; 121540b26b4fc597f105823bc1e2a640e4df8baea243John Reck 12164edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling case 0: 12174edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling if (!strcmp(long_options[option_index].name, "async_start")) { 12184edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling async = true; 12194edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling traceStop = false; 12204edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling traceDump = false; 12214edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling g_traceOverwrite = true; 12224edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling } else if (!strcmp(long_options[option_index].name, "async_stop")) { 12234edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling async = true; 12244ba2b63bff492815a86954c272a36d886f5bccecJohn Reck traceStart = false; 12254edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling } else if (!strcmp(long_options[option_index].name, "async_dump")) { 12264edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling async = true; 12274edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling traceStart = false; 12284edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling traceStop = false; 1229550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } else if (!strcmp(long_options[option_index].name, "only_userspace")) { 1230550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman onlyUserspace = true; 1231d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } else if (!strcmp(long_options[option_index].name, "stream")) { 1232d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen traceStream = true; 1233d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen traceDump = false; 12346eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis } else if (!strcmp(long_options[option_index].name, "list_categories")) { 12356eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis listSupportedCategories(); 12366eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis exit(0); 12374edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling } 12386f6f3f710b4dec2952298ae65d5f1674535c63f0Jamie Gennis break; 12394edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling 1240fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis default: 1241cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis fprintf(stderr, "\n"); 1242fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis showHelp(argv[0]); 1243fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis exit(-1); 1244fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis break; 1245fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1246fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1247fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1248550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (onlyUserspace) { 1249550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (!async || !(traceStart || traceStop)) { 1250550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman fprintf(stderr, "--only_userspace can only be used with " 1251550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman "--async_start or --async_stop\n"); 1252550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman exit(1); 1253550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } 1254550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } 1255550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 1256fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis registerSigHandler(); 1257fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 125831be80f02cddda55e75614884038fa4645b694cdGlenn Kasten if (g_initialSleepSecs > 0) { 125931be80f02cddda55e75614884038fa4645b694cdGlenn Kasten sleep(g_initialSleepSecs); 126031be80f02cddda55e75614884038fa4645b694cdGlenn Kasten } 126131be80f02cddda55e75614884038fa4645b694cdGlenn Kasten 1262e9b8cfb63297b14253c5b464190fc5752457a38eJamie Gennis bool ok = true; 1263550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 1264190cb7dd5e14e586916da51fdecaf446697633efWei Wang if (traceStart) { 1265550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setUpUserspaceTracing(); 1266550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } 1267550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 1268550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (ok && traceStart && !onlyUserspace) { 1269550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok &= setUpKernelTracing(); 1270190cb7dd5e14e586916da51fdecaf446697633efWei Wang ok &= startTrace(); 1271190cb7dd5e14e586916da51fdecaf446697633efWei Wang } 1272fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 12734edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling if (ok && traceStart) { 1274550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 1275550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (!traceStream && !onlyUserspace) { 1276ac53e73bba9b311bc92e40a58ad98c5e65d49d17Carmen Jackson printf("capturing trace..."); 1277d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen fflush(stdout); 1278d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 1279fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1280fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // We clear the trace after starting it because tracing gets enabled for 1281fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // each CPU individually in the kernel. Having the beginning of the trace 1282fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // contain entries from only one CPU can cause "begin" entries without a 1283fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // matching "end" entry to show up if a task gets migrated from one CPU to 1284fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // another. 1285550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (!onlyUserspace) 1286550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman ok = clearTrace(); 1287550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman 1288550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (!onlyUserspace) 1289550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman writeClockSyncMarker(); 1290fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1291d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen if (ok && !async && !traceStream) { 1292fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // Sleep to allow the trace to be captured. 1293fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis struct timespec timeLeft; 1294fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis timeLeft.tv_sec = g_traceDurationSeconds; 1295fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis timeLeft.tv_nsec = 0; 1296fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis do { 1297fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (g_traceAborted) { 1298fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis break; 1299fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1300fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR); 1301fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1302d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen 1303d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen if (traceStream) { 1304d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen streamTrace(); 1305d95358713b98875733e91fe8fb0459a0b88eab14Martijn Coenen } 1306fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1307fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1308fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis // Stop the trace and restore the default settings. 1309550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (traceStop && !onlyUserspace) 13106eea6fb259a6d0b1c585d3267b8df7ca29a1206dJamie Gennis stopTrace(); 1311fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1312550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (ok && traceDump && !onlyUserspace) { 1313fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis if (!g_traceAborted) { 131440b26b4fc597f105823bc1e2a640e4df8baea243John Reck printf(" done\n"); 1315fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis fflush(stdout); 131640b26b4fc597f105823bc1e2a640e4df8baea243John Reck int outFd = STDOUT_FILENO; 131740b26b4fc597f105823bc1e2a640e4df8baea243John Reck if (g_outputFile) { 1318c579198835539100087ba71f5bbf38c3c09422e6Martijn Coenen outFd = open(g_outputFile, O_WRONLY | O_CREAT | O_TRUNC, 0644); 131940b26b4fc597f105823bc1e2a640e4df8baea243John Reck } 132040b26b4fc597f105823bc1e2a640e4df8baea243John Reck if (outFd == -1) { 132140b26b4fc597f105823bc1e2a640e4df8baea243John Reck printf("Failed to open '%s', err=%d", g_outputFile, errno); 132240b26b4fc597f105823bc1e2a640e4df8baea243John Reck } else { 132340b26b4fc597f105823bc1e2a640e4df8baea243John Reck dprintf(outFd, "TRACE:\n"); 132440b26b4fc597f105823bc1e2a640e4df8baea243John Reck dumpTrace(outFd); 132540b26b4fc597f105823bc1e2a640e4df8baea243John Reck if (g_outputFile) { 132640b26b4fc597f105823bc1e2a640e4df8baea243John Reck close(outFd); 132740b26b4fc597f105823bc1e2a640e4df8baea243John Reck } 132840b26b4fc597f105823bc1e2a640e4df8baea243John Reck } 1329fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } else { 1330fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis printf("\ntrace aborted.\n"); 1331fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis fflush(stdout); 1332fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1333fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis clearTrace(); 13344edbd078cddcc1cbe59156a0e7ece01de75156e0Erik Gilling } else if (!ok) { 1335fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis fprintf(stderr, "unable to start tracing\n"); 1336fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis } 1337fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis 1338cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis // Reset the trace buffer size to 1. 1339550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (traceStop) { 1340550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman cleanUpUserspaceTracing(); 1341550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman if (!onlyUserspace) 1342550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman cleanUpKernelTracing(); 1343550b18cac578fd4faa9addaf172a21ecd99839ddHector Dearman } 1344cc24c8e6b48c2eb204bf3d7f974dbff6dc0cc862Jamie Gennis 1345fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis return g_traceAborted ? 1 : 0; 1346fb31ba69282e34df62005ec63afda2b8ec69533eJamie Gennis} 1347