dumpstate.cpp revision 1e9edc619c6b1ca3998a26eaa4882b55ce801f12
181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*
281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Copyright (C) 2008 The Android Open Source Project
381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *
481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * you may not use this file except in compliance with the License.
681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * You may obtain a copy of the License at
781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *
881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *
1081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * Unless required by applicable law or agreed to in writing, software
1181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
1281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * See the License for the specific language governing permissions and
1481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent * limitations under the License.
1581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent */
1681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <dirent.h>
1881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <errno.h>
1981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <fcntl.h>
2081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <libgen.h>
2181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <limits.h>
22153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include <memory>
23ad8510a339ffab330c2c46e5c247dd1cf9e15c22Glenn Kasten#include <regex>
2481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <stdbool.h>
25ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes#include <stdio.h>
2681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <stdlib.h>
2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <string>
2881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <string.h>
2981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/capability.h>
3081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/prctl.h>
3181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/resource.h>
3281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/stat.h>
3381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/time.h>
34da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <sys/wait.h>
35da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <unistd.h>
36c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten
37da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <android-base/stringprintf.h>
3881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cutils/properties.h>
3981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "private/android_filesystem_config.h"
4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define LOG_TAG "dumpstate"
4381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cutils/log.h>
4481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "dumpstate.h"
4681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ScopedFd.h"
4781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ziparchive/zip_writer.h"
4881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentusing android::base::StringPrintf;
5081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* read before root is shed */
5281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic char cmdline_buf[16384] = "(unknown)";
53e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hungstatic const char *dump_traces_path = NULL;
54e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
55e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hungstatic char build_type[PROPERTY_VALUE_MAX];
56e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
5881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define RAFT_DIR "/data/misc/raft/"
6081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define TOMBSTONE_DIR "/data/tombstones"
6181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_"
6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* Can accomodate a tombstone number up to 9999. */
63da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4)
64da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#define NUM_TOMBSTONES  10
6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurenttypedef struct {
6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent  char name[TOMBSTONE_MAX_LEN];
6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent  int fd;
6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} tombstone_data_t;
7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
7181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic tombstone_data_t tombstone_data[NUM_TOMBSTONES];
7281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
7383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent/* Get the fds of any tombstone that was modified in the last half an hour. */
74d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenstatic void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) {
75462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    time_t thirty_minutes_ago = time(NULL) - 60*30;
76755b0a611f539dfa49e88aac592a938427c7e1b8Glenn Kasten    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
77d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
7883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        int fd = TEMP_FAILURE_RETRY(open(data[i].name,
7983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                         O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        struct stat st;
8181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                (time_t) st.st_mtime >= thirty_minutes_ago) {
8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            data[i].fd = fd;
8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            close(fd);
8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            data[i].fd = -1;
8781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
8881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
89e541269be94f3a1072932d51537905b120ef4733Andy Hung}
90e541269be94f3a1072932d51537905b120ef4733Andy Hung
91e541269be94f3a1072932d51537905b120ef4733Andy Hungstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename)
92fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk{
9381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    DIR *d;
9481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct dirent *de;
95e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    char path[PATH_MAX];
96755b0a611f539dfa49e88aac592a938427c7e1b8Glenn Kasten
97e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    d = opendir(driverpath);
98da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (d == NULL) {
99bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return;
10083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
101aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent
102aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent    while ((de = readdir(d))) {
10381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (de->d_type != DT_LNK) {
104dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen            continue;
105dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen        }
106dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen        snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
107dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen        dump_file(title, path);
108dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen    }
109462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
110462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    closedir(d);
111462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen}
112462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
113462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissenstatic bool skip_not_stat(const char *path) {
11481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    static const char stat[] = "/stat";
11581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t len = strlen(path);
11683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (path[len - 1] == '/') { /* Directory? */
11783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return false;
11881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
11981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
12081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
12181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const char mmcblk0[] = "/sys/block/mmcblk0/";
123663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kastenunsigned long worst_write_perf = 20000; /* in KB/s */
124663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten
125c42e9b462661673dff480ee71757a58b0f806370Glenn Kastenstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
12681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    unsigned long fields[11], read_perf, write_perf;
127663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten    bool z;
12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char *cp, *buffer = NULL;
12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t i = 0;
13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    FILE *fp = fdopen(fd, "rb");
131e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    getline(&buffer, &i, fp);
132e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    fclose(fp);
13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!buffer) {
13481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -errno;
13581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
13681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    i = strlen(buffer);
13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while ((i > 0) && (buffer[i - 1] == '\n')) {
13881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        buffer[--i] = '\0';
139c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
140c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    if (!*buffer) {
141d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        free(buffer);
142d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        return 0;
143d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    }
144d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    z = true;
145d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
146d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        fields[i] = strtol(cp, &cp, 0);
147d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        if (fields[i] != 0) {
148d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            z = false;
149d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        }
150d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    }
151d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    if (z) { /* never accessed */
152d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        free(buffer);
15381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
154c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
155c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
156c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    if (!strncmp(path, mmcblk0, sizeof(mmcblk0) - 1)) {
157c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        path += sizeof(mmcblk0) - 1;
158c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
159c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
160c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    printf("%s: %s\n", path, buffer);
161c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    free(buffer);
162c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
163c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    read_perf = 0;
164c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    if (fields[3]) {
165d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        read_perf = 512 * fields[2] / fields[3];
16683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
167d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    write_perf = 0;
168d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    if (fields[7]) {
169d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten        write_perf = 512 * fields[6] / fields[7];
17083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
1719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("%s: read: %luKB/s write: %luKB/s\n", path, read_perf, write_perf);
172d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    if ((write_perf > 1) && (write_perf < worst_write_perf)) {
1739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        worst_write_perf = write_perf;
174d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten    }
175c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    return 0;
17683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
17783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
17883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent/* Copied policy from system/core/logd/LogBuffer.cpp */
17983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
18083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent#define LOG_BUFFER_SIZE (256 * 1024)
18183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
18281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
183da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
18446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kastenstatic bool valid_size(unsigned long value) {
185da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) {
186329f6511ee4e03a4605c70bbda8d3a96d2544884Glenn Kasten        return false;
1876e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten    }
18846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten
18946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    long pages = sysconf(_SC_PHYS_PAGES);
19046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    if (pages < 1) {
19146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten        return true;
19246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    }
19346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten
19446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    long pagesize = sysconf(_SC_PAGESIZE);
19546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    if (pagesize <= 1) {
19646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten        pagesize = PAGE_SIZE;
19746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    }
19846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten
19946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    // maximum memory impact a somewhat arbitrary ~3%
200da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    pages = (pages + 31) / 32;
20146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    unsigned long maximum = pages * pagesize;
202da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
20381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) {
20481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
20581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
20683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
20783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return value <= maximum;
20883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
20983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
21083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatic unsigned long property_get_size(const char *key) {
21183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    unsigned long value;
21283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    char *cp, property[PROPERTY_VALUE_MAX];
21383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
21483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    property_get(key, property, "");
21583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    value = strtoul(property, &cp, 10);
21683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
21781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    switch(*cp) {
21881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case 'm':
21946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    case 'M':
220da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        value *= 1024;
22146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    /* FALLTHRU */
222e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    case 'k':
223e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    case 'K':
22481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        value *= 1024;
22581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* FALLTHRU */
22681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case '\0':
22781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    default:
23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        value = 0;
23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
23281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
233021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent    if (!valid_size(value)) {
234021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        value = 0;
23581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
23681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
23781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return value;
23881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
23981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
2403bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent/* timeout in ms */
2413bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurentstatic unsigned long logcat_timeout(const char *name) {
24281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    static const char global_tuneable[] = "persist.logd.size"; // Settings App
24381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    static const char global_default[] = "ro.logd.size";       // BoardConfig.mk
24481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char key[PROP_NAME_MAX];
24581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    unsigned long property_size, default_size;
246d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten
24781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    default_size = property_get_size(global_tuneable);
24881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!default_size) {
24946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten        default_size = property_get_size(global_default);
250da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
251da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
252da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    snprintf(key, sizeof(key), "%s.%s", global_tuneable, name);
25346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten    property_size = property_get_size(key);
254da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (!property_size) {
2569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        snprintf(key, sizeof(key), "%s.%s", global_default, name);
2579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        property_size = property_get_size(key);
25881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
2599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
2609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (!property_size) {
26181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        property_size = default_size;
26281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
26381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!property_size) {
26581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        property_size = LOG_BUFFER_SIZE;
26681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
26781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* Engineering margin is ten-fold our guess */
26981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 10 * (property_size + worst_write_perf) / worst_write_perf;
27081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
27181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
27281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* End copy from system/core/logd/LogBuffer.cpp */
27381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
27481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* dumps the current system state to stdout */
27581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void print_header() {
27681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    time_t now = time(NULL);
27781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
27881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
27981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char network[PROPERTY_VALUE_MAX], date[80];
28081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("ro.build.display.id", build, "(unknown)");
28281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("ro.build.fingerprint", fingerprint, "(unknown)");
28381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("ro.build.type", build_type, "(unknown)");
28481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("ro.baseband", radio, "(unknown)");
28581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("ro.bootloader", bootloader, "(unknown)");
28681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    property_get("gsm.operator.alpha", network, "(unknown)");
28781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
28881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("========================================================\n");
29081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("== dumpstate: %s\n", date);
29181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("========================================================\n");
29281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("\n");
29481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Build: %s\n", build);
29581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Bootloader: %s\n", bootloader);
29781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Radio: %s\n", radio);
29881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Network: %s\n", network);
29981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Kernel: ");
30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/proc/version");
30281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
30381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("\n");
30481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void dumpstate(const std::string& screenshot_path) {
30781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    std::unique_ptr<DurationReporter> duration_reporter(new DurationReporter("DUMPSTATE"));
30881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    unsigned long timeout;
30981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
31181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("UPTIME", 10, "uptime", NULL);
3123dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
3133dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
3143dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    dump_file("MEMORY INFO", "/proc/meminfo");
3153dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
31653cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten    run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
31753cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten    dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
318573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    dump_file("VMALLOC INFO", "/proc/vmallocinfo");
31953cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten    dump_file("SLAB INFO", "/proc/slabinfo");
32053cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten    dump_file("ZONEINFO", "/proc/zoneinfo");
32159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
32259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    dump_file("BUDDYINFO", "/proc/buddyinfo");
32359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    dump_file("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
32459fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
32559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
32659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    dump_file("KERNEL WAKE SOURCES", "/d/wakeup_sources");
32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
32881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("KERNEL SYNC", "/d/sync");
32981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
33181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL);
33281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    do_dmesg();
33481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
33681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
33781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
33881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!screenshot_path.empty()) {
34081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("taking late screenshot\n");
34181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        take_screenshot(screenshot_path);
34281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
34381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
34483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
34581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
346d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten    // calculate timeout
347462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash");
34883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (timeout < 20000) {
34983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        timeout = 20000;
35083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
35183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    run_command("SYSTEM LOG", timeout / 1000, "logcat", "-v", "threadtime",
35283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                        "-v", "printable",
35383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                        "-d",
35483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                        "*:v", NULL);
35581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    timeout = logcat_timeout("events") + logcat_timeout("security");
35681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (timeout < 20000) {
35781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        timeout = 20000;
35881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
35981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events",
36081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                       "-b", "security",
36181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                       "-v", "threadtime",
36281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                       "-v", "printable",
36381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                       "-d",
364e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung                                                       "*:v", NULL);
365e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    timeout = logcat_timeout("radio");
36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (timeout < 20000) {
3675736c35b841de56ce394b4879389f669b61425e6Glenn Kasten        timeout = 20000;
3689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
369bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("RADIO LOG", timeout / 1000, "logcat", "-b", "radio",
3707844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George                                                       "-v", "threadtime",
3711b42097f38e72574ed853a35f4e8a66e4739c421Phil Burk                                                       "-v", "printable",
37281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                       "-d",
37383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                       "*:v", NULL);
37483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
37583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
376e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent
37783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
37883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
3793ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    /* show the traces we collected in main(), if that was done */
3803ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (dump_traces_path != NULL) {
3813ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        dump_file("VM TRACES JUST NOW", dump_traces_path);
3823ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
3833ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
3843ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    /* only show ANR traces if they're less than 15 minutes old */
38583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    struct stat st;
3863ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    char anr_traces_path[PATH_MAX];
3873ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
3883ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (!anr_traces_path[0]) {
3893ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
3903ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    } else {
3913ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten      int fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
392c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten                                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
3933ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten      if (fd < 0) {
3943ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
3953ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten      } else {
3963ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten          dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd);
3973ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten      }
3983ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
399a542782d0045588e55e075a763cedcd2d504ad22Andy Hung
400a542782d0045588e55e075a763cedcd2d504ad22Andy Hung    /* slow traces for slow operations */
401a542782d0045588e55e075a763cedcd2d504ad22Andy Hung    if (anr_traces_path[0] != 0) {
402a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        int tail = strlen(anr_traces_path)-1;
4033ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        while (tail > 0 && anr_traces_path[tail] != '/') {
4043ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten            tail--;
405dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten        }
4063ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        int i = 0;
4073ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        while (1) {
4083ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten            sprintf(anr_traces_path+tail+1, "slow%02d.txt", i);
4093ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten            if (stat(anr_traces_path, &st)) {
4103ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten                // No traces file at this index, done with the files.
4113ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten                break;
41281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
41381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            dump_file("VM TRACES WHEN SLOW", anr_traces_path);
41481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            i++;
41581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
41681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
41781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4180c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    int dumped = 0;
4190c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
4200c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten        if (tombstone_data[i].fd != -1) {
4210c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten            dumped = 1;
4220c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten            dump_file_from_fd("TOMBSTONE", tombstone_data[i].name, tombstone_data[i].fd);
4230c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten            tombstone_data[i].fd = -1;
4240c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten        }
4250c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    }
42681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!dumped) {
42781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
428030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    }
429030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten
430030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    dump_file("NETWORK DEV INFO", "/proc/net/dev");
431030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
432030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt");
433030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
434030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
435030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten
436030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    if (!stat(PSTORE_LAST_KMSG, &st)) {
43781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
43881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        dump_file("LAST KMSG", PSTORE_LAST_KMSG);
43981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
44081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
44181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        dump_file("LAST KMSG", "/proc/last_kmsg");
44281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
44381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
44481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
44581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("LAST LOGCAT", 10, "logcat", "-L",
44681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                             "-b", "all",
44781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                             "-v", "threadtime",
44881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                             "-v", "printable",
449aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent                                             "-d",
45081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                             "*:v", NULL);
45181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
45281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
45381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
454aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent    run_command("NETWORK INTERFACES", 10, "ip", "link", NULL);
455aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent
456aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent    run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL);
457d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten    run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL);
45881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
45981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("IP RULES", 10, "ip", "rule", "show", NULL);
46081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
46181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
46281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_route_tables();
46381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
464b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
46582aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten    run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
46681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
46781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
468b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
46981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
470c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    /* no ip6 nat */
47181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL);
472b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
473b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen
474b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    run_command("WIFI NETWORKS", 20,
47581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL);
476b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen
47781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef FWDUMP_bcmdhd
47881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("ND OFFLOAD TABLE", 5,
47981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            SU_PATH, "root", "wlutil", "nd_hostip", NULL);
480bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
48181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20,
482bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            SU_PATH, "root", "wlutil", "counters", NULL);
483bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
484bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("ND OFFLOAD STATUS (1)", 5,
485bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            SU_PATH, "root", "wlutil", "nd_status", NULL);
486bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
487bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif
488bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    dump_file("INTERRUPTS (1)", "/proc/interrupts");
489bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
490bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL);
491bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
492bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#ifdef FWDUMP_bcmdhd
493bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("DUMP WIFI STATUS", 20,
494bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
495bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
496bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20,
497bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            SU_PATH, "root", "wlutil", "counters", NULL);
498bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
499bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("ND OFFLOAD STATUS (2)", 5,
500bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            SU_PATH, "root", "wlutil", "nd_status", NULL);
501bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif
502bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    dump_file("INTERRUPTS (2)", "/proc/interrupts");
503bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
504bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    print_properties();
505bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
506bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
507bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
508bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
509bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
510bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
511bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
512bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
513bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    printf("------ BACKLIGHTS ------\n");
514bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    printf("LCD brightness=");
51581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
51681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Button brightness=");
51781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
51881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("Keyboard brightness=");
51981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
52081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("ALS mode=");
52181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
52281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("LCD driver registers:\n");
52381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
52481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("\n");
52581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
52681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* Binder state is expensive to look at as it uses a lot of memory. */
52781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
52881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
52981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
53081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
5311d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath    dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
532377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT
533b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    printf("========================================================\n");
53481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("== Board\n");
53581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("========================================================\n");
53681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
53781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    dumpstate_board();
53881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("\n");
53981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
54081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* Migrate the ril_dumpstate to a dumpstate_board()? */
54181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
5429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
543c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
544c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
545f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            // su does not exist on user builds, so try running without it.
546377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            // This way any implementations of vril-dump that do not require
547377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            // root can run on user builds.
54896f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
54982aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten                    "vril-dump", NULL);
55081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
55181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
55281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    SU_PATH, "root", "vril-dump", NULL);
5539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        }
5549f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
5559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("========================================================\n");
55781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("== Android Framework Services\n");
55881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("========================================================\n");
559d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten
56081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* the full dumpsys is starting to take a long time, so we need
5619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten       to increase its timeout.  we really need to do the timeouts in
5629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten       dumpsys itself... */
5639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    run_command("DUMPSYS", 60, "dumpsys", NULL);
5649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
5659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("========================================================\n");
5669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("== Checkins\n");
5679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("========================================================\n");
56882aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten
5692812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    run_command("CHECKIN BATTERYSTATS", 30, "dumpsys", "batterystats", "-c", NULL);
5702812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    run_command("CHECKIN MEMINFO", 30, "dumpsys", "meminfo", "--checkin", NULL);
57181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("CHECKIN NETSTATS", 30, "dumpsys", "netstats", "--checkin", NULL);
5722812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    run_command("CHECKIN PROCSTATS", 30, "dumpsys", "procstats", "-c", NULL);
5739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    run_command("CHECKIN USAGESTATS", 30, "dumpsys", "usagestats", "-c", NULL);
57481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("CHECKIN PACKAGE", 30, "dumpsys", "package", "--checkin", NULL);
57581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5766466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("========================================================\n");
5776466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("== Running Application Activities\n");
5786466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("========================================================\n");
5796466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
58027876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL);
58127876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung
58227876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    printf("========================================================\n");
58327876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    printf("== Running Application Services\n");
58481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    printf("========================================================\n");
58527876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung
58627876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL);
58727876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung
58827876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    printf("========================================================\n");
58927876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    printf("== Running Application Providers\n");
5909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    printf("========================================================\n");
59181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
59281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL);
593818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
5946466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
5956466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("========================================================\n");
5966466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("== dumpstate: done\n");
5976466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    printf("========================================================\n");
598818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung}
5996ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
6006ae5843c281301a9ffd1059d185620a9337e15a2Andy Hungstatic void usage() {
6016ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s] [-q]\n"
602818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            "  -o: write to file (instead of stdout)\n"
6036ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung            "  -d: append date to filename (requires -o)\n"
604818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            "  -z: generates zipped file (requires -o)\n"
6056ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung            "  -p: capture screenshot to filename.png (requires -o)\n"
6066ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung            "  -s: write output to control socket (for init)\n"
60781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "  -b: play sound file instead of vibrate, at beginning of job\n"
60881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            "  -e: play sound file instead of vibrate, at end of job\n"
6098d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly            "  -q: disable vibrate\n"
6108d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly            "  -B: send broadcast when finished (requires -o)\n"
6118d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly            "  -P: send broadacast when started and update system properties on progress (requires -o and -B)\n"
6128d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly                );
613164985121796cf214c7a83d32005d9b01125b558Eric Laurent}
614164985121796cf214c7a83d32005d9b01125b558Eric Laurent
615164985121796cf214c7a83d32005d9b01125b558Eric Laurentstatic void sigpipe_handler(int n) {
616164985121796cf214c7a83d32005d9b01125b558Eric Laurent    // don't complain to stderr or stdout
61781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    _exit(EXIT_FAILURE);
61881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
61981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
620e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burkstatic void vibrate(FILE* vibrator, int ms) {
62196f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    fprintf(vibrator, "%d\n", ms);
62281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    fflush(vibrator);
62396f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten}
62481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
62581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* adds a new entry to the existing zip file. */
62681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic bool add_zip_entry(ZipWriter* writer, const std::string& entry_name,
62781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const std::string& entry_path, time_t entry_time) {
62881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int32_t err = writer->StartEntryWithTime(entry_name.c_str(),
6290f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten            ZipWriter::kCompress, entry_time);
630d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten    if (err) {
63181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(), ZipWriter::ErrorCodeString(err));
63281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return false;
63381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
63481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
63581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ScopedFd fd(TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
63681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (fd.get() == -1) {
63781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno));
638813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        return false;
639813e2a74853bde19e37d878c596a044b3f299efcEric Laurent    }
640813e2a74853bde19e37d878c596a044b3f299efcEric Laurent
641813e2a74853bde19e37d878c596a044b3f299efcEric Laurent    while (1) {
6425baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent        std::vector<uint8_t> buffer(65536);
6435baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), sizeof(buffer)));
644813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        if (bytes_read == 0) {
645813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            break;
646813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        } else if (bytes_read == -1) {
647813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            ALOGE("read(%s): %s\n", entry_path.c_str(), strerror(errno));
648813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            return false;
64981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
65081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        err = writer->WriteBytes(buffer.data(), bytes_read);
65181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (err) {
652bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGE("writer->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err));
6538d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly            return false;
6548d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        }
6558d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    }
6568d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
657bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    err = writer->FinishEntry();
658bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (err) {
659bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGE("writer->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
660bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return false;
661bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
662bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
663bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    return true;
664bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
66581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
66681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* adds the temporary report to the existing .zip file, closes the .zip file, and removes the
66781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent   temporary file.
66881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent */
66981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic bool finish_zip_file(ZipWriter* writer,
670e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        const std::string& bugreport_name, const std::string& bugreport_path,
671e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        time_t now) {
672e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    if (!add_zip_entry(writer, bugreport_name, bugreport_path, now)) {
673e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        ALOGE("Failed to add text entry to .zip file\n");
674e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        return false;
675bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
676240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George
677240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George    int32_t err = writer->Finish();
678240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George    if (err) {
679240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        ALOGE("writer->Finish(): %s\n", ZipWriter::ErrorCodeString(err));
680240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        return false;
681240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George    }
682bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
683bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (remove(bugreport_path.c_str())) {
684bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGW("remove(%s): %s\n", bugreport_path.c_str(), strerror(errno));
685bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
686bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
687bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    return true;
68881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
68981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
690bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentint main(int argc, char *argv[]) {
691bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    struct sigaction sigact;
692bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    int do_add_date = 0;
69312022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    int do_zip_file = 0;
69412022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    int do_vibrate = 1;
69512022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    char* use_outfile = 0;
69612022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    int use_socket = 0;
69712022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    int do_fb = 0;
69812022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten    int do_broadcast = 0;
699e6fb82a207f5256933e2d83e77262331af50a27fAndy Hung    int do_early_screenshot = 0;
700564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent
701564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent    if (getuid() != 0) {
702564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent        // Old versions of the adb client would call the
70381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // dumpstate command directly. Newer clients
70481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // call /system/bin/bugreport instead. If we detect
70581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // we're being called incorrectly, then exec the
70681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // correct program.
70781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL);
70881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
70981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
71081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGI("begin\n");
71181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
71281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* clear SIGPIPE handler */
71381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    memset(&sigact, 0, sizeof(sigact));
71481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sigact.sa_handler = sigpipe_handler;
71581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sigaction(SIGPIPE, &sigact, NULL);
71681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
71781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* set as high priority, and protect from OOM killer */
71881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    setpriority(PRIO_PROCESS, 0, -20);
71981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    FILE *oom_adj = fopen("/proc/self/oom_adj", "we");
72081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (oom_adj) {
72181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        fputs("-17", oom_adj);
72281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        fclose(oom_adj);
723ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    }
72481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
72581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* parse arguments */
726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    int c;
727bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    while ((c = getopt(argc, argv, "dho:svqzpPB")) != -1) {
728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (c) {
729bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            case 'd': do_add_date = 1;          break;
73081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case 'z': do_zip_file = 1;          break;
731e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent            case 'o': use_outfile = optarg;     break;
732e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent            case 's': use_socket = 1;           break;
733e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent            case 'v': break;  // compatibility no-op
73481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case 'q': do_vibrate = 0;           break;
735b369cafd67beb63dd0278dba543f519956208a7fEric Laurent            case 'p': do_fb = 1;                break;
73681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case 'P': do_update_progress = 1;   break;
73781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case 'B': do_broadcast = 1;         break;
73881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case '?': printf("\n");
73981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            case 'h':
74081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                usage();
74181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                exit(1);
74281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
74381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
74481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
74581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) {
74681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        usage();
74781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        exit(1);
748bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
749bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
750bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (do_update_progress && !do_broadcast) {
751bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        usage();
752bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        exit(1);
753bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
754bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
755bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    do_early_screenshot = do_update_progress;
756bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
757bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // If we are going to use a socket, do it as early as possible
758bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // to avoid timeouts from bugreport.
759bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (use_socket) {
760bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        redirect_to_socket(stdout, "dumpstate");
761bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
76281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
76381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* full path of the directory where the bug report files will be written */
764ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent    std::string bugreport_dir;
765bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
766bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    /* full path of the temporary file containing the bug report */
767bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    std::string tmp_path;
768bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
76981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* full path of the temporary file containing the screenshot (when requested) */
77081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    std::string screenshot_path;
77181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
77281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* base name (without suffix or extensions) of the bug report files */
77381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    std::string base_name;
77481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
77581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* suffix of the bug report files - it's typically the date (when invoked with -d),
77681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent     * although it could be changed by the user using a system property */
77781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    std::string suffix;
77881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
77981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* pointer to the actual path, be it zip or text */
780bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    std::string path;
781bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
782bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    /* pointers to the zipped file file */
783bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    std::unique_ptr<FILE, int(*)(FILE*)> zip_file(NULL, fclose);
784bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    std::unique_ptr<ZipWriter> zip_writer;
785bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
786bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    time_t now = time(NULL);
787bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
788bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    /* redirect output if needed */
789bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    bool is_redirecting = !use_socket && use_outfile;
790bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
79181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (is_redirecting) {
792bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        bugreport_dir = dirname(use_outfile);
793bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        base_name = basename(use_outfile);
794bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (do_add_date) {
795bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            char date[80];
796bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&now));
797bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            suffix = date;
7987844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George        } else {
799bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            suffix = "undated";
800bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
801bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (do_fb) {
802bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // TODO: if dumpstate was an object, the paths could be internal variables and then
803bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // we could have a function to calculate the derived values, such as:
804bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            //     screenshot_path = GetPath(".png");
805bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            screenshot_path = bugreport_dir + "/" + base_name + "-" + suffix + ".png";
806bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
807bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        tmp_path = bugreport_dir + "/" + base_name + "-" + suffix + ".tmp";
808bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
809bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGD("Bugreport dir: %s\nBase name: %s\nSuffix: %s\nTemporary path: %s\n"
810bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                "Screenshot path: %s\n", bugreport_dir.c_str(), base_name.c_str(), suffix.c_str(),
811bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                tmp_path.c_str(), screenshot_path.c_str());
812d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent
813d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent        if (do_zip_file) {
814d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            ALOGD("Creating initial .zip file");
815bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip";
816bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            zip_file.reset(fopen(path.c_str(), "wb"));
817bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (!zip_file) {
81881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno));
819bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                do_zip_file = 0;
820bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            } else {
821bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                zip_writer.reset(new ZipWriter(zip_file.get()));
822ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent            }
82381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
82481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
82581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (do_update_progress) {
8267844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            std::vector<std::string> am_args = {
8277844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George                 "--receiver-permission", "android.permission.DUMP",
8287844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George                 "--es", "android.intent.extra.NAME", suffix,
829d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent                 "--ei", "android.intent.extra.PID", std::to_string(getpid()),
8307844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George                 "--ei", "android.intent.extra.MAX", std::to_string(WEIGHT_TOTAL),
8317844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            };
8327844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            send_broadcast("android.intent.action.BUGREPORT_STARTED", am_args);
8337844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George        }
8347844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    }
83581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
83681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    print_header();
83781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
83881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* open the vibrator before dropping root */
83981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    std::unique_ptr<FILE, int(*)(FILE*)> vibrator(NULL, fclose);
84081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (do_vibrate) {
84181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        vibrator.reset(fopen("/sys/class/timed_output/vibrator/enable", "we"));
84296f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        if (vibrator) {
84381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            vibrate(vibrator.get(), 150);
84481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
84581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
84681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
84781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (do_fb && do_early_screenshot) {
84881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (screenshot_path.empty()) {
84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // should not have happened
85081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGE("INTERNAL ERROR: skipping early screenshot because path was not set");
851bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        } else {
852bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGI("taking early screenshot\n");
853bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            take_screenshot(screenshot_path);
854bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
855bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) {
856bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGE("Unable to change ownership of screenshot file %s: %s\n",
857bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        screenshot_path.c_str(), strerror(errno));
858bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
859bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
860bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
861bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
862bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (do_zip_file) {
863bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (chown(path.c_str(), AID_SHELL, AID_SHELL)) {
864bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGE("Unable to change ownership of zip file %s: %s\n", path.c_str(), strerror(errno));
865573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten        }
866573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    }
867818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
868818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    /* read /proc/cmdline before dropping root */
869fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    FILE *cmdline = fopen("/proc/cmdline", "re");
870573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    if (cmdline) {
871573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
872fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten        fclose(cmdline);
873573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    }
8746140c79c31f5dc237fba69554de5be641cedf113Phil Burk
875573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    /* collect stack traces from Dalvik and native processes (needs root) */
876573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    dump_traces_path = dump_traces();
877818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
878573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    /* Get the tombstone fds here while we are running as root. */
879573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    get_tombstone_fds(tombstone_data);
88081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
88181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* ensure we will keep capabilities when we drop root */
88281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
88381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
88481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -1;
88581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
88681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
88781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* switch to non-root user and group */
88881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
88981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC };
89081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
89181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
89281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -1;
89381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
89481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (setgid(AID_SHELL) != 0) {
89581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("Unable to setgid, aborting: %s\n", strerror(errno));
89681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -1;
89781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
89881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (setuid(AID_SHELL) != 0) {
89981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("Unable to setuid, aborting: %s\n", strerror(errno));
90081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -1;
90181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
90281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
90381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct __user_cap_header_struct capheader;
90481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    struct __user_cap_data_struct capdata[2];
9055baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent    memset(&capheader, 0, sizeof(capheader));
9065baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent    memset(&capdata, 0, sizeof(capdata));
9075baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent    capheader.version = _LINUX_CAPABILITY_VERSION_3;
9085baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent    capheader.pid = 0;
9095baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent
91081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
91181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
91281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    capdata[0].inheritable = 0;
91381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    capdata[1].inheritable = 0;
91481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
91581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (capset(&capheader, &capdata[0]) < 0) {
91681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGE("capset failed: %s\n", strerror(errno));
91781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return -1;
91881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
91981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
92081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (is_redirecting) {
92181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        /* TODO: rather than generating a text file now and zipping it later,
92281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent           it would be more efficient to redirect stdout to the zip entry
92381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent           directly, but the libziparchive doesn't support that option yet. */
92481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str()));
92581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
92681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
927d72b7c0180ee83fc3754629ed68fc5887a125c4cEric Laurent    dumpstate(do_early_screenshot ? "": screenshot_path);
92881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
92981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* done */
93081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (vibrator) {
93181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (int i = 0; i < 3; i++) {
93281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            vibrate(vibrator.get(), 75);
93381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            usleep((75 + 50) * 1000);
93481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
93581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
93681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
93781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* close output if needed */
93881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (is_redirecting) {
93981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        fclose(stdout);
940818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    }
941818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
94281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* rename or zip the (now complete) .tmp file to its final location */
943818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    if (use_outfile) {
944818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
945818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        /* check if user changed the suffix using system properties */
94681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        char key[PROPERTY_KEY_MAX];
94781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        char value[PROPERTY_VALUE_MAX];
94881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sprintf(key, "dumpstate.%d.name", getpid());
949bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        property_get(key, value, "");
950bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        bool change_suffix= false;
951bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (value[0]) {
952bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            /* must whitelist which characters are allowed, otherwise it could cross directories */
953818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            std::regex valid_regex("^[-_a-zA-Z0-9]+$");
954818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            if (std::regex_match(value, valid_regex)) {
95581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                change_suffix = true;
95681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
957818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                ALOGE("invalid suffix provided by user: %s", value);
958818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            }
95981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
960bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (change_suffix) {
961c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung            ALOGI("changing suffix from %s to %s", suffix.c_str(), value);
962c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung            suffix = value;
963c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung            if (!screenshot_path.empty()) {
964c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                std::string new_screenshot_path =
965c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                        bugreport_dir + "/" + base_name + "-" + suffix + ".png";
966c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                if (rename(screenshot_path.c_str(), new_screenshot_path.c_str())) {
967c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                    ALOGE("rename(%s, %s): %s\n", screenshot_path.c_str(),
968c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                            new_screenshot_path.c_str(), strerror(errno));
969c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                } else {
970c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                    screenshot_path = new_screenshot_path;
971c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                }
97281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
973bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
97481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
97581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        bool do_text_file = true;
97681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (do_zip_file) {
97781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGD("Adding text entry to .zip bugreport");
97881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!finish_zip_file(zip_writer.get(), base_name + "-" + suffix + ".txt", tmp_path, now)) {
97981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("Failed to finish zip file; sending text bugreport instead\n");
98081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                do_text_file = true;
9813ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn            } else {
98281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                do_text_file = false;
98381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
98481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
98581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (do_text_file) {
98681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGD("Generating .txt bugreport");
98781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            path = bugreport_dir + "/" + base_name + "-" + suffix + ".txt";
98881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (rename(tmp_path.c_str(), path.c_str())) {
98981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("rename(%s, %s): %s\n", tmp_path.c_str(), path.c_str(), strerror(errno));
99081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                path.clear();
99181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
992c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        }
99381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
99481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
99581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    /* tell activity manager we're done */
996c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (do_broadcast) {
997c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        if (!path.empty()) {
998c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            ALOGI("Final bugreport path: %s\n", path.c_str());
99981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            std::vector<std::string> am_args = {
1000c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                 "--receiver-permission", "android.permission.DUMP",
1001c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten                 "--ei", "android.intent.extra.PID", std::to_string(getpid()),
100281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                 "--es", "android.intent.extra.BUGREPORT", path
1003c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            };
1004c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            if (do_fb) {
100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                am_args.push_back("--es");
100681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                am_args.push_back("android.intent.extra.SCREENSHOT");
100781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                am_args.push_back(screenshot_path);
100881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
100981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
101081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
1011c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            ALOGE("Skipping finished broadcast because bugreport could not be generated\n");
1012c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        }
101381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
101481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL);
101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGI("done\n");
101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return 0;
1019bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
102081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent