12b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
22b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Copyright (c) 2015, The Android Open Source Project
32b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * All rights reserved.
42b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *
52b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Redistribution and use in source and binary forms, with or without
62b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * modification, are permitted provided that the following conditions
72b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * are met:
82b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *   * Redistributions of source code must retain the above copyright
92b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     notice, this list of conditions and the following disclaimer.
102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *   * Redistributions in binary form must reproduce the above copyright
112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     notice, this list of conditions and the following disclaimer
122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     in the documentation and/or other materials provided with the
132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     distribution.
142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *   * Neither the name of Google, Inc. nor the names of its contributors
152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     may be used to endorse or promote products derived from this
162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *     software without specific prior written permission.
172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian *
182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * SUCH DAMAGE.
302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <binder/IBinder.h>
332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <binder/IServiceManager.h>
342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <binder/Parcel.h>
352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <ctime>
372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <cutils/properties.h>
382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <signal.h>
392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <stdbool.h>
402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <stdio.h>
412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <stdlib.h>
422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <string.h>
432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <sys/resource.h>
452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <sys/stat.h>
462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <sys/time.h>
472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <sys/types.h>
482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <unistd.h>
492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <utils/Log.h>
512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <utils/String8.h>
522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <utils/Trace.h>
532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#include <zlib.h>
542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianusing namespace android;
562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
572b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#ifdef LOG_TAG
582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#undef LOG_TAG
592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#endif
602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian#define LOG_TAG "anrdaemon"
622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
635b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const int check_period = 1;              // in sec
645b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const int tracing_check_period = 500000; // in micro sec
655b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const int cpu_stat_entries = 7;          // number of cpu stat entries
665b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const int min_buffer_size = 16;
675b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const int max_buffer_size = 2048;
685b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const char *min_buffer_size_str = "16";
695b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const char *max_buffer_size_str = "2048";
70d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qianstatic const int time_buf_size = 20;
71d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qianstatic const int path_buf_size = 60;
725b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian
732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qiantypedef struct cpu_stat {
742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    unsigned long utime, ntime, stime, itime;
752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    unsigned long iowtime, irqtime, sirqtime, steal;
762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    unsigned long total;
772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian} cpu_stat_t;
782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
796d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian/*
806d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian * Logging on/off threshold.
816d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian * Uint: 0.01%; default to 99.90% cpu.
826d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian */
836d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qianstatic int idle_threshold = 10;
842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool quit = false;
862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool suspend= false;
87b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qianstatic bool dump_requested = false;
882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool err = false;
892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic char err_msg[100];
902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool tracing = false;
912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
925b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const char *buf_size_kb = "2048";
935b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic const char *apps = "";
942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic uint64_t tag = 0;
952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic cpu_stat_t new_cpu;
972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic cpu_stat_t old_cpu;
982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/* Log certain kernel activity when enabled */
1002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool log_sched = false;
1012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool log_stack = false;
1022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool log_irq   = false;
1032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool log_sync  = false;
1042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool log_workq = false;
1052b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/* Paths for debugfs controls*/
1072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_trace_output_path =
1082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/trace";
1092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_irq_path =
1102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/events/irq/enable";
1112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_sync_path =
1122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/events/sync/enable";
1132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_workq_path =
1142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/events/workqueue/enable";
1152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_stack_path =
1162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/options/stacktrace";
1172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_sched_switch_path =
1182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/events/sched/sched_switch/enable";
1192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_sched_wakeup_path =
1202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/events/sched/sched_wakeup/enable";
1212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_control_path =
1222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/tracing_on";
1232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_buffer_size_path =
1242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    "/d/tracing/buffer_size_kb";
1252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_tags_property = "debug.atrace.tags.enableflags";
1262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic const char* dfs_apps_property = "debug.atrace.app_cmdlines";
1272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
1292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Read accumulated cpu data from /proc/stat
1302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
1312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void get_cpu_stat(cpu_stat_t *cpu) {
1322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    FILE *fp = NULL;
1332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    const char *params = "cpu  %lu %lu %lu %lu %lu %lu %lu %*d %*d %*d\n";
1342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if ((fp = fopen("/proc/stat", "r")) == NULL) {
1362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        err = true;
1372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sprintf(err_msg, "can't read from /proc/stat with errno %d", errno);
1382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    } else {
1392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if (fscanf(fp, params, &cpu->utime, &cpu->ntime,
1402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                &cpu->stime, &cpu->itime, &cpu->iowtime, &cpu->irqtime,
1415b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                &cpu->sirqtime) != cpu_stat_entries) {
1422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            /*
1432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian             * If failed in getting status, new_cpu won't be updated and
1442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian             * is_heavy_loaded() will return false.
1452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian             */
1462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            ALOGE("Error in getting cpu status. Skipping this check.");
1472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            return;
1482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
1492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        cpu->total = cpu->utime + cpu->ntime + cpu->stime + cpu->itime
1512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            + cpu->iowtime + cpu->irqtime + cpu->sirqtime;
1522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        fclose(fp);
1542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
1552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
1562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1572b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
1582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Calculate cpu usage in the past interval.
1596d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian * If tracing is on, increase the idle threshold by 1.00% so that we do not
1602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * turn on and off tracing frequently whe the cpu load is right close to
1612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * threshold.
1622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
1632b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic bool is_heavy_load(void) {
1642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    unsigned long diff_idle, diff_total;
1656d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian    int threshold = idle_threshold + (tracing?100:0);
1662b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    get_cpu_stat(&new_cpu);
1672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    diff_idle = new_cpu.itime - old_cpu.itime;
1682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    diff_total = new_cpu.total - old_cpu.total;
1692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    old_cpu = new_cpu;
1706d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian    return (diff_idle * 10000 < diff_total * threshold);
1712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
1722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
1742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Force the userland processes to refresh their property for logging.
1752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
1765b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qianstatic void dfs_poke_binder(void) {
1772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sp<IServiceManager> sm = defaultServiceManager();
1785b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian    Vector<String16> services = sm->listServices();
1792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    for (size_t i = 0; i < services.size(); i++) {
1802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sp<IBinder> obj = sm->checkService(services[i]);
1812b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if (obj != NULL) {
1822b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            Parcel data;
1832b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            obj->transact(IBinder::SYSPROPS_TRANSACTION, data, NULL, 0);
1842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
1852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
1862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
1872b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
1882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
1892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Enable/disable a debugfs property by writing 0/1 to its path.
1902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
1912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic int dfs_enable(bool enable, const char* path) {
1922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int fd = open(path, O_WRONLY);
1932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (fd == -1) {
1942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        err = true;
1952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sprintf(err_msg, "Can't open %s. Error: %d", path, errno);
1962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return -1;
1972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
1982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    const char* control = (enable?"1":"0");
1992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    ssize_t len = strlen(control);
2002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int max_try = 10; // Fail if write was interrupted for 10 times
2012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    while (write(fd, control, len) != len) {
2025b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        if (errno == EINTR && max_try-- > 0) {
2035b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian            usleep(100);
2042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            continue;
2055b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        }
2062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        err = true;
2082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sprintf(err_msg, "Error %d in writing to %s.", errno, path);
2092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    close(fd);
2112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    return (err?-1:0);
2122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
2132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
2152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Set the userland tracing properties.
2162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
2172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void dfs_set_property(uint64_t mtag, const char* mapp, bool enable) {
2182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    char buf[64];
2192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    snprintf(buf, 64, "%#" PRIx64, mtag);
2202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (property_set(dfs_tags_property, buf) < 0) {
2212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        err = true;
2222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sprintf(err_msg, "Failed to set debug tags system properties.");
2232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (strlen(mapp) > 0
2262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            && property_set(dfs_apps_property, mapp) < 0) {
2272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        err = true;
2282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        sprintf(err_msg, "Failed to set debug applications.");
2292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (log_sched) {
2322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_sched_switch_path);
2332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_sched_wakeup_path);
2342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (log_stack) {
2362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_stack_path);
2372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (log_irq) {
2392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_irq_path);
2402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (log_sync) {
2422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_sync_path);
2432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (log_workq) {
2452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        dfs_enable(enable, dfs_workq_path);
2462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
2482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
2502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Dump the log in a compressed format for systrace to visualize.
251b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * Create a dump file "dump_of_anrdaemon.<current_time>" under /data/misc/anrd
2522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
2532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void dump_trace()
2542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian{
2552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    time_t now = time(0);
2562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    struct tm  tstruct;
257d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian    char time_buf[time_buf_size];
258d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian    char path_buf[path_buf_size];
2592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    const char* header = " done\nTRACE:\n";
2602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    ssize_t header_len = strlen(header);
261b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
262b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    ALOGI("Started to dump ANRdaemon trace.");
263b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
2642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    tstruct = *localtime(&now);
265d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian    strftime(time_buf, time_buf_size, "%Y-%m-%d.%X", &tstruct);
266d93aa418071ba2bbf72de4003719d68650426c58Zhengyin Qian    snprintf(path_buf, path_buf_size, "/data/misc/anrd/dump_of_anrdaemon.%s", time_buf);
2672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int output_fd = creat(path_buf, S_IRWXU);
2682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (output_fd == -1) {
2692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("Failed to create %s. Dump aborted.", path_buf);
2702b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return;
2712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (write(output_fd, header, strlen(header)) != header_len) {
2742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("Failed to write the header.");
2752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        close(output_fd);
2762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return;
2772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int trace_fd = open(dfs_trace_output_path, O_RDWR);
2802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (trace_fd == -1) {
2812b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("Failed to open %s. Dump aborted.", dfs_trace_output_path);
2822b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        close(output_fd);
2832b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return;
2842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    z_stream zs;
2872b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    uint8_t *in, *out;
2882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int result, flush;
2892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    memset(&zs, 0, sizeof(zs));
2912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    result = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
2922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (result != Z_OK) {
2932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("error initializing zlib: %d\n", result);
2942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        close(trace_fd);
2952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        close(output_fd);
2962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return;
2972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
2982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
2992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    const size_t bufSize = 64*1024;
3002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    in = (uint8_t*)malloc(bufSize);
3012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    out = (uint8_t*)malloc(bufSize);
3022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    flush = Z_NO_FLUSH;
3032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    zs.next_out = out;
3052b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    zs.avail_out = bufSize;
3062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    do {
3082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if (zs.avail_in == 0) {
3092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            result = read(trace_fd, in, bufSize);
3102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            if (result < 0) {
3112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                ALOGE("error reading trace: %s", strerror(errno));
3122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                result = Z_STREAM_END;
3132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
3142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            } else if (result == 0) {
3152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                flush = Z_FINISH;
3162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            } else {
3172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                zs.next_in = in;
3182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                zs.avail_in = result;
3192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            }
3202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
3212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if (zs.avail_out == 0) {
3232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            result = write(output_fd, out, bufSize);
3242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            if ((size_t)result < bufSize) {
3252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                ALOGE("error writing deflated trace: %s", strerror(errno));
3262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                result = Z_STREAM_END;
3272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                zs.avail_out = bufSize;
3282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
3292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            }
3302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            zs.next_out = out;
3312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            zs.avail_out = bufSize;
3322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
3332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    } while ((result = deflate(&zs, flush)) == Z_OK);
3352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (result != Z_STREAM_END) {
3372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("error deflating trace: %s\n", zs.msg);
3382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
3392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (zs.avail_out < bufSize) {
3412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        size_t bytes = bufSize - zs.avail_out;
3422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        result = write(output_fd, out, bytes);
3432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if ((size_t)result < bytes) {
3442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            ALOGE("error writing deflated trace: %s", strerror(errno));
3452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
3462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
3472b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3482b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    result = deflateEnd(&zs);
3492b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (result != Z_OK) {
3502b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("error cleaning up zlib: %d\n", result);
3512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
3522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    free(in);
3542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    free(out);
3552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3562b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    close(trace_fd);
3572b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    close(output_fd);
3582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
3592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    ALOGI("Finished dump. Output file stored at: %s", path_buf);
3602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
3612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
362b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian/*
363b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * Start logging when cpu usage is high. Meanwhile, moniter the cpu usage and
364b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * stop logging when it drops down.
365b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian */
366b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qianstatic void start_tracing(void) {
367b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    ALOGD("High cpu usage, start logging.");
368b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
369b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (dfs_enable(true, dfs_control_path) != 0) {
370b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        ALOGE("Failed to start tracing.");
371b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        return;
372b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
373b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    tracing = true;
374b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
375b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    /* Stop logging when cpu usage drops or the daemon is suspended.*/
376b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    do {
377b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        usleep(tracing_check_period);
378b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    } while (!suspend && !dump_requested && is_heavy_load());
379b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
380b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (dfs_enable(false, dfs_control_path) != 0) {
381b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        ALOGE("Failed to stop tracing.");
382b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        err = true;
383b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        return;
384b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
385b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    tracing = false;
386b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
387b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (suspend) {
388b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        ALOGI("trace stopped due to suspend. Send SIGCONT to resume.");
389b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    } else if (dump_requested) {
390b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        ALOGI("trace stopped due to dump request.");
391b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        dump_trace();
392b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        dump_requested = false;
393b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    } else {
394b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        ALOGD("Usage back to low, stop logging.");
395b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
396b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian}
397b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
398b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian/*
399b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * Set the tracing log buffer size.
400b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * Note the actual buffer size will be buf_size_kb * number of cores.
401b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian */
402b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qianstatic int set_tracing_buffer_size(void) {
403b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    int fd = open(dfs_buffer_size_path, O_WRONLY);
404b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (fd == -1) {
405b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        err = true;
406b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        sprintf(err_msg, "Can't open atrace buffer size file under /d/tracing.");
407b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        return -1;
408b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
409b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    ssize_t len = strlen(buf_size_kb);
410b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (write(fd, buf_size_kb, len) != len) {
411b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        err = true;
412b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        sprintf(err_msg, "Error in writing to atrace buffer size file.");
413b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
414b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    close(fd);
415b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    return (err?-1:0);
416b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
417b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian}
418b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
419b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian/*
420b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * Main loop to moniter the cpu usage and decided whether to start logging.
421b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian */
422b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qianstatic void start(void) {
423b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if ((set_tracing_buffer_size()) != 0)
424b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        return;
425b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
426b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    dfs_set_property(tag, apps, true);
427b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    dfs_poke_binder();
428b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
429b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    get_cpu_stat(&old_cpu);
430b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    sleep(check_period);
431b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
432b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    while (!quit && !err) {
433b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        if (!suspend && is_heavy_load()) {
434b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian            /*
435b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian             * Increase process priority to make sure we can stop logging when
436b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian             * necessary and do not overwrite the buffer
437b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian             */
438b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian            setpriority(PRIO_PROCESS, 0, -20);
439b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian            start_tracing();
440b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian            setpriority(PRIO_PROCESS, 0, 0);
441b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        }
442b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        sleep(check_period);
443b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
444b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    return;
445b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian}
446b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
447b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian/*
448b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * If trace is not running, dump trace right away.
449b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian * If trace is running, request to dump trace.
450b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian */
451b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qianstatic void request_dump_trace()
452b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian{
453b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    if (!tracing) {
454b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        dump_trace();
455b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    } else if (!dump_requested) {
456b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian        dump_requested = true;
457b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian    }
458b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian}
459b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian
4602b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void handle_signal(int signo)
4612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian{
4622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    switch (signo) {
4632b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        case SIGQUIT:
4642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            suspend = true;
4652b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            quit = true;
4662b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            break;
4672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        case SIGSTOP:
4682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            suspend = true;
4692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            break;
4702b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        case SIGCONT:
4712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            suspend = false;
4722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            break;
4732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        case SIGUSR1:
474b403779c945a262dce678308f993f8d6ccd27ddaZhengyin Qian            request_dump_trace();
4752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
4762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
4772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
4782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian/*
4792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * Set the signal handler:
4802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * SIGQUIT: Reset debugfs and tracing property and terminate the daemon.
4812b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * SIGSTOP: Stop logging and suspend the daemon.
4822b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * SIGCONT: Resume the daemon as normal.
4832b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian * SIGUSR1: Dump the logging to a compressed format for systrace to visualize.
4842b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian */
4852b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void register_sighandler(void)
4862b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian{
4872b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    struct sigaction sa;
4882b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigset_t block_mask;
4892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
4902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigemptyset(&block_mask);
4912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaddset (&block_mask, SIGQUIT);
4922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaddset (&block_mask, SIGSTOP);
4932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaddset (&block_mask, SIGCONT);
4942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaddset (&block_mask, SIGUSR1);
4952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
4962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sa.sa_flags = 0;
4972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sa.sa_mask = block_mask;
4982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sa.sa_handler = handle_signal;
4992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaction(SIGQUIT, &sa, NULL);
5002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaction(SIGSTOP, &sa, NULL);
5012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaction(SIGCONT, &sa, NULL);
5022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    sigaction(SIGUSR1, &sa, NULL);
5032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
5042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
5052b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic void show_help(void) {
5062b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
5072b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    fprintf(stderr, "usage: ANRdaemon [options] [categoris...]\n");
5082b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    fprintf(stdout, "Options includes:\n"
5092b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   -a appname  enable app-level tracing for a comma "
5102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                       "separated list of cmdlines\n"
5112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   -t N        cpu threshold for logging to start "
5126d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian                        "(uint = 0.01%%, min = 5000, max = 9999, default = 9990)\n"
5132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   -s N        use a trace buffer size of N KB "
5145b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                        "default to 2048KB\n"
5152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   -h          show helps\n");
5162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    fprintf(stdout, "Categoris includes:\n"
5172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   am         - activity manager\n"
5182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   sm         - sync manager\n"
5192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   input      - input\n"
5202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   dalvik     - dalvik VM\n"
5215b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    "   audio      - Audio\n"
5225b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    "   gfx        - Graphics\n"
5235b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    "   rs         - RenderScript\n"
5245b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    "   hal        - Hardware Modules\n"
5252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   irq        - kernel irq events\n"
5262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   sched      - kernel scheduler activity\n"
5272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   stack      - kernel stack\n"
5282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   sync       - kernel sync activity\n"
5292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   workq      - kernel work queues\n");
5302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    fprintf(stdout, "Control includes:\n"
5312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   SIGQUIT: terminate the process\n"
5322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   SIGSTOP: suspend all function of the daemon\n"
5332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   SIGCONT: resume the normal function\n"
5342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "   SIGUSR1: dump the current logging in a compressed form\n");
5352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    exit(0);
5362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
5372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
5382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianstatic int get_options(int argc, char *argv[]) {
5392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int opt = 0;
5402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int threshold;
5412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    while ((opt = getopt(argc, argv, "a:s:t:h")) >= 0) {
5422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        switch(opt) {
5432b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            case 'a':
5442b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                apps = optarg;
5452b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
5462b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            case 's':
5475b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                if (atoi(optarg) > max_buffer_size)
5485b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    buf_size_kb = max_buffer_size_str;
5495b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                else if (atoi(optarg) < min_buffer_size)
5505b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian                    buf_size_kb = min_buffer_size_str;
5512b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                else
5522b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    buf_size_kb = optarg;
5532b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
5542b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            case 't':
5552b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                threshold = atoi(optarg);
5566d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian                if (threshold > 9999 || threshold < 5000) {
5576d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian                    fprintf(stderr, "logging threshold should be 5000-9999\n");
5582b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    return 1;
5592b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                }
5606d25c0bd81eee66810339d5db3d1ecd48691d229Zhengyin Qian                idle_threshold = 10000 - threshold;
5612b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
5622b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            case 'h':
5632b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                show_help();
5642b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                break;
5652b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            default:
5662b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                fprintf(stderr, "Error in getting options.\n"
5672b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                        "run \"%s -h\" for usage.\n", argv[0]);
5682b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                return 1;
5692b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
5702b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
5712b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
5722b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    for (int i = optind; i < argc; i++) {
5732b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        if (strcmp(argv[i], "am") == 0) {
5742b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            tag |= ATRACE_TAG_ACTIVITY_MANAGER;
5752b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "input") == 0) {
5762b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            tag |= ATRACE_TAG_INPUT;
5772b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "sm") == 0) {
5782b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            tag |= ATRACE_TAG_SYNC_MANAGER;
5792b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "dalvik") == 0) {
5802b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            tag |= ATRACE_TAG_DALVIK;
5815b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        } else if (strcmp(argv[i], "gfx") == 0) {
5825b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian            tag |= ATRACE_TAG_GRAPHICS;
5835b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        } else if (strcmp(argv[i], "audio") == 0) {
5845b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian            tag |= ATRACE_TAG_AUDIO;
5855b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        } else if (strcmp(argv[i], "hal") == 0) {
5865b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian            tag |= ATRACE_TAG_HAL;
5875b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        } else if (strcmp(argv[i], "rs") == 0) {
5885b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian            tag |= ATRACE_TAG_RS;
5892b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "sched") == 0) {
5902b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            log_sched = true;
5912b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "stack") == 0) {
5922b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            log_stack = true;
5932b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "workq") == 0) {
5942b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            log_workq = true;
5952b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "irq") == 0) {
5962b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            log_irq = true;
5972b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else if (strcmp(argv[i], "sync") == 0) {
5982b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            log_sync = true;
5992b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        } else {
6002b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            fprintf(stderr, "invalid category: %s\n"
6012b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian                    "run \"%s -h\" for usage.\n", argv[i], argv[0]);
6022b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian            return 1;
6032b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        }
6042b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
6052b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6065b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian    /* If nothing is enabled, don't run */
6075b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian    if (!tag && !log_sched && !log_stack && !log_workq && !log_irq && !log_sync) {
6085b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        ALOGE("Specify at least one category to trace.");
6095b42895d33d72e74e3e3446e1d43fc541fbf404fZhengyin Qian        return 1;
6102b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
6112b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6122b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    return 0;
6132b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
6142b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6152b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qianint main(int argc, char *argv[])
6162b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian{
6172b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if(get_options(argc, argv) != 0)
6182b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return 1;
6192b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6202b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (daemon(0, 0) != 0)
6212b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return 1;
6222b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6232b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    register_sighandler();
6242b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6252b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    /* Clear any the trace log file by overwrite it with a new file */
6262b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    int fd = creat(dfs_trace_output_path, 0);
6272b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (fd == -1) {
6282b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("Faield to open and cleaup previous log");
6292b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        return 1;
6302b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    }
6312b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    close(fd);
6322b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6332b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    ALOGI("ANRdaemon starting");
6342b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    start();
6352b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6362b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    if (err)
6372b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian        ALOGE("ANRdaemon stopped due to Error: %s", err_msg);
6382b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6392b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    ALOGI("ANRdaemon terminated.");
6402b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian
6412b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian    return (err?1:0);
6422b28ca2dcb5c6c6a510577f3ebd9c754d29638bfZhengyin Qian}
643