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