dumpstate.cpp revision 1e9edc619c6b1ca3998a26eaa4882b55ce801f12
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> 248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#include <stdbool.h> 25f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h> 26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdlib.h> 276e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include <string> 28f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h> 297dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/capability.h> 307dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/prctl.h> 31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/resource.h> 32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/stat.h> 33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h> 34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/wait.h> 35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <unistd.h> 36f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 379dc117c415d0df0a3acd900709d05deabe975704Elliott Hughes#include <android-base/stringprintf.h> 38f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <cutils/properties.h> 39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "private/android_filesystem_config.h" 41f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 42f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#define LOG_TAG "dumpstate" 43656a6b9e3645bfe2cf073b69cbb9d02832f62c26Alex Ray#include <cutils/log.h> 44f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 45f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "dumpstate.h" 466e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ScopedFd.h" 476e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ziparchive/zip_writer.h" 486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 496e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Lemeusing android::base::StringPrintf; 50f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 51f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* read before root is shed */ 52f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char cmdline_buf[16384] = "(unknown)"; 53f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic const char *dump_traces_path = NULL; 54f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic char build_type[PROPERTY_VALUE_MAX]; 5678f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 572a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops" 582a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 598d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati#define RAFT_DIR "/data/misc/raft/" 607dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_DIR "/data/tombstones" 617dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_" 627dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Can accomodate a tombstone number up to 9999. */ 637dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4) 647dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define NUM_TOMBSTONES 10 657dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 667dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferristypedef struct { 677dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris char name[TOMBSTONE_MAX_LEN]; 687dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int fd; 697dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} tombstone_data_t; 707dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 717dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES]; 727dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 737dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Get the fds of any tombstone that was modified in the last half an hour. */ 747dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) { 757dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris time_t thirty_minutes_ago = time(NULL) - 60*30; 767dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 777dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i); 7854bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(data[i].name, 7954bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 807dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris struct stat st; 817dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && 827dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris (time_t) st.st_mtime >= thirty_minutes_ago) { 837dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris data[i].fd = fd; 847dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 857dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris close(fd); 867dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris data[i].fd = -1; 877dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 887dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 897dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} 907dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 912db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevågstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename) 922db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg{ 932db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg DIR *d; 942db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg struct dirent *de; 952db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg char path[PATH_MAX]; 962db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 972db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg d = opendir(driverpath); 982db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (d == NULL) { 992db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg return; 1002db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1012db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1022db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg while ((de = readdir(d))) { 1032db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (de->d_type != DT_LNK) { 1042db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg continue; 1052db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1062db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename); 1072db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_file(title, path); 1082db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 1092db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1102db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg closedir(d); 1112db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg} 1122db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 113326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic bool skip_not_stat(const char *path) { 114326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn static const char stat[] = "/stat"; 115326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t len = strlen(path); 116326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (path[len - 1] == '/') { /* Directory? */ 117326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return false; 118326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 119326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ 120326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 121326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 122326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic const char mmcblk0[] = "/sys/block/mmcblk0/"; 1238f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynunsigned long worst_write_perf = 20000; /* in KB/s */ 124326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 125326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { 126326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn unsigned long fields[11], read_perf, write_perf; 127326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn bool z; 128326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn char *cp, *buffer = NULL; 129326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t i = 0; 130326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn FILE *fp = fdopen(fd, "rb"); 131326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn getline(&buffer, &i, fp); 132326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fclose(fp); 133326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!buffer) { 134326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return -errno; 135326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 136326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn i = strlen(buffer); 137326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn while ((i > 0) && (buffer[i - 1] == '\n')) { 138326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn buffer[--i] = '\0'; 139326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 140326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!*buffer) { 141326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 142326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 143326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 144326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = true; 145326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { 146326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fields[i] = strtol(cp, &cp, 0); 147326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[i] != 0) { 148326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = false; 149326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 150326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 151326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (z) { /* never accessed */ 152326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 153326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 154326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 155326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 156326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { 157326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn path += sizeof(mmcblk0) - 1; 158326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 159326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 160326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: %s\n", path, buffer); 161326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 162326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 163326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 0; 164326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[3]) { 165326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 512 * fields[2] / fields[3]; 166326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 167326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 0; 168326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[7]) { 169326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 512 * fields[6] / fields[7]; 170326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 171326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf); 1728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((write_perf > 1) && (write_perf < worst_write_perf)) { 1738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn worst_write_perf = write_perf; 1748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 175326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 176326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 177326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 1788f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* Copied policy from system/core/logd/LogBuffer.cpp */ 1798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_SIZE (256 * 1024) 1818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) 1828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) 1838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1848f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic bool valid_size(unsigned long value) { 1858f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { 1868f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return false; 1878f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1888f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1898f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pages = sysconf(_SC_PHYS_PAGES); 1908f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pages < 1) { 1918f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 1928f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1938f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1948f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pagesize = sysconf(_SC_PAGESIZE); 1958f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pagesize <= 1) { 1968f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pagesize = PAGE_SIZE; 1978f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1988f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1998f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // maximum memory impact a somewhat arbitrary ~3% 2008f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pages = (pages + 31) / 32; 2018f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long maximum = pages * pagesize; 2028f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2038f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { 2048f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 2058f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2068f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2078f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value <= maximum; 2088f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2098f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2108f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic unsigned long property_get_size(const char *key) { 2118f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long value; 2128f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char *cp, property[PROPERTY_VALUE_MAX]; 2138f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2148f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_get(key, property, ""); 2158f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = strtoul(property, &cp, 10); 2168f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2178f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn switch(*cp) { 2188f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'm': 2198f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'M': 2208f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2218f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2228f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'k': 2238f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'K': 2248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case '\0': 2278f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn break; 2288f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2298f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default: 2308f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2318f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2328f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2338f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!valid_size(value)) { 2348f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2358f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2368f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2378f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value; 2388f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2398f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2408f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* timeout in ms */ 2418620bb4118a68721d10c29529dc6978847d08d00Felipe Lemestatic unsigned long logcat_timeout(const char *name) { 2428f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_tuneable[] = "persist.logd.size"; // Settings App 2438f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_default[] = "ro.logd.size"; // BoardConfig.mk 2448f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char key[PROP_NAME_MAX]; 2458f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long property_size, default_size; 2468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_tuneable); 2488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!default_size) { 2498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_default); 2508f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2518f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2528f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_tuneable, name); 2538f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 2548f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2558f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2568f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_default, name); 2578f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 2588f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2598f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2608f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2618f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = default_size; 2628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = LOG_BUFFER_SIZE; 2668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2678f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2688f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* Engineering margin is ten-fold our guess */ 2698f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return 10 * (property_size + worst_write_perf) / worst_write_perf; 2708f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2718f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* End copy from system/core/logd/LogBuffer.cpp */ 2738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 274f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* dumps the current system state to stdout */ 27578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void print_header() { 276f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross time_t now = time(NULL); 277f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX]; 278f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; 279f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char network[PROPERTY_VALUE_MAX], date[80]; 280f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 281f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.display.id", build, "(unknown)"); 282f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.fingerprint", fingerprint, "(unknown)"); 283f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.type", build_type, "(unknown)"); 284f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.baseband", radio, "(unknown)"); 285f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.bootloader", bootloader, "(unknown)"); 286f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("gsm.operator.alpha", network, "(unknown)"); 287f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now)); 288f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 289f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 290f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: %s\n", date); 291f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 292f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 293f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 294f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build: %s\n", build); 295f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */ 296f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Bootloader: %s\n", bootloader); 297f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Radio: %s\n", radio); 298f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Network: %s\n", network); 299f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 300f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Kernel: "); 301f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/proc/version"); 302f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Command line: %s\n", strtok(cmdline_buf, "\n")); 303f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 30478f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme} 30578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 30678f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void dumpstate(const std::string& screenshot_path) { 30778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme std::unique_ptr<DurationReporter> duration_reporter(new DurationReporter("DUMPSTATE")); 30878f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme unsigned long timeout; 309f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 3102db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); 311f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("UPTIME", 10, "uptime", NULL); 312326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); 3138c8130eb68c89987a94db084608a4229bad06c18Mark Salyzyn dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd"); 314f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("MEMORY INFO", "/proc/meminfo"); 315b32c7e14ccc6507f6ce3fc02414ba04b797f4558Elliott Hughes run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL); 3162b1f88b6ac78e330ff006da6fecf8bc9d976ec67Nick Kralevich run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); 317f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); 318f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VMALLOC INFO", "/proc/vmallocinfo"); 319f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("SLAB INFO", "/proc/slabinfo"); 320f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("ZONEINFO", "/proc/zoneinfo"); 321f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("PAGETYPEINFO", "/proc/pagetypeinfo"); 322f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BUDDYINFO", "/proc/buddyinfo"); 3232281af967dd840aade7bc55b19ea7df0e6da36f2Colin Cross dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); 324f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 325f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL WAKELOCKS", "/proc/wakelocks"); 32629e27a84c144fe3b941648094cad2a3f1e61e8b3Todd Poynor dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources"); 327f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); 32885aea748861b5665e68b786b55f1c798f56fc0daMathias Agopian dump_file("KERNEL SYNC", "/d/sync"); 329f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 330a3533a3ae6bf8d0e1780c153cafdec86926ec22cElliott Hughes run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL); 331b82c925d3cd54d5eff9f4f9e6d5aeb41f75365f5Nick Kralevich run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL); 332f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 333f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross do_dmesg(); 334f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 335f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL); 3361dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); 3371dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); 338f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 3396e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!screenshot_path.empty()) { 340e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGI("taking late screenshot\n"); 341e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme take_screenshot(screenshot_path); 3426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 3435a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey } 3445a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey 345f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); 3468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // calculate timeout 3478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); 3488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3508f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3517831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", 3527831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 3537831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 3547831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 355c7ad8cb82f035576c28707a8cbeb16b7ead2a4e7Mark Salyzyn timeout = logcat_timeout("events") + logcat_timeout("security"); 3568f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3578f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3588f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3597831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", 360c7ad8cb82f035576c28707a8cbeb16b7ead2a4e7Mark Salyzyn "-b", "security", 3617831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 3627831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 3637831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 3647831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 3658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("radio"); 3668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3678f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3688f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", 3707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 3717831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 3727831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 3737831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 374f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 375ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); 376ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn 377804339a59e4abcbcf5a50a60ff0543e6b404e572Sharvil Nanavati run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); 3788d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati 379f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* show the traces we collected in main(), if that was done */ 380f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (dump_traces_path != NULL) { 381f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES JUST NOW", dump_traces_path); 382f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 383f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 384f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* only show ANR traces if they're less than 15 minutes old */ 385f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross struct stat st; 386f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char anr_traces_path[PATH_MAX]; 387f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("dalvik.vm.stack-trace-file", anr_traces_path, ""); 388f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (!anr_traces_path[0]) { 389f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"); 390f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 39154bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(anr_traces_path, 39254bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 3937dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fd < 0) { 3947dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno)); 3957dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 3967dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd); 3977dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 398f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 399f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 400f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* slow traces for slow operations */ 401f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (anr_traces_path[0] != 0) { 402f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int tail = strlen(anr_traces_path)-1; 403f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (tail > 0 && anr_traces_path[tail] != '/') { 404f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross tail--; 405f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 406f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int i = 0; 407f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (1) { 408f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sprintf(anr_traces_path+tail+1, "slow%02d.txt", i); 409f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (stat(anr_traces_path, &st)) { 410f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // No traces file at this index, done with the files. 411f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross break; 412f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 413f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES WHEN SLOW", anr_traces_path); 414f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross i++; 415f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 416f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 417f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4187dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int dumped = 0; 4197dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 4207dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (tombstone_data[i].fd != -1) { 4217dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dumped = 1; 4227dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("TOMBSTONE", tombstone_data[i].name, tombstone_data[i].fd); 4237dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris tombstone_data[i].fd = -1; 4247dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 4257dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 4267dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (!dumped) { 4277dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR); 4287dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 4297dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 430f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("NETWORK DEV INFO", "/proc/net/dev"); 431f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all"); 432012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt"); 433f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); 434f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); 435f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4362a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor if (!stat(PSTORE_LAST_KMSG, &st)) { 4372a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ 4382a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", PSTORE_LAST_KMSG); 4392a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } else { 4402a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ 4412a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", "/proc/last_kmsg"); 4422a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } 4432a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 4442262c16372570f57d3107d574abe2c80825d286eMark Salyzyn /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ 4457831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn run_command("LAST LOGCAT", 10, "logcat", "-L", 4467831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-b", "all", 4477831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "threadtime", 4487831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-v", "printable", 4497831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "-d", 4507831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn "*:v", NULL); 4512262c16372570f57d3107d574abe2c80825d286eMark Salyzyn 452f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ 453a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes 454a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes run_command("NETWORK INTERFACES", 10, "ip", "link", NULL); 455d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 456d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL); 457d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL); 458d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 459f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES", 10, "ip", "rule", "show", NULL); 460f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL); 4612b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 4622b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran dump_route_tables(); 4632b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 464d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); 465d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); 466d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 467f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); 468f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); 469012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); 470012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall /* no ip6 nat */ 471012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL); 472012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL); 473f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 474f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("WIFI NETWORKS", 20, 4751d6b97c869718001010cce3db387c73fd11bf32eDmitry Shmidt SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); 476f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 477c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 4786afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD TABLE", 5, 4796afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_hostip", NULL); 4806afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4816afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, 482c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt SU_PATH, "root", "wlutil", "counters", NULL); 4836afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4846afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (1)", 5, 4856afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 4866afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 487c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#endif 4880b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (1)", "/proc/interrupts"); 4890b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt 4906afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); 4916afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 492c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 493f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP WIFI STATUS", 20, 494f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); 4956afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4966afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, 497f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "wlutil", "counters", NULL); 4986afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4996afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (2)", 5, 5006afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 501f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#endif 5020b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (2)", "/proc/interrupts"); 503f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 504f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross print_properties(); 505f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 506f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("VOLD DUMP", 10, "vdc", "dump", NULL); 507f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL); 508f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 5098f75fa7bcfec553eddb59b919b44d7a93c9846a1Ken Sumrall run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL); 510f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 511f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL); 512f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 513f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("------ BACKLIGHTS ------\n"); 514f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD brightness="); 515f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); 516f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Button brightness="); 517f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/button-backlight/brightness"); 518f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Keyboard brightness="); 519f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness"); 520f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("ALS mode="); 521f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/als"); 522f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD driver registers:\n"); 523f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/registers"); 524f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 525f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 526f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Binder state is expensive to look at as it uses a lot of memory. */ 527f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); 528f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); 529f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); 530f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats"); 531f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATE", "/sys/kernel/debug/binder/state"); 532f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 533f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 534f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Board\n"); 535f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 536f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 537f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpstate_board(); 538f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 539f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 540f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Migrate the ril_dumpstate to a dumpstate_board()? */ 541f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; 542f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); 543f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { 544f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { 545f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // su does not exist on user builds, so try running without it. 546f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // This way any implementations of vril-dump that do not require 547f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // root can run on user builds. 548f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 549f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross "vril-dump", NULL); 550f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 551f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 552f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "vril-dump", NULL); 553f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 554f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 555f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 556f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 557f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Android Framework Services\n"); 558f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 559f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 560f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* the full dumpsys is starting to take a long time, so we need 561f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross to increase its timeout. we really need to do the timeouts in 562f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpsys itself... */ 563f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMPSYS", 60, "dumpsys", NULL); 564f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 565f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 56602bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("== Checkins\n"); 56702bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 56802bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 56959b1516f4cefcfd599f4e5e9c4a227a48d1ace65Dianne Hackborn run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL); 5703e5fa73722c100fc9017c7a47b17a8e727aa34e1Dianne Hackborn run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL); 57102bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL); 5725cd46aa3399ddeaf12a211390dfde66c796ab299Dianne Hackborn run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL); 5731bd5068a5180ac12dda374e15c7b1f70e8334284Dianne Hackborn run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL); 5748b3e133e413774047da8005771f57c21dd31e1e3Ashish Sharma run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL); 57502bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 57602bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 577f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Activities\n"); 578f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 579f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 580f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL); 581f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 582f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 583f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Services\n"); 584f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 585f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 586f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL); 587f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 588f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 589f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Providers\n"); 590f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 591f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 592f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL); 593f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 594f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 595f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 596f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: done\n"); 597f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 598f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 599f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 600f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void usage() { 6011f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n" 602f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -o: write to file (instead of stdout)\n" 603f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -d: append date to filename (requires -o)\n" 6046e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme " -z: generates zipped file (requires -o)\n" 605f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -p: capture screenshot to filename.png (requires -o)\n" 606f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -s: write output to control socket (for init)\n" 607f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -b: play sound file instead of vibrate, at beginning of job\n" 608f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -e: play sound file instead of vibrate, at end of job\n" 6091f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau " -q: disable vibrate\n" 61036b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme " -B: send broadcast when finished (requires -o)\n" 61171bbfc57974331dce79242ce806d92035fce06baFelipe Leme " -P: send broadacast when started and update system properties on progress (requires -o and -B)\n" 6122a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor ); 613f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 614f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 615885f888c55587e9366542b5155a06c321cde175aJohn Michelaustatic void sigpipe_handler(int n) { 6162e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales // don't complain to stderr or stdout 6172e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales _exit(EXIT_FAILURE); 618885f888c55587e9366542b5155a06c321cde175aJohn Michelau} 619885f888c55587e9366542b5155a06c321cde175aJohn Michelau 6201dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brownstatic void vibrate(FILE* vibrator, int ms) { 6211dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown fprintf(vibrator, "%d\n", ms); 6221dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown fflush(vibrator); 6231dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown} 6241dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 6251e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme/* adds a new entry to the existing zip file. */ 6261e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Lemestatic bool add_zip_entry(ZipWriter* writer, const std::string& entry_name, 6271e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme const std::string& entry_path, time_t entry_time) { 6281e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme int32_t err = writer->StartEntryWithTime(entry_name.c_str(), 6291e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ZipWriter::kCompress, entry_time); 6306e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (err) { 6311e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), ZipWriter::ErrorCodeString(err)); 6326e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6336e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6346e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6351e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); 6366e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (fd.get() == -1) { 6371e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno)); 6386e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6396e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6406e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6416e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme while (1) { 6426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme std::vector<uint8_t> buffer(65536); 6436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), sizeof(buffer))); 6446e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (bytes_read == 0) { 6456e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme break; 6466e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else if (bytes_read == -1) { 6471e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("read(%s): %s\n", entry_path.c_str(), strerror(errno)); 6486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6491e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 6501e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme err = writer->WriteBytes(buffer.data(), bytes_read); 6511e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (err) { 6521e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err)); 6531e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme return false; 6541e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 6556e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6566e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6571e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme err = writer->FinishEntry(); 6586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (err) { 6591e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err)); 6606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6616e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6626e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6631e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme return true; 6641e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme} 6651e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 6661e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the 6671e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme temporary file. 6681e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme */ 6691e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Lemestatic bool finish_zip_file(ZipWriter* writer, 6701e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme const std::string& bugreport_name, const std::string& bugreport_path, 6711e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme time_t now) { 6721e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (!add_zip_entry(writer, bugreport_name, bugreport_path, now)) { 6731e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to add text entry to .zip file\n"); 6746e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6756e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6766e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6771e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme int32_t err = writer->Finish(); 6781e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (err) { 6791e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err)); 6806e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return false; 6816e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 6826e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 6831e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (remove(bugreport_path.c_str())) { 6841e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGW("remove(%s): %s\n", bugreport_path.c_str(), strerror(errno)); 6851e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 6861e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 6876e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme return true; 6886e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme} 6896e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 690f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char *argv[]) { 691885f888c55587e9366542b5155a06c321cde175aJohn Michelau struct sigaction sigact; 692f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_add_date = 0; 6936e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme int do_zip_file = 0; 6941f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau int do_vibrate = 1; 695f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char* use_outfile = 0; 696f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int use_socket = 0; 697f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_fb = 0; 69827f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey int do_broadcast = 0; 699e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme int do_early_screenshot = 0; 700f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7011e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (getuid() != 0) { 7021e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // Old versions of the adb client would call the 7031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // dumpstate command directly. Newer clients 7041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // call /system/bin/bugreport instead. If we detect 7051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // we're being called incorrectly, then exec the 7061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // correct program. 7071e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL); 7081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 709f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7101dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown ALOGI("begin\n"); 7112e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales 7121dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* clear SIGPIPE handler */ 713885f888c55587e9366542b5155a06c321cde175aJohn Michelau memset(&sigact, 0, sizeof(sigact)); 714885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigact.sa_handler = sigpipe_handler; 715885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigaction(SIGPIPE, &sigact, NULL); 7163e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall 717f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* set as high priority, and protect from OOM killer */ 718f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross setpriority(PRIO_PROCESS, 0, -20); 719cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *oom_adj = fopen("/proc/self/oom_adj", "we"); 720f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (oom_adj) { 721f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fputs("-17", oom_adj); 722f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(oom_adj); 723f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 724f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7251dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* parse arguments */ 726f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int c; 72771bbfc57974331dce79242ce806d92035fce06baFelipe Leme while ((c = getopt(argc, argv, "dho:svqzpPB")) != -1) { 728f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross switch (c) { 72971bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'd': do_add_date = 1; break; 73071bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'z': do_zip_file = 1; break; 73171bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'o': use_outfile = optarg; break; 73271bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 's': use_socket = 1; break; 733f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'v': break; // compatibility no-op 73471bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'q': do_vibrate = 0; break; 73571bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'p': do_fb = 1; break; 73671bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'P': do_update_progress = 1; break; 73771bbfc57974331dce79242ce806d92035fce06baFelipe Leme case 'B': do_broadcast = 1; break; 738f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case '?': printf("\n"); 739f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'h': 740f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usage(); 741f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross exit(1); 742f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 743f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 744f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 74571bbfc57974331dce79242ce806d92035fce06baFelipe Leme if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) { 7466e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme usage(); 7476e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme exit(1); 7486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 7496e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 75071bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress && !do_broadcast) { 75171bbfc57974331dce79242ce806d92035fce06baFelipe Leme usage(); 75271bbfc57974331dce79242ce806d92035fce06baFelipe Leme exit(1); 75371bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 7546e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme 755e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme do_early_screenshot = do_update_progress; 756e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 757ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // If we are going to use a socket, do it as early as possible 758ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // to avoid timeouts from bugreport. 759ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris if (use_socket) { 760ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris redirect_to_socket(stdout, "dumpstate"); 761ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris } 762ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris 763ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the directory where the bug report files will be written */ 764ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string bugreport_dir; 765ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 766ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* full path of the temporary file containing the bug report */ 767ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string tmp_path; 768ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 769e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme /* full path of the temporary file containing the screenshot (when requested) */ 770e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme std::string screenshot_path; 771e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 772ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* base name (without suffix or extensions) of the bug report files */ 773ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string base_name; 774ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 775ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* suffix of the bug report files - it's typically the date (when invoked with -d), 776ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme * although it could be changed by the user using a system property */ 777ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string suffix; 77871bbfc57974331dce79242ce806d92035fce06baFelipe Leme 77971bbfc57974331dce79242ce806d92035fce06baFelipe Leme /* pointer to the actual path, be it zip or text */ 78071bbfc57974331dce79242ce806d92035fce06baFelipe Leme std::string path; 78171bbfc57974331dce79242ce806d92035fce06baFelipe Leme 7821e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme /* pointers to the zipped file file */ 7831e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose); 7841e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme std::unique_ptr<ZipWriter> zip_writer; 7851e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 78671bbfc57974331dce79242ce806d92035fce06baFelipe Leme time_t now = time(NULL); 78771bbfc57974331dce79242ce806d92035fce06baFelipe Leme 788ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* redirect output if needed */ 78971bbfc57974331dce79242ce806d92035fce06baFelipe Leme bool is_redirecting = !use_socket && use_outfile; 79071bbfc57974331dce79242ce806d92035fce06baFelipe Leme 79171bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 792ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir = dirname(use_outfile); 793ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme base_name = basename(use_outfile); 79471bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_add_date) { 79571bbfc57974331dce79242ce806d92035fce06baFelipe Leme char date[80]; 796ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now)); 797ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = date; 798ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 799ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = "undated"; 80071bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 80171bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_fb) { 802ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // TODO: if dumpstate was an object, the paths could be internal variables and then 803ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // we could have a function to calculate the derived values, such as: 804ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme // screenshot_path = GetPath(".png"); 805ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 80671bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 807ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp"; 80871bbfc57974331dce79242ce806d92035fce06baFelipe Leme 809ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Bugreport dir: %s\nBase name: %s\nSuffix: %s\nTemporary path: %s\n" 810ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "Screenshot path: %s\n", bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(), 811ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme tmp_path.c_str(), screenshot_path.c_str()); 81271bbfc57974331dce79242ce806d92035fce06baFelipe Leme 8131e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 8141e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Creating initial .zip file"); 8151e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip"; 8161e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_file.reset(fopen(path.c_str(), "wb")); 8171e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (!zip_file) { 8181e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno)); 8191e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme do_zip_file = 0; 8201e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } else { 8211e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme zip_writer.reset(new ZipWriter(zip_file.get())); 8221e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 8231e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 8241e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 82571bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_update_progress) { 826ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::vector<std::string> am_args = { 827ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--receiver-permission", "android.permission.DUMP", 828ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--es", "android.intent.extra.NAME", suffix, 829ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 830ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL), 831ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme }; 832ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args); 83371bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 83471bbfc57974331dce79242ce806d92035fce06baFelipe Leme } 83571bbfc57974331dce79242ce806d92035fce06baFelipe Leme 83678f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme print_header(); 83778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme 8381dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* open the vibrator before dropping root */ 8396e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose); 8401f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau if (do_vibrate) { 8416e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we")); 8421dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 8436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 150); 8441dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown } 8451f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau } 846f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8473634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (do_fb && do_early_screenshot) { 8483634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (screenshot_path.empty()) { 8493634a1e3459cb609da709646107e246cafbc01f9Felipe Leme // should not have happened 8503634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("INTERNAL ERROR: skipping early screenshot because path was not set"); 8513634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } else { 8523634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("taking early screenshot\n"); 8533634a1e3459cb609da709646107e246cafbc01f9Felipe Leme take_screenshot(screenshot_path); 8543634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 8553634a1e3459cb609da709646107e246cafbc01f9Felipe Leme if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) { 8563634a1e3459cb609da709646107e246cafbc01f9Felipe Leme ALOGE("Unable to change ownership of screenshot file %s: %s\n", 8573634a1e3459cb609da709646107e246cafbc01f9Felipe Leme screenshot_path.c_str(), strerror(errno)); 8583634a1e3459cb609da709646107e246cafbc01f9Felipe Leme } 859e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 860e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme } 861e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme 8621e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (do_zip_file) { 8631e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (chown(path.c_str(), AID_SHELL, AID_SHELL)) { 8641e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno)); 8651e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 8661e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme } 8671e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme 868f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* read /proc/cmdline before dropping root */ 869cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *cmdline = fopen("/proc/cmdline", "re"); 8706e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (cmdline) { 871f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fgets(cmdline_buf, sizeof(cmdline_buf), cmdline); 872f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(cmdline); 873f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 874f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8751dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* collect stack traces from Dalvik and native processes (needs root) */ 8761dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown dump_traces_path = dump_traces(); 8771dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 8781dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* Get the tombstone fds here while we are running as root. */ 8791dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown get_tombstone_fds(tombstone_data); 8801dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 8811dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* ensure we will keep capabilities when we drop root */ 8821e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 8831e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 8841e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 8851e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 886f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 8871e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich /* switch to non-root user and group */ 8881e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, 889ab46a4922655bc75848660da4268ab85d72a6010Nick Kralevich AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; 8901e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 8911e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); 8921e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 8931e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 8941e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgid(AID_SHELL) != 0) { 8951e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgid, aborting: %s\n", strerror(errno)); 8961e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 8971e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 8981e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setuid(AID_SHELL) != 0) { 8991e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setuid, aborting: %s\n", strerror(errno)); 9001e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 9011e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 902f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_header_struct capheader; 9041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_data_struct capdata[2]; 9051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capheader, 0, sizeof(capheader)); 9061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capdata, 0, sizeof(capdata)); 9071e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.version = _LINUX_CAPABILITY_VERSION_3; 9081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.pid = 0; 9091e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 9101e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); 9111e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); 9121e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[0].inheritable = 0; 9131e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[1].inheritable = 0; 9141e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 9151e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (capset(&capheader, &capdata[0]) < 0) { 9161e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("capset failed: %s\n", strerror(errno)); 9171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 918f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 919f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 92071bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 9216e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* TODO: rather than generating a text file now and zipping it later, 9226e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme it would be more efficient to redirect stdout to the zip entry 9236e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme directly, but the libziparchive doesn't support that option yet. */ 9246e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str())); 925f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 926f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9273634a1e3459cb609da709646107e246cafbc01f9Felipe Leme dumpstate(do_early_screenshot ? "": screenshot_path); 928f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9291dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* done */ 9301dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 9311dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for (int i = 0; i < 3; i++) { 9326e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme vibrate(vibrator.get(), 75); 933f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usleep((75 + 50) * 1000); 934f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 935f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 936f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 93755b42a67f69767976ff16ab443b3e7142db693e1Felipe Leme /* close output if needed */ 93871bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (is_redirecting) { 939f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(stdout); 940f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 941f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme /* rename or zip the (now complete) .tmp file to its final location */ 9436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (use_outfile) { 944ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 945ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* check if user changed the suffix using system properties */ 946ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char key[PROPERTY_KEY_MAX]; 947ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme char value[PROPERTY_VALUE_MAX]; 948ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme sprintf(key, "dumpstate.%d.name", getpid()); 949ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme property_get(key, value, ""); 950ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bool change_suffix= false; 951ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (value[0]) { 952ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme /* must whitelist which characters are allowed, otherwise it could cross directories */ 953ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::regex valid_regex("^[-_a-zA-Z0-9]+$"); 954ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (std::regex_match(value, valid_regex)) { 955ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme change_suffix = true; 956ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 957ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("invalid suffix provided by user: %s", value); 958ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 959ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 960ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (change_suffix) { 961ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGI("changing suffix from %s to %s", suffix.c_str(), value); 962ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme suffix = value; 963ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (!screenshot_path.empty()) { 964ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme std::string new_screenshot_path = 965ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 966ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) { 967ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", screenshot_path.c_str(), 968ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme new_screenshot_path.c_str(), strerror(errno)); 969ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } else { 970ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme screenshot_path = new_screenshot_path; 971ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 972ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 973ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme } 974ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme 9756e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme bool do_text_file = true; 9766e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_zip_file) { 9771e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGD("Adding text entry to .zip bugreport"); 9781e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme if (!finish_zip_file(zip_writer.get(), base_name + "-" + suffix + ".txt", tmp_path, now)) { 9791e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme ALOGE("Failed to finish zip file; sending text bugreport instead\n"); 9806e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = true; 9816e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 9826e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme do_text_file = false; 9836e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 9846e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 9856e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (do_text_file) { 986ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGD("Generating .txt bugreport"); 987ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt"; 988ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme if (rename(tmp_path.c_str(), path.c_str())) { 989ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme ALOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno)); 9906e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme path.clear(); 9916e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 9926e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 993f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 994f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 9951dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* tell activity manager we're done */ 99671bbfc57974331dce79242ce806d92035fce06baFelipe Leme if (do_broadcast) { 9976e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme if (!path.empty()) { 9986e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme ALOGI("Final bugreport path: %s\n", path.c_str()); 99936b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme std::vector<std::string> am_args = { 100036b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme "--receiver-permission", "android.permission.DUMP", 100171bbfc57974331dce79242ce806d92035fce06baFelipe Leme "--ei", "android.intent.extra.PID", std::to_string(getpid()), 100236b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme "--es", "android.intent.extra.BUGREPORT", path 100336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme }; 100436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme if (do_fb) { 100536b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("--es"); 100636b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back("android.intent.extra.SCREENSHOT"); 100736b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme am_args.push_back(screenshot_path); 100836b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme } 100936b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args); 10106e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } else { 101171bbfc57974331dce79242ce806d92035fce06baFelipe Leme ALOGE("Skipping finished broadcast because bugreport could not be generated\n"); 10126e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme } 101327f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey } 101427f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey 1015e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL); 1016f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ALOGI("done\n"); 1017f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 1018f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 0; 1019f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 1020