dumpstate.cpp revision ee2e4a01f9ca9aae7ee111abcd5c139fc810bf65
1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/* 2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2008 The Android Open Source Project 3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License. 6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at 7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software 11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and 14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License. 15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */ 16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <dirent.h> 18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <errno.h> 19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <fcntl.h> 20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <libgen.h> 216e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <limits.h> 2284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#include <memory> 2384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#include <regex> 246e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <set> 2584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#include <stdbool.h> 2684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#include <stdio.h> 276e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <stdlib.h> 286e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <string> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <string.h> 30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/capability.h> 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/prctl.h> 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/resource.h> 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/stat.h> 348d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber#include <sys/time.h> 358d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber#include <sys/wait.h> 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <unistd.h> 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <android-base/stringprintf.h> 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <cutils/properties.h> 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 41190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber#include "private/android_filesystem_config.h" 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 432bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#define LOG_TAG "dumpstate" 442bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#include <cutils/log.h> 45de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber 462bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#include "dumpstate.h" 47dab718bba3945332dc75e268e1e7f0fe2eb91c4aAndreas Huber#include "ScopedFd.h" 489b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber#include "ziparchive/zip_writer.h" 4984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 5084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#include "mincrypt/sha256.h" 5184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 5284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberusing android::base::StringPrintf; 5384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 5484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber/* read before root is shed */ 55100a4408968b90e314526185d572c72ea4cc784aAndreas Huberstatic char cmdline_buf[16384] = "(unknown)"; 56e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huberstatic const char *dump_traces_path = NULL; 57908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 58e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huber// TODO: should be part of dumpstate object 59e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huberstatic unsigned long id; 60e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huberstatic char build_type[PROPERTY_VALUE_MAX]; 61e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huberstatic time_t now; 62e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huberstatic std::unique_ptr<ZipWriter> zip_writer; 63908dbdee96856693decc04fa143c2ba525495d43Andreas Huberstatic std::set<std::string> mount_points; 64908dbdee96856693decc04fa143c2ba525495d43Andreas Hubervoid add_mountinfo(); 650955986e6c1c27ba752e293246086ea79c49d39cRoger Jönssonstatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path); 660955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson 67f30460b886b233033ffd30c71614bedc24bed79eWei Jia#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops" 68f30460b886b233033ffd30c71614bedc24bed79eWei Jia 69f30460b886b233033ffd30c71614bedc24bed79eWei Jia#define RAFT_DIR "/data/misc/raft/" 70f30460b886b233033ffd30c71614bedc24bed79eWei Jia#define RECOVERY_DIR "/cache/recovery" 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#define TOMBSTONE_DIR "/data/tombstones" 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_" 738d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber/* Can accomodate a tombstone number up to 9999. */ 748d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4) 758d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber#define NUM_TOMBSTONES 10 768d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 778d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubertypedef struct { 788d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber char name[TOMBSTONE_MAX_LEN]; 798d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber int fd; 808d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} tombstone_data_t; 818d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES]; 838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 848d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber// Root dir for all files copied as-is into the bugreport 858d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberconst std::string& ZIP_ROOT_DIR = "FS"; 868d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 878d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber/* 888d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * List of supported zip format versions. 898d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * 908d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * See bugreport-format.txt for more info. 918d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber */ 928d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber// TODO: change to "v1" before final N build 938d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic std::string VERSION_DEFAULT = "v1-dev1"; 948d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber// TODO: remove before final N build 958d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic std::string VERSION_DUMPSYS_SPLIT = "v1-dev1-dumpsys-split"; 968d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 978d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber/* gets the tombstone data, according to the bugreport type: if zipped gets all tombstones, 988d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber * otherwise gets just those modified in the last half an hour. */ 998d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) { 1008d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber time_t thirty_minutes_ago = now - 60*30; 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 1022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i); 1032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int fd = TEMP_FAILURE_RETRY(open(data[i].name, 1042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 1058d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih struct stat st; 1062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && 1072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber (zip_writer || (time_t) st.st_mtime >= thirty_minutes_ago)) { 1082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber data[i].fd = fd; 1092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } else { 1102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber close(fd); 1112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber data[i].fd = -1; 1122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1149b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber} 1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber// for_each_pid() callback to get mount info about a process. 1179b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid do_mountinfo(int pid, const char *name) { 1182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber char path[PATH_MAX]; 1192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1209b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber // Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points 121348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber // are added. 1229b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber sprintf(path, "/proc/%d/ns/mnt", pid); 123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char linkname[PATH_MAX]; 1244579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber ssize_t r = readlink(path, linkname, PATH_MAX); 125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (r == -1) { 126cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGE("Unable to read link for %s: %s\n", path, strerror(errno)); 127cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber return; 128cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1297e73e44c2d2208a7079e562f7b0b9b73ef6a29f1Andreas Huber linkname[r] = '\0'; 130100a4408968b90e314526185d572c72ea4cc784aAndreas Huber 131100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (mount_points.find(linkname) == mount_points.end()) { 132100a4408968b90e314526185d572c72ea4cc784aAndreas Huber // First time this mount point was found: add it 1338d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber sprintf(path, "/proc/%d/mountinfo", pid); 1347aef03379179c109c2547c33c410bfc93c8db576Andreas Huber if (add_zip_entry(ZIP_ROOT_DIR + path, path)) { 135a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber mount_points.insert(linkname); 1361a37ee3c877165c812734b405f922f6e0d747052joakim johansson } else { 137e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber MYLOGE("Unable to add mountinfo %s to zip file\n", path); 138f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber } 1390dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber } 140f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber} 141ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 142908dbdee96856693decc04fa143c2ba525495d43Andreas Hubervoid add_mountinfo() { 14346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (!zip_writer) return; 1440955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson const char *title = "MOUNT INFO"; 145c582fde93ded7219107157333a9e46d780adcf9cJean-Baptiste Queru mount_points.clear(); 146bbbf9c4552402ab18b255f4058e9e6e506f3f106Yajun Zeng DurationReporter duration_reporter(title, NULL); 147a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber for_each_pid(do_mountinfo, NULL); 148348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber MYLOGD("%s: %d entries added to zip file\n", title, (int) mount_points.size()); 149348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber} 150348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 1514579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huberstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename) 1524579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber{ 1534579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber DIR *d; 1544579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber struct dirent *de; 1554579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber char path[PATH_MAX]; 156de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber 157de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber d = opendir(driverpath); 158de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber if (d == NULL) { 159de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber return; 1604579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber } 1614579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber 1624579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber while ((de = readdir(d))) { 1634579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber if (de->d_type != DT_LNK) { 164a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes continue; 1654579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber } 1664579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename); 167a8b8488f703bb6bda039d7d98f87e4f9d845664dDavid Williams dump_file(title, path); 1684579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber } 169de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber 170de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber closedir(d); 171348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber} 172348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 1732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatic bool skip_not_stat(const char *path) { 1742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber static const char stat[] = "/stat"; 1752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber size_t len = strlen(path); 176348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (path[len - 1] == '/') { /* Directory? */ 1771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar return false; 1780792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 1790792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */ 1801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar} 1814579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool skip_none(const char *path) { 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 18481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé} 18581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 18681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhéstatic const char mmcblk0[] = "/sys/block/mmcblk0/"; 18781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhéunsigned long worst_write_perf = 20000; /* in KB/s */ 1881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar 18981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé// 19081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé// stat offsets 1911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar// Name units description 19281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé// ---- ----- ----------- 19381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé// read I/Os requests number of read I/Os processed 19481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé#define __STAT_READ_IOS 0 19581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé// read merges requests number of read I/Os merged with in-queue I/O 19684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define __STAT_READ_MERGES 1 197b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// read sectors sectors number of sectors read 198b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_READ_SECTORS 2 199b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// read ticks milliseconds total wait time for read requests 200b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_READ_TICKS 3 201b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// write I/Os requests number of write I/Os processed 202b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_WRITE_IOS 4 203b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// write merges requests number of write I/Os merged with in-queue I/O 204b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_WRITE_MERGES 5 205b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// write sectors sectors number of sectors written 206b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_WRITE_SECTORS 6 207b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// write ticks milliseconds total wait time for write requests 208b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_WRITE_TICKS 7 209b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// in_flight requests number of I/Os currently in flight 210b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_IN_FLIGHT 8 211b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// io_ticks milliseconds total time this block device has been active 212b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_IO_TICKS 9 213b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// time_in_queue milliseconds total wait time for all requests 214b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_IN_QUEUE 10 215b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher#define __STAT_NUMBER_FIELD 11 216b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher// 2172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber// read I/Os, write I/Os 2181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar// ===================== 219348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber// 220348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber// These values increment when an I/O request completes. 2212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber// 2221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar// read merges, write merges 223cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber// ========================= 2240955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson// 225cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber// These values increment when an I/O request is merged with an 226cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber// already-queued I/O request. 227cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber// 2288d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// read sectors, write sectors 2298d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// =========================== 2308d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// 2318d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// These values count the number of sectors read from or written to this 2328d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// block device. The "sectors" in question are the standard UNIX 512-byte 2338d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih// sectors, not any device- or filesystem-specific block size. The 2347f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber// counters are incremented when the I/O completes. 2357f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber#define SECTOR_SIZE 512 2367f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber// 2377f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber// read ticks, write ticks 23846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// ======================= 2391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar// 2400955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson// These values count the number of milliseconds that I/O requests have 2410955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson// waited on this block device. If there are multiple I/O requests waiting, 242641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih// these values will increase at a rate greater than 1000/second; for 24346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// example, if 60 read requests wait for an average of 30 ms, the read_ticks 24446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// field will increase by 60*30 = 1800. 24546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// 2461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar// in_flight 2470955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson// ========= 24846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// 24946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// This value counts the number of I/O requests that have been issued to 25046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson// the device driver but have not yet completed. It does not include I/O 2512bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// requests that are in the queue but not yet issued to the device driver. 2522bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// 2532bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// io_ticks 2542bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// ======== 2552bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// 2562bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// This value counts the number of milliseconds during which the device has 2572bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// had I/O requests queued. 2582bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// 2592bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// time_in_queue 2602bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// ============= 2612bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// 2622bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// This value counts the number of milliseconds that I/O requests have waited 2632bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// on this block device. If there are multiple I/O requests waiting, this 2642bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// value will increase as the product of the number of milliseconds times the 2652bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// number of requests waiting (see "read ticks" above for an example). 2662bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#define S_TO_MS 1000 2672bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber// 268820c4893fdec784321826fd903da34fe3d609b93Wei Jia 269820c4893fdec784321826fd903da34fe3d609b93Wei Jiastatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) { 270820c4893fdec784321826fd903da34fe3d609b93Wei Jia unsigned long long fields[__STAT_NUMBER_FIELD]; 2712bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber bool z; 2722bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber char *cp, *buffer = NULL; 2732bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber size_t i = 0; 2742bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber FILE *fp = fdopen(fd, "rb"); 2752bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber getline(&buffer, &i, fp); 2762bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber fclose(fp); 2772bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (!buffer) { 2782bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return -errno; 2792bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 2802bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber i = strlen(buffer); 2812bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber while ((i > 0) && (buffer[i - 1] == '\n')) { 2822bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber buffer[--i] = '\0'; 2832bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 2842bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (!*buffer) { 2852bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber free(buffer); 2862bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return 0; 2872bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 2882bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber z = true; 2892bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) { 2902bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber fields[i] = strtoull(cp, &cp, 10); 2912bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (fields[i] != 0) { 2922bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber z = false; 293190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber } 2942bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 2952bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (z) { /* never accessed */ 2962bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber free(buffer); 2972bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return 0; 2982bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 2992bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3002bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) { 3012bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber path += sizeof(mmcblk0) - 1; 3022bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 3032bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3042bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber printf("%s: %s\n", path, buffer); 3052bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber free(buffer); 3062bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3072bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (fields[__STAT_IO_TICKS]) { 3082bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long read_perf = 0; 3092bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long read_ios = 0; 3102bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (fields[__STAT_READ_TICKS]) { 3112bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long long divisor = fields[__STAT_READ_TICKS] 3122bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_IO_TICKS]; 3132bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber read_perf = ((unsigned long long)SECTOR_SIZE 3142bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_READ_SECTORS] 3152bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_IN_QUEUE] + (divisor >> 1)) 3162bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber / divisor; 3172bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber read_ios = ((unsigned long long)S_TO_MS * fields[__STAT_READ_IOS] 3182bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_IN_QUEUE] + (divisor >> 1)) 3192bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber / divisor; 3202bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 3212bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3222bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long write_perf = 0; 3232bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long write_ios = 0; 324dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if (fields[__STAT_WRITE_TICKS]) { 325de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber unsigned long long divisor = fields[__STAT_WRITE_TICKS] 326de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber * fields[__STAT_IO_TICKS]; 327de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber write_perf = ((unsigned long long)SECTOR_SIZE 328de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber * fields[__STAT_WRITE_SECTORS] 3292bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_IN_QUEUE] + (divisor >> 1)) 3302bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber / divisor; 3312bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber write_ios = ((unsigned long long)S_TO_MS * fields[__STAT_WRITE_IOS] 3322bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber * fields[__STAT_IN_QUEUE] + (divisor >> 1)) 333de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber / divisor; 3345ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block } 335de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber 336de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber unsigned queue = (fields[__STAT_IN_QUEUE] 337de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber + (fields[__STAT_IO_TICKS] >> 1)) 338de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber / fields[__STAT_IO_TICKS]; 33929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block 340de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber if (!write_perf && !write_ios) { 341de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber printf("%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", 342de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber path, read_perf, read_ios, queue); 343de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber } else { 344de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber printf("%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n", 345de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber path, read_perf, read_ios, write_perf, write_ios, queue); 346de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber } 347de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber 348de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber /* bugreport timeout factor adjustment */ 349de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber if ((write_perf > 1) && (write_perf < worst_write_perf)) { 350de9a20c274983d4f7a688acb68d5dfc6a432eb10Andreas Huber worst_write_perf = write_perf; 3512bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 3522bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 353df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block return 0; 354dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber} 3552bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3562bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber/* Copied policy from system/core/logd/LogBuffer.cpp */ 3572bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3582bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#define LOG_BUFFER_SIZE (256 * 1024) 3592bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) 3602bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) 361dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 36229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Blockstatic bool valid_size(unsigned long value) { 363dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { 364dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return false; 365dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 366dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 367dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber long pages = sysconf(_SC_PHYS_PAGES); 368dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if (pages < 1) { 369dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return true; 3705ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block } 371dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 372dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber long pagesize = sysconf(_SC_PAGESIZE); 3732bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (pagesize <= 1) { 3742bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber pagesize = PAGE_SIZE; 3752bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 376dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 377dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber // maximum memory impact a somewhat arbitrary ~3% 378dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber pages = (pages + 31) / 32; 379dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber unsigned long maximum = pages * pagesize; 380dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 381dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { 3822bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return true; 3832bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber } 3842bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3852bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return value <= maximum; 3862bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber} 3872bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3882bc940b4f961e588459c83862b2c6bea314a4027Andreas Huberstatic unsigned long property_get_size(const char *key) { 3892bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber unsigned long value; 3902bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber char *cp, property[PROPERTY_VALUE_MAX]; 3912bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 3922bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber property_get(key, property, ""); 3932bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber value = strtoul(property, &cp, 10); 3942bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber 395dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber switch(*cp) { 396dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber case 'm': 39729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block case 'M': 398dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber value *= 1024; 399dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber /* FALLTHRU */ 4002bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber case 'k': 4012bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber case 'K': 4022bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber value *= 1024; 4032bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber /* FALLTHRU */ 4042bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber case '\0': 4052bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber break; 406dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 407dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber default: 40829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block value = 0; 409dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 410dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 4112bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber if (!valid_size(value)) { 4123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block value = 0; 413dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 414dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 4152bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber return value; 4162bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber} 417ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 418ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson/* timeout in ms */ 419ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönssonstatic unsigned long logcat_timeout(const char *name) { 420ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson static const char global_tuneable[] = "persist.logd.size"; // Settings App 421ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson static const char global_default[] = "ro.logd.size"; // BoardConfig.mk 422ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson char key[PROP_NAME_MAX]; 423ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson unsigned long property_size, default_size; 424ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 425ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson default_size = property_get_size(global_tuneable); 426ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson if (!default_size) { 427ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson default_size = property_get_size(global_default); 428ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson } 429ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 430ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson snprintf(key, sizeof(key), "%s.%s", global_tuneable, name); 431ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson property_size = property_get_size(key); 432ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 433ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson if (!property_size) { 434ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson snprintf(key, sizeof(key), "%s.%s", global_default, name); 435ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson property_size = property_get_size(key); 436ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson } 437ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 438ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson if (!property_size) { 439ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson property_size = default_size; 440ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson } 441ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 442ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson if (!property_size) { 443ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson property_size = LOG_BUFFER_SIZE; 444ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson } 445ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 446ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson /* Engineering margin is ten-fold our guess */ 447ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson return 10 * (property_size + worst_write_perf) / worst_write_perf; 448ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson} 449ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/* End copy from system/core/logd/LogBuffer.cpp */ 451cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 452cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/* dumps the current system state to stdout */ 453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void print_header(std::string version) { 454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX]; 455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX]; 456cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char network[PROPERTY_VALUE_MAX], date[80]; 457df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block 4586e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber property_get("ro.build.display.id", build, "(unknown)"); 459cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber property_get("ro.build.fingerprint", fingerprint, "(unknown)"); 460cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber property_get("ro.build.type", build_type, "(unknown)"); 461cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber property_get("ro.baseband", radio, "(unknown)"); 462cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber property_get("ro.bootloader", bootloader, "(unknown)"); 463cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber property_get("gsm.operator.alpha", network, "(unknown)"); 464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now)); 465cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 466cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("========================================================\n"); 467cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("== dumpstate: %s\n", date); 4681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar printf("========================================================\n"); 469cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4700792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber printf("\n"); 4711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar printf("Build: %s\n", build); 472cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */ 473cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Bootloader: %s\n", bootloader); 474cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Radio: %s\n", radio); 475cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Network: %s\n", network); 476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 477cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Kernel: "); 478908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dump_file(NULL, "/proc/version"); 479908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("Command line: %s\n", strtok(cmdline_buf, "\n")); 4807aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("Bugreport format version: %s\n", version.c_str()); 4817aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("Dumpstate info: id=%lu pid=%d\n", id, getpid()); 4821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar printf("\n"); 4834579b7d49f6dd4f37e6043e59debfd72d69b8e7bAndreas Huber} 4847aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 4851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar/* adds a new entry to the existing zip file. */ 4867aef03379179c109c2547c33c410bfc93c8db576Andreas Huberstatic bool add_zip_entry_from_fd(const std::string& entry_name, int fd) { 487cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!zip_writer) { 488cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGD("Not adding zip entry %s from fd because zip_writer is not set\n", entry_name.c_str()); 489cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 490cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 491cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Logging statement below is useful to time how long each entry takes, but it's too verbose. 492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // MYLOGD("Adding zip entry %s\n", entry_name.c_str()); 493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(), 494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ZipWriter::kCompress, get_mtime(fd, now)); 495df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block if (err) { 4966e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MYLOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), 497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ZipWriter::ErrorCodeString(err)); 498cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber std::vector<uint8_t> buffer(65536); 502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (1) { 503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), sizeof(buffer))); 5044bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams if (bytes_read == 0) { 505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 506cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (bytes_read == -1) { 507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno)); 5084bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams return false; 5094bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams } 5104bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams err = zip_writer->WriteBytes(buffer.data(), bytes_read); 5114bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams if (err) { 5124bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams MYLOGE("zip_writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err)); 5134bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams return false; 5144bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams } 5154bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams } 5164bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams 5174bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams err = zip_writer->FinishEntry(); 5184bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams if (err) { 5194bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams MYLOGE("zip_writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err)); 5204bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams return false; 5214bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams } 522a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes 5234bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams return true; 5244bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams} 5254bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams 5264bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams/* adds a new entry to the existing zip file. */ 5274bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williamsstatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path) { 5281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); 5294bb026ba585d5b37795bd9765459f0607b7aa60aDavid Williams if (fd.get() == -1) { 530cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno)); 531cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 532cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 533e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 534e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber return add_zip_entry_from_fd(entry_name, fd.get()); 535d32b7b479fad359d7fe779a9c5b4c090cdc14b56Xuefei Chen} 536d32b7b479fad359d7fe779a9c5b4c090cdc14b56Xuefei Chen 537d32b7b479fad359d7fe779a9c5b4c090cdc14b56Xuefei Chen/* adds a file to the existing zipped bugreport */ 538e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huberstatic int _add_file_from_fd(const char *title, const char *path, int fd) { 539e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber return add_zip_entry_from_fd(ZIP_ROOT_DIR + path, fd) ? 0 : 1; 540cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 541e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 542e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber/* adds all files from a directory to the zipped bugreport file */ 543e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Hubervoid add_dir(const char *dir, bool recursive) { 544cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!zip_writer) { 5456f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGD("Not adding dir %s because zip_writer is not set\n", dir); 54629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block return; 5476f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber } 548cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber DurationReporter duration_reporter(dir, NULL); 5496f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber dump_files(NULL, dir, recursive ? skip_none : is_dir, _add_file_from_fd); 550e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber} 551e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 552e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber/* adds a text entry entry to the existing zip file. */ 5536f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huberstatic bool add_text_zip_entry(const std::string& entry_name, const std::string& content) { 5546f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber if (!zip_writer) { 5556f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGD("Not adding text zip entry %s because zip_writer is not set\n", entry_name.c_str()); 5566f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber return false; 5576f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber } 5586f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGD("Adding zip text entry %s\n", entry_name.c_str()); 559e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(), ZipWriter::kCompress, now); 560e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber if (err) { 561ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson MYLOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), 562ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson ZipWriter::ErrorCodeString(err)); 563dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return false; 564dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 565dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 566dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber err = zip_writer->WriteBytes(content.c_str(), content.length()); 567dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if (err) { 568dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber MYLOGE("zip_writer->WriteBytes(%s): %s\n", entry_name.c_str(), 5695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ZipWriter::ErrorCodeString(err)); 570dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return false; 571dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 572dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 573dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber err = zip_writer->FinishEntry(); 574dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber if (err) { 575dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber MYLOGE("zip_writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err)); 576dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return false; 577dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber } 578dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 579dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber return true; 580dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber} 581dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 58284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatic void dumpstate(const std::string& screenshot_path, const std::string& version) { 583b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher DurationReporter duration_reporter("DUMPSTATE"); 584f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber unsigned long timeout; 585f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber 586f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version"); 587f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber run_command("UPTIME", 10, "uptime", NULL); 588f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd); 5895ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd"); 590f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber dump_file("MEMORY INFO", "/proc/meminfo"); 591f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL); 592f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL); 593f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat"); 594f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber dump_file("VMALLOC INFO", "/proc/vmallocinfo"); 5956f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber dump_file("SLAB INFO", "/proc/slabinfo"); 596cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("ZONEINFO", "/proc/zoneinfo"); 597e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber dump_file("PAGETYPEINFO", "/proc/pagetypeinfo"); 598cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("BUDDYINFO", "/proc/buddyinfo"); 599e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); 6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar 601cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("KERNEL WAKELOCKS", "/proc/wakelocks"); 602cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources"); 603cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); 604cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("KERNEL SYNC", "/d/sync"); 605cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 60681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL); 60781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL); 60881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 60981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("ROUTE", 10, "route", NULL); 61081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("PRINTENV", 10, "printenv", NULL); 61181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("NETSTAT", 10, "netstat", NULL); 61281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("LSMOD", 10, "lsmod", NULL); 61381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 61481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé do_dmesg(); 61581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 61681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL); 61781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); 61881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); 61981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)"); 62081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 62181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (!screenshot_path.empty()) { 62281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé MYLOGI("taking late screenshot\n"); 62381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé take_screenshot(screenshot_path); 62481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé MYLOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 62581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 626ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson 627ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson // dump_file("EVENT LOG TAGS", "/etc/event-log-tags"); 62884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber // calculate timeout 629b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); 63081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (timeout < 20000) { 63181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé timeout = 20000; 63281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 63381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime", 63481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "-v", "printable", 63581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "-d", 63681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "*:v", NULL); 63781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé timeout = logcat_timeout("events"); 63881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (timeout < 20000) { 63981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé timeout = 20000; 64081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 64181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events", 64281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "-v", "threadtime", 64381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "-v", "printable", 64481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé "-d", 6451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar "*:v", NULL); 64681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé timeout = logcat_timeout("radio"); 64781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (timeout < 20000) { 64881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé timeout = 20000; 64981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 65081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio", 651cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "-v", "threadtime", 652cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "-v", "printable", 653cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "-d", 654cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "*:v", NULL); 655cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 65639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); 657cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 65839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); 65939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 66039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber /* show the traces we collected in main(), if that was done */ 661cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (dump_traces_path != NULL) { 662cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("VM TRACES JUST NOW", dump_traces_path); 663cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 664cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 6656d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar /* only show ANR traces if they're less than 15 minutes old */ 6666e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber struct stat st; 667cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char anr_traces_path[PATH_MAX]; 668e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber property_get("dalvik.vm.stack-trace-file", anr_traces_path, ""); 66939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (!anr_traces_path[0]) { 670cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n"); 671cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 672cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int fd = TEMP_FAILURE_RETRY(open(anr_traces_path, 673cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)); 674cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (fd < 0) { 675cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno)); 676e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber } else { 677e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd); 678e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber } 679e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber } 680e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 681cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber /* slow traces for slow operations */ 682cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (anr_traces_path[0] != 0) { 683908dbdee96856693decc04fa143c2ba525495d43Andreas Huber int tail = strlen(anr_traces_path)-1; 684908dbdee96856693decc04fa143c2ba525495d43Andreas Huber while (tail > 0 && anr_traces_path[tail] != '/') { 685908dbdee96856693decc04fa143c2ba525495d43Andreas Huber tail--; 686908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 687908dbdee96856693decc04fa143c2ba525495d43Andreas Huber int i = 0; 688908dbdee96856693decc04fa143c2ba525495d43Andreas Huber while (1) { 689908dbdee96856693decc04fa143c2ba525495d43Andreas Huber sprintf(anr_traces_path+tail+1, "slow%02d.txt", i); 690908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (stat(anr_traces_path, &st)) { 691908dbdee96856693decc04fa143c2ba525495d43Andreas Huber // No traces file at this index, done with the files. 692908dbdee96856693decc04fa143c2ba525495d43Andreas Huber break; 6935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block } 694908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dump_file("VM TRACES WHEN SLOW", anr_traces_path); 695908dbdee96856693decc04fa143c2ba525495d43Andreas Huber i++; 696908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 697908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 6985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block 699908dbdee96856693decc04fa143c2ba525495d43Andreas Huber int dumped = 0; 700908dbdee96856693decc04fa143c2ba525495d43Andreas Huber for (size_t i = 0; i < NUM_TOMBSTONES; i++) { 701908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (tombstone_data[i].fd != -1) { 702908dbdee96856693decc04fa143c2ba525495d43Andreas Huber const char *name = tombstone_data[i].name; 703908dbdee96856693decc04fa143c2ba525495d43Andreas Huber int fd = tombstone_data[i].fd; 704908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dumped = 1; 705908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (zip_writer) { 706df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block if (!add_zip_entry_from_fd(ZIP_ROOT_DIR + name, fd)) { 707908dbdee96856693decc04fa143c2ba525495d43Andreas Huber MYLOGE("Unable to add tombstone %s to zip file\n", name); 708908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 709908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } else { 710908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dump_file_from_fd("TOMBSTONE", name, fd); 711cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 712cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber close(fd); 713cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tombstone_data[i].fd = -1; 714cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 715cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 716cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!dumped) { 7171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR); 718e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber } 719cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 7202bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber dump_file("NETWORK DEV INFO", "/proc/net/dev"); 7212bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all"); 7222bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt"); 723b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl"); 724b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats"); 725b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund 726b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund if (!stat(PSTORE_LAST_KMSG, &st)) { 727b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */ 728b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund dump_file("LAST KMSG", PSTORE_LAST_KMSG); 729b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund } else { 730b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */ 731b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund dump_file("LAST KMSG", "/proc/last_kmsg"); 732b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund } 733b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund 7342bc940b4f961e588459c83862b2c6bea314a4027Andreas Huber /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */ 735b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund run_command("LAST LOGCAT", 10, "logcat", "-L", 736b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund "-b", "all", 737b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund "-v", "threadtime", 738b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund "-v", "printable", 739cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "-d", 740b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund "*:v", NULL); 741b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund 742b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */ 743b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund 744e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("NETWORK INTERFACES", 10, "ip", "link", NULL); 745e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 746e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL); 747e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL); 748e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 749e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IP RULES", 10, "ip", "rule", "show", NULL); 750a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL); 751a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma 752a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma dump_route_tables(); 7535908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker 754a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); 7555908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); 756a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma 757a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); 758e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); 759e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); 760e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber /* no ip6 nat */ 761e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL); 762e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL); 763e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 764cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("WIFI NETWORKS", 20, 765cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); 76639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 767b6f7642496f955da04d1eb9e33df0dab653c9c4eHenrik Backlund#ifdef FWDUMP_bcmdhd 76839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber run_command("ND OFFLOAD TABLE", 5, 76939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber SU_PATH, "root", "wlutil", "nd_hostip", NULL); 770908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 771908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, 772908dbdee96856693decc04fa143c2ba525495d43Andreas Huber SU_PATH, "root", "wlutil", "counters", NULL); 773cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 774b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher run_command("ND OFFLOAD STATUS (1)", 5, 775cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SU_PATH, "root", "wlutil", "nd_status", NULL); 776cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 777cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 778cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("INTERRUPTS (1)", "/proc/interrupts"); 779cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 780cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); 781cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 782cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#ifdef FWDUMP_bcmdhd 7831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar run_command("DUMP WIFI STATUS", 20, 784cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); 785cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 7861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, 787cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SU_PATH, "root", "wlutil", "counters", NULL); 788cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 789cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("ND OFFLOAD STATUS (2)", 5, 790cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SU_PATH, "root", "wlutil", "nd_status", NULL); 791cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 792cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("INTERRUPTS (2)", "/proc/interrupts"); 793cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 794cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber print_properties(); 795cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 796cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("VOLD DUMP", 10, "vdc", "dump", NULL); 797df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL); 7986e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 799cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL); 800cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 801cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL); 802cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 803cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("------ BACKLIGHTS ------\n"); 804cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("LCD brightness="); 805cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); 8066f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber printf("Button brightness="); 8076f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber dump_file(NULL, "/sys/class/leds/button-backlight/brightness"); 8086f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber printf("Keyboard brightness="); 8096f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness"); 810cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("ALS mode="); 8111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar dump_file(NULL, "/sys/class/leds/lcd-backlight/als"); 8121a37ee3c877165c812734b405f922f6e0d747052joakim johansson printf("LCD driver registers:\n"); 8131a37ee3c877165c812734b405f922f6e0d747052joakim johansson dump_file(NULL, "/sys/class/leds/lcd-backlight/registers"); 8146f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber printf("\n"); 8156f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber 8166f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber /* Binder state is expensive to look at as it uses a lot of memory. */ 8178d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); 8186f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); 8191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); 820cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats"); 821cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber dump_file("BINDER STATE", "/sys/kernel/debug/binder/state"); 822cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 823cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("========================================================\n"); 824cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("== Board\n"); 825cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("========================================================\n"); 826908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 827908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dumpstate_board(); 828908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("\n"); 829908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 830908dbdee96856693decc04fa143c2ba525495d43Andreas Huber /* Migrate the ril_dumpstate to a dumpstate_board()? */ 831908dbdee96856693decc04fa143c2ba525495d43Andreas Huber char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0}; 832908dbdee96856693decc04fa143c2ba525495d43Andreas Huber property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30"); 833908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) { 834908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) { 835908dbdee96856693decc04fa143c2ba525495d43Andreas Huber // su does not exist on user builds, so try running without it. 836908dbdee96856693decc04fa143c2ba525495d43Andreas Huber // This way any implementations of vril-dump that do not require 837908dbdee96856693decc04fa143c2ba525495d43Andreas Huber // root can run on user builds. 838908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 839908dbdee96856693decc04fa143c2ba525495d43Andreas Huber "vril-dump", NULL); 840908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } else { 841908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout), 842908dbdee96856693decc04fa143c2ba525495d43Andreas Huber SU_PATH, "root", "vril-dump", NULL); 843908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 844908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 8451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar 846908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("========================================================\n"); 847908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("== Android Framework Services\n"); 848908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("========================================================\n"); 849908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 850908dbdee96856693decc04fa143c2ba525495d43Andreas Huber /* the full dumpsys is starting to take a long time, so we need 851908dbdee96856693decc04fa143c2ba525495d43Andreas Huber to increase its timeout. we really need to do the timeouts in 852908dbdee96856693decc04fa143c2ba525495d43Andreas Huber dumpsys itself... */ 853908dbdee96856693decc04fa143c2ba525495d43Andreas Huber if (version == VERSION_DUMPSYS_SPLIT) { 854908dbdee96856693decc04fa143c2ba525495d43Andreas Huber // Skipping meminfo and cpuinfo services. 855908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("DUMPSYS", 60, "dumpsys", "--skip", "meminfo,cpuinfo", NULL); 856df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block } else { 857908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("DUMPSYS", 60, "dumpsys", NULL); 858908dbdee96856693decc04fa143c2ba525495d43Andreas Huber } 859908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 860908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("========================================================\n"); 861908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("== Checkins\n"); 862908dbdee96856693decc04fa143c2ba525495d43Andreas Huber printf("========================================================\n"); 863908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 864908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL); 865908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL); 866908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL); 867908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL); 868908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL); 869908dbdee96856693decc04fa143c2ba525495d43Andreas Huber run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL); 870908dbdee96856693decc04fa143c2ba525495d43Andreas Huber 871cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("========================================================\n"); 872cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("== Running Application Activities\n"); 873cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("========================================================\n"); 8747aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 8757aef03379179c109c2547c33c410bfc93c8db576Andreas Huber run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL); 8762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber printf("========================================================\n"); 8782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber printf("== Running Application Services\n"); 8797aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("========================================================\n"); 8807aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 8817aef03379179c109c2547c33c410bfc93c8db576Andreas Huber run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL); 8827aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 883a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma printf("========================================================\n"); 884a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma printf("== Running Application Providers\n"); 885a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma printf("========================================================\n"); 8865908f88a7e45380a9b0d71a3b1ea535d76c420b3Chad Brubaker 887a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL); 88859d3f809024ae5b5a7ea35dcfdd056f1c7ca42b2Chad Brubaker 889a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma 890a23456b306f35b9ecf973bf5818ca39295e9e029Ashish Sharma printf("========================================================\n"); 8917aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("== Final progress (pid %d): %d/%d (originally %d)\n", 8927aef03379179c109c2547c33c410bfc93c8db576Andreas Huber getpid(), progress, weight_total, WEIGHT_TOTAL); 8937aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("========================================================\n"); 894cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("== dumpstate: done\n"); 8957aef03379179c109c2547c33c410bfc93c8db576Andreas Huber printf("========================================================\n"); 896e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber} 897e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 898e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huberstatic void usage() { 8997e73e44c2d2208a7079e562f7b0b9b73ef6a29f1Andreas Huber fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q] [-B] [-P] [-R] [-V version]\n" 900100a4408968b90e314526185d572c72ea4cc784aAndreas Huber " -b: play sound file instead of vibrate, at beginning of job\n" 901100a4408968b90e314526185d572c72ea4cc784aAndreas Huber " -e: play sound file instead of vibrate, at end of job\n" 902e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber " -o: write to file (instead of stdout)\n" 903e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber " -d: append date to filename (requires -o)\n" 904f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber " -p: capture screenshot to filename.png (requires -o)\n" 90546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson " -z: generates zipped file (requires -o)\n" 906ec29a2bfb5364a5968b77559fd13821b827d173aRoger Jönsson " -s: write output to control socket (for init)\n" 907cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " -q: disable vibrate\n" 9081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar " -B: send broadcast when finished (requires -o)\n" 909cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " -P: send broadcast when started and update system properties on progress (requires -o and -B)\n" 9107aef03379179c109c2547c33c410bfc93c8db576Andreas Huber " -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n" 9117aef03379179c109c2547c33c410bfc93c8db576Andreas Huber " -V: sets the bugreport format version (%s or %s)\n", 9127aef03379179c109c2547c33c410bfc93c8db576Andreas Huber VERSION_DEFAULT.c_str(), VERSION_DUMPSYS_SPLIT.c_str()); 9137aef03379179c109c2547c33c410bfc93c8db576Andreas Huber} 9147aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 915cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void sigpipe_handler(int n) { 916cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // don't complain to stderr or stdout 917cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber _exit(EXIT_FAILURE); 918cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 919cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 920cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the 921cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber temporary file. 922cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */ 923cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic bool finish_zip_file(const std::string& bugreport_name, const std::string& bugreport_path, 924cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber time_t now) { 925cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!add_zip_entry(bugreport_name, bugreport_path)) { 926cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("Failed to add text entry to .zip file\n"); 927cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 928cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 929cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (!add_text_zip_entry("main_entry.txt", bugreport_name)) { 930cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("Failed to add main_entry.txt to .zip file\n"); 931cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return false; 932cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 933cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 934cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t err = zip_writer->Finish(); 935cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (err) { 936cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("zip_writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err)); 937df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block return false; 9386e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber } 939cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 9401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar return true; 9417aef03379179c109c2547c33c410bfc93c8db576Andreas Huber} 9427aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 9437aef03379179c109c2547c33c410bfc93c8db576Andreas Huberstatic std::string SHA256_file_hash(std::string filepath) { 9447aef03379179c109c2547c33c410bfc93c8db576Andreas Huber ScopedFd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC 9457aef03379179c109c2547c33c410bfc93c8db576Andreas Huber | O_NOFOLLOW))); 9467aef03379179c109c2547c33c410bfc93c8db576Andreas Huber if (fd.get() == -1) { 947cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber MYLOGE("open(%s): %s\n", filepath.c_str(), strerror(errno)); 948cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return NULL; 949cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 950cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 951cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SHA256_CTX ctx; 952cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber SHA256_init(&ctx); 9532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 9542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber std::vector<uint8_t> buffer(65536); 9552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber while (1) { 9562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size())); 957cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bytes_read == 0) { 958cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 959cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else if (bytes_read == -1) { 9608d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber MYLOGE("read(%s): %s\n", filepath.c_str(), strerror(errno)); 9618d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return NULL; 962a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber } 963a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber 964a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber SHA256_update(&ctx, buffer.data(), bytes_read); 965a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber } 966a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber 967a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber uint8_t hash[SHA256_DIGEST_SIZE]; 968a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE); 9698d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1]; 97091f230461288a2a5091182ef9e17079aabf8ebaaAndreas Huber for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++) { 971df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block sprintf(hash_buffer + (i * 2), "%02x", hash[i]); 9721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar } 9738d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber hash_buffer[sizeof(hash_buffer) - 1] = 0; 974f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber return std::string(hash_buffer); 975df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block} 976f0c86a83c687074be79397e082e3775ca56641b1Andreas Huber 9778d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber/* switch to non-root user and group */ 9788d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huberbool drop_root() { 9798d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber /* ensure we will keep capabilities when we drop root */ 980e56121bc4cb29c91d736eab181b1f51c4f125e78Andreas Huber if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 9818d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber MYLOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 9828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber return false; 9838d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 984cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 985cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, 986641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; 987641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { 988641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); 989641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih return false; 990641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 991100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (setgid(AID_SHELL) != 0) { 992100a4408968b90e314526185d572c72ea4cc784aAndreas Huber MYLOGE("Unable to setgid, aborting: %s\n", strerror(errno)); 993100a4408968b90e314526185d572c72ea4cc784aAndreas Huber return false; 994100a4408968b90e314526185d572c72ea4cc784aAndreas Huber } 995100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (setuid(AID_SHELL) != 0) { 996100a4408968b90e314526185d572c72ea4cc784aAndreas Huber MYLOGE("Unable to setuid, aborting: %s\n", strerror(errno)); 997100a4408968b90e314526185d572c72ea4cc784aAndreas Huber return false; 998100a4408968b90e314526185d572c72ea4cc784aAndreas Huber } 999100a4408968b90e314526185d572c72ea4cc784aAndreas Huber 1000100a4408968b90e314526185d572c72ea4cc784aAndreas Huber struct __user_cap_header_struct capheader; 1001100a4408968b90e314526185d572c72ea4cc784aAndreas Huber struct __user_cap_data_struct capdata[2]; 1002100a4408968b90e314526185d572c72ea4cc784aAndreas Huber memset(&capheader, 0, sizeof(capheader)); 1003100a4408968b90e314526185d572c72ea4cc784aAndreas Huber memset(&capdata, 0, sizeof(capdata)); 1004100a4408968b90e314526185d572c72ea4cc784aAndreas Huber capheader.version = _LINUX_CAPABILITY_VERSION_3; 1005f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber capheader.pid = 0; 1006f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber 1007e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); 1008e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); 1009e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber capdata[0].inheritable = 0; 1010e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber capdata[1].inheritable = 0; 1011f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber 1012f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber if (capset(&capheader, &capdata[0]) < 0) { 1013f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber MYLOGE("capset failed: %s\n", strerror(errno)); 1014f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber return false; 1015f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber } 10168d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 1017a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber return true; 10188d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber} 1019cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1020cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberint main(int argc, char *argv[]) { 1021cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct sigaction sigact; 10227aef03379179c109c2547c33c410bfc93c8db576Andreas Huber int do_add_date = 0; 10233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block int do_zip_file = 0; 10247aef03379179c109c2547c33c410bfc93c8db576Andreas Huber int do_vibrate = 1; 10257aef03379179c109c2547c33c410bfc93c8db576Andreas Huber char* use_outfile = 0; 10267aef03379179c109c2547c33c410bfc93c8db576Andreas Huber int use_socket = 0; 10278d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber int do_fb = 0; 10288d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber int do_broadcast = 0; 1029ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber int do_early_screenshot = 0; 1030ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber int is_remote_mode = 0; 10316d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar std::string version = VERSION_DEFAULT; 10321a37ee3c877165c812734b405f922f6e0d747052joakim johansson 10331a37ee3c877165c812734b405f922f6e0d747052joakim johansson now = time(NULL); 10341a37ee3c877165c812734b405f922f6e0d747052joakim johansson 10351a37ee3c877165c812734b405f922f6e0d747052joakim johansson if (getuid() != 0) { 10361a37ee3c877165c812734b405f922f6e0d747052joakim johansson // Old versions of the adb client would call the 10371a37ee3c877165c812734b405f922f6e0d747052joakim johansson // dumpstate command directly. Newer clients 10381a37ee3c877165c812734b405f922f6e0d747052joakim johansson // call /system/bin/bugreport instead. If we detect 10391a37ee3c877165c812734b405f922f6e0d747052joakim johansson // we're being called incorrectly, then exec the 10401a37ee3c877165c812734b405f922f6e0d747052joakim johansson // correct program. 10411a37ee3c877165c812734b405f922f6e0d747052joakim johansson return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL); 1042ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber } 1043ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber 1044ef7af7fec702db2fde72b16dedf9064585e6db77Andreas Huber MYLOGI("begin\n"); 10452d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber 10462d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber /* gets the sequential id */ 1047cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber char last_id[PROPERTY_VALUE_MAX]; 10488d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber property_get("dumpstate.last_id", last_id, "0"); 10498d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber id = strtoul(last_id, NULL, 10) + 1; 10506f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber sprintf(last_id, "%lu", id); 10513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block property_set("dumpstate.last_id", last_id); 10526f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGI("dumpstate id: %lu\n", id); 10536f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber 10546f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber /* clear SIGPIPE handler */ 10550aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia memset(&sigact, 0, sizeof(sigact)); 1056f30460b886b233033ffd30c71614bedc24bed79eWei Jia sigact.sa_handler = sigpipe_handler; 1057f30460b886b233033ffd30c71614bedc24bed79eWei Jia sigaction(SIGPIPE, &sigact, NULL); 1058f30460b886b233033ffd30c71614bedc24bed79eWei Jia 10590aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia /* set as high priority, and protect from OOM killer */ 1060f30460b886b233033ffd30c71614bedc24bed79eWei Jia setpriority(PRIO_PROCESS, 0, -20); 1061f30460b886b233033ffd30c71614bedc24bed79eWei Jia FILE *oom_adj = fopen("/proc/self/oom_adj", "we"); 1062f30460b886b233033ffd30c71614bedc24bed79eWei Jia if (oom_adj) { 1063f30460b886b233033ffd30c71614bedc24bed79eWei Jia fputs("-17", oom_adj); 1064f30460b886b233033ffd30c71614bedc24bed79eWei Jia fclose(oom_adj); 1065f30460b886b233033ffd30c71614bedc24bed79eWei Jia } 1066f30460b886b233033ffd30c71614bedc24bed79eWei Jia 1067f30460b886b233033ffd30c71614bedc24bed79eWei Jia /* parse arguments */ 1068f30460b886b233033ffd30c71614bedc24bed79eWei Jia int c; 1069f30460b886b233033ffd30c71614bedc24bed79eWei Jia while ((c = getopt(argc, argv, "dho:svqzpPBRV:")) != -1) { 1070f30460b886b233033ffd30c71614bedc24bed79eWei Jia switch (c) { 1071f30460b886b233033ffd30c71614bedc24bed79eWei Jia case 'd': do_add_date = 1; break; 1072f30460b886b233033ffd30c71614bedc24bed79eWei Jia case 'z': do_zip_file = 1; break; 1073f30460b886b233033ffd30c71614bedc24bed79eWei Jia case 'o': use_outfile = optarg; break; 10740aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 's': use_socket = 1; break; 10750aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'v': break; // compatibility no-op 10760aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'q': do_vibrate = 0; break; 10770aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'p': do_fb = 1; break; 10780aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'P': do_update_progress = 1; break; 10790aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'R': is_remote_mode = 1; break; 10800aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'B': do_broadcast = 1; break; 10810aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia case 'V': version = optarg; break; 10828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber case '?': printf("\n"); 10833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block case 'h': 10846e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber usage(); 10858d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber exit(1); 10868d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 10878d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 1088100a4408968b90e314526185d572c72ea4cc784aAndreas Huber 1089cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) { 1090cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber usage(); 1091cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber exit(1); 109246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 109346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 10940955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson if (do_update_progress && !do_broadcast) { 10950955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson usage(); 10960955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson exit(1); 10970955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson } 10980955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson 10990955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson if (is_remote_mode && (do_update_progress || !do_broadcast || !do_zip_file || !do_add_date)) { 11000955986e6c1c27ba752e293246086ea79c49d39cRoger Jönsson usage(); 110146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson exit(1); 110246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 110346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 110446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (version != VERSION_DEFAULT && version != VERSION_DUMPSYS_SPLIT) { 1105641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih usage(); 1106641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih exit(1); 1107641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 1108641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 1109641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih MYLOGI("bugreport format version: %s\n", version.c_str()); 1110641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 111146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson do_early_screenshot = do_update_progress; 111246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 111346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson // If we are going to use a socket, do it as early as possible 111446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson // to avoid timeouts from bugreport. 111546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (use_socket) { 1116b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher redirect_to_socket(stdout, "dumpstate"); 111746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 111846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 111946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* full path of the directory where the bugreport files will be written */ 112046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string bugreport_dir; 112146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 112246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* full path of the temporary file containing the bugreport */ 112346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string tmp_path; 112446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 11251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar /* full path of the file containing the dumpstate logs*/ 112646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string log_path; 112746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 112846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* full path of the temporary file containing the screenshot (when requested) */ 112946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string screenshot_path; 113046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 113146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* base name (without suffix or extensions) of the bugreport files */ 113246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string base_name; 113346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 11341a37ee3c877165c812734b405f922f6e0d747052joakim johansson /* suffix of the bugreport files - it's typically the date (when invoked with -d), 113546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson * although it could be changed by the user using a system property */ 113646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string suffix; 113746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 113846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* pointer to the actual path, be it zip or text */ 113946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string path; 114046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 114146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* pointer to the zipped file */ 114246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose); 114346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 114446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* redirect output if needed */ 114546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson bool is_redirecting = !use_socket && use_outfile; 114646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 114746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (is_redirecting) { 114846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson bugreport_dir = dirname(use_outfile); 114946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson base_name = basename(use_outfile); 115046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (do_add_date) { 115146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson char date[80]; 115246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now)); 1153b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher suffix = date; 115446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } else { 115546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson suffix = "undated"; 115646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 115746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (do_fb) { 115846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson // TODO: if dumpstate was an object, the paths could be internal variables and then 115946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson // we could have a function to calculate the derived values, such as: 116046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson // screenshot_path = GetPath(".png"); 116146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 11621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar } 116346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp"; 116446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson log_path = bugreport_dir + "/dumpstate_log-" + suffix + "-" 116546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson + std::to_string(getpid()) + ".txt"; 116646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 116746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson MYLOGD("Bugreport dir: %s\n" 116846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson "Base name: %s\n" 116946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson "Suffix: %s\n" 117046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson "Log path: %s\n" 117146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson "Temporary path: %s\n" 11729955f00adf5c947c0af39db1c038778e13975ffbWei Jia "Screenshot path: %s\n", 117346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(), 117446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson log_path.c_str(), tmp_path.c_str(), screenshot_path.c_str()); 117546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 11764ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia if (do_zip_file) { 117746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson MYLOGD("Creating initial .zip file\n"); 117846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip"; 117946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson create_parent_dirs(path.c_str()); 118046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson zip_file.reset(fopen(path.c_str(), "wb")); 118146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (!zip_file) { 118246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson MYLOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno)); 118346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson do_zip_file = 0; 118446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } else { 118546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson zip_writer.reset(new ZipWriter(zip_file.get())); 118646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 118746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson add_text_zip_entry("version.txt", version); 118846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 11891a37ee3c877165c812734b405f922f6e0d747052joakim johansson 11901a37ee3c877165c812734b405f922f6e0d747052joakim johansson if (do_update_progress) { 11911a37ee3c877165c812734b405f922f6e0d747052joakim johansson std::vector<std::string> am_args = { 11921d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar "--receiver-permission", "android.permission.DUMP", "--receiver-foreground", 11931a37ee3c877165c812734b405f922f6e0d747052joakim johansson "--es", "android.intent.extra.NAME", suffix, 11941a37ee3c877165c812734b405f922f6e0d747052joakim johansson "--ei", "android.intent.extra.ID", std::to_string(id), 11951a37ee3c877165c812734b405f922f6e0d747052joakim johansson "--ei", "android.intent.extra.PID", std::to_string(getpid()), 119646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL), 119746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson }; 119846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args); 119946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 120046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 12011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar 120246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson /* read /proc/cmdline before dropping root */ 120346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson FILE *cmdline = fopen("/proc/cmdline", "re"); 120446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (cmdline) { 120546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson fgets(cmdline_buf, sizeof(cmdline_buf), cmdline); 120646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson fclose(cmdline); 120746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 1208cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber 1209cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber /* open the vibrator before dropping root */ 12100dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose); 12115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block if (do_vibrate) { 12122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we")); 12132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (vibrator) { 12142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber vibrate(vibrator.get(), 150); 12152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1216cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1217cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber 1218cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (do_fb && do_early_screenshot) { 1219cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (screenshot_path.empty()) { 1220cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber // should not have happened 1221cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGE("INTERNAL ERROR: skipping early screenshot because path was not set\n"); 1222cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } else { 1223cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGI("taking early screenshot\n"); 1224a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber take_screenshot(screenshot_path); 1225a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber MYLOGI("wrote screenshot: %s\n", screenshot_path.c_str()); 1226a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) { 1227a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber MYLOGE("Unable to change ownership of screenshot file %s: %s\n", 1228a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber screenshot_path.c_str(), strerror(errno)); 12298d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 123046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 123146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 123246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson 123346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (do_zip_file) { 123446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (chown(path.c_str(), AID_SHELL, AID_SHELL)) { 123546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson MYLOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno)); 123646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 123746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 1238cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber 1239b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher if (is_redirecting) { 1240cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber redirect_to_file(stderr, const_cast<char*>(log_path.c_str())); 1241cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (chown(log_path.c_str(), AID_SHELL, AID_SHELL)) { 1242cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", 1243cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber log_path.c_str(), strerror(errno)); 1244cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1245cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber /* TODO: rather than generating a text file now and zipping it later, 1246cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber it would be more efficient to redirect stdout to the zip entry 1247cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber directly, but the libziparchive doesn't support that option yet. */ 1248cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str())); 1249cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (chown(tmp_path.c_str(), AID_SHELL, AID_SHELL)) { 1250cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n", 1251cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber tmp_path.c_str(), strerror(errno)); 12528d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 1253cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 12548d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber // NOTE: there should be no stdout output until now, otherwise it would break the header. 12558d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih // In particular, DurationReport objects should be created passing 'title, NULL', so their 12568d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih // duration is logged into MYLOG instead. 12578d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih print_header(version); 12588d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 12598d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih if (version == VERSION_DUMPSYS_SPLIT) { 12608d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih // Invoking the following dumpsys calls before dump_traces() to try and 12618d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih // keep the system stats as close to its initial state as possible. 12628d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih run_command("DUMPSYS MEMINFO", 30, SU_PATH, "shell", "dumpsys", "meminfo", "-a", NULL); 12638d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih run_command("DUMPSYS CPUINFO", 30, SU_PATH, "shell", "dumpsys", "cpuinfo", "-a", NULL); 12648d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 12658d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 12668d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* collect stack traces from Dalvik and native processes (needs root) */ 12678d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih dump_traces_path = dump_traces(); 12688d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 12698d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */ 12708d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih get_tombstone_fds(tombstone_data); 12718d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih add_dir(RECOVERY_DIR, true); 12728d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber add_mountinfo(); 1273100a4408968b90e314526185d572c72ea4cc784aAndreas Huber 1274100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (!drop_root()) { 12752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return -1; 12761a37ee3c877165c812734b405f922f6e0d747052joakim johansson } 12772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1278100a4408968b90e314526185d572c72ea4cc784aAndreas Huber dumpstate(do_early_screenshot ? "": screenshot_path, version); 1279100a4408968b90e314526185d572c72ea4cc784aAndreas Huber 12808d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber /* done */ 12818d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (vibrator) { 12827e73e44c2d2208a7079e562f7b0b9b73ef6a29f1Andreas Huber for (int i = 0; i < 3; i++) { 1283100a4408968b90e314526185d572c72ea4cc784aAndreas Huber vibrate(vibrator.get(), 75); 1284100a4408968b90e314526185d572c72ea4cc784aAndreas Huber usleep((75 + 50) * 1000); 12851a37ee3c877165c812734b405f922f6e0d747052joakim johansson } 12861a37ee3c877165c812734b405f922f6e0d747052joakim johansson } 12871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar 12881a37ee3c877165c812734b405f922f6e0d747052joakim johansson /* close output if needed */ 12891a37ee3c877165c812734b405f922f6e0d747052joakim johansson if (is_redirecting) { 12901a37ee3c877165c812734b405f922f6e0d747052joakim johansson fclose(stdout); 12911a37ee3c877165c812734b405f922f6e0d747052joakim johansson fclose(stderr); 1292cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1293cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber 1294cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber /* rename or zip the (now complete) .tmp file to its final location */ 1295cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (use_outfile) { 1296b6ec588faa7728ff3b518bf809ff75e8dd14f08cMåns Zigher 1297cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber /* check if user changed the suffix using system properties */ 1298cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber char key[PROPERTY_KEY_MAX]; 1299cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber char value[PROPERTY_VALUE_MAX]; 1300cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber sprintf(key, "dumpstate.%d.name", getpid()); 1301cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber property_get(key, value, ""); 1302cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber bool change_suffix= false; 1303cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (value[0]) { 1304a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes /* must whitelist which characters are allowed, otherwise it could cross directories */ 1305cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber std::regex valid_regex("^[-_a-zA-Z0-9]+$"); 1306cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (std::regex_match(value, valid_regex)) { 1307cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber change_suffix = true; 1308cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } else { 13091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar MYLOGE("invalid suffix provided by user: %s\n", value); 1310cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1311cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1312cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (change_suffix) { 1313cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGI("changing suffix from %s to %s\n", suffix.c_str(), value); 1314cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber suffix = value; 1315cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber if (!screenshot_path.empty()) { 131646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson std::string new_screenshot_path = 131746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson bugreport_dir + "/" + base_name + "-" + suffix + ".png"; 131846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) { 131946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson MYLOGE("rename(%s, %s): %s\n", screenshot_path.c_str(), 1320cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber new_screenshot_path.c_str(), strerror(errno)); 1321cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } else { 1322cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber screenshot_path = new_screenshot_path; 13238d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber } 13249955f00adf5c947c0af39db1c038778e13975ffbWei Jia } 13256e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber } 13268d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber 1327a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber bool do_text_file = true; 13284ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia if (do_zip_file) { 1329a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber MYLOGD("Adding text entry to .zip bugreport\n"); 1330a9d9dd2425c32f6868c35f49a3e8f29aafba931aAndreas Huber if (!finish_zip_file(base_name + "-" + suffix + ".txt", tmp_path, now)) { 13316f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGE("Failed to finish zip file; sending text bugreport instead\n"); 13326f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber do_text_file = true; 13336f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber } else { 13346f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber do_text_file = false; 13356f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber } 1336cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 13376f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber if (do_text_file) { 13386f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber MYLOGD("Generating .txt bugreport\n"); 13396f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt"; 13406f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber if (rename(tmp_path.c_str(), path.c_str())) { 1341cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno)); 13421a37ee3c877165c812734b405f922f6e0d747052joakim johansson path.clear(); 13431a37ee3c877165c812734b405f922f6e0d747052joakim johansson } 13441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar } 13451a37ee3c877165c812734b405f922f6e0d747052joakim johansson } 13461a37ee3c877165c812734b405f922f6e0d747052joakim johansson 13471a37ee3c877165c812734b405f922f6e0d747052joakim johansson /* tell activity manager we're done */ 13481a37ee3c877165c812734b405f922f6e0d747052joakim johansson if (do_broadcast) { 1349100a4408968b90e314526185d572c72ea4cc784aAndreas Huber if (!path.empty()) { 1350100a4408968b90e314526185d572c72ea4cc784aAndreas Huber MYLOGI("Final bugreport path: %s\n", path.c_str()); 1351100a4408968b90e314526185d572c72ea4cc784aAndreas Huber std::vector<std::string> am_args = { 13523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block "--receiver-permission", "android.permission.DUMP", "--receiver-foreground", 1353100a4408968b90e314526185d572c72ea4cc784aAndreas Huber "--ei", "android.intent.extra.ID", std::to_string(id), 1354df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block "--ei", "android.intent.extra.PID", std::to_string(getpid()), 13556f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber "--ei", "android.intent.extra.MAX", std::to_string(weight_total), 13566f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber "--es", "android.intent.extra.BUGREPORT", path, 1357cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber "--es", "android.intent.extra.DUMPSTATE_LOG", log_path 13586f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber }; 135929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block if (do_fb) { 13601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar am_args.push_back("--es"); 13616f85dba3768089679ff5e35ad2f1841918d0adb2Andreas Huber am_args.push_back("android.intent.extra.SCREENSHOT"); 13628d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber am_args.push_back(screenshot_path); 136346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson } 13648d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber if (is_remote_mode) { 13650dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber am_args.push_back("--es"); 13660aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH"); 13670aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia am_args.push_back(SHA256_file_hash(path)); 13680aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args); 13690aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia } else { 13700aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args); 13710aeffde14aceec3272dcbd3d835d4a8663e8b745Wei Jia } 13722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } else { 13732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber MYLOGE("Skipping finished broadcast because bugreport could not be generated\n"); 13742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1375cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber } 1376cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber 1377cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber MYLOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL); 13780792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber MYLOGI("done\n"); 13790792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 13802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber return 0; 13812d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber} 13820792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber