dumpstate.cpp revision 43fd1bbc6675430a4ecfde07e88a414ed5c41c0c
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) { 360770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme DurationReporter duration_reporter(("ADD ZIP ENTRY " + entry_name).c_str()); 361770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme ALOGD("Adding zip entry %s", entry_name.c_str()); 362e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(), 363e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ZipWriter::kCompress, get_mtime(fd, now)); 364e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 365e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), ZipWriter::ErrorCodeString(err)); 366e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 367e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 368e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 369770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme std::vector<uint8_t> buffer(65536); 370e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme while (1) { 371e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), sizeof(buffer))); 372e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (bytes_read == 0) { 373e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme break; 374e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } else if (bytes_read == -1) { 375e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno)); 376e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 377e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 378e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme err = zip_writer->WriteBytes(buffer.data(), bytes_read); 379e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 380e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err)); 381e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 382e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 383e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 384e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 385e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme err = zip_writer->FinishEntry(); 386e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (err) { 387e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err)); 388e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 389e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 390e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 391e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return true; 392e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 393e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 394e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a new entry to the existing zip file. */ 395e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path) { 396e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); 397e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (fd.get() == -1) { 398e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno)); 399e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return false; 400e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 401e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 402e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return add_zip_entry_from_fd(entry_name, fd.get()); 403e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 404e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 405e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a file to the existing zipped bugreport */ 406e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic int _add_file_from_fd(const char *title, const char *path, int fd) { 407e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme return add_zip_entry_from_fd(ZIP_ROOT_DIR + path, fd) ? 0 : 1; 408e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 409e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 410e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds all files from a directory to the zipped bugreport file */ 411e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemevoid add_dir(const char *dir, bool recursive) { 412e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!zip_writer) return; 413e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme DurationReporter duration_reporter(dir); 414e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme dump_files(NULL, dir, recursive ? skip_none : is_dir, _add_file_from_fd); 415e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme} 416e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 41778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void dumpstate(const std::string& screenshot_path) { 418770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme DurationReporter duration_reporter("DUMPSTATE"); 41978f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme unsigned long timeout; 420f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4212db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); 422f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("UPTIME", 10, "uptime", NULL); 423326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); 4248c8130eb68c89987a94db084608a4229bad06c18Mark Salyzyn dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd"); 425f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("MEMORY INFO", "/proc/meminfo"); 426b32c7e14ccc6507f6ce3fc02414ba04b797f4558Elliott Hughes run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL); 4272b1f88b6ac78e330ff006da6fecf8bc9d976ec67Nick Kralevich run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); 428f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); 429f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VMALLOC INFO", "/proc/vmallocinfo"); 430f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("SLAB INFO", "/proc/slabinfo"); 431f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("ZONEINFO", "/proc/zoneinfo"); 432f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("PAGETYPEINFO", "/proc/pagetypeinfo"); 433f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BUDDYINFO", "/proc/buddyinfo"); 4342281af967dd840aade7bc55b19ea7df0e6da36f2Colin Cross dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); 435f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 436f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL WAKELOCKS", "/proc/wakelocks"); 43729e27a84c144fe3b941648094cad2a3f1e61e8b3Todd Poynor dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources"); 438f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); 43985aea748861b5665e68b786b55f1c798f56fc0daMathias Agopian dump_file("KERNEL SYNC", "/d/sync"); 440f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 441a3533a3ae6bf8d0e1780c153cafdec86926ec22cElliott Hughes run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL); 442b82c925d3cd54d5eff9f4f9e6d5aeb41f75365f5Nick Kralevich run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL); 443f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4444db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("ROUTE", 10, "route", NULL); 4454db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("PRINTENV", 10, "printenv", NULL); 4464db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("NETSTAT", 10, "netstat", NULL); 4474db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski run_command("LSMOD", 10, "lsmod", NULL); 4484db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 449f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross do_dmesg(); 450f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 451f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL); 4521dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); 4531dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); 454f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4556e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!screenshot_path.empty()) { 456e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGI("taking late screenshot\n"); 457e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme take_screenshot(screenshot_path); 4586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 4595a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey } 4605a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey 461f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); 4628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // calculate timeout 4638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); 4648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4677831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", 4687831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 47143afe5d0b537999d5de9613626eca24f34cc52efMark Salyzyn timeout = logcat_timeout("events"); 4728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4757831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", 4767831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 4777831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4787831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4797831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 4808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("radio"); 4818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 4828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 4838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 4847831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", 4857831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 4867831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4877831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4887831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 489f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 490ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); 491ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn 492804339a59e4abcbcf5a50a60ff0543e6b404e572Sharvil Nanavati run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); 4938d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati 494f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* show the traces we collected in main(), if that was done */ 495f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (dump_traces_path != NULL) { 496f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES JUST NOW", dump_traces_path); 497f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 498f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 499f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* only show ANR traces if they're less than 15 minutes old */ 500f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross struct stat st; 501f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char anr_traces_path[PATH_MAX]; 502f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("dalvik.vm.stack-trace-file", anr_traces_path, ""); 503f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (!anr_traces_path[0]) { 504f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"); 505f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 50654bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(anr_traces_path, 50754bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 5087dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fd < 0) { 5097dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno)); 5107dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 5117dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd); 5127dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 513f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 514f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 515f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* slow traces for slow operations */ 516f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (anr_traces_path[0] != 0) { 517f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int tail = strlen(anr_traces_path)-1; 518f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (tail > 0 && anr_traces_path[tail] != '/') { 519f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross tail--; 520f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 521f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int i = 0; 522f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (1) { 523f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sprintf(anr_traces_path+tail+1, "slow%02d.txt", i); 524f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (stat(anr_traces_path, &st)) { 525f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // No traces file at this index, done with the files. 526f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross break; 527f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 528f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES WHEN SLOW", anr_traces_path); 529f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross i++; 530f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 531f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 532f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5337dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int dumped = 0; 5347dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 5357dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (tombstone_data[i].fd != -1) { 536e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme const char *name = tombstone_data[i].name; 537e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int fd = tombstone_data[i].fd; 5387dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dumped = 1; 539e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (zip_writer) { 540e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!add_zip_entry_from_fd(ZIP_ROOT_DIR + name, fd)) { 541e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("Unable to add tombstone %s to zip file\n", name); 542e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 543e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } else { 544e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme dump_file_from_fd("TOMBSTONE", name, fd); 545e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme } 546e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme close(fd); 5477dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris tombstone_data[i].fd = -1; 5487dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5497dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5507dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (!dumped) { 5517dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR); 5527dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 5537dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 554f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("NETWORK DEV INFO", "/proc/net/dev"); 555f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all"); 556012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt"); 557f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); 558f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); 559f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5602a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor if (!stat(PSTORE_LAST_KMSG, &st)) { 5612a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ 5622a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", PSTORE_LAST_KMSG); 5632a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } else { 5642a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ 5652a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", "/proc/last_kmsg"); 5662a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } 5672a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 5682262c16372570f57d3107d574abe2c80825d286eMark Salyzyn /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ 5697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("LAST LOGCAT", 10, "logcat", "-L", 5707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-b", "all", 5717831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 5727831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 5737831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 5747831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 5752262c16372570f57d3107d574abe2c80825d286eMark Salyzyn 576f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ 577a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes 578a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes run_command("NETWORK INTERFACES", 10, "ip", "link", NULL); 579d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 580d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL); 581d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL); 582d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 583f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES", 10, "ip", "rule", "show", NULL); 584f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL); 5852b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 5862b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran dump_route_tables(); 5872b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 588d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); 589d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); 590d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 591f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); 592f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); 593012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); 594012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall /* no ip6 nat */ 595012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL); 596012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL); 597f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 598f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("WIFI NETWORKS", 20, 5991d6b97c869718001010cce3db387c73fd11bf32eDmitry Shmidt SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); 600f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 601c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 6026afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD TABLE", 5, 6036afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_hostip", NULL); 6046afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6056afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, 606c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt SU_PATH, "root", "wlutil", "counters", NULL); 6076afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6086afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (1)", 5, 6096afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 6106afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 611c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#endif 6120b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (1)", "/proc/interrupts"); 6130b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt 6146afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); 6156afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 616c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 617f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP WIFI STATUS", 20, 618f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); 6196afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6206afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, 621f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "wlutil", "counters", NULL); 6226afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 6236afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (2)", 5, 6246afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 625f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#endif 6260b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (2)", "/proc/interrupts"); 627f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 628f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross print_properties(); 629f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 630f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("VOLD DUMP", 10, "vdc", "dump", NULL); 631f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL); 632f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6338f75fa7bcfec553eddb59b919b44d7a93c9846a1Ken Sumrall run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL); 634f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 635f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL); 636f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 637f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("------ BACKLIGHTS ------\n"); 638f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD brightness="); 639f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); 640f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Button brightness="); 641f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/button-backlight/brightness"); 642f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Keyboard brightness="); 643f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness"); 644f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("ALS mode="); 645f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/als"); 646f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD driver registers:\n"); 647f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/registers"); 648f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 649f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 650f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Binder state is expensive to look at as it uses a lot of memory. */ 651f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); 652f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); 653f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); 654f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats"); 655f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATE", "/sys/kernel/debug/binder/state"); 656f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 657f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 658f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Board\n"); 659f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 660f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 661f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpstate_board(); 662f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 663f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 664f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Migrate the ril_dumpstate to a dumpstate_board()? */ 665f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; 666f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); 667f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { 668f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { 669f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // su does not exist on user builds, so try running without it. 670f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // This way any implementations of vril-dump that do not require 671f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // root can run on user builds. 672f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 673f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross "vril-dump", NULL); 674f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 675f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 676f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "vril-dump", NULL); 677f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 678f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 679f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 680f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 681f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Android Framework Services\n"); 682f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 683f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 684f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* the full dumpsys is starting to take a long time, so we need 685f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross to increase its timeout. we really need to do the timeouts in 686f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpsys itself... */ 687f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMPSYS", 60, "dumpsys", NULL); 688f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 689f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 69002bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("== Checkins\n"); 69102bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 69202bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 69359b1516f4cefcfd599f4e5e9c4a227a48d1ace65Dianne Hackborn run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL); 6943e5fa73722c100fc9017c7a47b17a8e727aa34e1Dianne Hackborn run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL); 69502bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL); 6965cd46aa3399ddeaf12a211390dfde66c796ab299Dianne Hackborn run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL); 6971bd5068a5180ac12dda374e15c7b1f70e8334284Dianne Hackborn run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL); 6988b3e133e413774047da8005771f57c21dd31e1e3Ashish Sharma run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL); 69902bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 70002bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 701f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Activities\n"); 702f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 703f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 704f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL); 705f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 706f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 707f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Services\n"); 708f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 709f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 710f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL); 711f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 712f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 713f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Providers\n"); 714f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 715f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 716f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL); 717f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 718f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 719f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 720f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: done\n"); 721f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 722f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 723f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 724f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void usage() { 7251f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n" 726f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -o: write to file (instead of stdout)\n" 727f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -d: append date to filename (requires -o)\n" 7286e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme " -z: generates zipped file (requires -o)\n" 729f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -p: capture screenshot to filename.png (requires -o)\n" 730f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -s: write output to control socket (for init)\n" 731f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -b: play sound file instead of vibrate, at beginning of job\n" 732f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -e: play sound file instead of vibrate, at end of job\n" 7331f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau " -q: disable vibrate\n" 73436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme " -B: send broadcast when finished (requires -o)\n" 73571bbfc57974331dce79242ce806d92035fce06baFelipe Leme " -P: send broadacast when started and update system properties on progress (requires -o and -B)\n" 7364db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski " -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n" 7372a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor ); 738f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 739f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 740885f888c55587e9366542b5155a06c321cde175aJohn Michelaustatic void sigpipe_handler(int n) { 7412e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales // don't complain to stderr or stdout 7422e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales _exit(EXIT_FAILURE); 743885f888c55587e9366542b5155a06c321cde175aJohn Michelau} 744885f888c55587e9366542b5155a06c321cde175aJohn Michelau 7451e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the 7461e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme temporary file. 7471e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme */ 748e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool finish_zip_file(const std::string& bugreport_name, const std::string& bugreport_path, 7491e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme time_t now) { 750e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!add_zip_entry(bugreport_name, bugreport_path)) { 7511e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to add text entry to .zip file\n"); 7526e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 7536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 7546e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 755e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme int32_t err = zip_writer->Finish(); 7561e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (err) { 757e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme ALOGE("zip_writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err)); 7586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 7596e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 7606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 7611e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (remove(bugreport_path.c_str())) { 7621e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGW("remove(%s): %s\n", bugreport_path.c_str(), strerror(errno)); 7631e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 7641e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 7656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return true; 7666e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme} 7676e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 7684db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinskistatic std::string SHA256_file_hash(std::string filepath) { 769cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski ScopedFd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC 770cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski | O_NOFOLLOW))); 7714db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (fd.get() == -1) { 7724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ALOGE("open(%s): %s\n", filepath.c_str(), strerror(errno)); 7734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return NULL; 7744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7754db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_CTX ctx; 7774db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_init(&ctx); 7784db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7794db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski std::vector<uint8_t> buffer(65536); 7804db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski while (1) { 7814db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size())); 7824db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (bytes_read == 0) { 7834db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski break; 7844db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } else if (bytes_read == -1) { 7854db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski ALOGE("read(%s): %s\n", filepath.c_str(), strerror(errno)); 7864db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return NULL; 7874db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7884db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7894db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski SHA256_update(&ctx, buffer.data(), bytes_read); 7904db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7914db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 7924db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski uint8_t hash[SHA256_DIGEST_SIZE]; 7934db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE); 7944db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1]; 795cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++) { 796cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski sprintf(hash_buffer + (i * 2), "%02x", hash[i]); 7974db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 7984db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski hash_buffer[sizeof(hash_buffer) - 1] = 0; 7994db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski return std::string(hash_buffer); 8004db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski} 8014db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 8024db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 803f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char *argv[]) { 804885f888c55587e9366542b5155a06c321cde175aJohn Michelau struct sigaction sigact; 805f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_add_date = 0; 8066e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme int do_zip_file = 0; 8071f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau int do_vibrate = 1; 808f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char* use_outfile = 0; 809f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int use_socket = 0; 810f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_fb = 0; 81127f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey int do_broadcast = 0; 812e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme int do_early_screenshot = 0; 8134db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski int is_remote_mode = 0; 814f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 815e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme now = time(NULL); 816e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme 8171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (getuid() != 0) { 8181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // Old versions of the adb client would call the 8191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // dumpstate command directly. Newer clients 8201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // call /system/bin/bugreport instead. If we detect 8211e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // we're being called incorrectly, then exec the 8221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // correct program. 8231e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL); 8241e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 825f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8261dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown ALOGI("begin\n"); 8272e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales 8281dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* clear SIGPIPE handler */ 829885f888c55587e9366542b5155a06c321cde175aJohn Michelau memset(&sigact, 0, sizeof(sigact)); 830885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigact.sa_handler = sigpipe_handler; 831885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigaction(SIGPIPE, &sigact, NULL); 8323e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall 833f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* set as high priority, and protect from OOM killer */ 834f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross setpriority(PRIO_PROCESS, 0, -20); 835cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *oom_adj = fopen("/proc/self/oom_adj", "we"); 836f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (oom_adj) { 837f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fputs("-17", oom_adj); 838f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(oom_adj); 839f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 840f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8411dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* parse arguments */ 842f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int c; 8434db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski while ((c = getopt(argc, argv, "dho:svqzpPBR")) != -1) { 844f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross switch (c) { 84571bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'd': do_add_date = 1; break; 84671bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'z': do_zip_file = 1; break; 84771bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'o': use_outfile = optarg; break; 84871bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 's': use_socket = 1; break; 849f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'v': break; // compatibility no-op 85071bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'q': do_vibrate = 0; break; 85171bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'p': do_fb = 1; break; 85271bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'P': do_update_progress = 1; break; 8534db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski case 'R': is_remote_mode = 1; break; 85471bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'B': do_broadcast = 1; break; 855f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case '?': printf("\n"); 856f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'h': 857f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usage(); 858f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross exit(1); 859f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 860f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 861f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 86271bbfc57974331dce79242ce806d92035fce06baFelipe Leme if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) { 8636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme usage(); 8646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme exit(1); 8656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 8666e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 86771bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress && !do_broadcast) { 86871bbfc57974331dce79242ce806d92035fce06baFelipe Leme usage(); 86971bbfc57974331dce79242ce806d92035fce06baFelipe Leme exit(1); 87071bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 8716e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 8724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (is_remote_mode && (do_update_progress || !do_broadcast || !do_zip_file || !do_add_date)) { 8734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski usage(); 8744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski exit(1); 8754db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 8764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski 877e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme do_early_screenshot = do_update_progress; 878e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 879ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // If we are going to use a socket, do it as early as possible 880ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // to avoid timeouts from bugreport. 881ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris if (use_socket) { 882ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris redirect_to_socket(stdout, "dumpstate"); 883ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris } 884ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris 885ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the directory where the bug report files will be written */ 886ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string bugreport_dir; 887ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 888ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the temporary file containing the bug report */ 889ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string tmp_path; 890ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 891e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme /* full path of the temporary file containing the screenshot (when requested) */ 892e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme std::string screenshot_path; 893e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 894ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* base name (without suffix or extensions) of the bug report files */ 895ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string base_name; 896ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 897ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* suffix of the bug report files - it's typically the date (when invoked with -d), 898ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme * although it could be changed by the user using a system property */ 899ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string suffix; 90071bbfc57974331dce79242ce806d92035fce06baFelipe Leme 90171bbfc57974331dce79242ce806d92035fce06baFelipe Leme /* pointer to the actual path, be it zip or text */ 90271bbfc57974331dce79242ce806d92035fce06baFelipe Leme std::string path; 90371bbfc57974331dce79242ce806d92035fce06baFelipe Leme 904635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme /* pointer to the zipped file */ 9051e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose); 90671bbfc57974331dce79242ce806d92035fce06baFelipe Leme 907ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* redirect output if needed */ 90871bbfc57974331dce79242ce806d92035fce06baFelipe Leme bool is_redirecting = !use_socket && use_outfile; 90971bbfc57974331dce79242ce806d92035fce06baFelipe Leme 91071bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 911ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir = dirname(use_outfile); 912ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme base_name = basename(use_outfile); 91371bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_add_date) { 91471bbfc57974331dce79242ce806d92035fce06baFelipe Leme char date[80]; 915ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now)); 916ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = date; 917ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 918ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = "undated"; 91971bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 92071bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_fb) { 921ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // TODO: if dumpstate was an object, the paths could be internal variables and then 922ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // we could have a function to calculate the derived values, such as: 923ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // screenshot_path = GetPath(".png"); 924ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 92571bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 926ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp"; 92771bbfc57974331dce79242ce806d92035fce06baFelipe Leme 928ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Bugreport dir: %s\nBase name: %s\nSuffix: %s\nTemporary path: %s\n" 929ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "Screenshot path: %s\n", bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(), 930ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path.c_str(), screenshot_path.c_str()); 93171bbfc57974331dce79242ce806d92035fce06baFelipe Leme 9321e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 9331e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Creating initial .zip file"); 9341e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip"; 9351e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_file.reset(fopen(path.c_str(), "wb")); 9361e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (!zip_file) { 9371e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno)); 9381e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme do_zip_file = 0; 9391e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } else { 9401e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_writer.reset(new ZipWriter(zip_file.get())); 9411e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9421e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9431e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 94471bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress) { 945ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::vector<std::string> am_args = { 946ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--receiver-permission", "android.permission.DUMP", 947ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--es", "android.intent.extra.NAME", suffix, 948ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 949ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL), 950ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme }; 951ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args); 95271bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 95371bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 95471bbfc57974331dce79242ce806d92035fce06baFelipe Leme 955f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich /* read /proc/cmdline before dropping root */ 956f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich FILE *cmdline = fopen("/proc/cmdline", "re"); 957f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich if (cmdline) { 958f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich fgets(cmdline_buf, sizeof(cmdline_buf), cmdline); 959f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich fclose(cmdline); 960f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich } 961f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich 96278f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme print_header(); 96378f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 9641dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* open the vibrator before dropping root */ 9656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose); 9661f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau if (do_vibrate) { 9676e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we")); 9681dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 9696e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 150); 9701dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown } 9711f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau } 972f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9733634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (do_fb && do_early_screenshot) { 9743634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (screenshot_path.empty()) { 9753634a1e3459cb609da709646107e246cafbc01f9Felipe Leme // should not have happened 9763634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("INTERNAL ERROR: skipping early screenshot because path was not set"); 9773634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } else { 9783634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("taking early screenshot\n"); 9793634a1e3459cb609da709646107e246cafbc01f9Felipe Leme take_screenshot(screenshot_path); 9803634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 9813634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) { 9823634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("Unable to change ownership of screenshot file %s: %s\n", 9833634a1e3459cb609da709646107e246cafbc01f9Felipe Leme screenshot_path.c_str(), strerror(errno)); 9843634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } 985e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 986e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 987e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 9881e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 9891e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (chown(path.c_str(), AID_SHELL, AID_SHELL)) { 9901e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno)); 9911e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9921e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 9931e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 9941dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* collect stack traces from Dalvik and native processes (needs root) */ 9951dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown dump_traces_path = dump_traces(); 9961dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 997635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */ 9981dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown get_tombstone_fds(tombstone_data); 999e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme add_dir(RECOVERY_DIR, true); 1000635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme add_mountinfo(); 10011dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 10021dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* ensure we will keep capabilities when we drop root */ 10031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 10041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 10051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 1007f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich /* switch to non-root user and group */ 10091e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, 1010ab46a4922655bc75848660da4268ab85d72a6010Nick Kralevich AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; 10111e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 10121e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); 10131e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10141e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 10151e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgid(AID_SHELL) != 0) { 10161e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgid, aborting: %s\n", strerror(errno)); 10171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 10191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setuid(AID_SHELL) != 0) { 10201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setuid, aborting: %s\n", strerror(errno)); 10211e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 10221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 1023f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10241e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_header_struct capheader; 10251e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_data_struct capdata[2]; 10261e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capheader, 0, sizeof(capheader)); 10271e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capdata, 0, sizeof(capdata)); 10281e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.version = _LINUX_CAPABILITY_VERSION_3; 10291e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.pid = 0; 10301e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 10311e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); 10321e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); 10331e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[0].inheritable = 0; 10341e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[1].inheritable = 0; 10351e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 10361e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (capset(&capheader, &capdata[0]) < 0) { 10371e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("capset failed: %s\n", strerror(errno)); 10381e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 1039f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1040f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 104171bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 10426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* TODO: rather than generating a text file now and zipping it later, 10436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme it would be more efficient to redirect stdout to the zip entry 10446e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme directly, but the libziparchive doesn't support that option yet. */ 10456e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str())); 1046f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1047f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10483634a1e3459cb609da709646107e246cafbc01f9Felipe Leme dumpstate(do_early_screenshot ? "": screenshot_path); 1049f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10501dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* done */ 10511dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 10521dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for (int i = 0; i < 3; i++) { 10536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 75); 1054f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usleep((75 + 50) * 1000); 1055f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1056f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1057f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 105855b42a67f69767976ff16ab443b3e7142db693e1Felipe Leme /* close output if needed */ 105971bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 1060f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(stdout); 1061f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1062f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 10636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* rename or zip the (now complete) .tmp file to its final location */ 10646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (use_outfile) { 1065ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 1066ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* check if user changed the suffix using system properties */ 1067ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char key[PROPERTY_KEY_MAX]; 1068ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char value[PROPERTY_VALUE_MAX]; 1069ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme sprintf(key, "dumpstate.%d.name", getpid()); 1070ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme property_get(key, value, ""); 1071ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bool change_suffix= false; 1072ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (value[0]) { 1073ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* must whitelist which characters are allowed, otherwise it could cross directories */ 1074ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::regex valid_regex("^[-_a-zA-Z0-9]+$"); 1075ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (std::regex_match(value, valid_regex)) { 1076ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme change_suffix = true; 1077ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 1078ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("invalid suffix provided by user: %s", value); 1079ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1080ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1081ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (change_suffix) { 1082ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGI("changing suffix from %s to %s", suffix.c_str(), value); 1083ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = value; 1084ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (!screenshot_path.empty()) { 1085ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string new_screenshot_path = 1086ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 1087ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) { 1088ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", screenshot_path.c_str(), 1089ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme new_screenshot_path.c_str(), strerror(errno)); 1090ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 1091ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = new_screenshot_path; 1092ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1093ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1094ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 1095ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 10966e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme bool do_text_file = true; 10976e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_zip_file) { 10981e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Adding text entry to .zip bugreport"); 1099e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme if (!finish_zip_file(base_name + "-" + suffix + ".txt", tmp_path, now)) { 11001e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to finish zip file; sending text bugreport instead\n"); 11016e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = true; 11026e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 11036e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = false; 11046e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11056e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11066e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_text_file) { 1107ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Generating .txt bugreport"); 1108ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt"; 1109ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(tmp_path.c_str(), path.c_str())) { 1110ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno)); 11116e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme path.clear(); 11126e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 11136e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 1114f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1115f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 11161dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* tell activity manager we're done */ 111771bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_broadcast) { 11186e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!path.empty()) { 11196e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("Final bugreport path: %s\n", path.c_str()); 112036b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme std::vector<std::string> am_args = { 112143fd1bbc6675430a4ecfde07e88a414ed5c41c0cFelipe Leme "--receiver-permission", "android.permission.DUMP", "--receiver-foreground", 112271bbfc57974331dce79242ce806d92035fce06baFelipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 112336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme "--es", "android.intent.extra.BUGREPORT", path 112436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme }; 112536b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme if (do_fb) { 112636b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("--es"); 112736b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("android.intent.extra.SCREENSHOT"); 112836b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back(screenshot_path); 112936b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme } 11304db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski if (is_remote_mode) { 11314db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back("--es"); 11324db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH"); 11334db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski am_args.push_back(SHA256_file_hash(path)); 11344db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args); 11354db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } else { 11364db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args); 11374db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski } 11386e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 113971bbfc57974331dce79242ce806d92035fce06baFelipe Leme ALOGE("Skipping finished broadcast because bugreport could not be generated\n"); 11406e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 114127f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey } 114227f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey 1143e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL); 1144f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ALOGI("done\n"); 1145f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 1146f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 0; 1147f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 1148