summaryrefslogtreecommitdiff
path: root/ANRdaemon
diff options
context:
space:
mode:
authorZhengyin Qian <qianzy@google.com>2016-09-07 15:57:23 -0700
committerZhengyin Qian <qianzy@google.com>2016-09-07 16:45:13 -0700
commitb403779c945a262dce678308f993f8d6ccd27dda (patch)
tree9854894b481750b96cbcf2796a945d59188343b3 /ANRdaemon
parent6199f023a7296cdd6d420e133c0ce5d728722432 (diff)
downloadextras-b403779c945a262dce678308f993f8d6ccd27dda.tar.gz
ANRdaemon: fix a bug in handling dump request when trace is running.
Change-Id: I16e2be8b90841eef251c83eda9f71c8e70f519ad
Diffstat (limited to 'ANRdaemon')
-rw-r--r--ANRdaemon/ANRdaemon.cpp197
1 files changed, 104 insertions, 93 deletions
diff --git a/ANRdaemon/ANRdaemon.cpp b/ANRdaemon/ANRdaemon.cpp
index d611bf62..35f2ecbb 100644
--- a/ANRdaemon/ANRdaemon.cpp
+++ b/ANRdaemon/ANRdaemon.cpp
@@ -84,6 +84,7 @@ static int idle_threshold = 10;
static bool quit = false;
static bool suspend= false;
+static bool dump_requested = false;
static bool err = false;
static char err_msg[100];
static bool tracing = false;
@@ -246,107 +247,20 @@ static void dfs_set_property(uint64_t mtag, const char* mapp, bool enable) {
}
/*
- * Start logging when cpu usage is high. Meanwhile, moniter the cpu usage and
- * stop logging when it drops down.
- */
-static void start_tracing(void) {
- ALOGD("High cpu usage, start logging.");
-
- if (dfs_enable(true, dfs_control_path) != 0) {
- ALOGE("Failed to start tracing.");
- return;
- }
- tracing = true;
-
- /* Stop logging when cpu usage drops or the daemon is suspended.*/
- do {
- usleep(tracing_check_period);
- } while (!suspend && is_heavy_load());
-
- if (dfs_enable(false, dfs_control_path) != 0) {
- ALOGE("Failed to stop tracing.");
- }
-
- ALOGD("Usage back to low, stop logging.");
- tracing = false;
-}
-
-/*
- * Set the tracing log buffer size.
- * Note the actual buffer size will be buf_size_kb * number of cores.
- * E.g. for dory, the total buffer size is buf_size_kb * 4.
- */
-static int set_tracing_buffer_size(void) {
- int fd = open(dfs_buffer_size_path, O_WRONLY);
- if (fd == -1) {
- err = true;
- sprintf(err_msg, "Can't open atrace buffer size file under /d/tracing.");
- return -1;
- }
- ssize_t len = strlen(buf_size_kb);
- if (write(fd, buf_size_kb, len) != len) {
- err = true;
- sprintf(err_msg, "Error in writing to atrace buffer size file.");
- }
- close(fd);
- return (err?-1:0);
-
-}
-
-/*
- * Main loop to moniter the cpu usage and decided whether to start logging.
- */
-static void start(void) {
- if ((set_tracing_buffer_size()) != 0)
- return;
-
- dfs_set_property(tag, apps, true);
- dfs_poke_binder();
-
- get_cpu_stat(&old_cpu);
- sleep(check_period);
-
- while (!quit && !err) {
- if (!suspend && is_heavy_load()) {
- /*
- * Increase process priority to make sure we can stop logging when
- * necessary and do not overwrite the buffer
- */
- setpriority(PRIO_PROCESS, 0, -20);
- start_tracing();
- setpriority(PRIO_PROCESS, 0, 0);
- }
- sleep(check_period);
- }
- return;
-}
-
-/*
* Dump the log in a compressed format for systrace to visualize.
+ * Create a dump file "dump_of_anrdaemon.<current_time>" under /data/misc/anrd
*/
static void dump_trace()
{
- int remain_attempts = 5;
- suspend = true;
- while (tracing) {
- ALOGI("Waiting logging to stop.");
- usleep(tracing_check_period);
- remain_attempts--;
- if (remain_attempts == 0) {
- ALOGE("Can't stop logging after 5 attempts. Dump aborted.");
- return;
- }
- }
-
- /*
- * Create a dump file "dump_of_anrdaemon.<current_time>" under /data/misc/anrd
- */
time_t now = time(0);
struct tm tstruct;
char time_buf[time_buf_size];
char path_buf[path_buf_size];
const char* header = " done\nTRACE:\n";
ssize_t header_len = strlen(header);
+
+ ALOGI("Started to dump ANRdaemon trace.");
+
tstruct = *localtime(&now);
strftime(time_buf, time_buf_size, "%Y-%m-%d.%X", &tstruct);
snprintf(path_buf, path_buf_size, "/data/misc/anrd/dump_of_anrdaemon.%s", time_buf);
@@ -442,10 +356,107 @@ static void dump_trace()
close(trace_fd);
close(output_fd);
- suspend = false;
ALOGI("Finished dump. Output file stored at: %s", path_buf);
}
+/*
+ * Start logging when cpu usage is high. Meanwhile, moniter the cpu usage and
+ * stop logging when it drops down.
+ */
+static void start_tracing(void) {
+ ALOGD("High cpu usage, start logging.");
+
+ if (dfs_enable(true, dfs_control_path) != 0) {
+ ALOGE("Failed to start tracing.");
+ return;
+ }
+ tracing = true;
+
+ /* Stop logging when cpu usage drops or the daemon is suspended.*/
+ do {
+ usleep(tracing_check_period);
+ } while (!suspend && !dump_requested && is_heavy_load());
+
+ if (dfs_enable(false, dfs_control_path) != 0) {
+ ALOGE("Failed to stop tracing.");
+ err = true;
+ return;
+ }
+ tracing = false;
+
+ if (suspend) {
+ ALOGI("trace stopped due to suspend. Send SIGCONT to resume.");
+ } else if (dump_requested) {
+ ALOGI("trace stopped due to dump request.");
+ dump_trace();
+ dump_requested = false;
+ } else {
+ ALOGD("Usage back to low, stop logging.");
+ }
+}
+
+/*
+ * Set the tracing log buffer size.
+ * Note the actual buffer size will be buf_size_kb * number of cores.
+ */
+static int set_tracing_buffer_size(void) {
+ int fd = open(dfs_buffer_size_path, O_WRONLY);
+ if (fd == -1) {
+ err = true;
+ sprintf(err_msg, "Can't open atrace buffer size file under /d/tracing.");
+ return -1;
+ }
+ ssize_t len = strlen(buf_size_kb);
+ if (write(fd, buf_size_kb, len) != len) {
+ err = true;
+ sprintf(err_msg, "Error in writing to atrace buffer size file.");
+ }
+ close(fd);
+ return (err?-1:0);
+
+}
+
+/*
+ * Main loop to moniter the cpu usage and decided whether to start logging.
+ */
+static void start(void) {
+ if ((set_tracing_buffer_size()) != 0)
+ return;
+
+ dfs_set_property(tag, apps, true);
+ dfs_poke_binder();
+
+ get_cpu_stat(&old_cpu);
+ sleep(check_period);
+
+ while (!quit && !err) {
+ if (!suspend && is_heavy_load()) {
+ /*
+ * Increase process priority to make sure we can stop logging when
+ * necessary and do not overwrite the buffer
+ */
+ setpriority(PRIO_PROCESS, 0, -20);
+ start_tracing();
+ setpriority(PRIO_PROCESS, 0, 0);
+ }
+ sleep(check_period);
+ }
+ return;
+}
+
+/*
+ * If trace is not running, dump trace right away.
+ * If trace is running, request to dump trace.
+ */
+static void request_dump_trace()
+{
+ if (!tracing) {
+ dump_trace();
+ } else if (!dump_requested) {
+ dump_requested = true;
+ }
+}
+
static void handle_signal(int signo)
{
switch (signo) {
@@ -460,7 +471,7 @@ static void handle_signal(int signo)
suspend = false;
break;
case SIGUSR1:
- dump_trace();
+ request_dump_trace();
}
}