dumpstate.cpp revision 43fd1bbc6675430a4ecfde07e88a414ed5c41c0c
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/*
2f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Copyright (C) 2008 The Android Open Source Project
3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
4f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * you may not use this file except in compliance with the License.
6f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * You may obtain a copy of the License at
7f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
8f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
10f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Unless required by applicable law or agreed to in writing, software
11f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * See the License for the specific language governing permissions and
14f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * limitations under the License.
15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */
16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
172db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg#include <dirent.h>
18f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <errno.h>
19f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <fcntl.h>
20ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme#include <libgen.h>
21f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <limits.h>
226e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include <memory>
23ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme#include <regex>
24635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme#include <set>
258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#include <stdbool.h>
26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h>
27f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdlib.h>
286e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include <string>
29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h>
307dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/capability.h>
317dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/prctl.h>
32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/resource.h>
33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/stat.h>
34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h>
35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/wait.h>
36f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <unistd.h>
37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
389dc117c415d0df0a3acd900709d05deabe975704Elliott Hughes#include <android-base/stringprintf.h>
39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <cutils/properties.h>
40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
41f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "private/android_filesystem_config.h"
42f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
43f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#define LOG_TAG "dumpstate"
44656a6b9e3645bfe2cf073b69cbb9d02832f62c26Alex Ray#include <cutils/log.h>
45f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
46f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "dumpstate.h"
476e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ScopedFd.h"
486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme#include "ziparchive/zip_writer.h"
496e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
504db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski#include "mincrypt/sha256.h"
514db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
526e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Lemeusing android::base::StringPrintf;
53f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
54f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* read before root is shed */
55f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char cmdline_buf[16384] = "(unknown)";
56f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic const char *dump_traces_path = NULL;
57f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
58e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme// TODO: should be part of dumpstate object
5978f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic char build_type[PROPERTY_VALUE_MAX];
60e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic time_t now;
61e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic std::unique_ptr<ZipWriter> zip_writer;
62635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemestatic std::set<std::string> mount_points;
63635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo();
64635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemestatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path);
6578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme
662a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
672a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor
688d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati#define RAFT_DIR "/data/misc/raft/"
69e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme#define RECOVERY_DIR "/cache/recovery"
707dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_DIR "/data/tombstones"
717dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_"
727dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris/* Can accomodate a tombstone number up to 9999. */
737dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4)
747dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#define NUM_TOMBSTONES  10
757dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
767dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferristypedef struct {
777dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris  char name[TOMBSTONE_MAX_LEN];
787dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris  int fd;
797dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris} tombstone_data_t;
807dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
817dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES];
827dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
83e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme// Root dir for all files copied as-is into the bugreport
84e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemeconst std::string& ZIP_ROOT_DIR = "FS";
85e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
86e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* gets the tombstone data, according to the bugreport type: if zipped gets all tombstones,
87e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme * otherwise gets just those modified in the last half an hour. */
887dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferrisstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) {
89e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    time_t thirty_minutes_ago = now - 60*30;
907dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
917dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
9254bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris        int fd = TEMP_FAILURE_RETRY(open(data[i].name,
9354bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris                                         O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
947dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        struct stat st;
957dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
96e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            (zip_writer || (time_t) st.st_mtime >= thirty_minutes_ago)) {
97e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        data[i].fd = fd;
987dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        } else {
99e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        close(fd);
1007dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris            data[i].fd = -1;
1017dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        }
1027dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    }
1037dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris}
1047dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
105635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme// for_each_pid() callback to get mount info about a process.
106635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid do_mountinfo(int pid, const char *name) {
107635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    char path[PATH_MAX];
108635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
109635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    // Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points
110635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    // are added.
111635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    sprintf(path, "/proc/%d/ns/mnt", pid);
112635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    char linkname[PATH_MAX];
113635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    ssize_t r = readlink(path, linkname, PATH_MAX);
114635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    if (r == -1) {
115635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        ALOGE("Unable to read link for %s: %s\n", path, strerror(errno));
116635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        return;
117635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    }
118635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    linkname[r] = '\0';
119635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
120635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    if (mount_points.find(linkname) == mount_points.end()) {
121635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        // First time this mount point was found: add it
122635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        sprintf(path, "/proc/%d/mountinfo", pid);
123635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        if (add_zip_entry(ZIP_ROOT_DIR + path, path)) {
124635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme            mount_points.insert(linkname);
125635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        } else {
126635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme            ALOGE("Unable to add mountinfo %s to zip file\n", path);
127635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        }
128635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    }
129635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme}
130635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
131635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo() {
132635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    if (!zip_writer) return;
133635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    const char *title = "MOUNT INFO";
134635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    mount_points.clear();
135635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    DurationReporter duration_reporter(title);
136635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    for_each_pid(do_mountinfo, NULL);
137635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    printf("%s: %d entries added to zip file\n", title, mount_points.size());
138635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme}
139635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
1402db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevågstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename)
1412db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg{
1422db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    DIR *d;
1432db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    struct dirent *de;
1442db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    char path[PATH_MAX];
1452db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
1462db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    d = opendir(driverpath);
1472db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    if (d == NULL) {
1482db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        return;
1492db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    }
1502db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
1512db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    while ((de = readdir(d))) {
1522db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        if (de->d_type != DT_LNK) {
1532db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg            continue;
1542db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        }
1552db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
1562db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        dump_file(title, path);
1572db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    }
1582db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
1592db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    closedir(d);
1602db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg}
1612db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
162326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic bool skip_not_stat(const char *path) {
163326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    static const char stat[] = "/stat";
164326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    size_t len = strlen(path);
165326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (path[len - 1] == '/') { /* Directory? */
166326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return false;
167326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
168326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
169326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn}
170326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
171e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool skip_none(const char *path) {
172e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    return false;
173e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
174e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
175326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic const char mmcblk0[] = "/sys/block/mmcblk0/";
1768f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynunsigned long worst_write_perf = 20000; /* in KB/s */
177326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
178326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
179326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    unsigned long fields[11], read_perf, write_perf;
180326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    bool z;
181326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    char *cp, *buffer = NULL;
182326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    size_t i = 0;
183326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    FILE *fp = fdopen(fd, "rb");
184326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    getline(&buffer, &i, fp);
185326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    fclose(fp);
186326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (!buffer) {
187326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return -errno;
188326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
189326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    i = strlen(buffer);
190326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    while ((i > 0) && (buffer[i - 1] == '\n')) {
191326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        buffer[--i] = '\0';
192326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
193326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (!*buffer) {
194326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        free(buffer);
195326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return 0;
196326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
197326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    z = true;
198326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
199326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        fields[i] = strtol(cp, &cp, 0);
200326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        if (fields[i] != 0) {
201326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn            z = false;
202326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        }
203326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
204326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (z) { /* never accessed */
205326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        free(buffer);
206326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return 0;
207326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
208326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
209326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) {
210326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        path += sizeof(mmcblk0) - 1;
211326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
212326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
213326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    printf("%s: %s\n", path, buffer);
214326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    free(buffer);
215326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
216326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    read_perf = 0;
217326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (fields[3]) {
218326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        read_perf = 512 * fields[2] / fields[3];
219326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
220326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    write_perf = 0;
221326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (fields[7]) {
222326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        write_perf = 512 * fields[6] / fields[7];
223326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
224326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf);
2258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if ((write_perf > 1) && (write_perf < worst_write_perf)) {
2268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        worst_write_perf = write_perf;
2278f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
228326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    return 0;
229326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn}
230326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
2318f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* Copied policy from system/core/logd/LogBuffer.cpp */
2328f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2338f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_SIZE (256 * 1024)
2348f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
2358f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
2368f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2378f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic bool valid_size(unsigned long value) {
2388f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) {
2398f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        return false;
2408f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2418f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2428f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    long pages = sysconf(_SC_PHYS_PAGES);
2438f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (pages < 1) {
2448f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        return true;
2458f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2468f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2478f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    long pagesize = sysconf(_SC_PAGESIZE);
2488f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (pagesize <= 1) {
2498f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        pagesize = PAGE_SIZE;
2508f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2518f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2528f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    // maximum memory impact a somewhat arbitrary ~3%
2538f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    pages = (pages + 31) / 32;
2548f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    unsigned long maximum = pages * pagesize;
2558f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2568f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) {
2578f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        return true;
2588f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2598f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2608f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    return value <= maximum;
2618f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn}
2628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynstatic unsigned long property_get_size(const char *key) {
2648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    unsigned long value;
2658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    char *cp, property[PROPERTY_VALUE_MAX];
2668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2678f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    property_get(key, property, "");
2688f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    value = strtoul(property, &cp, 10);
2698f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2708f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    switch(*cp) {
2718f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    case 'm':
2728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    case 'M':
2738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        value *= 1024;
2748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    /* FALLTHRU */
2758f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    case 'k':
2768f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    case 'K':
2778f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        value *= 1024;
2788f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    /* FALLTHRU */
2798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    case '\0':
2808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        break;
2818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    default:
2838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        value = 0;
2848f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2858f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2868f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (!valid_size(value)) {
2878f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        value = 0;
2888f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
2898f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2908f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    return value;
2918f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn}
2928f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
2938f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* timeout in ms */
2948620bb4118a68721d10c29529dc6978847d08d00Felipe Lemestatic unsigned long logcat_timeout(const char *name) {
2958f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    static const char global_tuneable[] = "persist.logd.size"; // Settings App
2968f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    static const char global_default[] = "ro.logd.size";       // BoardConfig.mk
2978f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    char key[PROP_NAME_MAX];
2988f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    unsigned long property_size, default_size;
2998f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3008f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    default_size = property_get_size(global_tuneable);
3018f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (!default_size) {
3028f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        default_size = property_get_size(global_default);
3038f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
3048f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3058f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    snprintf(key, sizeof(key), "%s.%s", global_tuneable, name);
3068f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    property_size = property_get_size(key);
3078f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3088f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (!property_size) {
3098f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        snprintf(key, sizeof(key), "%s.%s", global_default, name);
3108f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        property_size = property_get_size(key);
3118f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
3128f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3138f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (!property_size) {
3148f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        property_size = default_size;
3158f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
3168f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3178f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (!property_size) {
3188f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        property_size = LOG_BUFFER_SIZE;
3198f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
3208f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3218f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    /* Engineering margin is ten-fold our guess */
3228f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    return 10 * (property_size + worst_write_perf) / worst_write_perf;
3238f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn}
3248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
3258f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn/* End copy from system/core/logd/LogBuffer.cpp */
3268f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
327f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* dumps the current system state to stdout */
32878f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void print_header() {
329f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
330f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
331f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char network[PROPERTY_VALUE_MAX], date[80];
332f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
333f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ro.build.display.id", build, "(unknown)");
334f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ro.build.fingerprint", fingerprint, "(unknown)");
335f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ro.build.type", build_type, "(unknown)");
336f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ro.baseband", radio, "(unknown)");
337f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ro.bootloader", bootloader, "(unknown)");
338f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("gsm.operator.alpha", network, "(unknown)");
339f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
340f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
341f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
342f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== dumpstate: %s\n", date);
343f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
344f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
345f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("\n");
346f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Build: %s\n", build);
347f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
348f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Bootloader: %s\n", bootloader);
349f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Radio: %s\n", radio);
350f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Network: %s\n", network);
351f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
352f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Kernel: ");
353f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/proc/version");
354f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
355f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("\n");
35678f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme}
35778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme
358e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a new entry to the existing zip file. */
359e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool add_zip_entry_from_fd(const std::string& entry_name, int fd) {
360770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme    DurationReporter duration_reporter(("ADD ZIP ENTRY " + entry_name).c_str());
361770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme    ALOGD("Adding zip entry %s", entry_name.c_str());
362e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(),
363e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            ZipWriter::kCompress, get_mtime(fd, now));
364e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    if (err) {
365e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        ALOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), ZipWriter::ErrorCodeString(err));
366e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        return false;
367e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
368e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
369770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme    std::vector<uint8_t> buffer(65536);
370e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    while (1) {
371e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), sizeof(buffer)));
372e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        if (bytes_read == 0) {
373e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            break;
374e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        } else if (bytes_read == -1) {
375e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            ALOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno));
376e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            return false;
377e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        }
378e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        err = zip_writer->WriteBytes(buffer.data(), bytes_read);
379e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        if (err) {
380e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            ALOGE("zip_writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err));
381e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            return false;
382e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        }
383e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
384e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
385e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    err = zip_writer->FinishEntry();
386e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    if (err) {
387e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        ALOGE("zip_writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
388e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        return false;
389e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
390e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
391e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    return true;
392e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
393e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
394e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a new entry to the existing zip file. */
395e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool add_zip_entry(const std::string& entry_name, const std::string& entry_path) {
396e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
397e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    if (fd.get() == -1) {
398e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        ALOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno));
399e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        return false;
400e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
401e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
402e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    return add_zip_entry_from_fd(entry_name, fd.get());
403e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
404e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
405e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a file to the existing zipped bugreport */
406e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic int _add_file_from_fd(const char *title, const char *path, int fd) {
407e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    return add_zip_entry_from_fd(ZIP_ROOT_DIR + path, fd) ? 0 : 1;
408e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
409e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
410e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds all files from a directory to the zipped bugreport file */
411e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemevoid add_dir(const char *dir, bool recursive) {
412e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    if (!zip_writer) return;
413e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    DurationReporter duration_reporter(dir);
414e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    dump_files(NULL, dir, recursive ? skip_none : is_dir, _add_file_from_fd);
415e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
416e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
41778f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Lemestatic void dumpstate(const std::string& screenshot_path) {
418770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme    DurationReporter duration_reporter("DUMPSTATE");
41978f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme    unsigned long timeout;
420f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
4212db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
422f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("UPTIME", 10, "uptime", NULL);
423326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
4248c8130eb68c89987a94db084608a4229bad06c18Mark Salyzyn    dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
425f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("MEMORY INFO", "/proc/meminfo");
426b32c7e14ccc6507f6ce3fc02414ba04b797f4558Elliott Hughes    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
4272b1f88b6ac78e330ff006da6fecf8bc9d976ec67Nick Kralevich    run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
428f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
429f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("VMALLOC INFO", "/proc/vmallocinfo");
430f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("SLAB INFO", "/proc/slabinfo");
431f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("ZONEINFO", "/proc/zoneinfo");
432f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
433f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BUDDYINFO", "/proc/buddyinfo");
4342281af967dd840aade7bc55b19ea7df0e6da36f2Colin Cross    dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
435f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
436f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
43729e27a84c144fe3b941648094cad2a3f1e61e8b3Todd Poynor    dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources");
438f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
43985aea748861b5665e68b786b55f1c798f56fc0daMathias Agopian    dump_file("KERNEL SYNC", "/d/sync");
440f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
441a3533a3ae6bf8d0e1780c153cafdec86926ec22cElliott Hughes    run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
442b82c925d3cd54d5eff9f4f9e6d5aeb41f75365f5Nick Kralevich    run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL);
443f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
4444db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    run_command("ROUTE", 10, "route", NULL);
4454db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    run_command("PRINTENV", 10, "printenv", NULL);
4464db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    run_command("NETSTAT", 10, "netstat", NULL);
4474db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    run_command("LSMOD", 10, "lsmod", NULL);
4484db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
449f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    do_dmesg();
450f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
451f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
4521dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
4531dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
454f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
4556e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    if (!screenshot_path.empty()) {
456e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme        ALOGI("taking late screenshot\n");
457e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme        take_screenshot(screenshot_path);
4586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
4595a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey    }
4605a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey
461f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
4628f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    // calculate timeout
4638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
4648f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (timeout < 20000) {
4658f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        timeout = 20000;
4668f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
4677831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn    run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime",
4687831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                        "-v", "printable",
4697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                        "-d",
4707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                        "*:v", NULL);
47143afe5d0b537999d5de9613626eca24f34cc52efMark Salyzyn    timeout = logcat_timeout("events");
4728f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (timeout < 20000) {
4738f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        timeout = 20000;
4748f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
4757831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn    run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events",
4767831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-v", "threadtime",
4777831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-v", "printable",
4787831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-d",
4797831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "*:v", NULL);
4808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    timeout = logcat_timeout("radio");
4818f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    if (timeout < 20000) {
4828f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn        timeout = 20000;
4838f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
4847831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn    run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio",
4857831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-v", "threadtime",
4867831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-v", "printable",
4877831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "-d",
4887831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                                       "*:v", NULL);
489f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
490ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn    run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
491ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn
492804339a59e4abcbcf5a50a60ff0543e6b404e572Sharvil Nanavati    run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
4938d4cb7ffc11050eebb4d06684e0eb14d9aadacb5Sharvil Nanavati
494f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* show the traces we collected in main(), if that was done */
495f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (dump_traces_path != NULL) {
496f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        dump_file("VM TRACES JUST NOW", dump_traces_path);
497f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
498f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
499f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* only show ANR traces if they're less than 15 minutes old */
500f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    struct stat st;
501f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char anr_traces_path[PATH_MAX];
502f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
503f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (!anr_traces_path[0]) {
504f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
505f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    } else {
50654bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris      int fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
50754bcc5ffd5a79f4f194089c58d3de571532bf39bChristopher Ferris                                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
5087dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris      if (fd < 0) {
5097dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
5107dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris      } else {
5117dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris          dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd);
5127dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris      }
513f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
514f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
515f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* slow traces for slow operations */
516f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (anr_traces_path[0] != 0) {
517f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        int tail = strlen(anr_traces_path)-1;
518f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        while (tail > 0 && anr_traces_path[tail] != '/') {
519f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            tail--;
520f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
521f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        int i = 0;
522f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        while (1) {
523f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            sprintf(anr_traces_path+tail+1, "slow%02d.txt", i);
524f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            if (stat(anr_traces_path, &st)) {
525f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                // No traces file at this index, done with the files.
526f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                break;
527f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
528f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            dump_file("VM TRACES WHEN SLOW", anr_traces_path);
529f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            i++;
530f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
531f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
532f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
5337dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    int dumped = 0;
5347dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
5357dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        if (tombstone_data[i].fd != -1) {
536e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            const char *name = tombstone_data[i].name;
537e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            int fd = tombstone_data[i].fd;
5387dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris            dumped = 1;
539e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            if (zip_writer) {
540e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme                if (!add_zip_entry_from_fd(ZIP_ROOT_DIR + name, fd)) {
541e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme                    ALOGE("Unable to add tombstone %s to zip file\n", name);
542e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme                }
543e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            } else {
544e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme                dump_file_from_fd("TOMBSTONE", name, fd);
545e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            }
546e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            close(fd);
5477dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris            tombstone_data[i].fd = -1;
5487dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        }
5497dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    }
5507dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    if (!dumped) {
5517dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
5527dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    }
5537dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
554f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("NETWORK DEV INFO", "/proc/net/dev");
555f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
556012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall    dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt");
557f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
558f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
559f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
5602a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor    if (!stat(PSTORE_LAST_KMSG, &st)) {
5612a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor        /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
5622a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor        dump_file("LAST KMSG", PSTORE_LAST_KMSG);
5632a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor    } else {
5642a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor        /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
5652a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor        dump_file("LAST KMSG", "/proc/last_kmsg");
5662a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor    }
5672a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor
5682262c16372570f57d3107d574abe2c80825d286eMark Salyzyn    /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
5697831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn    run_command("LAST LOGCAT", 10, "logcat", "-L",
5707831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                             "-b", "all",
5717831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                             "-v", "threadtime",
5727831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                             "-v", "printable",
5737831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                             "-d",
5747831638e2a142cbb082d63a60ad5c04ff63933e8Mark Salyzyn                                             "*:v", NULL);
5752262c16372570f57d3107d574abe2c80825d286eMark Salyzyn
576f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
577a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes
578a59828a5d2740433164872e9a0b44363e2ba0cd4Elliott Hughes    run_command("NETWORK INTERFACES", 10, "ip", "link", NULL);
579d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti
580d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti    run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL);
581d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti    run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL);
582d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti
583f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("IP RULES", 10, "ip", "rule", "show", NULL);
584f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
5852b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran
5862b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran    dump_route_tables();
5872b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran
588d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti    run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
589d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti    run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
590d4c3d38957870fa27423dbc55d99d68772fbd490Lorenzo Colitti
591f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
592f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
593012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
594012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall    /* no ip6 nat */
595012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall    run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL);
596012c2ea5651a56218a4359c78db26dd700d9930bJP Abgrall    run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
597f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
598f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("WIFI NETWORKS", 20,
5991d6b97c869718001010cce3db387c73fd11bf32eDmitry Shmidt            SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
600f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
601c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd
6026afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("ND OFFLOAD TABLE", 5,
6036afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti            SU_PATH, "root", "wlutil", "nd_hostip", NULL);
6046afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
6056afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20,
606c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt            SU_PATH, "root", "wlutil", "counters", NULL);
6076afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
6086afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("ND OFFLOAD STATUS (1)", 5,
6096afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti            SU_PATH, "root", "wlutil", "nd_status", NULL);
6106afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
611c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#endif
6120b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt    dump_file("INTERRUPTS (1)", "/proc/interrupts");
6130b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt
6146afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL);
6156afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
616c11f56e5615c5d388c072705322df5bcf22c2012Dmitry Shmidt#ifdef FWDUMP_bcmdhd
617f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("DUMP WIFI STATUS", 20,
618f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
6196afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
6206afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20,
621f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            SU_PATH, "root", "wlutil", "counters", NULL);
6226afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
6236afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti    run_command("ND OFFLOAD STATUS (2)", 5,
6246afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti            SU_PATH, "root", "wlutil", "nd_status", NULL);
625f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#endif
6260b2c9268265e9a165551eaa66cb461d3fab8b564Dmitry Shmidt    dump_file("INTERRUPTS (2)", "/proc/interrupts");
627f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
628f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    print_properties();
629f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
630f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
631f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
632f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
6338f75fa7bcfec553eddb59b919b44d7a93c9846a1Ken Sumrall    run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
634f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
635f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
636f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
637f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("------ BACKLIGHTS ------\n");
638f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("LCD brightness=");
639f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
640f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Button brightness=");
641f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
642f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("Keyboard brightness=");
643f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
644f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("ALS mode=");
645f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
646f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("LCD driver registers:\n");
647f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
648f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("\n");
649f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
650f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* Binder state is expensive to look at as it uses a lot of memory. */
651f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
652f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
653f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
654f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
655f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
656f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
657f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
658f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== Board\n");
659f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
660f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
661f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    dumpstate_board();
662f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("\n");
663f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
664f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* Migrate the ril_dumpstate to a dumpstate_board()? */
665f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
666f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
667f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
668f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
669f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            // su does not exist on user builds, so try running without it.
670f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            // This way any implementations of vril-dump that do not require
671f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            // root can run on user builds.
672f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
673f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                    "vril-dump", NULL);
674f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        } else {
675f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
676f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                    SU_PATH, "root", "vril-dump", NULL);
677f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
678f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
679f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
680f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
681f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== Android Framework Services\n");
682f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
683f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
684f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* the full dumpsys is starting to take a long time, so we need
685f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross       to increase its timeout.  we really need to do the timeouts in
686f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross       dumpsys itself... */
687f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("DUMPSYS", 60, "dumpsys", NULL);
688f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
689f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
69002bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn    printf("== Checkins\n");
69102bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn    printf("========================================================\n");
69202bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn
69359b1516f4cefcfd599f4e5e9c4a227a48d1ace65Dianne Hackborn    run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL);
6943e5fa73722c100fc9017c7a47b17a8e727aa34e1Dianne Hackborn    run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL);
69502bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn    run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL);
6965cd46aa3399ddeaf12a211390dfde66c796ab299Dianne Hackborn    run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL);
6971bd5068a5180ac12dda374e15c7b1f70e8334284Dianne Hackborn    run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL);
6988b3e133e413774047da8005771f57c21dd31e1e3Ashish Sharma    run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL);
69902bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn
70002bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn    printf("========================================================\n");
701f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== Running Application Activities\n");
702f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
703f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
704f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL);
705f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
706f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
707f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== Running Application Services\n");
708f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
709f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
710f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL);
711f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
712f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
713f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== Running Application Providers\n");
714f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
715f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
716f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL);
717f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
718f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
719f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
720f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("== dumpstate: done\n");
721f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    printf("========================================================\n");
722f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
723f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
724f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic void usage() {
7251f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n"
726f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -o: write to file (instead of stdout)\n"
727f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -d: append date to filename (requires -o)\n"
7286e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            "  -z: generates zipped file (requires -o)\n"
729f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -p: capture screenshot to filename.png (requires -o)\n"
730f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -s: write output to control socket (for init)\n"
731f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -b: play sound file instead of vibrate, at beginning of job\n"
732f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            "  -e: play sound file instead of vibrate, at end of job\n"
7331f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau            "  -q: disable vibrate\n"
73436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            "  -B: send broadcast when finished (requires -o)\n"
73571bbfc57974331dce79242ce806d92035fce06baFelipe Leme            "  -P: send broadacast when started and update system properties on progress (requires -o and -B)\n"
7364db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            "  -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n"
7372a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor                );
738f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
739f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
740885f888c55587e9366542b5155a06c321cde175aJohn Michelaustatic void sigpipe_handler(int n) {
7412e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales    // don't complain to stderr or stdout
7422e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales    _exit(EXIT_FAILURE);
743885f888c55587e9366542b5155a06c321cde175aJohn Michelau}
744885f888c55587e9366542b5155a06c321cde175aJohn Michelau
7451e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the
7461e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme   temporary file.
7471e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme */
748e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Lemestatic bool finish_zip_file(const std::string& bugreport_name, const std::string& bugreport_path,
7491e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        time_t now) {
750e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    if (!add_zip_entry(bugreport_name, bugreport_path)) {
7511e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        ALOGE("Failed to add text entry to .zip file\n");
7526e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        return false;
7536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
7546e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
755e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    int32_t err = zip_writer->Finish();
7561e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    if (err) {
757e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        ALOGE("zip_writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err));
7586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        return false;
7596e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
7606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
7611e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    if (remove(bugreport_path.c_str())) {
7621e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        ALOGW("remove(%s): %s\n", bugreport_path.c_str(), strerror(errno));
7631e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    }
7641e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme
7656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    return true;
7666e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme}
7676e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
7684db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinskistatic std::string SHA256_file_hash(std::string filepath) {
769cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski    ScopedFd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC
770cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski            | O_NOFOLLOW)));
7714db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    if (fd.get() == -1) {
7724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        ALOGE("open(%s): %s\n", filepath.c_str(), strerror(errno));
7734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        return NULL;
7744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
7754db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
7764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    SHA256_CTX ctx;
7774db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    SHA256_init(&ctx);
7784db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
7794db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    std::vector<uint8_t> buffer(65536);
7804db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    while (1) {
7814db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size()));
7824db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        if (bytes_read == 0) {
7834db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            break;
7844db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        } else if (bytes_read == -1) {
7854db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            ALOGE("read(%s): %s\n", filepath.c_str(), strerror(errno));
7864db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            return NULL;
7874db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        }
7884db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
7894db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        SHA256_update(&ctx, buffer.data(), bytes_read);
7904db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
7914db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
7924db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    uint8_t hash[SHA256_DIGEST_SIZE];
7934db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE);
7944db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1];
795cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski    for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++) {
796cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski        sprintf(hash_buffer + (i * 2), "%02x", hash[i]);
7974db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
7984db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    hash_buffer[sizeof(hash_buffer) - 1] = 0;
7994db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    return std::string(hash_buffer);
8004db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski}
8014db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
8024db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
803f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char *argv[]) {
804885f888c55587e9366542b5155a06c321cde175aJohn Michelau    struct sigaction sigact;
805f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int do_add_date = 0;
8066e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    int do_zip_file = 0;
8071f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    int do_vibrate = 1;
808f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char* use_outfile = 0;
809f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int use_socket = 0;
810f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int do_fb = 0;
81127f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey    int do_broadcast = 0;
812e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    int do_early_screenshot = 0;
8134db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    int is_remote_mode = 0;
814f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
815e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    now = time(NULL);
816e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
8171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (getuid() != 0) {
8181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        // Old versions of the adb client would call the
8191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        // dumpstate command directly. Newer clients
8201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        // call /system/bin/bugreport instead. If we detect
8211e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        // we're being called incorrectly, then exec the
8221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        // correct program.
8231e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL);
8241e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    }
825f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
8261dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    ALOGI("begin\n");
8272e671bbdb741c2926b6df7b240fdc31c7361f330Andres Morales
8281dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* clear SIGPIPE handler */
829885f888c55587e9366542b5155a06c321cde175aJohn Michelau    memset(&sigact, 0, sizeof(sigact));
830885f888c55587e9366542b5155a06c321cde175aJohn Michelau    sigact.sa_handler = sigpipe_handler;
831885f888c55587e9366542b5155a06c321cde175aJohn Michelau    sigaction(SIGPIPE, &sigact, NULL);
8323e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall
833f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* set as high priority, and protect from OOM killer */
834f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    setpriority(PRIO_PROCESS, 0, -20);
835cd67e9f059e270017d5defd8784c89dd8e6bcde7Nick Kralevich    FILE *oom_adj = fopen("/proc/self/oom_adj", "we");
836f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (oom_adj) {
837f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        fputs("-17", oom_adj);
838f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        fclose(oom_adj);
839f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
840f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
8411dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* parse arguments */
842f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int c;
8434db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    while ((c = getopt(argc, argv, "dho:svqzpPBR")) != -1) {
844f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        switch (c) {
84571bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'd': do_add_date = 1;          break;
84671bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'z': do_zip_file = 1;          break;
84771bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'o': use_outfile = optarg;     break;
84871bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 's': use_socket = 1;           break;
849f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            case 'v': break;  // compatibility no-op
85071bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'q': do_vibrate = 0;           break;
85171bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'p': do_fb = 1;                break;
85271bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'P': do_update_progress = 1;   break;
8534db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            case 'R': is_remote_mode = 1;       break;
85471bbfc57974331dce79242ce806d92035fce06baFelipe Leme            case 'B': do_broadcast = 1;         break;
855f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            case '?': printf("\n");
856f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            case 'h':
857f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                usage();
858f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                exit(1);
859f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
860f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
861f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
86271bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) {
8636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        usage();
8646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        exit(1);
8656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
8666e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
86771bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (do_update_progress && !do_broadcast) {
86871bbfc57974331dce79242ce806d92035fce06baFelipe Leme        usage();
86971bbfc57974331dce79242ce806d92035fce06baFelipe Leme        exit(1);
87071bbfc57974331dce79242ce806d92035fce06baFelipe Leme    }
8716e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
8724db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    if (is_remote_mode && (do_update_progress || !do_broadcast || !do_zip_file || !do_add_date)) {
8734db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        usage();
8744db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        exit(1);
8754db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
8764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
877e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    do_early_screenshot = do_update_progress;
878e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme
879ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    // If we are going to use a socket, do it as early as possible
880ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    // to avoid timeouts from bugreport.
881ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    if (use_socket) {
882ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris        redirect_to_socket(stdout, "dumpstate");
883ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    }
884ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris
885ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    /* full path of the directory where the bug report files will be written */
886ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    std::string bugreport_dir;
887ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
888ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    /* full path of the temporary file containing the bug report */
889ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    std::string tmp_path;
890ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
891e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    /* full path of the temporary file containing the screenshot (when requested) */
892e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    std::string screenshot_path;
893e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme
894ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    /* base name (without suffix or extensions) of the bug report files */
895ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    std::string base_name;
896ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
897ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    /* suffix of the bug report files - it's typically the date (when invoked with -d),
898ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme     * although it could be changed by the user using a system property */
899ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    std::string suffix;
90071bbfc57974331dce79242ce806d92035fce06baFelipe Leme
90171bbfc57974331dce79242ce806d92035fce06baFelipe Leme    /* pointer to the actual path, be it zip or text */
90271bbfc57974331dce79242ce806d92035fce06baFelipe Leme    std::string path;
90371bbfc57974331dce79242ce806d92035fce06baFelipe Leme
904635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    /* pointer to the zipped file */
9051e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose);
90671bbfc57974331dce79242ce806d92035fce06baFelipe Leme
907ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme    /* redirect output if needed */
90871bbfc57974331dce79242ce806d92035fce06baFelipe Leme    bool is_redirecting = !use_socket && use_outfile;
90971bbfc57974331dce79242ce806d92035fce06baFelipe Leme
91071bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
911ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        bugreport_dir = dirname(use_outfile);
912ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        base_name = basename(use_outfile);
91371bbfc57974331dce79242ce806d92035fce06baFelipe Leme        if (do_add_date) {
91471bbfc57974331dce79242ce806d92035fce06baFelipe Leme            char date[80];
915ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now));
916ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            suffix = date;
917ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        } else {
918ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            suffix = "undated";
91971bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
92071bbfc57974331dce79242ce806d92035fce06baFelipe Leme        if (do_fb) {
921ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            // TODO: if dumpstate was an object, the paths could be internal variables and then
922ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            // we could have a function to calculate the derived values, such as:
923ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            //     screenshot_path = GetPath(".png");
924ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png";
92571bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
926ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp";
92771bbfc57974331dce79242ce806d92035fce06baFelipe Leme
928ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        ALOGD("Bugreport dir: %s\nBase name: %s\nSuffix: %s\nTemporary path: %s\n"
929ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                "Screenshot path: %s\n", bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(),
930ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                tmp_path.c_str(), screenshot_path.c_str());
93171bbfc57974331dce79242ce806d92035fce06baFelipe Leme
9321e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        if (do_zip_file) {
9331e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            ALOGD("Creating initial .zip file");
9341e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip";
9351e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            zip_file.reset(fopen(path.c_str(), "wb"));
9361e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            if (!zip_file) {
9371e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme                ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno));
9381e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme                do_zip_file = 0;
9391e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            } else {
9401e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme                zip_writer.reset(new ZipWriter(zip_file.get()));
9411e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            }
9421e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        }
9431e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme
94471bbfc57974331dce79242ce806d92035fce06baFelipe Leme        if (do_update_progress) {
945ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            std::vector<std::string> am_args = {
946ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                 "--receiver-permission", "android.permission.DUMP",
947ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                 "--es", "android.intent.extra.NAME", suffix,
948ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                 "--ei", "android.intent.extra.PID", std::to_string(getpid()),
949ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                 "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL),
950ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            };
951ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
95271bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
95371bbfc57974331dce79242ce806d92035fce06baFelipe Leme    }
95471bbfc57974331dce79242ce806d92035fce06baFelipe Leme
955f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    /* read /proc/cmdline before dropping root */
956f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    FILE *cmdline = fopen("/proc/cmdline", "re");
957f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    if (cmdline) {
958f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
959f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich        fclose(cmdline);
960f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    }
961f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich
96278f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme    print_header();
96378f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme
9641dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* open the vibrator before dropping root */
9656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose);
9661f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    if (do_vibrate) {
9676e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we"));
9681dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown        if (vibrator) {
9696e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            vibrate(vibrator.get(), 150);
9701dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown        }
9711f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    }
972f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
9733634a1e3459cb609da709646107e246cafbc01f9Felipe Leme    if (do_fb && do_early_screenshot) {
9743634a1e3459cb609da709646107e246cafbc01f9Felipe Leme        if (screenshot_path.empty()) {
9753634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            // should not have happened
9763634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            ALOGE("INTERNAL ERROR: skipping early screenshot because path was not set");
9773634a1e3459cb609da709646107e246cafbc01f9Felipe Leme        } else {
9783634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            ALOGI("taking early screenshot\n");
9793634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            take_screenshot(screenshot_path);
9803634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
9813634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) {
9823634a1e3459cb609da709646107e246cafbc01f9Felipe Leme                ALOGE("Unable to change ownership of screenshot file %s: %s\n",
9833634a1e3459cb609da709646107e246cafbc01f9Felipe Leme                        screenshot_path.c_str(), strerror(errno));
9843634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            }
985e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme        }
986e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    }
987e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme
9881e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    if (do_zip_file) {
9891e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        if (chown(path.c_str(), AID_SHELL, AID_SHELL)) {
9901e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            ALOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno));
9911e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        }
9921e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    }
9931e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme
9941dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* collect stack traces from Dalvik and native processes (needs root) */
9951dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    dump_traces_path = dump_traces();
9961dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown
997635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    /* Get the tombstone fds, recovery files, and mount info here while we are running as root. */
9981dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    get_tombstone_fds(tombstone_data);
999e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    add_dir(RECOVERY_DIR, true);
1000635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    add_mountinfo();
10011dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown
10021dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* ensure we will keep capabilities when we drop root */
10031e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
10041e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
10051e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return -1;
10061e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    }
1007f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
10081e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    /* switch to non-root user and group */
10091e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
1010ab46a4922655bc75848660da4268ab85d72a6010Nick Kralevich            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC };
10111e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
10121e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
10131e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return -1;
10141e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    }
10151e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (setgid(AID_SHELL) != 0) {
10161e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        ALOGE("Unable to setgid, aborting: %s\n", strerror(errno));
10171e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return -1;
10181e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    }
10191e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (setuid(AID_SHELL) != 0) {
10201e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        ALOGE("Unable to setuid, aborting: %s\n", strerror(errno));
10211e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return -1;
10221e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    }
1023f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
10241e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    struct __user_cap_header_struct capheader;
10251e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    struct __user_cap_data_struct capdata[2];
10261e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    memset(&capheader, 0, sizeof(capheader));
10271e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    memset(&capdata, 0, sizeof(capdata));
10281e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capheader.version = _LINUX_CAPABILITY_VERSION_3;
10291e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capheader.pid = 0;
10301e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich
10311e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
10321e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
10331e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capdata[0].inheritable = 0;
10341e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    capdata[1].inheritable = 0;
10351e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich
10361e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich    if (capset(&capheader, &capdata[0]) < 0) {
10371e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        ALOGE("capset failed: %s\n", strerror(errno));
10381e339878c128ef47271278779c2685a8dfa49cd1Nick Kralevich        return -1;
1039f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1040f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
104171bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
10426e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        /* TODO: rather than generating a text file now and zipping it later,
10436e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme           it would be more efficient to redirect stdout to the zip entry
10446e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme           directly, but the libziparchive doesn't support that option yet. */
10456e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str()));
1046f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1047f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
10483634a1e3459cb609da709646107e246cafbc01f9Felipe Leme    dumpstate(do_early_screenshot ? "": screenshot_path);
1049f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
10501dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* done */
10511dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    if (vibrator) {
10521dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown        for (int i = 0; i < 3; i++) {
10536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            vibrate(vibrator.get(), 75);
1054f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            usleep((75 + 50) * 1000);
1055f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
1056f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1057f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
105855b42a67f69767976ff16ab443b3e7142db693e1Felipe Leme    /* close output if needed */
105971bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
1060f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        fclose(stdout);
1061f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1062f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
10636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    /* rename or zip the (now complete) .tmp file to its final location */
10646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    if (use_outfile) {
1065ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
1066ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        /* check if user changed the suffix using system properties */
1067ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        char key[PROPERTY_KEY_MAX];
1068ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        char value[PROPERTY_VALUE_MAX];
1069ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        sprintf(key, "dumpstate.%d.name", getpid());
1070ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        property_get(key, value, "");
1071ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        bool change_suffix= false;
1072ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        if (value[0]) {
1073ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            /* must whitelist which characters are allowed, otherwise it could cross directories */
1074ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            std::regex valid_regex("^[-_a-zA-Z0-9]+$");
1075ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            if (std::regex_match(value, valid_regex)) {
1076ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                change_suffix = true;
1077ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            } else {
1078ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                ALOGE("invalid suffix provided by user: %s", value);
1079ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            }
1080ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        }
1081ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        if (change_suffix) {
1082ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            ALOGI("changing suffix from %s to %s", suffix.c_str(), value);
1083ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            suffix = value;
1084ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            if (!screenshot_path.empty()) {
1085ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                std::string new_screenshot_path =
1086ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                        bugreport_dir + "/" + base_name + "-" + suffix + ".png";
1087ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) {
1088ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                    ALOGE("rename(%s, %s): %s\n", screenshot_path.c_str(),
1089ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                            new_screenshot_path.c_str(), strerror(errno));
1090ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                } else {
1091ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                    screenshot_path = new_screenshot_path;
1092ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                }
1093ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            }
1094ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        }
1095ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
10966e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        bool do_text_file = true;
10976e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        if (do_zip_file) {
10981e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            ALOGD("Adding text entry to .zip bugreport");
1099e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            if (!finish_zip_file(base_name + "-" + suffix + ".txt", tmp_path, now)) {
11001e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme                ALOGE("Failed to finish zip file; sending text bugreport instead\n");
11016e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme                do_text_file = true;
11026e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            } else {
11036e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme                do_text_file = false;
11046e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            }
11056e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
11066e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        if (do_text_file) {
1107ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            ALOGD("Generating .txt bugreport");
1108ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt";
1109ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            if (rename(tmp_path.c_str(), path.c_str())) {
1110ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                ALOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno));
11116e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme                path.clear();
11126e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            }
11136e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
1114f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1115f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
11161dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* tell activity manager we're done */
111771bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (do_broadcast) {
11186e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        if (!path.empty()) {
11196e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            ALOGI("Final bugreport path: %s\n", path.c_str());
112036b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            std::vector<std::string> am_args = {
112143fd1bbc6675430a4ecfde07e88a414ed5c41c0cFelipe Leme                 "--receiver-permission", "android.permission.DUMP", "--receiver-foreground",
112271bbfc57974331dce79242ce806d92035fce06baFelipe Leme                 "--ei", "android.intent.extra.PID", std::to_string(getpid()),
112336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                 "--es", "android.intent.extra.BUGREPORT", path
112436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            };
112536b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            if (do_fb) {
112636b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                am_args.push_back("--es");
112736b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                am_args.push_back("android.intent.extra.SCREENSHOT");
112836b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                am_args.push_back(screenshot_path);
112936b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            }
11304db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            if (is_remote_mode) {
11314db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                am_args.push_back("--es");
11324db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
11334db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                am_args.push_back(SHA256_file_hash(path));
11344db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
11354db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            } else {
11364db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
11374db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            }
11386e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        } else {
113971bbfc57974331dce79242ce806d92035fce06baFelipe Leme            ALOGE("Skipping finished broadcast because bugreport could not be generated\n");
11406e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
114127f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey    }
114227f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey
1143e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL);
1144f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    ALOGI("done\n");
1145f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1146f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return 0;
1147f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
1148