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> 20f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <limits.h> 218f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#include <stdbool.h> 22f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h> 23f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdlib.h> 24f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h> 257dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/capability.h> 267dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/prctl.h> 27f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/resource.h> 28f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/stat.h> 29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h> 30f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/wait.h> 31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <unistd.h> 32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <cutils/properties.h> 34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "private/android_filesystem_config.h" 36f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#define LOG_TAG "dumpstate" 38656a6b9e3645bfe2cf073b69cbb9d02832f62c26Alex Ray#include <cutils/log.h> 39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "dumpstate.h" 41f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 42f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* read before root is shed */ 43f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char cmdline_buf[16384] = "(unknown)"; 44f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic const char *dump_traces_path = NULL; 45f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 46f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char screenshot_path[PATH_MAX] = ""; 47f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 482a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops" 492a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 507dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_DIR "/data/tombstones" 517dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_" 527dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Can accomodate a tombstone number up to 9999. */ 537dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4) 547dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define NUM_TOMBSTONES 10 557dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 567dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferristypedef struct { 577dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris char name[TOMBSTONE_MAX_LEN]; 587dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int fd; 597dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} tombstone_data_t; 607dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 617dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES]; 627dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 637dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Get the fds of any tombstone that was modified in the last half an hour. */ 647dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) { 657dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris time_t thirty_minutes_ago = time(NULL) - 60*30; 667dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 677dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i); 6854bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(data[i].name, 6954bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 707dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris struct stat st; 717dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && 727dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris (time_t) st.st_mtime >= thirty_minutes_ago) { 737dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris data[i].fd = fd; 747dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 757dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris close(fd); 767dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris data[i].fd = -1; 777dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 787dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 797dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} 807dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 812db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevågstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename) 822db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg{ 832db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg DIR *d; 842db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg struct dirent *de; 852db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg char path[PATH_MAX]; 862db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 872db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg d = opendir(driverpath); 882db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (d == NULL) { 892db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg return; 902db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 912db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 922db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg while ((de = readdir(d))) { 932db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg if (de->d_type != DT_LNK) { 942db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg continue; 952db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 962db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename); 972db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_file(title, path); 982db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg } 992db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 1002db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg closedir(d); 1012db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg} 1022db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg 103326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic bool skip_not_stat(const char *path) { 104326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn static const char stat[] = "/stat"; 105326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t len = strlen(path); 106326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (path[len - 1] == '/') { /* Directory? */ 107326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return false; 108326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 109326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ 110326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 111326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 112326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic const char mmcblk0[] = "/sys/block/mmcblk0/"; 1138f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynunsigned long worst_write_perf = 20000; /* in KB/s */ 114326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 115326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { 116326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn unsigned long fields[11], read_perf, write_perf; 117326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn bool z; 118326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn char *cp, *buffer = NULL; 119326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn size_t i = 0; 120326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn FILE *fp = fdopen(fd, "rb"); 121326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn getline(&buffer, &i, fp); 122326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fclose(fp); 123326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!buffer) { 124326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return -errno; 125326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 126326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn i = strlen(buffer); 127326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn while ((i > 0) && (buffer[i - 1] == '\n')) { 128326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn buffer[--i] = '\0'; 129326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 130326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!*buffer) { 131326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 132326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 133326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 134326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = true; 135326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { 136326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn fields[i] = strtol(cp, &cp, 0); 137326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[i] != 0) { 138326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn z = false; 139326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 140326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 141326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (z) { /* never accessed */ 142326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 143326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 144326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 145326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 146326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { 147326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn path += sizeof(mmcblk0) - 1; 148326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 149326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 150326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: %s\n", path, buffer); 151326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn free(buffer); 152326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 153326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 0; 154326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[3]) { 155326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn read_perf = 512 * fields[2] / fields[3]; 156326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 157326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 0; 158326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn if (fields[7]) { 159326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn write_perf = 512 * fields[6] / fields[7]; 160326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn } 161326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf); 1628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((write_perf > 1) && (write_perf < worst_write_perf)) { 1638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn worst_write_perf = write_perf; 1648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 165326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn return 0; 166326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn} 167326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn 1688f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* Copied policy from system/core/logd/LogBuffer.cpp */ 1698f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1708f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_SIZE (256 * 1024) 1718f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) 1728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) 1738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic bool valid_size(unsigned long value) { 1758f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { 1768f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return false; 1778f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1788f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pages = sysconf(_SC_PHYS_PAGES); 1808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pages < 1) { 1818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 1828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1848f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn long pagesize = sysconf(_SC_PAGESIZE); 1858f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (pagesize <= 1) { 1868f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pagesize = PAGE_SIZE; 1878f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1888f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1898f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // maximum memory impact a somewhat arbitrary ~3% 1908f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn pages = (pages + 31) / 32; 1918f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long maximum = pages * pagesize; 1928f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1938f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { 1948f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return true; 1958f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 1968f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 1978f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value <= maximum; 1988f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 1998f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2008f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic unsigned long property_get_size(const char *key) { 2018f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long value; 2028f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char *cp, property[PROPERTY_VALUE_MAX]; 2038f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2048f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_get(key, property, ""); 2058f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = strtoul(property, &cp, 10); 2068f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2078f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn switch(*cp) { 2088f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'm': 2098f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'M': 2108f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2118f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2128f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'k': 2138f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case 'K': 2148f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value *= 1024; 2158f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* FALLTHRU */ 2168f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn case '\0': 2178f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn break; 2188f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2198f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default: 2208f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2218f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2228f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2238f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!valid_size(value)) { 2248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn value = 0; 2258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2278f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return value; 2288f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2298f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2308f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* timeout in ms */ 2318f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic unsigned long logcat_timeout(char *name) { 2328f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_tuneable[] = "persist.logd.size"; // Settings App 2338f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn static const char global_default[] = "ro.logd.size"; // BoardConfig.mk 2348f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn char key[PROP_NAME_MAX]; 2358f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long property_size, default_size; 2368f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2378f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_tuneable); 2388f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!default_size) { 2398f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn default_size = property_get_size(global_default); 2408f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2418f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2428f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_tuneable, name); 2438f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 2448f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2458f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn snprintf(key, sizeof(key), "%s.%s", global_default, name); 2478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = property_get_size(key); 2488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2508f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2518f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = default_size; 2528f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2538f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2548f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (!property_size) { 2558f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn property_size = LOG_BUFFER_SIZE; 2568f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 2578f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2588f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn /* Engineering margin is ten-fold our guess */ 2598f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn return 10 * (property_size + worst_write_perf) / worst_write_perf; 2608f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn} 2618f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 2628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* End copy from system/core/logd/LogBuffer.cpp */ 2638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn 264f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* dumps the current system state to stdout */ 265f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void dumpstate() { 2668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn unsigned long timeout; 267f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross time_t now = time(NULL); 268f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX]; 269f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; 270f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char network[PROPERTY_VALUE_MAX], date[80]; 271f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char build_type[PROPERTY_VALUE_MAX]; 272f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 273f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.display.id", build, "(unknown)"); 274f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.fingerprint", fingerprint, "(unknown)"); 275f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.build.type", build_type, "(unknown)"); 276f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.baseband", radio, "(unknown)"); 277f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ro.bootloader", bootloader, "(unknown)"); 278f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("gsm.operator.alpha", network, "(unknown)"); 279f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now)); 280f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 281f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 282f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: %s\n", date); 283f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 284f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 285f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 286f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build: %s\n", build); 287f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */ 288f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Bootloader: %s\n", bootloader); 289f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Radio: %s\n", radio); 290f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Network: %s\n", network); 291f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 292f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Kernel: "); 293f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/proc/version"); 294f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Command line: %s\n", strtok(cmdline_buf, "\n")); 295f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 296f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 2972db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); 298f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("UPTIME", 10, "uptime", NULL); 299326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); 300f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("MEMORY INFO", "/proc/meminfo"); 301f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL); 302f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("PROCRANK", 20, "procrank", NULL); 303f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); 304f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VMALLOC INFO", "/proc/vmallocinfo"); 305f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("SLAB INFO", "/proc/slabinfo"); 306f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("ZONEINFO", "/proc/zoneinfo"); 307f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("PAGETYPEINFO", "/proc/pagetypeinfo"); 308f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BUDDYINFO", "/proc/buddyinfo"); 3092281af967dd840aade7bc55b19ea7df0e6da36f2Colin Cross dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); 310f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 311f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL WAKELOCKS", "/proc/wakelocks"); 31229e27a84c144fe3b941648094cad2a3f1e61e8b3Todd Poynor dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources"); 313f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); 31485aea748861b5665e68b786b55f1c798f56fc0daMathias Agopian dump_file("KERNEL SYNC", "/d/sync"); 315f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 316f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("PROCESSES", 10, "ps", "-P", NULL); 317f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL); 31876b45c126be0208f6f8e8f3025b0aa8a26d3fc3aNick Kralevich run_command("PROCESSES (SELINUX LABELS)", 10, "ps", "-Z", NULL); 319f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LIBRANK", 10, "librank", NULL); 320f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 321f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross do_dmesg(); 322f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 323f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL); 3241dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); 3251dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); 326f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 3275a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey if (screenshot_path[0]) { 3285a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey ALOGI("taking screenshot\n"); 3295a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey run_command(NULL, 10, "/system/bin/screencap", "-p", screenshot_path, NULL); 3305a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey ALOGI("wrote screenshot: %s\n", screenshot_path); 3315a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey } 3325a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey 333f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); 3348f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn // calculate timeout 3358f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); 3368f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3378f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3388f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3398f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", "-d", "*:v", NULL); 3408f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("events"); 3418f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3428f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3438f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3448f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL); 3458f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = logcat_timeout("radio"); 3468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn if (timeout < 20000) { 3478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn timeout = 20000; 3488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn } 3498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL); 350f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 351ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); 352ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn 353f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* show the traces we collected in main(), if that was done */ 354f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (dump_traces_path != NULL) { 355f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES JUST NOW", dump_traces_path); 356f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 357f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 358f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* only show ANR traces if they're less than 15 minutes old */ 359f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross struct stat st; 360f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char anr_traces_path[PATH_MAX]; 361f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("dalvik.vm.stack-trace-file", anr_traces_path, ""); 362f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (!anr_traces_path[0]) { 363f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"); 364f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 36554bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris int fd = TEMP_FAILURE_RETRY(open(anr_traces_path, 36654bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 3677dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (fd < 0) { 3687dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno)); 3697dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } else { 3707dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd); 3717dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 372f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 373f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 374f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* slow traces for slow operations */ 375f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (anr_traces_path[0] != 0) { 376f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int tail = strlen(anr_traces_path)-1; 377f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (tail > 0 && anr_traces_path[tail] != '/') { 378f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross tail--; 379f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 380f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int i = 0; 381f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross while (1) { 382f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sprintf(anr_traces_path+tail+1, "slow%02d.txt", i); 383f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (stat(anr_traces_path, &st)) { 384f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // No traces file at this index, done with the files. 385f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross break; 386f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 387f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("VM TRACES WHEN SLOW", anr_traces_path); 388f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross i++; 389f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 390f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 391f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 3927dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris int dumped = 0; 3937dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 3947dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (tombstone_data[i].fd != -1) { 3957dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dumped = 1; 3967dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris dump_file_from_fd("TOMBSTONE", tombstone_data[i].name, tombstone_data[i].fd); 3977dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris tombstone_data[i].fd = -1; 3987dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 3997dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 4007dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris if (!dumped) { 4017dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR); 4027dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris } 4037dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris 404f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("NETWORK DEV INFO", "/proc/net/dev"); 405f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all"); 406012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt"); 407f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); 408f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); 409f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4102a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor if (!stat(PSTORE_LAST_KMSG, &st)) { 4112a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ 4122a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", PSTORE_LAST_KMSG); 4132a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } else { 4142a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ 4152a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor dump_file("LAST KMSG", "/proc/last_kmsg"); 4162a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor } 4172a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor 4182262c16372570f57d3107d574abe2c80825d286eMark Salyzyn /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ 4192262c16372570f57d3107d574abe2c80825d286eMark Salyzyn run_command("LAST LOGCAT", 10, "logcat", "-L", "-v", "threadtime", 4202262c16372570f57d3107d574abe2c80825d286eMark Salyzyn "-b", "all", "-d", "*:v", NULL); 4212262c16372570f57d3107d574abe2c80825d286eMark Salyzyn 422f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ 423a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes 424a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes run_command("NETWORK INTERFACES", 10, "ip", "link", NULL); 425d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 426d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL); 427d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL); 428d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 429f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES", 10, "ip", "rule", "show", NULL); 430f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL); 4312b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 4322b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran dump_route_tables(); 4332b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran 434d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); 435d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); 436d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti 437f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); 438f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); 439012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); 440012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall /* no ip6 nat */ 441012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL); 442012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL); 443f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 444f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("WIFI NETWORKS", 20, 4451d6b97c869718001010cce3db387c73fd11bf32eDmitry Shmidt SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); 446f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 447c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 4486afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD TABLE", 5, 4496afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_hostip", NULL); 4506afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4516afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, 452c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt SU_PATH, "root", "wlutil", "counters", NULL); 4536afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4546afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (1)", 5, 4556afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 4566afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 457c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#endif 4580b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (1)", "/proc/interrupts"); 4590b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt 4606afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); 4616afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 462c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd 463f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP WIFI STATUS", 20, 464f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); 4656afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4666afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, 467f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "wlutil", "counters", NULL); 4686afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti 4696afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti run_command("ND OFFLOAD STATUS (2)", 5, 4706afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti SU_PATH, "root", "wlutil", "nd_status", NULL); 471f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#endif 4720b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt dump_file("INTERRUPTS (2)", "/proc/interrupts"); 473f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 474f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross print_properties(); 475f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 476f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("VOLD DUMP", 10, "vdc", "dump", NULL); 477f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL); 478f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 4798f75fa7bcfec553eddb59b919b44d7a93c9846a1Ken Sumrall run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL); 480f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 481f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL); 482f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 483f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("------ BACKLIGHTS ------\n"); 484f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD brightness="); 485f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); 486f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Button brightness="); 487f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/button-backlight/brightness"); 488f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("Keyboard brightness="); 489f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness"); 490f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("ALS mode="); 491f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/als"); 492f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("LCD driver registers:\n"); 493f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file(NULL, "/sys/class/leds/lcd-backlight/registers"); 494f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 495f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 496f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Binder state is expensive to look at as it uses a lot of memory. */ 497f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); 498f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); 499f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); 500f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats"); 501f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dump_file("BINDER STATE", "/sys/kernel/debug/binder/state"); 502f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 503f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 504f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Board\n"); 505f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 506f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 507f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpstate_board(); 508f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("\n"); 509f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 510f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* Migrate the ril_dumpstate to a dumpstate_board()? */ 511f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; 512f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); 513f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { 514f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { 515f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // su does not exist on user builds, so try running without it. 516f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // This way any implementations of vril-dump that do not require 517f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // root can run on user builds. 518f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 519f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross "vril-dump", NULL); 520f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 521f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 522f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross SU_PATH, "root", "vril-dump", NULL); 523f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 524f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 525f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 526f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 527f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Android Framework Services\n"); 528f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 529f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 530f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* the full dumpsys is starting to take a long time, so we need 531f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross to increase its timeout. we really need to do the timeouts in 532f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpsys itself... */ 533f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("DUMPSYS", 60, "dumpsys", NULL); 534f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 535f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 53602bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("== Checkins\n"); 53702bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 53802bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 53959b1516f4cefcfd599f4e5e9c4a227a48d1ace65Dianne Hackborn run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL); 5403e5fa73722c100fc9017c7a47b17a8e727aa34e1Dianne Hackborn run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL); 54102bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL); 5425cd46aa3399ddeaf12a211390dfde66c796ab299Dianne Hackborn run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL); 5431bd5068a5180ac12dda374e15c7b1f70e8334284Dianne Hackborn run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL); 5448b3e133e413774047da8005771f57c21dd31e1e3Ashish Sharma run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL); 54502bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn 54602bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn printf("========================================================\n"); 547f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Activities\n"); 548f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 549f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 550f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL); 551f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 552f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 553f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Services\n"); 554f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 555f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 556f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL); 557f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 558f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 559f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== Running Application Providers\n"); 560f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 561f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 562f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL); 563f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 564f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 565f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 566f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("== dumpstate: done\n"); 567f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross printf("========================================================\n"); 568f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 569f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 570f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void usage() { 5711f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n" 572f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -o: write to file (instead of stdout)\n" 573f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -d: append date to filename (requires -o)\n" 574f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -p: capture screenshot to filename.png (requires -o)\n" 575f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -s: write output to control socket (for init)\n" 576f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -b: play sound file instead of vibrate, at beginning of job\n" 577f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross " -e: play sound file instead of vibrate, at end of job\n" 5781f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau " -q: disable vibrate\n" 57927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey " -B: send broadcast when finished (requires -o and -p)\n" 5802a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor ); 581f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 582f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 583885f888c55587e9366542b5155a06c321cde175aJohn Michelaustatic void sigpipe_handler(int n) { 5842e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales // don't complain to stderr or stdout 5852e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales _exit(EXIT_FAILURE); 586885f888c55587e9366542b5155a06c321cde175aJohn Michelau} 587885f888c55587e9366542b5155a06c321cde175aJohn Michelau 5881dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brownstatic void vibrate(FILE* vibrator, int ms) { 5891dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown fprintf(vibrator, "%d\n", ms); 5901dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown fflush(vibrator); 5911dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown} 5921dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 593f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char *argv[]) { 594885f888c55587e9366542b5155a06c321cde175aJohn Michelau struct sigaction sigact; 595f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_add_date = 0; 5961f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau int do_vibrate = 1; 597f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char* use_outfile = 0; 598f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int use_socket = 0; 599f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int do_fb = 0; 60027f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey int do_broadcast = 0; 601f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6021e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (getuid() != 0) { 6031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // Old versions of the adb client would call the 6041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // dumpstate command directly. Newer clients 6051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // call /system/bin/bugreport instead. If we detect 6061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // we're being called incorrectly, then exec the 6071e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich // correct program. 6081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL); 6091e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 610f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6111dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown ALOGI("begin\n"); 6122e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales 6131dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* clear SIGPIPE handler */ 614885f888c55587e9366542b5155a06c321cde175aJohn Michelau memset(&sigact, 0, sizeof(sigact)); 615885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigact.sa_handler = sigpipe_handler; 616885f888c55587e9366542b5155a06c321cde175aJohn Michelau sigaction(SIGPIPE, &sigact, NULL); 6173e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall 618f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* set as high priority, and protect from OOM killer */ 619f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross setpriority(PRIO_PROCESS, 0, -20); 620cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *oom_adj = fopen("/proc/self/oom_adj", "we"); 621f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (oom_adj) { 622f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fputs("-17", oom_adj); 623f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(oom_adj); 624f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 625f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6261dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* parse arguments */ 627f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross int c; 6281dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown while ((c = getopt(argc, argv, "dho:svqzpB")) != -1) { 629f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross switch (c) { 630f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'd': do_add_date = 1; break; 631f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'o': use_outfile = optarg; break; 632f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 's': use_socket = 1; break; 633f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'v': break; // compatibility no-op 6341f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau case 'q': do_vibrate = 0; break; 635f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'p': do_fb = 1; break; 63627f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey case 'B': do_broadcast = 1; break; 637f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case '?': printf("\n"); 638f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross case 'h': 639f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usage(); 640f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross exit(1); 641f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 642f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 643f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 644ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // If we are going to use a socket, do it as early as possible 645ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris // to avoid timeouts from bugreport. 646ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris if (use_socket) { 647ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris redirect_to_socket(stdout, "dumpstate"); 648ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris } 649ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris 6501dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* open the vibrator before dropping root */ 6511f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau FILE *vibrator = 0; 6521f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau if (do_vibrate) { 653cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich vibrator = fopen("/sys/class/timed_output/vibrator/enable", "we"); 6541dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 6551dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown vibrate(vibrator, 150); 6561dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown } 6571f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau } 658f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 659f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* read /proc/cmdline before dropping root */ 660cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich FILE *cmdline = fopen("/proc/cmdline", "re"); 661f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (cmdline != NULL) { 662f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fgets(cmdline_buf, sizeof(cmdline_buf), cmdline); 663f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(cmdline); 664f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 665f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6661dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* collect stack traces from Dalvik and native processes (needs root) */ 6671dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown dump_traces_path = dump_traces(); 6681dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 6691dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* Get the tombstone fds here while we are running as root. */ 6701dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown get_tombstone_fds(tombstone_data); 6711dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown 6721dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* ensure we will keep capabilities when we drop root */ 6731e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 6741e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 6751e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 6761e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 677f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6781e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich /* switch to non-root user and group */ 6791e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, 6801e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich AID_MOUNT, AID_INET, AID_NET_BW_STATS }; 6811e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 6821e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); 6831e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 6841e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 6851e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setgid(AID_SHELL) != 0) { 6861e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setgid, aborting: %s\n", strerror(errno)); 6871e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 6881e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 6891e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (setuid(AID_SHELL) != 0) { 6901e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("Unable to setuid, aborting: %s\n", strerror(errno)); 6911e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 6921e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich } 693f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 6941e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_header_struct capheader; 6951e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich struct __user_cap_data_struct capdata[2]; 6961e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capheader, 0, sizeof(capheader)); 6971e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich memset(&capdata, 0, sizeof(capdata)); 6981e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.version = _LINUX_CAPABILITY_VERSION_3; 6991e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capheader.pid = 0; 7001e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 7011e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); 7021e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); 7031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[0].inheritable = 0; 7041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich capdata[1].inheritable = 0; 7051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich 7061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich if (capset(&capheader, &capdata[0]) < 0) { 7071e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich ALOGE("capset failed: %s\n", strerror(errno)); 7081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich return -1; 709f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 710f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7111dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* redirect output if needed */ 712f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char path[PATH_MAX], tmp_path[PATH_MAX]; 713f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross pid_t gzip_pid = -1; 714f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 715ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris if (!use_socket && use_outfile) { 716f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcpy(path, use_outfile, sizeof(path)); 717f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (do_add_date) { 718f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross char date[80]; 719f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross time_t now = time(NULL); 720f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now)); 721f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcat(path, date, sizeof(path)); 722f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 723f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (do_fb) { 724f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcpy(screenshot_path, path, sizeof(screenshot_path)); 725f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcat(screenshot_path, ".png", sizeof(screenshot_path)); 726f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 727f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcat(path, ".txt", sizeof(path)); 728f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcpy(tmp_path, path, sizeof(tmp_path)); 729f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross strlcat(tmp_path, ".tmp", sizeof(tmp_path)); 730ff4a4dc7e6e3ead12020b4dc17548d767a419ddeChristopher Ferris redirect_to_file(stdout, tmp_path); 731f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 732f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 733f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross dumpstate(); 734f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7351dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* done */ 7361dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown if (vibrator) { 7371dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown for (int i = 0; i < 3; i++) { 7381dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown vibrate(vibrator, 75); 739f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross usleep((75 + 50) * 1000); 740f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 741f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(vibrator); 742f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 743f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 744f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* wait for gzip to finish, otherwise it might get killed when we exit */ 745f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (gzip_pid > 0) { 746f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fclose(stdout); 747f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross waitpid(gzip_pid, NULL, 0); 748f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 749f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 750f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross /* rename the (now complete) .tmp file to its final location */ 751f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (use_outfile && rename(tmp_path, path)) { 752f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno)); 753f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 754f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 7551dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown /* tell activity manager we're done */ 75627f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey if (do_broadcast && use_outfile && do_fb) { 757aaaa57bf8904ef383a9e766ace09725bc392acebJeff Sharkey run_command(NULL, 5, "/system/bin/am", "broadcast", "--user", "0", 75827f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey "-a", "android.intent.action.BUGREPORT_FINISHED", 75927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey "--es", "android.intent.extra.BUGREPORT", path, 76027f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey "--es", "android.intent.extra.SCREENSHOT", screenshot_path, 76127f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey "--receiver-permission", "android.permission.DUMP", NULL); 76227f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey } 76327f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey 764f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross ALOGI("done\n"); 765f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 766f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 0; 767f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 768