xref: /aosp_15_r20/system/extras/ANRdaemon/ANRdaemon.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
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