dumpstate.cpp revision 4db754fd7c13993d81d98157f10e8015422d1e3a
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* 2f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Copyright (C) 2008 The Android Open Source Project 3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 4f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 5f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * you may not use this file except in compliance with the License. 6f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * You may obtain a copy of the License at 7f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 8f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 9f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * 10f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Unless required by applicable law or agreed to in writing, software 11f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 12f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * See the License for the specific language governing permissions and 14f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * limitations under the License. 15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */ 16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 172db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg#include <dirent.h> 18f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <errno.h> 19f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <fcntl.h> 20ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme#include <libgen.h> 21f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <limits.h> 226e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include <memory> 23ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme#include <regex> 24635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme#include <set> 258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#include <stdbool.h> 26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h> 27f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdlib.h> 286e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include <string> 29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h> 307dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/capability.h> 317dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/prctl.h> 32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/resource.h> 33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/stat.h> 34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h> 35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/wait.h> 36f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <unistd.h> 37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 389dc117c415d0df0a3acd900709d05deabe975704Elliott Hughes#include <android-base/stringprintf.h> 39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <cutils/properties.h> 40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 41f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "private/android_filesystem_config.h" 42f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 43f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#define LOG_TAG "dumpstate" 44656a6b9e3645bfe2cf073b69cbb9d02832f62c26Alex Ray#include <cutils/log.h> 45f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 46f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "dumpstate.h" 476e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ScopedFd.h" 486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ziparchive/zip_writer.h" 496e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 504db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski#include "mincrypt/sha256.h" 514db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 526e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Lemeusing android::base::StringPrintf; 53f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 54f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* read before root is shed */ 55f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char cmdline_buf[16384] = "(unknown)"; 56f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic const char *dump_traces_path = NULL; 57f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 58e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme// TODO: should be part of dumpstate object 5978f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic char build_type[PROPERTY_VALUE_MAX]; 60e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic time_t now; 61e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic std::unique_ptr<ZipWriter> zip_writer; 62635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemestatic std::set<std::string> mount_points; 63635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo(); 64635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemestatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path); 6578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 662a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops" 672a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 688d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati#define RAFT_DIR "/data/misc/raft/" 69e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme#define RECOVERY_DIR "/cache/recovery" 707dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_DIR "/data/tombstones" 717dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_" 727dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Can accomodate a tombstone number up to 9999. */ 737dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4) 747dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define NUM_TOMBSTONES 10 757dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 767dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferristypedef struct { 777dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris char name[TOMBSTONE_MAX_LEN]; 787dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int fd; 797dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} tombstone_data_t; 807dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 817dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES]; 827dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 83e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme// Root dir for all files copied as-is into the bugreport 84e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemeconst std::string& ZIP_ROOT_DIR = "FS"; 85e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 86e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* gets the tombstone data, according to the bugreport type: if zipped gets all tombstones, 87e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme * otherwise gets just those modified in the last half an hour. */ 887dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) { 89e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme time_t thirty_minutes_ago = now - 60*30; 907dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 917dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i); 9254bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(data[i].name, 9354bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 947dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris struct stat st; 957dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && 96e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme (zip_writer || (time_t) st.st_mtime >= thirty_minutes_ago)) { 97e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme data[i].fd = fd; 987dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 99e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme close(fd); 1007dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris data[i].fd = -1; 1017dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 1027dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 1037dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} 1047dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 105635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme// for_each_pid() callback to get mount info about a process. 106635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid do_mountinfo(int pid, const char *name) { 107635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme char path[PATH_MAX]; 108635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme 109635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme // Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points 110635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme // are added. 111635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme sprintf(path, "/proc/%d/ns/mnt", pid); 112635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme char linkname[PATH_MAX]; 113635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme ssize_t r = readlink(path, linkname, PATH_MAX); 114635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme if (r == -1) { 115635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme ALOGE("Unable to read link for %s: %s\n", path, strerror(errno)); 116635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme return; 117635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme } 118635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme linkname[r] = '\0'; 119635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme 120635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme if (mount_points.find(linkname) == mount_points.end()) { 121635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme // First time this mount point was found: add it 122635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme sprintf(path, "/proc/%d/mountinfo", pid); 123635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme if (add_zip_entry(ZIP_ROOT_DIR + path, path)) { 124635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme mount_points.insert(linkname); 125635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme } else { 126635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme ALOGE("Unable to add mountinfo %s to zip file\n", path); 127635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme } 128635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme } 129635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme} 130635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme 131635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo() { 132635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme if (!zip_writer) return; 133635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme const char *title = "MOUNT INFO"; 134635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme mount_points.clear(); 135635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme DurationReporter duration_reporter(title); 136635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme for_each_pid(do_mountinfo, NULL); 137635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme printf("%s: %d entries added to zip file\n", title, mount_points.size()); 138635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme} 139635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme 1402db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevågstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename) 1412db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg{ 1422db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg DIR *d; 1432db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg struct dirent *de; 1442db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg char path[PATH_MAX]; 1452db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1462db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg d = opendir(driverpath); 1472db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (d == NULL) { 1482db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg return; 1492db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1502db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1512db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg while ((de = readdir(d))) { 1522db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (de->d_type != DT_LNK) { 1532db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg continue; 1542db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1552db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename); 1562db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_file(title, path); 1572db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1582db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1592db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg closedir(d); 1602db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg} 1612db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 162326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic bool skip_not_stat(const char *path) { 163326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn static const char stat[] = "/stat"; 164326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t len = strlen(path); 165326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (path[len - 1] == '/') { /* Directory? */ 166326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return false; 167326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 168326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ 169326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 170326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 171e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool skip_none(const char *path) { 172e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 173e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 174e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 175326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic const char mmcblk0[] = "/sys/block/mmcblk0/"; 1768f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynunsigned long worst_write_perf = 20000; /* in KB/s */ 177326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 178326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { 179326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn unsigned long fields[11], read_perf, write_perf; 180326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn bool z; 181326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn char *cp, *buffer = NULL; 182326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t i = 0; 183326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn FILE *fp = fdopen(fd, "rb"); 184326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn getline(&buffer, &i, fp); 185326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fclose(fp); 186326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!buffer) { 187326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return -errno; 188326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 189326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn i = strlen(buffer); 190326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn while ((i > 0) && (buffer[i - 1] == '\n')) { 191326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn buffer[--i] = '\0'; 192326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 193326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!*buffer) { 194326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 195326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 196326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 197326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = true; 198326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { 199326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fields[i] = strtol(cp, &cp, 0); 200326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[i] != 0) { 201326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = false; 202326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 203326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 204326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (z) { /* never accessed */ 205326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 206326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 207326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 208326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 209326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { 210326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn path += sizeof(mmcblk0) - 1; 211326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 212326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 213326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: %s\n", path, buffer); 214326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 215326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 216326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 0; 217326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[3]) { 218326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 512 * fields[2] / fields[3]; 219326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 220326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 0; 221326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[7]) { 222326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 512 * fields[6] / fields[7]; 223326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 224326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf); 2258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((write_perf > 1) && (write_perf < worst_write_perf)) { 2268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn worst_write_perf = write_perf; 2278f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 228326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 229326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 230326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 2318f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* Copied policy from system/core/logd/LogBuffer.cpp */ 2328f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2338f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_SIZE (256 * 1024) 2348f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) 2358f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) 2368f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2378f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic bool valid_size(unsigned long value) { 2388f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { 2398f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return false; 2408f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2418f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2428f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pages = sysconf(_SC_PHYS_PAGES); 2438f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pages < 1) { 2448f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 2458f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pagesize = sysconf(_SC_PAGESIZE); 2488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pagesize <= 1) { 2498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pagesize = PAGE_SIZE; 2508f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2518f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2528f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // maximum memory impact a somewhat arbitrary ~3% 2538f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pages = (pages + 31) / 32; 2548f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long maximum = pages * pagesize; 2558f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2568f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { 2578f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 2588f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2598f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2608f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value <= maximum; 2618f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic unsigned long property_get_size(const char *key) { 2648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long value; 2658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char *cp, property[PROPERTY_VALUE_MAX]; 2668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2678f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_get(key, property, ""); 2688f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = strtoul(property, &cp, 10); 2698f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2708f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn switch(*cp) { 2718f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'm': 2728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'M': 2738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2758f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'k': 2768f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'K': 2778f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2788f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case '\0': 2808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn break; 2818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default: 2838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2848f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2858f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2868f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!valid_size(value)) { 2878f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2888f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2898f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2908f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value; 2918f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2928f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2938f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* timeout in ms */ 2948620bb4118a68721d10c29529dc6978847d08d00Felipe Lemestatic unsigned long logcat_timeout(const char *name) { 2958f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_tuneable[] = "persist.logd.size"; // Settings App 2968f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_default[] = "ro.logd.size"; // BoardConfig.mk 2978f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char key[PROP_NAME_MAX]; 2988f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long property_size, default_size; 2998f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3008f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_tuneable); 3018f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!default_size) { 3028f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_default); 3038f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3048f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3058f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_tuneable, name); 3068f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 3078f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3088f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 3098f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_default, name); 3108f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 3118f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3128f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3138f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 3148f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = default_size; 3158f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3168f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3178f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 3188f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = LOG_BUFFER_SIZE; 3198f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3208f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3218f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* Engineering margin is ten-fold our guess */ 3228f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return 10 * (property_size + worst_write_perf) / worst_write_perf; 3238f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 3248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 3258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* End copy from system/core/logd/LogBuffer.cpp */ 3268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 327f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* dumps the current system state to stdout */ 32878f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void print_header() { 329f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX]; 330f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; 331f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char network[PROPERTY_VALUE_MAX], date[80]; 332f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 333f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.display.id", build, "(unknown)"); 334f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.fingerprint", fingerprint, "(unknown)"); 335f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.type", build_type, "(unknown)"); 336f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.baseband", radio, "(unknown)"); 337f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.bootloader", bootloader, "(unknown)"); 338f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("gsm.operator.alpha", network, "(unknown)"); 339f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now)); 340f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 341f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 342f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: %s\n", date); 343f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 344f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 345f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 346f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build: %s\n", build); 347f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */ 348f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Bootloader: %s\n", bootloader); 349f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Radio: %s\n", radio); 350f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Network: %s\n", network); 351f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 352f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Kernel: "); 353f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/proc/version"); 354f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Command line: %s\n", strtok(cmdline_buf, "\n")); 355f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 35678f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme} 35778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 358e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a new entry to the existing zip file. */ 359e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool add_zip_entry_from_fd(const std::string& entry_name, int fd) { 360e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(), 361e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ZipWriter::kCompress, get_mtime(fd, now)); 362e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 363e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), ZipWriter::ErrorCodeString(err)); 364e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 365e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 366e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 367e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme while (1) { 368e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme std::vector<uint8_t> buffer(65536); 369e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), sizeof(buffer))); 370e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (bytes_read == 0) { 371e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme break; 372e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } else if (bytes_read == -1) { 373e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno)); 374e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 375e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 376e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme err = zip_writer->WriteBytes(buffer.data(), bytes_read); 377e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 378e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err)); 379e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 380e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 381e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 382e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 383e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme err = zip_writer->FinishEntry(); 384e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 385e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err)); 386e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 387e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 388e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 389e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return true; 390e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 391e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 392e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a new entry to the existing zip file. */ 393e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path) { 394e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); 395e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (fd.get() == -1) { 396e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno)); 397e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 398e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 399e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 400e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return add_zip_entry_from_fd(entry_name, fd.get()); 401e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 402e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 403e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a file to the existing zipped bugreport */ 404e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic int _add_file_from_fd(const char *title, const char *path, int fd) { 405e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return add_zip_entry_from_fd(ZIP_ROOT_DIR + path, fd) ? 0 : 1; 406e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 407e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 408e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds all files from a directory to the zipped bugreport file */ 409e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemevoid add_dir(const char *dir, bool recursive) { 410e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!zip_writer) return; 411e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme DurationReporter duration_reporter(dir); 412e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme dump_files(NULL, dir, recursive ? skip_none : is_dir, _add_file_from_fd); 413e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 414e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 41578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void dumpstate(const std::string& screenshot_path) { 416e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme std::unique_ptr<DurationReporter> duration_reporter(new DurationReporter("DUMPSTATE")); 41778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme unsigned long timeout; 418f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4192db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); 420f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("UPTIME", 10, "uptime", NULL); 421326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); 4228c8130eb68c89987a94db084608a4229bad06c18Mark Salyzyn dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd"); 423f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("MEMORY INFO", "/proc/meminfo"); 424b32c7e14ccc6507f6ce3fc02414ba04b797f4558Elliott Hughes run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL); 4252b1f88b6ac78e330ff006da6fecf8bc9d976ec67Nick Kralevich run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); 426f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); 427f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VMALLOC INFO", "/proc/vmallocinfo"); 428f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("SLAB INFO", "/proc/slabinfo"); 429f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("ZONEINFO", "/proc/zoneinfo"); 430f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("PAGETYPEINFO", "/proc/pagetypeinfo"); 431f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BUDDYINFO", "/proc/buddyinfo"); 4322281af967dd840aade7bc55b19ea7df0e6da36f2Colin Cross dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); 433f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 434f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL WAKELOCKS", "/proc/wakelocks"); 43529e27a84c144fe3b941648094cad2a3f1e61e8b3Todd Poynor dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources"); 436f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); 43785aea748861b5665e68b786b55f1c798f56fc0daMathias Agopian dump_file("KERNEL SYNC", "/d/sync"); 438f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 439a3533a3ae6bf8d0e1780c153cafdec86926ec22cElliott Hughes run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL); 440b82c925d3cd54d5eff9f4f9e6d5aeb41f75365f5Nick Kralevich run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL); 441f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4424db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("ROUTE", 10, "route", NULL); 4434db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("PRINTENV", 10, "printenv", NULL); 4444db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("NETSTAT", 10, "netstat", NULL); 4454db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("LSMOD", 10, "lsmod", NULL); 4464db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 447f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross do_dmesg(); 448f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 449f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL); 4501dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); 4511dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); 452f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!screenshot_path.empty()) { 454e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGI("taking late screenshot\n"); 455e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme take_screenshot(screenshot_path); 4566e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 4575a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey } 4585a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey 459f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); 4608f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // calculate timeout 4618f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); 4628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4657831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", 4667831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4677831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4687831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 469c7ad8cb82f035576c28707a8cbeb16b7ead2a4e7Mark Salyzyn timeout = logcat_timeout("events") + logcat_timeout("security"); 4708f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4718f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4737831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", 474c7ad8cb82f035576c28707a8cbeb16b7ead2a4e7Mark Salyzyn "-b", "security", 4757831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 4767831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4777831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4787831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 4798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("radio"); 4808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4837831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", 4847831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 4857831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4867831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4877831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 488f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 489ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); 490ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn 491804339a59e4abcbcf5a50a60ff0543e6b404e572Sharvil Nanavati run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); 4928d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati 493f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* show the traces we collected in main(), if that was done */ 494f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (dump_traces_path != NULL) { 495f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES JUST NOW", dump_traces_path); 496f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 497f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 498f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* only show ANR traces if they're less than 15 minutes old */ 499f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross struct stat st; 500f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char anr_traces_path[PATH_MAX]; 501f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("dalvik.vm.stack-trace-file", anr_traces_path, ""); 502f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (!anr_traces_path[0]) { 503f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"); 504f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 50554bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(anr_traces_path, 50654bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 5077dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fd < 0) { 5087dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno)); 5097dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 5107dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd); 5117dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 512f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 513f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 514f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* slow traces for slow operations */ 515f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (anr_traces_path[0] != 0) { 516f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int tail = strlen(anr_traces_path)-1; 517f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (tail > 0 && anr_traces_path[tail] != '/') { 518f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross tail--; 519f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 520f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int i = 0; 521f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (1) { 522f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sprintf(anr_traces_path+tail+1, "slow%02d.txt", i); 523f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (stat(anr_traces_path, &st)) { 524f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // No traces file at this index, done with the files. 525f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross break; 526f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 527f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES WHEN SLOW", anr_traces_path); 528f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross i++; 529f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 530f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 531f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5327dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int dumped = 0; 5337dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 5347dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (tombstone_data[i].fd != -1) { 535e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme const char *name = tombstone_data[i].name; 536e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int fd = tombstone_data[i].fd; 5377dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dumped = 1; 538e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (zip_writer) { 539e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!add_zip_entry_from_fd(ZIP_ROOT_DIR + name, fd)) { 540e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("Unable to add tombstone %s to zip file\n", name); 541e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 542e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } else { 543e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme dump_file_from_fd("TOMBSTONE", name, fd); 544e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 545e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme close(fd); 5467dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris tombstone_data[i].fd = -1; 5477dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5487dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5497dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (!dumped) { 5507dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR); 5517dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5527dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 553f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("NETWORK DEV INFO", "/proc/net/dev"); 554f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all"); 555012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt"); 556f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); 557f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); 558f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5592a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor if (!stat(PSTORE_LAST_KMSG, &st)) { 5602a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ 5612a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", PSTORE_LAST_KMSG); 5622a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } else { 5632a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ 5642a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", "/proc/last_kmsg"); 5652a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } 5662a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 5672262c16372570f57d3107d574abe2c80825d286eMark Salyzyn /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ 5687831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("LAST LOGCAT", 10, "logcat", "-L", 5697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-b", "all", 5707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 5717831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 5727831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 5737831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 5742262c16372570f57d3107d574abe2c80825d286eMark Salyzyn 575f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ 576a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes 577a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes run_command("NETWORK INTERFACES", 10, "ip", "link", NULL); 578d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 579d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL); 580d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL); 581d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 582f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES", 10, "ip", "rule", "show", NULL); 583f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL); 5842b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 5852b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran dump_route_tables(); 5862b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 587d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); 588d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); 589d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 590f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); 591f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); 592012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); 593012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall /* no ip6 nat */ 594012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL); 595012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL); 596f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 597f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("WIFI NETWORKS", 20, 5981d6b97c869718001010cce3db387c73fd11bf32eDmitry Shmidt SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); 599f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 600c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 6016afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD TABLE", 5, 6026afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_hostip", NULL); 6036afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6046afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, 605c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt SU_PATH, "root", "wlutil", "counters", NULL); 6066afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6076afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (1)", 5, 6086afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 6096afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 610c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#endif 6110b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (1)", "/proc/interrupts"); 6120b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt 6136afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); 6146afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 615c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 616f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP WIFI STATUS", 20, 617f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); 6186afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6196afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, 620f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "wlutil", "counters", NULL); 6216afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6226afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (2)", 5, 6236afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 624f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#endif 6250b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (2)", "/proc/interrupts"); 626f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 627f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross print_properties(); 628f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 629f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("VOLD DUMP", 10, "vdc", "dump", NULL); 630f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL); 631f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6328f75fa7bcfec553eddb59b919b44d7a93c9846a1Ken Sumrall run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL); 633f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 634f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL); 635f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 636f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("------ BACKLIGHTS ------\n"); 637f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD brightness="); 638f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); 639f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Button brightness="); 640f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/button-backlight/brightness"); 641f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Keyboard brightness="); 642f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness"); 643f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("ALS mode="); 644f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/als"); 645f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD driver registers:\n"); 646f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/registers"); 647f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 648f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 649f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Binder state is expensive to look at as it uses a lot of memory. */ 650f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); 651f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); 652f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); 653f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats"); 654f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATE", "/sys/kernel/debug/binder/state"); 655f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 656f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 657f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Board\n"); 658f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 659f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 660f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpstate_board(); 661f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 662f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 663f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Migrate the ril_dumpstate to a dumpstate_board()? */ 664f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; 665f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); 666f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { 667f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { 668f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // su does not exist on user builds, so try running without it. 669f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // This way any implementations of vril-dump that do not require 670f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // root can run on user builds. 671f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 672f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross "vril-dump", NULL); 673f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 674f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 675f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "vril-dump", NULL); 676f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 677f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 678f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 679f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 680f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Android Framework Services\n"); 681f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 682f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 683f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* the full dumpsys is starting to take a long time, so we need 684f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross to increase its timeout. we really need to do the timeouts in 685f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpsys itself... */ 686f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMPSYS", 60, "dumpsys", NULL); 687f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 688f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 68902bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("== Checkins\n"); 69002bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 69102bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 69259b1516f4cefcfd599f4e5e9c4a227a48d1ace65Dianne Hackborn run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL); 6933e5fa73722c100fc9017c7a47b17a8e727aa34e1Dianne Hackborn run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL); 69402bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL); 6955cd46aa3399ddeaf12a211390dfde66c796ab299Dianne Hackborn run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL); 6961bd5068a5180ac12dda374e15c7b1f70e8334284Dianne Hackborn run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL); 6978b3e133e413774047da8005771f57c21dd31e1e3Ashish Sharma run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL); 69802bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 69902bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 700f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Activities\n"); 701f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 702f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 703f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL); 704f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 705f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 706f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Services\n"); 707f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 708f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 709f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL); 710f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 711f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 712f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Providers\n"); 713f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 714f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 715f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL); 716f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 717f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 718f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 719f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: done\n"); 720f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 721f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 722f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 723f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void usage() { 7241f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n" 725f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -o: write to file (instead of stdout)\n" 726f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -d: append date to filename (requires -o)\n" 7276e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme " -z: generates zipped file (requires -o)\n" 728f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -p: capture screenshot to filename.png (requires -o)\n" 729f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -s: write output to control socket (for init)\n" 730f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -b: play sound file instead of vibrate, at beginning of job\n" 731f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -e: play sound file instead of vibrate, at end of job\n" 7321f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau " -q: disable vibrate\n" 73336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme " -B: send broadcast when finished (requires -o)\n" 73471bbfc57974331dce79242ce806d92035fce06baFelipe Leme " -P: send broadacast when started and update system properties on progress (requires -o and -B)\n" 7354db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski " -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n" 7362a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor ); 737f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 738f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 739885f888c55587e9366542b5155a06c321cde175aJohn Michelaustatic void sigpipe_handler(int n) { 7402e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales // don't complain to stderr or stdout 7412e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales _exit(EXIT_FAILURE); 742885f888c55587e9366542b5155a06c321cde175aJohn Michelau} 743885f888c55587e9366542b5155a06c321cde175aJohn Michelau 7441e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the 7451e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme temporary file. 7461e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme */ 747e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool finish_zip_file(const std::string& bugreport_name, const std::string& bugreport_path, 7481e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme time_t now) { 749e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!add_zip_entry(bugreport_name, bugreport_path)) { 7501e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to add text entry to .zip file\n"); 7516e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 7526e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 7536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 754e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int32_t err = zip_writer->Finish(); 7551e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (err) { 756e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err)); 7576e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 7586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 7596e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 7601e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (remove(bugreport_path.c_str())) { 7611e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGW("remove(%s): %s\n", bugreport_path.c_str(), strerror(errno)); 7621e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 7631e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 7646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return true; 7656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme} 7666e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 7674db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinskistatic std::string SHA256_file_hash(std::string filepath) { 7684db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ScopedFd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); 7694db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (fd.get() == -1) { 7704db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ALOGE("open(%s): %s\n", filepath.c_str(), strerror(errno)); 7714db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return NULL; 7724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_CTX ctx; 7754db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_init(&ctx); 7764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7774db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski std::vector<uint8_t> buffer(65536); 7784db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski while (1) { 7794db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size())); 7804db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (bytes_read == 0) { 7814db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski break; 7824db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } else if (bytes_read == -1) { 7834db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ALOGE("read(%s): %s\n", filepath.c_str(), strerror(errno)); 7844db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return NULL; 7854db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7864db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7874db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_update(&ctx, buffer.data(), bytes_read); 7884db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7894db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7904db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski uint8_t hash[SHA256_DIGEST_SIZE]; 7914db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE); 7924db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1]; 7934db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski for(int i = 0; i < SHA256_DIGEST_SIZE; i++) { 7944db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski snprintf(hash_buffer + (i * 2), sizeof(hash_buffer), "%02x", hash[i]); 7954db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7964db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski hash_buffer[sizeof(hash_buffer) - 1] = 0; 7974db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return std::string(hash_buffer); 7984db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski} 7994db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 8004db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 801f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char *argv[]) { 802885f888c55587e9366542b5155a06c321cde175aJohn Michelau struct sigaction sigact; 803f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_add_date = 0; 8046e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme int do_zip_file = 0; 8051f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau int do_vibrate = 1; 806f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char* use_outfile = 0; 807f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int use_socket = 0; 808f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_fb = 0; 80927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey int do_broadcast = 0; 810e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme int do_early_screenshot = 0; 8114db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski int is_remote_mode = 0; 812f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 813e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme now = time(NULL); 814e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 8151e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (getuid() != 0) { 8161e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // Old versions of the adb client would call the 8171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // dumpstate command directly. Newer clients 8181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // call /system/bin/bugreport instead. If we detect 8191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // we're being called incorrectly, then exec the 8201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // correct program. 8211e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL); 8221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 823f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8241dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown ALOGI("begin\n"); 8252e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales 8261dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* clear SIGPIPE handler */ 827885f888c55587e9366542b5155a06c321cde175aJohn Michelau memset(&sigact, 0, sizeof(sigact)); 828885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigact.sa_handler = sigpipe_handler; 829885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigaction(SIGPIPE, &sigact, NULL); 8303e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall 831f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* set as high priority, and protect from OOM killer */ 832f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross setpriority(PRIO_PROCESS, 0, -20); 833cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *oom_adj = fopen("/proc/self/oom_adj", "we"); 834f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (oom_adj) { 835f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fputs("-17", oom_adj); 836f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(oom_adj); 837f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 838f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8391dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* parse arguments */ 840f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int c; 8414db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski while ((c = getopt(argc, argv, "dho:svqzpPBR")) != -1) { 842f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross switch (c) { 84371bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'd': do_add_date = 1; break; 84471bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'z': do_zip_file = 1; break; 84571bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'o': use_outfile = optarg; break; 84671bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 's': use_socket = 1; break; 847f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'v': break; // compatibility no-op 84871bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'q': do_vibrate = 0; break; 84971bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'p': do_fb = 1; break; 85071bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'P': do_update_progress = 1; break; 8514db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski case 'R': is_remote_mode = 1; break; 85271bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'B': do_broadcast = 1; break; 853f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case '?': printf("\n"); 854f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'h': 855f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usage(); 856f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross exit(1); 857f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 858f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 859f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 86071bbfc57974331dce79242ce806d92035fce06baFelipe Leme if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) { 8616e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme usage(); 8626e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme exit(1); 8636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 8646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 86571bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress && !do_broadcast) { 86671bbfc57974331dce79242ce806d92035fce06baFelipe Leme usage(); 86771bbfc57974331dce79242ce806d92035fce06baFelipe Leme exit(1); 86871bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 8696e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 8704db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (is_remote_mode && (do_update_progress || !do_broadcast || !do_zip_file || !do_add_date)) { 8714db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski usage(); 8724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski exit(1); 8734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 8744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 875e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme do_early_screenshot = do_update_progress; 876e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 877ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // If we are going to use a socket, do it as early as possible 878ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // to avoid timeouts from bugreport. 879ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris if (use_socket) { 880ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris redirect_to_socket(stdout, "dumpstate"); 881ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris } 882ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris 883ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the directory where the bug report files will be written */ 884ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string bugreport_dir; 885ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 886ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the temporary file containing the bug report */ 887ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string tmp_path; 888ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 889e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme /* full path of the temporary file containing the screenshot (when requested) */ 890e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme std::string screenshot_path; 891e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 892ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* base name (without suffix or extensions) of the bug report files */ 893ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string base_name; 894ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 895ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* suffix of the bug report files - it's typically the date (when invoked with -d), 896ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme * although it could be changed by the user using a system property */ 897ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string suffix; 89871bbfc57974331dce79242ce806d92035fce06baFelipe Leme 89971bbfc57974331dce79242ce806d92035fce06baFelipe Leme /* pointer to the actual path, be it zip or text */ 90071bbfc57974331dce79242ce806d92035fce06baFelipe Leme std::string path; 90171bbfc57974331dce79242ce806d92035fce06baFelipe Leme 902635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme /* pointer to the zipped file */ 9031e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose); 90471bbfc57974331dce79242ce806d92035fce06baFelipe Leme 905ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* redirect output if needed */ 90671bbfc57974331dce79242ce806d92035fce06baFelipe Leme bool is_redirecting = !use_socket && use_outfile; 90771bbfc57974331dce79242ce806d92035fce06baFelipe Leme 90871bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 909ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir = dirname(use_outfile); 910ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme base_name = basename(use_outfile); 91171bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_add_date) { 91271bbfc57974331dce79242ce806d92035fce06baFelipe Leme char date[80]; 913ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now)); 914ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = date; 915ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 916ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = "undated"; 91771bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 91871bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_fb) { 919ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // TODO: if dumpstate was an object, the paths could be internal variables and then 920ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // we could have a function to calculate the derived values, such as: 921ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // screenshot_path = GetPath(".png"); 922ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 92371bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 924ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp"; 92571bbfc57974331dce79242ce806d92035fce06baFelipe Leme 926ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Bugreport dir: %s\nBase name: %s\nSuffix: %s\nTemporary path: %s\n" 927ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "Screenshot path: %s\n", bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(), 928ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path.c_str(), screenshot_path.c_str()); 92971bbfc57974331dce79242ce806d92035fce06baFelipe Leme 9301e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 9311e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Creating initial .zip file"); 9321e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip"; 9331e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_file.reset(fopen(path.c_str(), "wb")); 9341e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (!zip_file) { 9351e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno)); 9361e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme do_zip_file = 0; 9371e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } else { 9381e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_writer.reset(new ZipWriter(zip_file.get())); 9391e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9401e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9411e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 94271bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress) { 943ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::vector<std::string> am_args = { 944ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--receiver-permission", "android.permission.DUMP", 945ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--es", "android.intent.extra.NAME", suffix, 946ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 947ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL), 948ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme }; 949ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args); 95071bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 95171bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 95271bbfc57974331dce79242ce806d92035fce06baFelipe Leme 95378f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme print_header(); 95478f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 9551dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* open the vibrator before dropping root */ 9566e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose); 9571f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau if (do_vibrate) { 9586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we")); 9591dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 9606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 150); 9611dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown } 9621f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau } 963f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9643634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (do_fb && do_early_screenshot) { 9653634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (screenshot_path.empty()) { 9663634a1e3459cb609da709646107e246cafbc01f9Felipe Leme // should not have happened 9673634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("INTERNAL ERROR: skipping early screenshot because path was not set"); 9683634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } else { 9693634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("taking early screenshot\n"); 9703634a1e3459cb609da709646107e246cafbc01f9Felipe Leme take_screenshot(screenshot_path); 9713634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 9723634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) { 9733634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("Unable to change ownership of screenshot file %s: %s\n", 9743634a1e3459cb609da709646107e246cafbc01f9Felipe Leme screenshot_path.c_str(), strerror(errno)); 9753634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } 976e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 977e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 978e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 9791e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 9801e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (chown(path.c_str(), AID_SHELL, AID_SHELL)) { 9811e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno)); 9821e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9831e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9841e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 985f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* read /proc/cmdline before dropping root */ 986cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *cmdline = fopen("/proc/cmdline", "re"); 9876e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (cmdline) { 988f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fgets(cmdline_buf, sizeof(cmdline_buf), cmdline); 989f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(cmdline); 990f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 991f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9921dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* collect stack traces from Dalvik and native processes (needs root) */ 9931dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown dump_traces_path = dump_traces(); 9941dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 995635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */ 9961dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown get_tombstone_fds(tombstone_data); 997e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme add_dir(RECOVERY_DIR, true); 998635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme add_mountinfo(); 9991dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 10001dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* ensure we will keep capabilities when we drop root */ 10011e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 10021e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 10031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 1005f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich /* switch to non-root user and group */ 10071e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, 1008ab46a4922655bc75848660da4268ab85d72a6010Nick Kralevich AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; 10091e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 10101e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); 10111e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10121e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 10131e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgid(AID_SHELL) != 0) { 10141e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgid, aborting: %s\n", strerror(errno)); 10151e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10161e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 10171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setuid(AID_SHELL) != 0) { 10181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setuid, aborting: %s\n", strerror(errno)); 10191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 1021f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_header_struct capheader; 10231e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_data_struct capdata[2]; 10241e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capheader, 0, sizeof(capheader)); 10251e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capdata, 0, sizeof(capdata)); 10261e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.version = _LINUX_CAPABILITY_VERSION_3; 10271e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.pid = 0; 10281e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 10291e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); 10301e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); 10311e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[0].inheritable = 0; 10321e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[1].inheritable = 0; 10331e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 10341e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (capset(&capheader, &capdata[0]) < 0) { 10351e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("capset failed: %s\n", strerror(errno)); 10361e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 1037f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1038f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 103971bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 10406e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* TODO: rather than generating a text file now and zipping it later, 10416e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme it would be more efficient to redirect stdout to the zip entry 10426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme directly, but the libziparchive doesn't support that option yet. */ 10436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str())); 1044f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1045f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10463634a1e3459cb609da709646107e246cafbc01f9Felipe Leme dumpstate(do_early_screenshot ? "": screenshot_path); 1047f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10481dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* done */ 10491dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 10501dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for (int i = 0; i < 3; i++) { 10516e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 75); 1052f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usleep((75 + 50) * 1000); 1053f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1054f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1055f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 105655b42a67f69767976ff16ab443b3e7142db693e1Felipe Leme /* close output if needed */ 105771bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 1058f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(stdout); 1059f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1060f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10616e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* rename or zip the (now complete) .tmp file to its final location */ 10626e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (use_outfile) { 1063ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 1064ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* check if user changed the suffix using system properties */ 1065ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char key[PROPERTY_KEY_MAX]; 1066ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char value[PROPERTY_VALUE_MAX]; 1067ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme sprintf(key, "dumpstate.%d.name", getpid()); 1068ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme property_get(key, value, ""); 1069ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bool change_suffix= false; 1070ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (value[0]) { 1071ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* must whitelist which characters are allowed, otherwise it could cross directories */ 1072ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::regex valid_regex("^[-_a-zA-Z0-9]+$"); 1073ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (std::regex_match(value, valid_regex)) { 1074ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme change_suffix = true; 1075ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 1076ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("invalid suffix provided by user: %s", value); 1077ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1078ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1079ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (change_suffix) { 1080ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGI("changing suffix from %s to %s", suffix.c_str(), value); 1081ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = value; 1082ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (!screenshot_path.empty()) { 1083ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string new_screenshot_path = 1084ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 1085ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) { 1086ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", screenshot_path.c_str(), 1087ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme new_screenshot_path.c_str(), strerror(errno)); 1088ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 1089ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = new_screenshot_path; 1090ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1091ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1092ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1093ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 10946e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme bool do_text_file = true; 10956e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_zip_file) { 10961e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Adding text entry to .zip bugreport"); 1097e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!finish_zip_file(base_name + "-" + suffix + ".txt", tmp_path, now)) { 10981e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to finish zip file; sending text bugreport instead\n"); 10996e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = true; 11006e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 11016e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = false; 11026e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11036e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11046e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_text_file) { 1105ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Generating .txt bugreport"); 1106ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt"; 1107ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(tmp_path.c_str(), path.c_str())) { 1108ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno)); 11096e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme path.clear(); 11106e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11116e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 1112f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1113f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 11141dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* tell activity manager we're done */ 111571bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_broadcast) { 11166e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!path.empty()) { 11176e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("Final bugreport path: %s\n", path.c_str()); 111836b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme std::vector<std::string> am_args = { 111936b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme "--receiver-permission", "android.permission.DUMP", 112071bbfc57974331dce79242ce806d92035fce06baFelipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 112136b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme "--es", "android.intent.extra.BUGREPORT", path 112236b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme }; 112336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme if (do_fb) { 112436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("--es"); 112536b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("android.intent.extra.SCREENSHOT"); 112636b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back(screenshot_path); 112736b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme } 11284db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (is_remote_mode) { 11294db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back("--es"); 11304db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH"); 11314db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back(SHA256_file_hash(path)); 11324db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args); 11334db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } else { 11344db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args); 11354db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 11366e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 113771bbfc57974331dce79242ce806d92035fce06baFelipe Leme ALOGE("Skipping finished broadcast because bugreport could not be generated\n"); 11386e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 113927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey } 114027f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey 1141e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL); 1142f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ALOGI("done\n"); 1143f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 1144f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 0; 1145f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 1146