Loading cmds/atrace/atrace.rc +1 −1 Original line number Diff line number Diff line ## Permissions to allow system-wide tracing to the kernel trace buffer. ## on fs on post-fs # Allow writing to the kernel trace log. chmod 0222 /sys/kernel/debug/tracing/trace_marker Loading cmds/dumpstate/dumpstate.cpp +330 −82 Original line number Diff line number Diff line Loading @@ -34,7 +34,9 @@ #include <sys/wait.h> #include <unistd.h> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/properties.h> #include "private/android_filesystem_config.h" Loading Loading @@ -179,6 +181,136 @@ static void dump_dev_files(const char *title, const char *driverpath, const char closedir(d); } // return pid of a userspace process. If not found or error, return 0. static unsigned int pid_of_process(const char* ps_name) { DIR *proc_dir; struct dirent *ps; unsigned int pid; std::string cmdline; if (!(proc_dir = opendir("/proc"))) { MYLOGE("Can't open /proc\n"); return 0; } while ((ps = readdir(proc_dir))) { if (!(pid = atoi(ps->d_name))) { continue; } android::base::ReadFileToString("/proc/" + std::string(ps->d_name) + "/cmdline", &cmdline); if (cmdline.find(ps_name) == std::string::npos) { continue; } else { closedir(proc_dir); return pid; } } closedir(proc_dir); return 0; } // dump anrd's trace and add to the zip file. // 1. check if anrd is running on this device. // 2. send a SIGUSR1 to its pid which will dump anrd's trace. // 3. wait until the trace generation completes and add to the zip file. static bool dump_anrd_trace() { unsigned int pid; char buf[50], path[PATH_MAX]; struct dirent *trace; struct stat st; DIR *trace_dir; int retry = 5; long max_ctime = 0, old_mtime; long long cur_size = 0; const char *trace_path = "/data/misc/anrd/"; if (!zip_writer) { MYLOGE("Not dumping anrd trace because zip_writer is not set\n"); return false; } // find anrd's pid if it is running. pid = pid_of_process("/system/xbin/anrd"); if (pid > 0) { if (stat(trace_path, &st) == 0) { old_mtime = st.st_mtime; } else { MYLOGE("Failed to find: %s\n", trace_path); return false; } // send SIGUSR1 to the anrd to generate a trace. sprintf(buf, "%u", pid); if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) { MYLOGE("anrd signal timed out. Please manually collect trace\n"); return false; } while (retry-- > 0 && old_mtime == st.st_mtime) { sleep(1); stat(trace_path, &st); } if (retry < 0 && old_mtime == st.st_mtime) { MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path); return false; } // identify the trace file by its creation time. if (!(trace_dir = opendir(trace_path))) { MYLOGE("Can't open trace file under %s\n", trace_path); } while ((trace = readdir(trace_dir))) { if (strcmp(trace->d_name, ".") == 0 || strcmp(trace->d_name, "..") == 0) { continue; } sprintf(path, "%s%s", trace_path, trace->d_name); if (stat(path, &st) == 0) { if (st.st_ctime > max_ctime) { max_ctime = st.st_ctime; sprintf(buf, "%s", trace->d_name); } } } closedir(trace_dir); // Wait until the dump completes by checking the size of the trace. if (max_ctime > 0) { sprintf(path, "%s%s", trace_path, buf); while(true) { sleep(1); if (stat(path, &st) == 0) { if (st.st_size == cur_size) { break; } else if (st.st_size > cur_size) { cur_size = st.st_size; } else { return false; } } else { MYLOGE("Cant stat() %s anymore\n", path); return false; } } // Add to the zip file. if (!add_zip_entry("anrd_trace.txt", path)) { MYLOGE("Unable to add anrd_trace file %s to zip file\n", path); } else { if (remove(path)) { MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno)); } return true; } } else { MYLOGE("Can't stats any trace file under %s\n", trace_path); } } return false; } static void dump_systrace() { if (!is_zipping()) { MYLOGD("Not dumping systrace because dumpstate is not zipping\n"); Loading Loading @@ -254,6 +386,83 @@ static void dump_raft() { } } /** * Finds the last modified file in the directory dir whose name starts with file_prefix * Function returns empty string when it does not find a file */ static std::string get_last_modified_file_matching_prefix(const std::string& dir, const std::string& file_prefix) { std::unique_ptr<DIR, decltype(&closedir)> d(opendir(dir.c_str()), closedir); if (d == nullptr) { MYLOGD("Error %d opening %s\n", errno, dir.c_str()); return ""; } // Find the newest file matching the file_prefix in dir struct dirent *de; time_t last_modified = 0; std::string last_modified_file = ""; struct stat s; while ((de = readdir(d.get()))) { std::string file = std::string(de->d_name); if (!file_prefix.empty()) { if (!android::base::StartsWith(file, file_prefix.c_str())) continue; } file = dir + "/" + file; int ret = stat(file.c_str(), &s); if ((ret == 0) && (s.st_mtime > last_modified)) { last_modified_file = file; last_modified = s.st_mtime; } } return last_modified_file; } void dump_modem_logs() { DurationReporter duration_reporter("dump_modem_logs"); if (is_user_build()) { return; } if (!is_zipping()) { MYLOGD("Not dumping modem logs. dumpstate is not generating a zipping bugreport\n"); return; } char property[PROPERTY_VALUE_MAX]; property_get("ro.radio.log_prefix", property, ""); std::string file_prefix = std::string(property); if(file_prefix.empty()) { MYLOGD("No modem log : file_prefix is empty\n"); return; } MYLOGD("dump_modem_logs: directory is %s and file_prefix is %s\n", bugreport_dir.c_str(), file_prefix.c_str()); std::string modem_log_file = get_last_modified_file_matching_prefix(bugreport_dir, file_prefix); struct stat s; if (modem_log_file.empty() || stat(modem_log_file.c_str(), &s) != 0) { MYLOGD("Modem log %s does not exist\n", modem_log_file.c_str()); return; } std::string filename = basename(modem_log_file.c_str()); if (!add_zip_entry(filename, modem_log_file)) { MYLOGE("Unable to add modem log %s to zip file\n", modem_log_file.c_str()); } else { MYLOGD("Modem Log %s is added to zip\n", modem_log_file.c_str()); if (remove(modem_log_file.c_str())) { MYLOGE("Error removing modem log %s\n", modem_log_file.c_str()); } } } static bool skip_not_stat(const char *path) { static const char stat[] = "/stat"; size_t len = strlen(path); Loading Loading @@ -702,9 +911,63 @@ static void dump_iptables() { run_command("IP6TABLES RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL); } static void do_kmsg() { struct stat st; if (!stat(PSTORE_LAST_KMSG, &st)) { /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ dump_file("LAST KMSG", PSTORE_LAST_KMSG); } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) { dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG); } else { /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ dump_file("LAST KMSG", "/proc/last_kmsg"); } } static void do_logcat() { unsigned long timeout; // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ run_command("LAST LOGCAT", 10, "logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); } static void dumpstate(const std::string& screenshot_path, const std::string& version) { DurationReporter duration_reporter("DUMPSTATE"); unsigned long timeout; dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); run_command("UPTIME", 10, "uptime", NULL); Loading Loading @@ -739,42 +1002,16 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)"); /* Dump Bluetooth HCI logs */ add_dir("/data/misc/bluetooth/logs", true); if (!screenshot_path.empty()) { MYLOGI("taking late screenshot\n"); take_screenshot(screenshot_path); MYLOGI("wrote screenshot: %s\n", screenshot_path.c_str()); } // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); do_logcat(); /* show the traces we collected in main(), if that was done */ if (dump_traces_path != NULL) { Loading Loading @@ -842,23 +1079,7 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); if (!stat(PSTORE_LAST_KMSG, &st)) { /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ dump_file("LAST KMSG", PSTORE_LAST_KMSG); } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) { dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG); } else { /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ dump_file("LAST KMSG", "/proc/last_kmsg"); } /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ run_command("LAST LOGCAT", 10, "logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); do_kmsg(); /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ Loading Loading @@ -991,6 +1212,10 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver run_command("APP PROVIDERS", 30, "dumpsys", "-t", "30", "activity", "provider", "all", NULL); // dump_modem_logs adds the modem logs if available to the bugreport. // Do this at the end to allow for sufficient time for the modem logs to be // collected. dump_modem_logs(); printf("========================================================\n"); printf("== Final progress (pid %d): %d/%d (originally %d)\n", Loading @@ -1002,14 +1227,15 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver static void usage() { fprintf(stderr, "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] " "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n" "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-t]" "[-z] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n" " -h: display this help message\n" " -b: play sound file instead of vibrate, at beginning of job\n" " -e: play sound file instead of vibrate, at end of job\n" " -o: write to file (instead of stdout)\n" " -d: append date to filename (requires -o)\n" " -p: capture screenshot to filename.png (requires -o)\n" " -t: only captures telephony sections\n" " -z: generate zipped file (requires -o)\n" " -s: write output to control socket (for init)\n" " -S: write file location to control socket (for init; requires -o and -z)" Loading Loading @@ -1106,6 +1332,8 @@ int main(int argc, char *argv[]) { int do_broadcast = 0; int do_early_screenshot = 0; int is_remote_mode = 0; bool telephony_only = false; std::string version = VERSION_DEFAULT; now = time(NULL); Loading Loading @@ -1146,9 +1374,10 @@ int main(int argc, char *argv[]) { format_args(argc, const_cast<const char **>(argv), &args); MYLOGD("Dumpstate command line: %s\n", args.c_str()); int c; while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) { while ((c = getopt(argc, argv, "dho:svqzptPBRSV:")) != -1) { switch (c) { case 'd': do_add_date = 1; break; case 't': telephony_only = true; break; case 'z': do_zip_file = 1; break; case 'o': use_outfile = optarg; break; case 's': use_socket = 1; break; Loading Loading @@ -1245,6 +1474,9 @@ int main(int argc, char *argv[]) { char build_id[PROPERTY_VALUE_MAX]; property_get("ro.build.id", build_id, "UNKNOWN_BUILD"); base_name = base_name + "-" + build_id; if (telephony_only) { base_name = base_name + "-telephony"; } if (do_fb) { // TODO: if dumpstate was an object, the paths could be internal variables and then // we could have a function to calculate the derived values, such as: Loading Loading @@ -1354,8 +1586,23 @@ int main(int argc, char *argv[]) { // duration is logged into MYLOG instead. print_header(version); if (telephony_only) { dump_iptables(); if (!drop_root_user()) { return -1; } do_dmesg(); do_logcat(); do_kmsg(); dumpstate_board(); dump_modem_logs(); } else { // Dumps systrace right away, otherwise it will be filled with unnecessary events. // First try to dump anrd trace if the daemon is running. Otherwise, dump // the raw trace. if (!dump_anrd_trace()) { dump_systrace(); } // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed. dump_raft(); Loading Loading @@ -1391,6 +1638,7 @@ int main(int argc, char *argv[]) { } dumpstate(do_early_screenshot ? "": screenshot_path, version); } /* close output if needed */ if (is_redirecting) { Loading cmds/dumpstate/dumpstate.rc +8 −0 Original line number Diff line number Diff line Loading @@ -46,3 +46,11 @@ service bugreportwear /system/bin/dumpstate -d -B -P -p -z \ class main disabled oneshot # bugreportelefony is a lightweight version of bugreport that only includes a few, urgent # sections used to report telephony bugs. service bugreportelefony /system/bin/dumpstate -t -d -B -z \ -o /data/user_de/0/com.android.shell/files/bugreports/bugreport class main disabled oneshot cmds/dumpstate/utils.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -828,7 +828,8 @@ bool drop_root_user() { } gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_BLUETOOTH }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); return false; Loading data/etc/android.hardware.sensor.heartrate.fitness.xml 0 → 100644 +20 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2009 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- Feature for devices supporting a fitness heart rate monitor --> <permissions> <feature name="android.hardware.sensor.heartrate.fitness" /> </permissions> Loading
cmds/atrace/atrace.rc +1 −1 Original line number Diff line number Diff line ## Permissions to allow system-wide tracing to the kernel trace buffer. ## on fs on post-fs # Allow writing to the kernel trace log. chmod 0222 /sys/kernel/debug/tracing/trace_marker Loading
cmds/dumpstate/dumpstate.cpp +330 −82 Original line number Diff line number Diff line Loading @@ -34,7 +34,9 @@ #include <sys/wait.h> #include <unistd.h> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/properties.h> #include "private/android_filesystem_config.h" Loading Loading @@ -179,6 +181,136 @@ static void dump_dev_files(const char *title, const char *driverpath, const char closedir(d); } // return pid of a userspace process. If not found or error, return 0. static unsigned int pid_of_process(const char* ps_name) { DIR *proc_dir; struct dirent *ps; unsigned int pid; std::string cmdline; if (!(proc_dir = opendir("/proc"))) { MYLOGE("Can't open /proc\n"); return 0; } while ((ps = readdir(proc_dir))) { if (!(pid = atoi(ps->d_name))) { continue; } android::base::ReadFileToString("/proc/" + std::string(ps->d_name) + "/cmdline", &cmdline); if (cmdline.find(ps_name) == std::string::npos) { continue; } else { closedir(proc_dir); return pid; } } closedir(proc_dir); return 0; } // dump anrd's trace and add to the zip file. // 1. check if anrd is running on this device. // 2. send a SIGUSR1 to its pid which will dump anrd's trace. // 3. wait until the trace generation completes and add to the zip file. static bool dump_anrd_trace() { unsigned int pid; char buf[50], path[PATH_MAX]; struct dirent *trace; struct stat st; DIR *trace_dir; int retry = 5; long max_ctime = 0, old_mtime; long long cur_size = 0; const char *trace_path = "/data/misc/anrd/"; if (!zip_writer) { MYLOGE("Not dumping anrd trace because zip_writer is not set\n"); return false; } // find anrd's pid if it is running. pid = pid_of_process("/system/xbin/anrd"); if (pid > 0) { if (stat(trace_path, &st) == 0) { old_mtime = st.st_mtime; } else { MYLOGE("Failed to find: %s\n", trace_path); return false; } // send SIGUSR1 to the anrd to generate a trace. sprintf(buf, "%u", pid); if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) { MYLOGE("anrd signal timed out. Please manually collect trace\n"); return false; } while (retry-- > 0 && old_mtime == st.st_mtime) { sleep(1); stat(trace_path, &st); } if (retry < 0 && old_mtime == st.st_mtime) { MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path); return false; } // identify the trace file by its creation time. if (!(trace_dir = opendir(trace_path))) { MYLOGE("Can't open trace file under %s\n", trace_path); } while ((trace = readdir(trace_dir))) { if (strcmp(trace->d_name, ".") == 0 || strcmp(trace->d_name, "..") == 0) { continue; } sprintf(path, "%s%s", trace_path, trace->d_name); if (stat(path, &st) == 0) { if (st.st_ctime > max_ctime) { max_ctime = st.st_ctime; sprintf(buf, "%s", trace->d_name); } } } closedir(trace_dir); // Wait until the dump completes by checking the size of the trace. if (max_ctime > 0) { sprintf(path, "%s%s", trace_path, buf); while(true) { sleep(1); if (stat(path, &st) == 0) { if (st.st_size == cur_size) { break; } else if (st.st_size > cur_size) { cur_size = st.st_size; } else { return false; } } else { MYLOGE("Cant stat() %s anymore\n", path); return false; } } // Add to the zip file. if (!add_zip_entry("anrd_trace.txt", path)) { MYLOGE("Unable to add anrd_trace file %s to zip file\n", path); } else { if (remove(path)) { MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno)); } return true; } } else { MYLOGE("Can't stats any trace file under %s\n", trace_path); } } return false; } static void dump_systrace() { if (!is_zipping()) { MYLOGD("Not dumping systrace because dumpstate is not zipping\n"); Loading Loading @@ -254,6 +386,83 @@ static void dump_raft() { } } /** * Finds the last modified file in the directory dir whose name starts with file_prefix * Function returns empty string when it does not find a file */ static std::string get_last_modified_file_matching_prefix(const std::string& dir, const std::string& file_prefix) { std::unique_ptr<DIR, decltype(&closedir)> d(opendir(dir.c_str()), closedir); if (d == nullptr) { MYLOGD("Error %d opening %s\n", errno, dir.c_str()); return ""; } // Find the newest file matching the file_prefix in dir struct dirent *de; time_t last_modified = 0; std::string last_modified_file = ""; struct stat s; while ((de = readdir(d.get()))) { std::string file = std::string(de->d_name); if (!file_prefix.empty()) { if (!android::base::StartsWith(file, file_prefix.c_str())) continue; } file = dir + "/" + file; int ret = stat(file.c_str(), &s); if ((ret == 0) && (s.st_mtime > last_modified)) { last_modified_file = file; last_modified = s.st_mtime; } } return last_modified_file; } void dump_modem_logs() { DurationReporter duration_reporter("dump_modem_logs"); if (is_user_build()) { return; } if (!is_zipping()) { MYLOGD("Not dumping modem logs. dumpstate is not generating a zipping bugreport\n"); return; } char property[PROPERTY_VALUE_MAX]; property_get("ro.radio.log_prefix", property, ""); std::string file_prefix = std::string(property); if(file_prefix.empty()) { MYLOGD("No modem log : file_prefix is empty\n"); return; } MYLOGD("dump_modem_logs: directory is %s and file_prefix is %s\n", bugreport_dir.c_str(), file_prefix.c_str()); std::string modem_log_file = get_last_modified_file_matching_prefix(bugreport_dir, file_prefix); struct stat s; if (modem_log_file.empty() || stat(modem_log_file.c_str(), &s) != 0) { MYLOGD("Modem log %s does not exist\n", modem_log_file.c_str()); return; } std::string filename = basename(modem_log_file.c_str()); if (!add_zip_entry(filename, modem_log_file)) { MYLOGE("Unable to add modem log %s to zip file\n", modem_log_file.c_str()); } else { MYLOGD("Modem Log %s is added to zip\n", modem_log_file.c_str()); if (remove(modem_log_file.c_str())) { MYLOGE("Error removing modem log %s\n", modem_log_file.c_str()); } } } static bool skip_not_stat(const char *path) { static const char stat[] = "/stat"; size_t len = strlen(path); Loading Loading @@ -702,9 +911,63 @@ static void dump_iptables() { run_command("IP6TABLES RAW", 10, "ip6tables", "-t", "raw", "-L", "-nvx", NULL); } static void do_kmsg() { struct stat st; if (!stat(PSTORE_LAST_KMSG, &st)) { /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ dump_file("LAST KMSG", PSTORE_LAST_KMSG); } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) { dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG); } else { /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ dump_file("LAST KMSG", "/proc/last_kmsg"); } } static void do_logcat() { unsigned long timeout; // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ run_command("LAST LOGCAT", 10, "logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); } static void dumpstate(const std::string& screenshot_path, const std::string& version) { DurationReporter duration_reporter("DUMPSTATE"); unsigned long timeout; dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); run_command("UPTIME", 10, "uptime", NULL); Loading Loading @@ -739,42 +1002,16 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)"); /* Dump Bluetooth HCI logs */ add_dir("/data/misc/bluetooth/logs", true); if (!screenshot_path.empty()) { MYLOGI("taking late screenshot\n"); take_screenshot(screenshot_path); MYLOGI("wrote screenshot: %s\n", screenshot_path.c_str()); } // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; } run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; } run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; } run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); do_logcat(); /* show the traces we collected in main(), if that was done */ if (dump_traces_path != NULL) { Loading Loading @@ -842,23 +1079,7 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); if (!stat(PSTORE_LAST_KMSG, &st)) { /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ dump_file("LAST KMSG", PSTORE_LAST_KMSG); } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) { dump_file("LAST KMSG", ALT_PSTORE_LAST_KMSG); } else { /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ dump_file("LAST KMSG", "/proc/last_kmsg"); } /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ run_command("LAST LOGCAT", 10, "logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable", "-d", "*:v", NULL); do_kmsg(); /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ Loading Loading @@ -991,6 +1212,10 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver run_command("APP PROVIDERS", 30, "dumpsys", "-t", "30", "activity", "provider", "all", NULL); // dump_modem_logs adds the modem logs if available to the bugreport. // Do this at the end to allow for sufficient time for the modem logs to be // collected. dump_modem_logs(); printf("========================================================\n"); printf("== Final progress (pid %d): %d/%d (originally %d)\n", Loading @@ -1002,14 +1227,15 @@ static void dumpstate(const std::string& screenshot_path, const std::string& ver static void usage() { fprintf(stderr, "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] " "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n" "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-t]" "[-z] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n" " -h: display this help message\n" " -b: play sound file instead of vibrate, at beginning of job\n" " -e: play sound file instead of vibrate, at end of job\n" " -o: write to file (instead of stdout)\n" " -d: append date to filename (requires -o)\n" " -p: capture screenshot to filename.png (requires -o)\n" " -t: only captures telephony sections\n" " -z: generate zipped file (requires -o)\n" " -s: write output to control socket (for init)\n" " -S: write file location to control socket (for init; requires -o and -z)" Loading Loading @@ -1106,6 +1332,8 @@ int main(int argc, char *argv[]) { int do_broadcast = 0; int do_early_screenshot = 0; int is_remote_mode = 0; bool telephony_only = false; std::string version = VERSION_DEFAULT; now = time(NULL); Loading Loading @@ -1146,9 +1374,10 @@ int main(int argc, char *argv[]) { format_args(argc, const_cast<const char **>(argv), &args); MYLOGD("Dumpstate command line: %s\n", args.c_str()); int c; while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) { while ((c = getopt(argc, argv, "dho:svqzptPBRSV:")) != -1) { switch (c) { case 'd': do_add_date = 1; break; case 't': telephony_only = true; break; case 'z': do_zip_file = 1; break; case 'o': use_outfile = optarg; break; case 's': use_socket = 1; break; Loading Loading @@ -1245,6 +1474,9 @@ int main(int argc, char *argv[]) { char build_id[PROPERTY_VALUE_MAX]; property_get("ro.build.id", build_id, "UNKNOWN_BUILD"); base_name = base_name + "-" + build_id; if (telephony_only) { base_name = base_name + "-telephony"; } if (do_fb) { // TODO: if dumpstate was an object, the paths could be internal variables and then // we could have a function to calculate the derived values, such as: Loading Loading @@ -1354,8 +1586,23 @@ int main(int argc, char *argv[]) { // duration is logged into MYLOG instead. print_header(version); if (telephony_only) { dump_iptables(); if (!drop_root_user()) { return -1; } do_dmesg(); do_logcat(); do_kmsg(); dumpstate_board(); dump_modem_logs(); } else { // Dumps systrace right away, otherwise it will be filled with unnecessary events. // First try to dump anrd trace if the daemon is running. Otherwise, dump // the raw trace. if (!dump_anrd_trace()) { dump_systrace(); } // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed. dump_raft(); Loading Loading @@ -1391,6 +1638,7 @@ int main(int argc, char *argv[]) { } dumpstate(do_early_screenshot ? "": screenshot_path, version); } /* close output if needed */ if (is_redirecting) { Loading
cmds/dumpstate/dumpstate.rc +8 −0 Original line number Diff line number Diff line Loading @@ -46,3 +46,11 @@ service bugreportwear /system/bin/dumpstate -d -B -P -p -z \ class main disabled oneshot # bugreportelefony is a lightweight version of bugreport that only includes a few, urgent # sections used to report telephony bugs. service bugreportelefony /system/bin/dumpstate -t -d -B -z \ -o /data/user_de/0/com.android.shell/files/bugreports/bugreport class main disabled oneshot
cmds/dumpstate/utils.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -828,7 +828,8 @@ bool drop_root_user() { } gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_BLUETOOTH }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); return false; Loading
data/etc/android.hardware.sensor.heartrate.fitness.xml 0 → 100644 +20 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2009 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- Feature for devices supporting a fitness heart rate monitor --> <permissions> <feature name="android.hardware.sensor.heartrate.fitness" /> </permissions>