diff options
author | Zhengyin Qian <qianzy@google.com> | 2016-09-08 01:26:26 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-09-08 01:26:26 +0000 |
commit | fbf4e2b72b3d03311eb7d144a0c0ce264b9cc588 (patch) | |
tree | e73fc82c5a3a8920f94584655134ffcef39025d3 /ANRdaemon | |
parent | 0a28ed886724284e1eb80735e7bb73ccabff5e6c (diff) | |
parent | 81f3edcdf139a0a1af9fe3699bfdda8fe8bc5426 (diff) | |
download | extras-fbf4e2b72b3d03311eb7d144a0c0ce264b9cc588.tar.gz |
ANRdaemon: fix a bug in handling dump request when trace is running. am: b403779c94
am: 81f3edcdf1
Change-Id: I6e530a534db44578d83b95b14586d1e04098c541
Diffstat (limited to 'ANRdaemon')
-rw-r--r-- | ANRdaemon/ANRdaemon.cpp | 197 |
1 files changed, 104 insertions, 93 deletions
diff --git a/ANRdaemon/ANRdaemon.cpp b/ANRdaemon/ANRdaemon.cpp index 18227044..2419da32 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; @@ -247,107 +248,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); @@ -443,10 +357,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) { @@ -461,7 +472,7 @@ static void handle_signal(int signo) suspend = false; break; case SIGUSR1: - dump_trace(); + request_dump_trace(); } } |