1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker * Copyright (c) 2015, The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker * All rights reserved.
4*288bf522SAndroid Build Coastguard Worker *
5*288bf522SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*288bf522SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*288bf522SAndroid Build Coastguard Worker * are met:
8*288bf522SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
9*288bf522SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*288bf522SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright
11*288bf522SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer
12*288bf522SAndroid Build Coastguard Worker * in the documentation and/or other materials provided with the
13*288bf522SAndroid Build Coastguard Worker * distribution.
14*288bf522SAndroid Build Coastguard Worker * * Neither the name of Google, Inc. nor the names of its contributors
15*288bf522SAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this
16*288bf522SAndroid Build Coastguard Worker * software without specific prior written permission.
17*288bf522SAndroid Build Coastguard Worker *
18*288bf522SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19*288bf522SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20*288bf522SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21*288bf522SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22*288bf522SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23*288bf522SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24*288bf522SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25*288bf522SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26*288bf522SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27*288bf522SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28*288bf522SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*288bf522SAndroid Build Coastguard Worker * SUCH DAMAGE.
30*288bf522SAndroid Build Coastguard Worker */
31*288bf522SAndroid Build Coastguard Worker
32*288bf522SAndroid Build Coastguard Worker #include <binder/IBinder.h>
33*288bf522SAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
34*288bf522SAndroid Build Coastguard Worker #include <binder/Parcel.h>
35*288bf522SAndroid Build Coastguard Worker
36*288bf522SAndroid Build Coastguard Worker #include <cutils/properties.h>
37*288bf522SAndroid Build Coastguard Worker #include <signal.h>
38*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
39*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
40*288bf522SAndroid Build Coastguard Worker #include <string.h>
41*288bf522SAndroid Build Coastguard Worker #include <ctime>
42*288bf522SAndroid Build Coastguard Worker
43*288bf522SAndroid Build Coastguard Worker #include <sys/resource.h>
44*288bf522SAndroid Build Coastguard Worker #include <sys/stat.h>
45*288bf522SAndroid Build Coastguard Worker #include <sys/time.h>
46*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
47*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
48*288bf522SAndroid Build Coastguard Worker
49*288bf522SAndroid Build Coastguard Worker #include <utils/Log.h>
50*288bf522SAndroid Build Coastguard Worker #include <utils/String8.h>
51*288bf522SAndroid Build Coastguard Worker #include <utils/Trace.h>
52*288bf522SAndroid Build Coastguard Worker #include <zlib.h>
53*288bf522SAndroid Build Coastguard Worker
54*288bf522SAndroid Build Coastguard Worker using namespace android;
55*288bf522SAndroid Build Coastguard Worker
56*288bf522SAndroid Build Coastguard Worker #ifdef LOG_TAG
57*288bf522SAndroid Build Coastguard Worker #undef LOG_TAG
58*288bf522SAndroid Build Coastguard Worker #endif
59*288bf522SAndroid Build Coastguard Worker
60*288bf522SAndroid Build Coastguard Worker #define LOG_TAG "anrdaemon"
61*288bf522SAndroid Build Coastguard Worker
62*288bf522SAndroid Build Coastguard Worker static const int check_period = 1; // in sec
63*288bf522SAndroid Build Coastguard Worker static const int tracing_check_period = 500000; // in micro sec
64*288bf522SAndroid Build Coastguard Worker static const int cpu_stat_entries = 7; // number of cpu stat entries
65*288bf522SAndroid Build Coastguard Worker static const int min_buffer_size = 16;
66*288bf522SAndroid Build Coastguard Worker static const int max_buffer_size = 2048;
67*288bf522SAndroid Build Coastguard Worker static const char* min_buffer_size_str = "16";
68*288bf522SAndroid Build Coastguard Worker static const char* max_buffer_size_str = "2048";
69*288bf522SAndroid Build Coastguard Worker static const int time_buf_size = 20;
70*288bf522SAndroid Build Coastguard Worker static const int path_buf_size = 60;
71*288bf522SAndroid Build Coastguard Worker
72*288bf522SAndroid Build Coastguard Worker typedef struct cpu_stat {
73*288bf522SAndroid Build Coastguard Worker unsigned long utime, ntime, stime, itime;
74*288bf522SAndroid Build Coastguard Worker unsigned long iowtime, irqtime, sirqtime, steal;
75*288bf522SAndroid Build Coastguard Worker unsigned long total;
76*288bf522SAndroid Build Coastguard Worker } cpu_stat_t;
77*288bf522SAndroid Build Coastguard Worker
78*288bf522SAndroid Build Coastguard Worker /*
79*288bf522SAndroid Build Coastguard Worker * Logging on/off threshold.
80*288bf522SAndroid Build Coastguard Worker * Uint: 0.01%; default to 99.90% cpu.
81*288bf522SAndroid Build Coastguard Worker */
82*288bf522SAndroid Build Coastguard Worker static int idle_threshold = 10;
83*288bf522SAndroid Build Coastguard Worker
84*288bf522SAndroid Build Coastguard Worker static bool quit = false;
85*288bf522SAndroid Build Coastguard Worker static bool suspend = false;
86*288bf522SAndroid Build Coastguard Worker static bool dump_requested = false;
87*288bf522SAndroid Build Coastguard Worker static bool err = false;
88*288bf522SAndroid Build Coastguard Worker static char err_msg[100];
89*288bf522SAndroid Build Coastguard Worker static bool tracing = false;
90*288bf522SAndroid Build Coastguard Worker
91*288bf522SAndroid Build Coastguard Worker static const char* buf_size_kb = "2048";
92*288bf522SAndroid Build Coastguard Worker static const char* apps = "";
93*288bf522SAndroid Build Coastguard Worker static uint64_t tag = 0;
94*288bf522SAndroid Build Coastguard Worker
95*288bf522SAndroid Build Coastguard Worker static cpu_stat_t new_cpu;
96*288bf522SAndroid Build Coastguard Worker static cpu_stat_t old_cpu;
97*288bf522SAndroid Build Coastguard Worker
98*288bf522SAndroid Build Coastguard Worker /* Log certain kernel activity when enabled */
99*288bf522SAndroid Build Coastguard Worker static bool log_sched = false;
100*288bf522SAndroid Build Coastguard Worker static bool log_stack = false;
101*288bf522SAndroid Build Coastguard Worker static bool log_irq = false;
102*288bf522SAndroid Build Coastguard Worker static bool log_sync = false;
103*288bf522SAndroid Build Coastguard Worker static bool log_workq = false;
104*288bf522SAndroid Build Coastguard Worker
105*288bf522SAndroid Build Coastguard Worker /* Paths for debugfs controls*/
106*288bf522SAndroid Build Coastguard Worker static const char* dfs_trace_output_path = "/d/tracing/trace";
107*288bf522SAndroid Build Coastguard Worker static const char* dfs_irq_path = "/d/tracing/events/irq/enable";
108*288bf522SAndroid Build Coastguard Worker static const char* dfs_sync_path = "/d/tracing/events/sync/enable";
109*288bf522SAndroid Build Coastguard Worker static const char* dfs_workq_path = "/d/tracing/events/workqueue/enable";
110*288bf522SAndroid Build Coastguard Worker static const char* dfs_stack_path = "/d/tracing/options/stacktrace";
111*288bf522SAndroid Build Coastguard Worker static const char* dfs_sched_switch_path = "/d/tracing/events/sched/sched_switch/enable";
112*288bf522SAndroid Build Coastguard Worker static const char* dfs_sched_wakeup_path = "/d/tracing/events/sched/sched_wakeup/enable";
113*288bf522SAndroid Build Coastguard Worker static const char* dfs_control_path = "/d/tracing/tracing_on";
114*288bf522SAndroid Build Coastguard Worker static const char* dfs_buffer_size_path = "/d/tracing/buffer_size_kb";
115*288bf522SAndroid Build Coastguard Worker static const char* dfs_tags_property = "debug.atrace.tags.enableflags";
116*288bf522SAndroid Build Coastguard Worker static const char* dfs_apps_property = "debug.atrace.app_cmdlines";
117*288bf522SAndroid Build Coastguard Worker
118*288bf522SAndroid Build Coastguard Worker /*
119*288bf522SAndroid Build Coastguard Worker * Read accumulated cpu data from /proc/stat
120*288bf522SAndroid Build Coastguard Worker */
get_cpu_stat(cpu_stat_t * cpu)121*288bf522SAndroid Build Coastguard Worker static void get_cpu_stat(cpu_stat_t* cpu) {
122*288bf522SAndroid Build Coastguard Worker FILE* fp = NULL;
123*288bf522SAndroid Build Coastguard Worker const char* params = "cpu %lu %lu %lu %lu %lu %lu %lu %*d %*d %*d\n";
124*288bf522SAndroid Build Coastguard Worker
125*288bf522SAndroid Build Coastguard Worker if ((fp = fopen("/proc/stat", "r")) == NULL) {
126*288bf522SAndroid Build Coastguard Worker err = true;
127*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "can't read from /proc/stat with errno %d", errno);
128*288bf522SAndroid Build Coastguard Worker } else {
129*288bf522SAndroid Build Coastguard Worker if (fscanf(fp, params, &cpu->utime, &cpu->ntime, &cpu->stime, &cpu->itime, &cpu->iowtime,
130*288bf522SAndroid Build Coastguard Worker &cpu->irqtime, &cpu->sirqtime) != cpu_stat_entries) {
131*288bf522SAndroid Build Coastguard Worker /*
132*288bf522SAndroid Build Coastguard Worker * If failed in getting status, new_cpu won't be updated and
133*288bf522SAndroid Build Coastguard Worker * is_heavy_loaded() will return false.
134*288bf522SAndroid Build Coastguard Worker */
135*288bf522SAndroid Build Coastguard Worker ALOGE("Error in getting cpu status. Skipping this check.");
136*288bf522SAndroid Build Coastguard Worker fclose(fp);
137*288bf522SAndroid Build Coastguard Worker return;
138*288bf522SAndroid Build Coastguard Worker }
139*288bf522SAndroid Build Coastguard Worker
140*288bf522SAndroid Build Coastguard Worker cpu->total = cpu->utime + cpu->ntime + cpu->stime + cpu->itime + cpu->iowtime +
141*288bf522SAndroid Build Coastguard Worker cpu->irqtime + cpu->sirqtime;
142*288bf522SAndroid Build Coastguard Worker
143*288bf522SAndroid Build Coastguard Worker fclose(fp);
144*288bf522SAndroid Build Coastguard Worker }
145*288bf522SAndroid Build Coastguard Worker }
146*288bf522SAndroid Build Coastguard Worker
147*288bf522SAndroid Build Coastguard Worker /*
148*288bf522SAndroid Build Coastguard Worker * Calculate cpu usage in the past interval.
149*288bf522SAndroid Build Coastguard Worker * If tracing is on, increase the idle threshold by 1.00% so that we do not
150*288bf522SAndroid Build Coastguard Worker * turn on and off tracing frequently when the cpu load is right close to
151*288bf522SAndroid Build Coastguard Worker * threshold.
152*288bf522SAndroid Build Coastguard Worker */
is_heavy_load(void)153*288bf522SAndroid Build Coastguard Worker static bool is_heavy_load(void) {
154*288bf522SAndroid Build Coastguard Worker unsigned long diff_idle, diff_total;
155*288bf522SAndroid Build Coastguard Worker int threshold = idle_threshold + (tracing ? 100 : 0);
156*288bf522SAndroid Build Coastguard Worker get_cpu_stat(&new_cpu);
157*288bf522SAndroid Build Coastguard Worker diff_idle = new_cpu.itime - old_cpu.itime;
158*288bf522SAndroid Build Coastguard Worker diff_total = new_cpu.total - old_cpu.total;
159*288bf522SAndroid Build Coastguard Worker old_cpu = new_cpu;
160*288bf522SAndroid Build Coastguard Worker return (diff_idle * 10000 < diff_total * threshold);
161*288bf522SAndroid Build Coastguard Worker }
162*288bf522SAndroid Build Coastguard Worker
163*288bf522SAndroid Build Coastguard Worker /*
164*288bf522SAndroid Build Coastguard Worker * Force the userland processes to refresh their property for logging.
165*288bf522SAndroid Build Coastguard Worker */
dfs_poke_binder(void)166*288bf522SAndroid Build Coastguard Worker static void dfs_poke_binder(void) {
167*288bf522SAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
168*288bf522SAndroid Build Coastguard Worker Vector<String16> services = sm->listServices();
169*288bf522SAndroid Build Coastguard Worker for (size_t i = 0; i < services.size(); i++) {
170*288bf522SAndroid Build Coastguard Worker sp<IBinder> obj = sm->checkService(services[i]);
171*288bf522SAndroid Build Coastguard Worker if (obj != NULL) {
172*288bf522SAndroid Build Coastguard Worker Parcel data;
173*288bf522SAndroid Build Coastguard Worker obj->transact(IBinder::SYSPROPS_TRANSACTION, data, NULL, 0);
174*288bf522SAndroid Build Coastguard Worker }
175*288bf522SAndroid Build Coastguard Worker }
176*288bf522SAndroid Build Coastguard Worker }
177*288bf522SAndroid Build Coastguard Worker
178*288bf522SAndroid Build Coastguard Worker /*
179*288bf522SAndroid Build Coastguard Worker * Enable/disable a debugfs property by writing 0/1 to its path.
180*288bf522SAndroid Build Coastguard Worker */
dfs_enable(bool enable,const char * path)181*288bf522SAndroid Build Coastguard Worker static int dfs_enable(bool enable, const char* path) {
182*288bf522SAndroid Build Coastguard Worker int fd = open(path, O_WRONLY);
183*288bf522SAndroid Build Coastguard Worker if (fd == -1) {
184*288bf522SAndroid Build Coastguard Worker err = true;
185*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Can't open %s. Error: %d", path, errno);
186*288bf522SAndroid Build Coastguard Worker return -1;
187*288bf522SAndroid Build Coastguard Worker }
188*288bf522SAndroid Build Coastguard Worker const char* control = (enable ? "1" : "0");
189*288bf522SAndroid Build Coastguard Worker ssize_t len = strlen(control);
190*288bf522SAndroid Build Coastguard Worker int max_try = 10; // Fail if write was interrupted for 10 times
191*288bf522SAndroid Build Coastguard Worker while (write(fd, control, len) != len) {
192*288bf522SAndroid Build Coastguard Worker if (errno == EINTR && max_try-- > 0) {
193*288bf522SAndroid Build Coastguard Worker usleep(100);
194*288bf522SAndroid Build Coastguard Worker continue;
195*288bf522SAndroid Build Coastguard Worker }
196*288bf522SAndroid Build Coastguard Worker
197*288bf522SAndroid Build Coastguard Worker err = true;
198*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Error %d in writing to %s.", errno, path);
199*288bf522SAndroid Build Coastguard Worker }
200*288bf522SAndroid Build Coastguard Worker close(fd);
201*288bf522SAndroid Build Coastguard Worker return (err ? -1 : 0);
202*288bf522SAndroid Build Coastguard Worker }
203*288bf522SAndroid Build Coastguard Worker
204*288bf522SAndroid Build Coastguard Worker /*
205*288bf522SAndroid Build Coastguard Worker * Set the userland tracing properties.
206*288bf522SAndroid Build Coastguard Worker */
dfs_set_property(uint64_t mtag,const char * mapp,bool enable)207*288bf522SAndroid Build Coastguard Worker static void dfs_set_property(uint64_t mtag, const char* mapp, bool enable) {
208*288bf522SAndroid Build Coastguard Worker char buf[64];
209*288bf522SAndroid Build Coastguard Worker snprintf(buf, sizeof(buf), "%#" PRIx64, mtag);
210*288bf522SAndroid Build Coastguard Worker if (property_set(dfs_tags_property, buf) < 0) {
211*288bf522SAndroid Build Coastguard Worker err = true;
212*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Failed to set debug tags system properties.");
213*288bf522SAndroid Build Coastguard Worker }
214*288bf522SAndroid Build Coastguard Worker
215*288bf522SAndroid Build Coastguard Worker if (strlen(mapp) > 0 && property_set(dfs_apps_property, mapp) < 0) {
216*288bf522SAndroid Build Coastguard Worker err = true;
217*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Failed to set debug applications.");
218*288bf522SAndroid Build Coastguard Worker }
219*288bf522SAndroid Build Coastguard Worker
220*288bf522SAndroid Build Coastguard Worker if (log_sched) {
221*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_sched_switch_path);
222*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_sched_wakeup_path);
223*288bf522SAndroid Build Coastguard Worker }
224*288bf522SAndroid Build Coastguard Worker if (log_stack) {
225*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_stack_path);
226*288bf522SAndroid Build Coastguard Worker }
227*288bf522SAndroid Build Coastguard Worker if (log_irq) {
228*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_irq_path);
229*288bf522SAndroid Build Coastguard Worker }
230*288bf522SAndroid Build Coastguard Worker if (log_sync) {
231*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_sync_path);
232*288bf522SAndroid Build Coastguard Worker }
233*288bf522SAndroid Build Coastguard Worker if (log_workq) {
234*288bf522SAndroid Build Coastguard Worker dfs_enable(enable, dfs_workq_path);
235*288bf522SAndroid Build Coastguard Worker }
236*288bf522SAndroid Build Coastguard Worker }
237*288bf522SAndroid Build Coastguard Worker
238*288bf522SAndroid Build Coastguard Worker /*
239*288bf522SAndroid Build Coastguard Worker * Dump the log in a compressed format for systrace to visualize.
240*288bf522SAndroid Build Coastguard Worker * Create a dump file "dump_of_anrdaemon.<current_time>" under /data/misc/anrd
241*288bf522SAndroid Build Coastguard Worker */
dump_trace()242*288bf522SAndroid Build Coastguard Worker static void dump_trace() {
243*288bf522SAndroid Build Coastguard Worker time_t now = time(0);
244*288bf522SAndroid Build Coastguard Worker struct tm tstruct;
245*288bf522SAndroid Build Coastguard Worker char time_buf[time_buf_size];
246*288bf522SAndroid Build Coastguard Worker char path_buf[path_buf_size];
247*288bf522SAndroid Build Coastguard Worker const char* header = " done\nTRACE:\n";
248*288bf522SAndroid Build Coastguard Worker ssize_t header_len = strlen(header);
249*288bf522SAndroid Build Coastguard Worker
250*288bf522SAndroid Build Coastguard Worker ALOGI("Started to dump ANRdaemon trace.");
251*288bf522SAndroid Build Coastguard Worker
252*288bf522SAndroid Build Coastguard Worker tstruct = *localtime(&now);
253*288bf522SAndroid Build Coastguard Worker strftime(time_buf, time_buf_size, "%Y-%m-%d.%X", &tstruct);
254*288bf522SAndroid Build Coastguard Worker snprintf(path_buf, path_buf_size, "/data/misc/anrd/dump_of_anrdaemon.%s", time_buf);
255*288bf522SAndroid Build Coastguard Worker int output_fd = creat(path_buf, S_IRWXU);
256*288bf522SAndroid Build Coastguard Worker if (output_fd == -1) {
257*288bf522SAndroid Build Coastguard Worker ALOGE("Failed to create %s. Dump aborted.", path_buf);
258*288bf522SAndroid Build Coastguard Worker return;
259*288bf522SAndroid Build Coastguard Worker }
260*288bf522SAndroid Build Coastguard Worker
261*288bf522SAndroid Build Coastguard Worker if (write(output_fd, header, strlen(header)) != header_len) {
262*288bf522SAndroid Build Coastguard Worker ALOGE("Failed to write the header.");
263*288bf522SAndroid Build Coastguard Worker close(output_fd);
264*288bf522SAndroid Build Coastguard Worker return;
265*288bf522SAndroid Build Coastguard Worker }
266*288bf522SAndroid Build Coastguard Worker
267*288bf522SAndroid Build Coastguard Worker int trace_fd = open(dfs_trace_output_path, O_RDWR);
268*288bf522SAndroid Build Coastguard Worker if (trace_fd == -1) {
269*288bf522SAndroid Build Coastguard Worker ALOGE("Failed to open %s. Dump aborted.", dfs_trace_output_path);
270*288bf522SAndroid Build Coastguard Worker close(output_fd);
271*288bf522SAndroid Build Coastguard Worker return;
272*288bf522SAndroid Build Coastguard Worker }
273*288bf522SAndroid Build Coastguard Worker
274*288bf522SAndroid Build Coastguard Worker z_stream zs;
275*288bf522SAndroid Build Coastguard Worker uint8_t *in, *out;
276*288bf522SAndroid Build Coastguard Worker int result, flush;
277*288bf522SAndroid Build Coastguard Worker
278*288bf522SAndroid Build Coastguard Worker memset(&zs, 0, sizeof(zs));
279*288bf522SAndroid Build Coastguard Worker result = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
280*288bf522SAndroid Build Coastguard Worker if (result != Z_OK) {
281*288bf522SAndroid Build Coastguard Worker ALOGE("error initializing zlib: %d\n", result);
282*288bf522SAndroid Build Coastguard Worker close(trace_fd);
283*288bf522SAndroid Build Coastguard Worker close(output_fd);
284*288bf522SAndroid Build Coastguard Worker return;
285*288bf522SAndroid Build Coastguard Worker }
286*288bf522SAndroid Build Coastguard Worker
287*288bf522SAndroid Build Coastguard Worker const size_t bufSize = 64 * 1024;
288*288bf522SAndroid Build Coastguard Worker in = (uint8_t*)malloc(bufSize);
289*288bf522SAndroid Build Coastguard Worker out = (uint8_t*)malloc(bufSize);
290*288bf522SAndroid Build Coastguard Worker flush = Z_NO_FLUSH;
291*288bf522SAndroid Build Coastguard Worker
292*288bf522SAndroid Build Coastguard Worker zs.next_out = out;
293*288bf522SAndroid Build Coastguard Worker zs.avail_out = bufSize;
294*288bf522SAndroid Build Coastguard Worker
295*288bf522SAndroid Build Coastguard Worker do {
296*288bf522SAndroid Build Coastguard Worker if (zs.avail_in == 0) {
297*288bf522SAndroid Build Coastguard Worker result = read(trace_fd, in, bufSize);
298*288bf522SAndroid Build Coastguard Worker if (result < 0) {
299*288bf522SAndroid Build Coastguard Worker ALOGE("error reading trace: %s", strerror(errno));
300*288bf522SAndroid Build Coastguard Worker result = Z_STREAM_END;
301*288bf522SAndroid Build Coastguard Worker break;
302*288bf522SAndroid Build Coastguard Worker } else if (result == 0) {
303*288bf522SAndroid Build Coastguard Worker flush = Z_FINISH;
304*288bf522SAndroid Build Coastguard Worker } else {
305*288bf522SAndroid Build Coastguard Worker zs.next_in = in;
306*288bf522SAndroid Build Coastguard Worker zs.avail_in = result;
307*288bf522SAndroid Build Coastguard Worker }
308*288bf522SAndroid Build Coastguard Worker }
309*288bf522SAndroid Build Coastguard Worker
310*288bf522SAndroid Build Coastguard Worker if (zs.avail_out == 0) {
311*288bf522SAndroid Build Coastguard Worker result = write(output_fd, out, bufSize);
312*288bf522SAndroid Build Coastguard Worker if ((size_t)result < bufSize) {
313*288bf522SAndroid Build Coastguard Worker ALOGE("error writing deflated trace: %s", strerror(errno));
314*288bf522SAndroid Build Coastguard Worker result = Z_STREAM_END;
315*288bf522SAndroid Build Coastguard Worker zs.avail_out = bufSize;
316*288bf522SAndroid Build Coastguard Worker break;
317*288bf522SAndroid Build Coastguard Worker }
318*288bf522SAndroid Build Coastguard Worker zs.next_out = out;
319*288bf522SAndroid Build Coastguard Worker zs.avail_out = bufSize;
320*288bf522SAndroid Build Coastguard Worker }
321*288bf522SAndroid Build Coastguard Worker
322*288bf522SAndroid Build Coastguard Worker } while ((result = deflate(&zs, flush)) == Z_OK);
323*288bf522SAndroid Build Coastguard Worker
324*288bf522SAndroid Build Coastguard Worker if (result != Z_STREAM_END) {
325*288bf522SAndroid Build Coastguard Worker ALOGE("error deflating trace: %s\n", zs.msg);
326*288bf522SAndroid Build Coastguard Worker }
327*288bf522SAndroid Build Coastguard Worker
328*288bf522SAndroid Build Coastguard Worker if (zs.avail_out < bufSize) {
329*288bf522SAndroid Build Coastguard Worker size_t bytes = bufSize - zs.avail_out;
330*288bf522SAndroid Build Coastguard Worker result = write(output_fd, out, bytes);
331*288bf522SAndroid Build Coastguard Worker if ((size_t)result < bytes) {
332*288bf522SAndroid Build Coastguard Worker ALOGE("error writing deflated trace: %s", strerror(errno));
333*288bf522SAndroid Build Coastguard Worker }
334*288bf522SAndroid Build Coastguard Worker }
335*288bf522SAndroid Build Coastguard Worker
336*288bf522SAndroid Build Coastguard Worker result = deflateEnd(&zs);
337*288bf522SAndroid Build Coastguard Worker if (result != Z_OK) {
338*288bf522SAndroid Build Coastguard Worker ALOGE("error cleaning up zlib: %d\n", result);
339*288bf522SAndroid Build Coastguard Worker }
340*288bf522SAndroid Build Coastguard Worker
341*288bf522SAndroid Build Coastguard Worker free(in);
342*288bf522SAndroid Build Coastguard Worker free(out);
343*288bf522SAndroid Build Coastguard Worker
344*288bf522SAndroid Build Coastguard Worker close(trace_fd);
345*288bf522SAndroid Build Coastguard Worker close(output_fd);
346*288bf522SAndroid Build Coastguard Worker
347*288bf522SAndroid Build Coastguard Worker ALOGI("Finished dump. Output file stored at: %s", path_buf);
348*288bf522SAndroid Build Coastguard Worker }
349*288bf522SAndroid Build Coastguard Worker
350*288bf522SAndroid Build Coastguard Worker /*
351*288bf522SAndroid Build Coastguard Worker * Start logging when cpu usage is high. Meanwhile, moniter the cpu usage and
352*288bf522SAndroid Build Coastguard Worker * stop logging when it drops down.
353*288bf522SAndroid Build Coastguard Worker */
start_tracing(void)354*288bf522SAndroid Build Coastguard Worker static void start_tracing(void) {
355*288bf522SAndroid Build Coastguard Worker ALOGD("High cpu usage, start logging.");
356*288bf522SAndroid Build Coastguard Worker
357*288bf522SAndroid Build Coastguard Worker if (dfs_enable(true, dfs_control_path) != 0) {
358*288bf522SAndroid Build Coastguard Worker ALOGE("Failed to start tracing.");
359*288bf522SAndroid Build Coastguard Worker return;
360*288bf522SAndroid Build Coastguard Worker }
361*288bf522SAndroid Build Coastguard Worker tracing = true;
362*288bf522SAndroid Build Coastguard Worker
363*288bf522SAndroid Build Coastguard Worker /* Stop logging when cpu usage drops or the daemon is suspended.*/
364*288bf522SAndroid Build Coastguard Worker do {
365*288bf522SAndroid Build Coastguard Worker usleep(tracing_check_period);
366*288bf522SAndroid Build Coastguard Worker } while (!suspend && !dump_requested && is_heavy_load());
367*288bf522SAndroid Build Coastguard Worker
368*288bf522SAndroid Build Coastguard Worker if (dfs_enable(false, dfs_control_path) != 0) {
369*288bf522SAndroid Build Coastguard Worker ALOGE("Failed to stop tracing.");
370*288bf522SAndroid Build Coastguard Worker err = true;
371*288bf522SAndroid Build Coastguard Worker return;
372*288bf522SAndroid Build Coastguard Worker }
373*288bf522SAndroid Build Coastguard Worker tracing = false;
374*288bf522SAndroid Build Coastguard Worker
375*288bf522SAndroid Build Coastguard Worker if (suspend) {
376*288bf522SAndroid Build Coastguard Worker ALOGI("trace stopped due to suspend. Send SIGCONT to resume.");
377*288bf522SAndroid Build Coastguard Worker } else if (dump_requested) {
378*288bf522SAndroid Build Coastguard Worker ALOGI("trace stopped due to dump request.");
379*288bf522SAndroid Build Coastguard Worker dump_trace();
380*288bf522SAndroid Build Coastguard Worker dump_requested = false;
381*288bf522SAndroid Build Coastguard Worker } else {
382*288bf522SAndroid Build Coastguard Worker ALOGD("Usage back to low, stop logging.");
383*288bf522SAndroid Build Coastguard Worker }
384*288bf522SAndroid Build Coastguard Worker }
385*288bf522SAndroid Build Coastguard Worker
386*288bf522SAndroid Build Coastguard Worker /*
387*288bf522SAndroid Build Coastguard Worker * Set the tracing log buffer size.
388*288bf522SAndroid Build Coastguard Worker * Note the actual buffer size will be buf_size_kb * number of cores.
389*288bf522SAndroid Build Coastguard Worker */
set_tracing_buffer_size(void)390*288bf522SAndroid Build Coastguard Worker static int set_tracing_buffer_size(void) {
391*288bf522SAndroid Build Coastguard Worker int fd = open(dfs_buffer_size_path, O_WRONLY);
392*288bf522SAndroid Build Coastguard Worker if (fd == -1) {
393*288bf522SAndroid Build Coastguard Worker err = true;
394*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Can't open atrace buffer size file under /d/tracing.");
395*288bf522SAndroid Build Coastguard Worker return -1;
396*288bf522SAndroid Build Coastguard Worker }
397*288bf522SAndroid Build Coastguard Worker ssize_t len = strlen(buf_size_kb);
398*288bf522SAndroid Build Coastguard Worker if (write(fd, buf_size_kb, len) != len) {
399*288bf522SAndroid Build Coastguard Worker err = true;
400*288bf522SAndroid Build Coastguard Worker snprintf(err_msg, sizeof(err_msg), "Error in writing to atrace buffer size file.");
401*288bf522SAndroid Build Coastguard Worker }
402*288bf522SAndroid Build Coastguard Worker close(fd);
403*288bf522SAndroid Build Coastguard Worker return (err ? -1 : 0);
404*288bf522SAndroid Build Coastguard Worker }
405*288bf522SAndroid Build Coastguard Worker
406*288bf522SAndroid Build Coastguard Worker /*
407*288bf522SAndroid Build Coastguard Worker * Main loop to moniter the cpu usage and decided whether to start logging.
408*288bf522SAndroid Build Coastguard Worker */
start(void)409*288bf522SAndroid Build Coastguard Worker static void start(void) {
410*288bf522SAndroid Build Coastguard Worker if ((set_tracing_buffer_size()) != 0) return;
411*288bf522SAndroid Build Coastguard Worker
412*288bf522SAndroid Build Coastguard Worker dfs_set_property(tag, apps, true);
413*288bf522SAndroid Build Coastguard Worker dfs_poke_binder();
414*288bf522SAndroid Build Coastguard Worker
415*288bf522SAndroid Build Coastguard Worker get_cpu_stat(&old_cpu);
416*288bf522SAndroid Build Coastguard Worker sleep(check_period);
417*288bf522SAndroid Build Coastguard Worker
418*288bf522SAndroid Build Coastguard Worker while (!quit && !err) {
419*288bf522SAndroid Build Coastguard Worker if (!suspend && is_heavy_load()) {
420*288bf522SAndroid Build Coastguard Worker /*
421*288bf522SAndroid Build Coastguard Worker * Increase process priority to make sure we can stop logging when
422*288bf522SAndroid Build Coastguard Worker * necessary and do not overwrite the buffer
423*288bf522SAndroid Build Coastguard Worker */
424*288bf522SAndroid Build Coastguard Worker setpriority(PRIO_PROCESS, 0, -20);
425*288bf522SAndroid Build Coastguard Worker start_tracing();
426*288bf522SAndroid Build Coastguard Worker setpriority(PRIO_PROCESS, 0, 0);
427*288bf522SAndroid Build Coastguard Worker }
428*288bf522SAndroid Build Coastguard Worker sleep(check_period);
429*288bf522SAndroid Build Coastguard Worker }
430*288bf522SAndroid Build Coastguard Worker return;
431*288bf522SAndroid Build Coastguard Worker }
432*288bf522SAndroid Build Coastguard Worker
433*288bf522SAndroid Build Coastguard Worker /*
434*288bf522SAndroid Build Coastguard Worker * If trace is not running, dump trace right away.
435*288bf522SAndroid Build Coastguard Worker * If trace is running, request to dump trace.
436*288bf522SAndroid Build Coastguard Worker */
request_dump_trace()437*288bf522SAndroid Build Coastguard Worker static void request_dump_trace() {
438*288bf522SAndroid Build Coastguard Worker if (!tracing) {
439*288bf522SAndroid Build Coastguard Worker dump_trace();
440*288bf522SAndroid Build Coastguard Worker } else if (!dump_requested) {
441*288bf522SAndroid Build Coastguard Worker dump_requested = true;
442*288bf522SAndroid Build Coastguard Worker }
443*288bf522SAndroid Build Coastguard Worker }
444*288bf522SAndroid Build Coastguard Worker
handle_signal(int signo)445*288bf522SAndroid Build Coastguard Worker static void handle_signal(int signo) {
446*288bf522SAndroid Build Coastguard Worker switch (signo) {
447*288bf522SAndroid Build Coastguard Worker case SIGQUIT:
448*288bf522SAndroid Build Coastguard Worker suspend = true;
449*288bf522SAndroid Build Coastguard Worker quit = true;
450*288bf522SAndroid Build Coastguard Worker break;
451*288bf522SAndroid Build Coastguard Worker case SIGSTOP:
452*288bf522SAndroid Build Coastguard Worker suspend = true;
453*288bf522SAndroid Build Coastguard Worker break;
454*288bf522SAndroid Build Coastguard Worker case SIGCONT:
455*288bf522SAndroid Build Coastguard Worker suspend = false;
456*288bf522SAndroid Build Coastguard Worker break;
457*288bf522SAndroid Build Coastguard Worker case SIGUSR1:
458*288bf522SAndroid Build Coastguard Worker request_dump_trace();
459*288bf522SAndroid Build Coastguard Worker }
460*288bf522SAndroid Build Coastguard Worker }
461*288bf522SAndroid Build Coastguard Worker
462*288bf522SAndroid Build Coastguard Worker /*
463*288bf522SAndroid Build Coastguard Worker * Set the signal handler:
464*288bf522SAndroid Build Coastguard Worker * SIGQUIT: Reset debugfs and tracing property and terminate the daemon.
465*288bf522SAndroid Build Coastguard Worker * SIGSTOP: Stop logging and suspend the daemon.
466*288bf522SAndroid Build Coastguard Worker * SIGCONT: Resume the daemon as normal.
467*288bf522SAndroid Build Coastguard Worker * SIGUSR1: Dump the logging to a compressed format for systrace to visualize.
468*288bf522SAndroid Build Coastguard Worker */
register_sighandler(void)469*288bf522SAndroid Build Coastguard Worker static void register_sighandler(void) {
470*288bf522SAndroid Build Coastguard Worker struct sigaction sa;
471*288bf522SAndroid Build Coastguard Worker sigset_t block_mask;
472*288bf522SAndroid Build Coastguard Worker
473*288bf522SAndroid Build Coastguard Worker sigemptyset(&block_mask);
474*288bf522SAndroid Build Coastguard Worker sigaddset(&block_mask, SIGQUIT);
475*288bf522SAndroid Build Coastguard Worker sigaddset(&block_mask, SIGSTOP);
476*288bf522SAndroid Build Coastguard Worker sigaddset(&block_mask, SIGCONT);
477*288bf522SAndroid Build Coastguard Worker sigaddset(&block_mask, SIGUSR1);
478*288bf522SAndroid Build Coastguard Worker
479*288bf522SAndroid Build Coastguard Worker sa.sa_flags = 0;
480*288bf522SAndroid Build Coastguard Worker sa.sa_mask = block_mask;
481*288bf522SAndroid Build Coastguard Worker sa.sa_handler = handle_signal;
482*288bf522SAndroid Build Coastguard Worker sigaction(SIGQUIT, &sa, NULL);
483*288bf522SAndroid Build Coastguard Worker sigaction(SIGSTOP, &sa, NULL);
484*288bf522SAndroid Build Coastguard Worker sigaction(SIGCONT, &sa, NULL);
485*288bf522SAndroid Build Coastguard Worker sigaction(SIGUSR1, &sa, NULL);
486*288bf522SAndroid Build Coastguard Worker }
487*288bf522SAndroid Build Coastguard Worker
show_help(void)488*288bf522SAndroid Build Coastguard Worker static void show_help(void) {
489*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "usage: anrd [options] [categoris...]\n");
490*288bf522SAndroid Build Coastguard Worker fprintf(stdout,
491*288bf522SAndroid Build Coastguard Worker "Options includes:\n"
492*288bf522SAndroid Build Coastguard Worker " -a appname enable app-level tracing for a comma "
493*288bf522SAndroid Build Coastguard Worker "separated list of cmdlines\n"
494*288bf522SAndroid Build Coastguard Worker " -t N cpu threshold for logging to start "
495*288bf522SAndroid Build Coastguard Worker "(uint = 0.01%%, min = 5000, max = 9999, default = 9990)\n"
496*288bf522SAndroid Build Coastguard Worker " -s N use a trace buffer size of N KB "
497*288bf522SAndroid Build Coastguard Worker "default to 2048KB\n"
498*288bf522SAndroid Build Coastguard Worker " -h show helps\n");
499*288bf522SAndroid Build Coastguard Worker fprintf(stdout,
500*288bf522SAndroid Build Coastguard Worker "Categoris includes:\n"
501*288bf522SAndroid Build Coastguard Worker " am - activity manager\n"
502*288bf522SAndroid Build Coastguard Worker " sm - sync manager\n"
503*288bf522SAndroid Build Coastguard Worker " input - input\n"
504*288bf522SAndroid Build Coastguard Worker " dalvik - dalvik VM\n"
505*288bf522SAndroid Build Coastguard Worker " audio - Audio\n"
506*288bf522SAndroid Build Coastguard Worker " gfx - Graphics\n"
507*288bf522SAndroid Build Coastguard Worker " rs - RenderScript\n"
508*288bf522SAndroid Build Coastguard Worker " hal - Hardware Modules\n"
509*288bf522SAndroid Build Coastguard Worker " irq - kernel irq events\n"
510*288bf522SAndroid Build Coastguard Worker " sched - kernel scheduler activity\n"
511*288bf522SAndroid Build Coastguard Worker " stack - kernel stack\n"
512*288bf522SAndroid Build Coastguard Worker " sync - kernel sync activity\n"
513*288bf522SAndroid Build Coastguard Worker " workq - kernel work queues\n");
514*288bf522SAndroid Build Coastguard Worker fprintf(stdout,
515*288bf522SAndroid Build Coastguard Worker "Control includes:\n"
516*288bf522SAndroid Build Coastguard Worker " SIGQUIT: terminate the process\n"
517*288bf522SAndroid Build Coastguard Worker " SIGSTOP: suspend all function of the daemon\n"
518*288bf522SAndroid Build Coastguard Worker " SIGCONT: resume the normal function\n"
519*288bf522SAndroid Build Coastguard Worker " SIGUSR1: dump the current logging in a compressed form\n");
520*288bf522SAndroid Build Coastguard Worker exit(0);
521*288bf522SAndroid Build Coastguard Worker }
522*288bf522SAndroid Build Coastguard Worker
get_options(int argc,char * argv[])523*288bf522SAndroid Build Coastguard Worker static int get_options(int argc, char* argv[]) {
524*288bf522SAndroid Build Coastguard Worker int opt = 0;
525*288bf522SAndroid Build Coastguard Worker int threshold;
526*288bf522SAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "a:s:t:h")) >= 0) {
527*288bf522SAndroid Build Coastguard Worker switch (opt) {
528*288bf522SAndroid Build Coastguard Worker case 'a':
529*288bf522SAndroid Build Coastguard Worker apps = optarg;
530*288bf522SAndroid Build Coastguard Worker break;
531*288bf522SAndroid Build Coastguard Worker case 's':
532*288bf522SAndroid Build Coastguard Worker if (atoi(optarg) > max_buffer_size)
533*288bf522SAndroid Build Coastguard Worker buf_size_kb = max_buffer_size_str;
534*288bf522SAndroid Build Coastguard Worker else if (atoi(optarg) < min_buffer_size)
535*288bf522SAndroid Build Coastguard Worker buf_size_kb = min_buffer_size_str;
536*288bf522SAndroid Build Coastguard Worker else
537*288bf522SAndroid Build Coastguard Worker buf_size_kb = optarg;
538*288bf522SAndroid Build Coastguard Worker break;
539*288bf522SAndroid Build Coastguard Worker case 't':
540*288bf522SAndroid Build Coastguard Worker threshold = atoi(optarg);
541*288bf522SAndroid Build Coastguard Worker if (threshold > 9999 || threshold < 5000) {
542*288bf522SAndroid Build Coastguard Worker fprintf(stderr, "logging threshold should be 5000-9999\n");
543*288bf522SAndroid Build Coastguard Worker return 1;
544*288bf522SAndroid Build Coastguard Worker }
545*288bf522SAndroid Build Coastguard Worker idle_threshold = 10000 - threshold;
546*288bf522SAndroid Build Coastguard Worker break;
547*288bf522SAndroid Build Coastguard Worker case 'h':
548*288bf522SAndroid Build Coastguard Worker show_help();
549*288bf522SAndroid Build Coastguard Worker break;
550*288bf522SAndroid Build Coastguard Worker default:
551*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
552*288bf522SAndroid Build Coastguard Worker "Error in getting options.\n"
553*288bf522SAndroid Build Coastguard Worker "run \"%s -h\" for usage.\n",
554*288bf522SAndroid Build Coastguard Worker argv[0]);
555*288bf522SAndroid Build Coastguard Worker return 1;
556*288bf522SAndroid Build Coastguard Worker }
557*288bf522SAndroid Build Coastguard Worker }
558*288bf522SAndroid Build Coastguard Worker
559*288bf522SAndroid Build Coastguard Worker for (int i = optind; i < argc; i++) {
560*288bf522SAndroid Build Coastguard Worker if (strcmp(argv[i], "am") == 0) {
561*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_ACTIVITY_MANAGER;
562*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "input") == 0) {
563*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_INPUT;
564*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "sm") == 0) {
565*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_SYNC_MANAGER;
566*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "dalvik") == 0) {
567*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_DALVIK;
568*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "gfx") == 0) {
569*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_GRAPHICS;
570*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "audio") == 0) {
571*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_AUDIO;
572*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "hal") == 0) {
573*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_HAL;
574*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "rs") == 0) {
575*288bf522SAndroid Build Coastguard Worker tag |= ATRACE_TAG_RS;
576*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "sched") == 0) {
577*288bf522SAndroid Build Coastguard Worker log_sched = true;
578*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "stack") == 0) {
579*288bf522SAndroid Build Coastguard Worker log_stack = true;
580*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "workq") == 0) {
581*288bf522SAndroid Build Coastguard Worker log_workq = true;
582*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "irq") == 0) {
583*288bf522SAndroid Build Coastguard Worker log_irq = true;
584*288bf522SAndroid Build Coastguard Worker } else if (strcmp(argv[i], "sync") == 0) {
585*288bf522SAndroid Build Coastguard Worker log_sync = true;
586*288bf522SAndroid Build Coastguard Worker } else {
587*288bf522SAndroid Build Coastguard Worker fprintf(stderr,
588*288bf522SAndroid Build Coastguard Worker "invalid category: %s\n"
589*288bf522SAndroid Build Coastguard Worker "run \"%s -h\" for usage.\n",
590*288bf522SAndroid Build Coastguard Worker argv[i], argv[0]);
591*288bf522SAndroid Build Coastguard Worker return 1;
592*288bf522SAndroid Build Coastguard Worker }
593*288bf522SAndroid Build Coastguard Worker }
594*288bf522SAndroid Build Coastguard Worker
595*288bf522SAndroid Build Coastguard Worker /* If nothing is enabled, don't run */
596*288bf522SAndroid Build Coastguard Worker if (!tag && !log_sched && !log_stack && !log_workq && !log_irq && !log_sync) {
597*288bf522SAndroid Build Coastguard Worker ALOGE("Specify at least one category to trace.");
598*288bf522SAndroid Build Coastguard Worker return 1;
599*288bf522SAndroid Build Coastguard Worker }
600*288bf522SAndroid Build Coastguard Worker
601*288bf522SAndroid Build Coastguard Worker return 0;
602*288bf522SAndroid Build Coastguard Worker }
603*288bf522SAndroid Build Coastguard Worker
main(int argc,char * argv[])604*288bf522SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
605*288bf522SAndroid Build Coastguard Worker if (get_options(argc, argv) != 0) return 1;
606*288bf522SAndroid Build Coastguard Worker
607*288bf522SAndroid Build Coastguard Worker if (daemon(0, 0) != 0) return 1;
608*288bf522SAndroid Build Coastguard Worker
609*288bf522SAndroid Build Coastguard Worker register_sighandler();
610*288bf522SAndroid Build Coastguard Worker
611*288bf522SAndroid Build Coastguard Worker /* Clear any the trace log file by overwrite it with a new file */
612*288bf522SAndroid Build Coastguard Worker int fd = creat(dfs_trace_output_path, 0);
613*288bf522SAndroid Build Coastguard Worker if (fd == -1) {
614*288bf522SAndroid Build Coastguard Worker ALOGE("Faield to open and cleaup previous log");
615*288bf522SAndroid Build Coastguard Worker return 1;
616*288bf522SAndroid Build Coastguard Worker }
617*288bf522SAndroid Build Coastguard Worker close(fd);
618*288bf522SAndroid Build Coastguard Worker
619*288bf522SAndroid Build Coastguard Worker ALOGI("ANRdaemon starting");
620*288bf522SAndroid Build Coastguard Worker start();
621*288bf522SAndroid Build Coastguard Worker
622*288bf522SAndroid Build Coastguard Worker if (err) ALOGE("ANRdaemon stopped due to Error: %s", err_msg);
623*288bf522SAndroid Build Coastguard Worker
624*288bf522SAndroid Build Coastguard Worker ALOGI("ANRdaemon terminated.");
625*288bf522SAndroid Build Coastguard Worker
626*288bf522SAndroid Build Coastguard Worker return (err ? 1 : 0);
627*288bf522SAndroid Build Coastguard Worker }
628