dumpstate.cpp revision 558e1ef07fb6169a1501a9b8637387abef611f34
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/*
2f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Copyright (C) 2008 The Android Open Source Project
3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
4f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * you may not use this file except in compliance with the License.
6f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * You may obtain a copy of the License at
7f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
8f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
10f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Unless required by applicable law or agreed to in writing, software
11f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * See the License for the specific language governing permissions and
14f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * limitations under the License.
15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */
16f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
176c3d90f89a4313eb449c770db6f05b2819cdd8bbMark Salyzyn#define LOG_TAG "dumpstate"
18f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
192db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg#include <dirent.h>
20f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <errno.h>
21f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <fcntl.h>
22ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme#include <libgen.h>
23f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <limits.h>
248f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn#include <stdbool.h>
25f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h>
26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdlib.h>
27f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h>
28e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair#include <sys/poll.h>
297dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris#include <sys/prctl.h>
30f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/resource.h>
31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/stat.h>
32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h>
33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/wait.h>
34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <unistd.h>
358f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath#include <memory>
368f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath#include <regex>
378f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath#include <set>
388f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath#include <string>
398f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath#include <vector>
40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
4196c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme#include <android-base/file.h>
4296c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme#include <android-base/properties.h>
439dc117c415d0df0a3acd900709d05deabe975704Elliott Hughes#include <android-base/stringprintf.h>
44058e1e8ce51327e00636d3b0008671dc09c20259Naveen Kalla#include <android-base/strings.h>
45aff684300a3b7d6984d3b3c1efddb810cd0205e7Andreas Gampe#include <android-base/unique_fd.h>
466f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
4744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland#include <android/hidl/manager/1.0/IServiceManager.h>
486f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme#include <cutils/native_handle.h>
49f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <cutils/properties.h>
50e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair#include <dumpsys.h>
5144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland#include <hidl/ServiceManagement.h>
5275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#include <openssl/sha.h>
536c3d90f89a4313eb449c770db6f05b2819cdd8bbMark Salyzyn#include <private/android_filesystem_config.h>
546c3d90f89a4313eb449c770db6f05b2819cdd8bbMark Salyzyn#include <private/android_logger.h>
55e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair#include <serviceutils/PriorityDumper.h>
56f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme#include "DumpstateInternal.h"
57e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair#include "DumpstateSectionReporter.h"
5875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme#include "DumpstateService.h"
59f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include "dumpstate.h"
606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
61cb7ef82aef52e766c45f65f446d02fd9356afea4Steven Morelandusing ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
62e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing ::std::literals::chrono_literals::operator""ms;
63e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing ::std::literals::chrono_literals::operator""s;
64cb7ef82aef52e766c45f65f446d02fd9356afea4Steven Moreland
6547e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme// TODO: remove once moved to namespace
66e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::defaultServiceManager;
67e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::Dumpsys;
68e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::INVALID_OPERATION;
69e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::IServiceManager;
70e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::OK;
71e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::sp;
72e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::status_t;
73e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::String16;
74e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::String8;
75e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::TIMED_OUT;
76e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::UNKNOWN_ERROR;
77e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::Vector;
7847e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemeusing android::os::dumpstate::CommandOptions;
7947e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemeusing android::os::dumpstate::DumpFileToFd;
80e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::os::dumpstate::DumpstateSectionReporter;
8147e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Lemeusing android::os::dumpstate::GetPidByName;
82e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairusing android::os::dumpstate::PropertiesHelper;
8347e9be2d71c5eca9002e289c98e8bbc20dffc073Felipe Leme
84f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/* read before root is shed */
85f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic char cmdline_buf[16384] = "(unknown)";
86f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic const char *dump_traces_path = NULL;
87f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
881d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme// TODO: variables and functions below should be part of dumpstate object
891d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme
90635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemestatic std::set<std::string> mount_points;
91635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo();
9278f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme
932a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
947d0a762ecaf9f4d005f0f6db913034c2e084d362Mark Salyzyn#define ALT_PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops-0"
95509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang#define BLK_DEV_SYS_DIR "/sys/block"
962a83daa8a3e1eab292dc1464bbe78f025f4bc0e9Todd Poynor
97341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu#define RAFT_DIR "/data/misc/raft"
98e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme#define RECOVERY_DIR "/cache/recovery"
99d6ab01105bbd80dfa2fc2debc8e31d6422c378eeMark Salyzyn#define RECOVERY_DATA_DIR "/data/misc/recovery"
1004d42dea08915ccbb61ca05903af5330d02d66755Mark Salyzyn#define LOGPERSIST_DATA_DIR "/data/misc/logd"
101d2991962b7120319a4fa63f1a93b100adaad5dbeDavid Brazdil#define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
102d2991962b7120319a4fa63f1a93b100adaad5dbeDavid Brazdil#define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
1030816520c5cd60519d8e221ed92497aa5464e3039Erik Kline#define WLUTIL "/vendor/xbin/wlutil"
10436b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair#define WMTRACE_DATA_DIR "/data/misc/wmtrace"
1057dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
1068f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath// TODO(narayan): Since this information has to be kept in sync
1078f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath// with tombstoned, we should just put it in a common header.
1088f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath//
1098f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath// File: system/core/debuggerd/tombstoned/tombstoned.cpp
110bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamathstatic const std::string TOMBSTONE_DIR = "/data/tombstones/";
111bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamathstatic const std::string TOMBSTONE_FILE_PREFIX = "tombstone_";
112bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamathstatic const std::string ANR_DIR = "/data/anr/";
113bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamathstatic const std::string ANR_FILE_PREFIX = "anr_";
1148f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
115e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme// TODO: temporary variables and functions used during C++ refactoring
116e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Lemestatic Dumpstate& ds = Dumpstate::GetInstance();
117678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Lemestatic int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
118678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme                      const CommandOptions& options = CommandOptions::DEFAULT) {
119678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    return ds.RunCommand(title, fullCommand, options);
120678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme}
121678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Lemestatic void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs,
122bda15a00929b836a53bf03473b1ec36285e5944bFelipe Leme                       const CommandOptions& options = Dumpstate::DEFAULT_DUMPSYS,
1236921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair                       long dumpsysTimeoutMs = 0) {
1246921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeoutMs);
125678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme}
126678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Lemestatic int DumpFile(const std::string& title, const std::string& path) {
127678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    return ds.DumpFile(title, path);
128678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme}
129e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
130e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme// Relative directory (inside the zip) for all files copied as-is into the bugreport.
131e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Lemestatic const std::string ZIP_ROOT_DIR = "FS";
132e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme
1337440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland// Must be hardcoded because dumpstate HAL implementation need SELinux access to it
1349fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Songstatic const std::string kDumpstateBoardPath = "/bugreports/";
135e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairstatic const std::string kProtoPath = "proto/";
136e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairstatic const std::string kProtoExt = ".proto";
1379fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Songstatic const std::string kDumpstateBoardFiles[] = {
1389fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    "dumpstate_board.txt",
13995d6ca5df402889c4a9819e1422867b61283c0c8Felipe Leme    "dumpstate_board.bin"
1409fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song};
1419fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Songstatic const int NUM_OF_DUMPS = arraysize(kDumpstateBoardFiles);
1429fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song
1439ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Lemestatic constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
14496c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Lemestatic constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
145d071c6802a03031b26de7b92a76d03849681149bFelipe Lemestatic constexpr char PROPERTY_VERSION[] = "dumpstate.version";
146b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kallastatic constexpr char PROPERTY_EXTRA_TITLE[] = "dumpstate.options.title";
147b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kallastatic constexpr char PROPERTY_EXTRA_DESCRIPTION[] = "dumpstate.options.description";
1489ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme
149f029297f673ae06d219bd727a318a48b885db6fdFelipe Lemestatic const CommandOptions AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot().Build();
150f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme
1518f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath/*
152bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath * Returns a vector of dump fds under |dir_path| with a given |file_prefix|.
153bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath * The returned vector is sorted by the mtimes of the dumps. If |limit_by_mtime|
154bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath * is set, the vector only contains files that were written in the last 30 minutes.
155d0d7695ecbfd12aaecc8aec66aacb487b116ac0bAndreas Gampe * If |limit_by_count| is set, the vector only contains the ten latest files.
1568f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath */
1575f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavezstatic std::vector<DumpData> GetDumpFds(const std::string& dir_path,
1585f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez                                        const std::string& file_prefix,
1595f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez                                        bool limit_by_mtime,
1605f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez                                        bool limit_by_count = true) {
1618f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    const time_t thirty_minutes_ago = ds.now_ - 60 * 30;
1628f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
163bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir);
1648f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
165d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez    if (dump_dir == nullptr) {
166d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez        MYLOGW("Unable to open directory %s: %s\n", dir_path.c_str(), strerror(errno));
1675f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        return std::vector<DumpData>();
168d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez    }
169d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez
1705f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    std::vector<DumpData> dump_data;
171bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    struct dirent* entry = nullptr;
172bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    while ((entry = readdir(dump_dir.get()))) {
173bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        if (entry->d_type != DT_REG) {
174bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath            continue;
1758f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
1768f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
177bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        const std::string base_name(entry->d_name);
178bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        if (base_name.find(file_prefix) != 0) {
1798f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            continue;
1808f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
1818f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
182bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        const std::string abs_path = dir_path + base_name;
183bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        android::base::unique_fd fd(
184bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath            TEMP_FAILURE_RETRY(open(abs_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
185bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        if (fd == -1) {
186d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez            MYLOGW("Unable to open dump file %s: %s\n", abs_path.c_str(), strerror(errno));
187bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath            break;
188bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        }
189bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath
190bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        struct stat st = {};
191bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        if (fstat(fd, &st) == -1) {
192d05127172ce1f113230b1774119b6d54475dc158Luis Hector Chavez            MYLOGW("Unable to stat dump file %s: %s\n", abs_path.c_str(), strerror(errno));
1938f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            continue;
1948f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
1958f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
1963f31b6319f88ba81470c21711dacfb0b8bf11beeNarayan Kamath        if (limit_by_mtime && st.st_mtime < thirty_minutes_ago) {
197bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath            MYLOGI("Excluding stale dump file: %s\n", abs_path.c_str());
1988f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            continue;
1998f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
2008f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
2015f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        dump_data.emplace_back(DumpData{abs_path, std::move(fd), st.st_mtime});
2028f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    }
2038f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
2045f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    // Sort in descending modification time so that we only keep the newest
2055f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    // reports if |limit_by_count| is true.
2065f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    std::sort(dump_data.begin(), dump_data.end(),
2075f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez              [](const DumpData& d1, const DumpData& d2) { return d1.mtime > d2.mtime; });
2088f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
2095f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    if (limit_by_count && dump_data.size() > 10) {
2105f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        dump_data.erase(dump_data.begin() + 10, dump_data.end());
211d0d7695ecbfd12aaecc8aec66aacb487b116ac0bAndreas Gampe    }
212d0d7695ecbfd12aaecc8aec66aacb487b116ac0bAndreas Gampe
2135f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    return dump_data;
2148f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath}
2158f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
216bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamathstatic bool AddDumps(const std::vector<DumpData>::const_iterator start,
217bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath                     const std::vector<DumpData>::const_iterator end,
218bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath                     const char* type_name, const bool add_to_zip) {
2198f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    bool dumped = false;
220bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    for (auto it = start; it != end; ++it) {
221bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        const std::string& name = it->name;
222bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        const int fd = it->fd;
2238f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        dumped = true;
2246b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath
2256b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // Seek to the beginning of the file before dumping any data. A given
2266b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // DumpData entry might be dumped multiple times in the report.
2276b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        //
2286b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // For example, the most recent ANR entry is dumped to the body of the
2296b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // main entry and it also shows up as a separate entry in the bugreport
2306b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // ZIP file.
2316b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        if (lseek(fd, 0, SEEK_SET) != static_cast<off_t>(0)) {
2326b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath            MYLOGE("Unable to add %s to zip file, lseek failed: %s\n", name.c_str(),
2336b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath                   strerror(errno));
2346b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        }
2356b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath
2368f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        if (ds.IsZipping() && add_to_zip) {
237e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            if (ds.AddZipEntryFromFd(ZIP_ROOT_DIR + name, fd, /* timeout = */ 0ms) != OK) {
2386b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath                MYLOGE("Unable to add %s to zip file, addZipEntryFromFd failed\n", name.c_str());
2398f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            }
2407dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        } else {
2418f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            dump_file_from_fd(type_name, name.c_str(), fd);
2427dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris        }
2437dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    }
2448f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
2458f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    return dumped;
2467dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris}
2477dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
248635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme// for_each_pid() callback to get mount info about a process.
2494c2d66379753e2b7680811726424026b9e54b18aFelipe Lemevoid do_mountinfo(int pid, const char* name __attribute__((unused))) {
250635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    char path[PATH_MAX];
251635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
252635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    // Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points
253635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    // are added.
254f0922cc1786c0c2fbf44c10b0005243ecbb4227dNick Kralevich    snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
255635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    char linkname[PATH_MAX];
256635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    ssize_t r = readlink(path, linkname, PATH_MAX);
257635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    if (r == -1) {
258cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGE("Unable to read link for %s: %s\n", path, strerror(errno));
259635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        return;
260635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    }
261635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    linkname[r] = '\0';
262635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
263635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    if (mount_points.find(linkname) == mount_points.end()) {
264635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        // First time this mount point was found: add it
265f0922cc1786c0c2fbf44c10b0005243ecbb4227dNick Kralevich        snprintf(path, sizeof(path), "/proc/%d/mountinfo", pid);
2661d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        if (ds.AddZipEntry(ZIP_ROOT_DIR + path, path)) {
267635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme            mount_points.insert(linkname);
268635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        } else {
269cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGE("Unable to add mountinfo %s to zip file\n", path);
270635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme        }
271635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    }
272635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme}
273635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
274635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Lemevoid add_mountinfo() {
2751d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.IsZipping()) return;
276678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    std::string title = "MOUNT INFO";
277635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme    mount_points.clear();
27846b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    DurationReporter duration_reporter(title, true);
279678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    for_each_pid(do_mountinfo, nullptr);
280678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    MYLOGD("%s: %d entries added to zip file\n", title.c_str(), (int)mount_points.size());
281635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme}
282635ca31754ae734b0c540ac5600d58ae55cd4237Felipe Leme
2832db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevågstatic void dump_dev_files(const char *title, const char *driverpath, const char *filename)
2842db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg{
2852db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    DIR *d;
2862db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    struct dirent *de;
2872db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    char path[PATH_MAX];
2882db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
2892db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    d = opendir(driverpath);
2902db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    if (d == NULL) {
2912db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        return;
2922db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    }
2932db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
2942db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    while ((de = readdir(d))) {
2952db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        if (de->d_type != DT_LNK) {
2962db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg            continue;
2972db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        }
2982db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg        snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
299b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        DumpFile(title, path);
3002db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    }
3012db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
3022db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    closedir(d);
3032db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg}
3042db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg
305068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
306068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
307068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian// dump anrd's trace and add to the zip file.
308068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian// 1. check if anrd is running on this device.
309068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian// 2. send a SIGUSR1 to its pid which will dump anrd's trace.
310068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian// 3. wait until the trace generation completes and add to the zip file.
311068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qianstatic bool dump_anrd_trace() {
312068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    unsigned int pid;
313068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    char buf[50], path[PATH_MAX];
314068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    struct dirent *trace;
315068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    struct stat st;
316068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    DIR *trace_dir;
317afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian    int retry = 5;
318afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian    long max_ctime = 0, old_mtime;
319068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    long long cur_size = 0;
320068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    const char *trace_path = "/data/misc/anrd/";
321068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
3221d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.IsZipping()) {
3231d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGE("Not dumping anrd trace because it's not a zipped bugreport\n");
324068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        return false;
325068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    }
326068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
327068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    // find anrd's pid if it is running.
32861ffcf73d50dbed5b52265e79bb73abf1849324dEcco Park    pid = GetPidByName("/system/xbin/anrd");
329068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
330068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    if (pid > 0) {
331afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        if (stat(trace_path, &st) == 0) {
332afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            old_mtime = st.st_mtime;
333afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        } else {
334afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            MYLOGE("Failed to find: %s\n", trace_path);
335afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            return false;
336afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        }
337afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian
338068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        // send SIGUSR1 to the anrd to generate a trace.
339068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        sprintf(buf, "%u", pid);
340b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        if (RunCommand("ANRD_DUMP", {"kill", "-SIGUSR1", buf},
34130dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme                       CommandOptions::WithTimeout(1).Build())) {
342068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            MYLOGE("anrd signal timed out. Please manually collect trace\n");
343068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            return false;
344068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        }
345068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
346afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        while (retry-- > 0 && old_mtime == st.st_mtime) {
347afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            sleep(1);
348afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            stat(trace_path, &st);
349afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        }
350afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian
351afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        if (retry < 0 && old_mtime == st.st_mtime) {
352afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path);
353afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian            return false;
354afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian        }
355afc38fe263c0997385529d72d9211189b3d6d075Zhengyin Qian
356068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        // identify the trace file by its creation time.
357068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        if (!(trace_dir = opendir(trace_path))) {
358068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            MYLOGE("Can't open trace file under %s\n", trace_path);
359068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        }
360068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        while ((trace = readdir(trace_dir))) {
361068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            if (strcmp(trace->d_name, ".") == 0
362068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    || strcmp(trace->d_name, "..") == 0) {
363068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                continue;
364068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            }
365068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            sprintf(path, "%s%s", trace_path, trace->d_name);
366068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            if (stat(path, &st) == 0) {
367068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                if (st.st_ctime > max_ctime) {
368068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    max_ctime = st.st_ctime;
369068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    sprintf(buf, "%s", trace->d_name);
370068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                }
371068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            }
372068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        }
373068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        closedir(trace_dir);
374068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
375068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        // Wait until the dump completes by checking the size of the trace.
376068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        if (max_ctime > 0) {
377068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            sprintf(path, "%s%s", trace_path, buf);
378068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            while(true) {
379068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                sleep(1);
380068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                if (stat(path, &st) == 0) {
381068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    if (st.st_size == cur_size) {
382068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                        break;
383068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    } else if (st.st_size > cur_size) {
384068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                        cur_size = st.st_size;
385068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    } else {
386068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                        return false;
387068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    }
388068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                } else {
389068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    MYLOGE("Cant stat() %s anymore\n", path);
390068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    return false;
391068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                }
392068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            }
393068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            // Add to the zip file.
3941d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme            if (!ds.AddZipEntry("anrd_trace.txt", path)) {
395068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                MYLOGE("Unable to add anrd_trace file %s to zip file\n", path);
396068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            } else {
397068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                if (remove(path)) {
398068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                    MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno));
399068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                }
400068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian                return true;
401068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            }
402068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        } else {
403068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian            MYLOGE("Can't stats any trace file under %s\n", trace_path);
404068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian        }
405068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    }
406068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian    return false;
407068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian}
408068ecc731ec96f1fd1a0819dfed642c510ea69bcZhengyin Qian
409efd7e27569b69ed854ed75fca40fc638e3c0268bFelipe Lemestatic void dump_systrace() {
4101d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.IsZipping()) {
4111d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGD("Not dumping systrace because it's not a zipped bugreport\n");
41271a74ac75c8687195d27642fa0db31a796102c59Felipe Leme        return;
41371a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    }
414bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme    std::string systrace_path = ds.GetPath("-systrace.txt");
41514e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme    if (systrace_path.empty()) {
41614e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        MYLOGE("Not dumping systrace because path is empty\n");
41714e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        return;
41814e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme    }
41971a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    const char* path = "/sys/kernel/debug/tracing/tracing_on";
42071a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    long int is_tracing;
42171a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    if (read_file_as_long(path, &is_tracing)) {
42271a74ac75c8687195d27642fa0db31a796102c59Felipe Leme        return; // error already logged
42371a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    }
42471a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    if (is_tracing <= 0) {
42571a74ac75c8687195d27642fa0db31a796102c59Felipe Leme        MYLOGD("Skipping systrace because '%s' content is '%ld'\n", path, is_tracing);
42671a74ac75c8687195d27642fa0db31a796102c59Felipe Leme        return;
42771a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    }
42871a74ac75c8687195d27642fa0db31a796102c59Felipe Leme
42914e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme    MYLOGD("Running '/system/bin/atrace --async_dump -o %s', which can take several minutes",
43014e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme            systrace_path.c_str());
431b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    if (RunCommand("SYSTRACE", {"/system/bin/atrace", "--async_dump", "-o", systrace_path},
43230dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme                   CommandOptions::WithTimeout(120).Build())) {
43314e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        MYLOGE("systrace timed out, its zip entry will be incomplete\n");
434c7fe8fe5b525a1a071af92f3ebbeef2f6d4b06afFelipe Leme        // TODO: RunCommand tries to kill the process, but atrace doesn't die
43530dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // peacefully; ideally, we should call strace to stop itself, but there is no such option
43630dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // yet (just a --async_stop, which stops and dump
437b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        // if (RunCommand("SYSTRACE", {"/system/bin/atrace", "--kill"})) {
43830dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        //   MYLOGE("could not stop systrace ");
43930dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // }
44014e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme    }
4411d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.AddZipEntry("systrace.txt", systrace_path)) {
44214e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        MYLOGE("Unable to add systrace file %s to zip file\n", systrace_path.c_str());
44371a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    } else {
44414e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        if (remove(systrace_path.c_str())) {
44514e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme            MYLOGE("Error removing systrace file %s: %s", systrace_path.c_str(), strerror(errno));
44614e034a02ec34b2c76afb06975bdfc943a9b5607Felipe Leme        }
44771a74ac75c8687195d27642fa0db31a796102c59Felipe Leme    }
44871a74ac75c8687195d27642fa0db31a796102c59Felipe Leme}
44971a74ac75c8687195d27642fa0db31a796102c59Felipe Leme
450efd7e27569b69ed854ed75fca40fc638e3c0268bFelipe Lemestatic void dump_raft() {
451f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    if (PropertiesHelper::IsUserBuild()) {
452341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu        return;
453341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu    }
454341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu
4551d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    std::string raft_path = ds.GetPath("-raft_log.txt");
4561d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (raft_path.empty()) {
4571d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGD("raft_path is empty\n");
458341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu        return;
459341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu    }
460f0e78d4391fd5cea487af116106a7887720b950eWei Liu
461f0e78d4391fd5cea487af116106a7887720b950eWei Liu    struct stat s;
462f0e78d4391fd5cea487af116106a7887720b950eWei Liu    if (stat(RAFT_DIR, &s) != 0 || !S_ISDIR(s.st_mode)) {
463f0e78d4391fd5cea487af116106a7887720b950eWei Liu        MYLOGD("%s does not exist or is not a directory\n", RAFT_DIR);
464f0e78d4391fd5cea487af116106a7887720b950eWei Liu        return;
465f0e78d4391fd5cea487af116106a7887720b950eWei Liu    }
466f0e78d4391fd5cea487af116106a7887720b950eWei Liu
46730dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme    CommandOptions options = CommandOptions::WithTimeout(600).Build();
4681d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.IsZipping()) {
4691d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        // Write compressed and encoded raft logs to stdout if it's not a zipped bugreport.
470b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        RunCommand("RAFT LOGS", {"logcompressor", "-r", RAFT_DIR}, options);
471341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu        return;
472341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu    }
473341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu
4741d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    RunCommand("RAFT LOGS", {"logcompressor", "-n", "-r", RAFT_DIR, "-o", raft_path}, options);
4751d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!ds.AddZipEntry("raft_log.txt", raft_path)) {
4761d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGE("Unable to add raft log %s to zip file\n", raft_path.c_str());
477341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu    } else {
4781d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        if (remove(raft_path.c_str())) {
4791d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme            MYLOGE("Error removing raft file %s: %s\n", raft_path.c_str(), strerror(errno));
480341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu        }
481341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu    }
482341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu}
483341938b446576ebf60865d8b6e5e6175f47766d0Wei Liu
484326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic bool skip_not_stat(const char *path) {
485326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    static const char stat[] = "/stat";
486326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    size_t len = strlen(path);
487326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (path[len - 1] == '/') { /* Directory? */
488326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return false;
489326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
490326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
491326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn}
492326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
4934c2d66379753e2b7680811726424026b9e54b18aFelipe Lemestatic bool skip_none(const char* path __attribute__((unused))) {
494e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    return false;
495e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
496e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
4978f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzynunsigned long worst_write_perf = 20000; /* in KB/s */
498326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
49901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
50001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//  stat offsets
50101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// Name            units         description
50201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// ----            -----         -----------
50301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read I/Os       requests      number of read I/Os processed
50401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_READ_IOS      0
50501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read merges     requests      number of read I/Os merged with in-queue I/O
50601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_READ_MERGES   1
50701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read sectors    sectors       number of sectors read
50801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_READ_SECTORS  2
50901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read ticks      milliseconds  total wait time for read requests
51001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_READ_TICKS    3
51101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// write I/Os      requests      number of write I/Os processed
51201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_WRITE_IOS     4
51301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// write merges    requests      number of write I/Os merged with in-queue I/O
51401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_WRITE_MERGES  5
51501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// write sectors   sectors       number of sectors written
51601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_WRITE_SECTORS 6
51701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// write ticks     milliseconds  total wait time for write requests
51801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_WRITE_TICKS   7
51901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// in_flight       requests      number of I/Os currently in flight
52001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_IN_FLIGHT     8
52101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// io_ticks        milliseconds  total time this block device has been active
52201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_IO_TICKS      9
52301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// time_in_queue   milliseconds  total wait time for all requests
52401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_IN_QUEUE     10
52501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define __STAT_NUMBER_FIELD 11
52601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
52701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read I/Os, write I/Os
52801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// =====================
52901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
53001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// These values increment when an I/O request completes.
53101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
53201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read merges, write merges
53301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// =========================
53401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
53501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// These values increment when an I/O request is merged with an
53601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// already-queued I/O request.
53701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
53801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read sectors, write sectors
53901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// ===========================
54001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
54101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// These values count the number of sectors read from or written to this
54201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// block device.  The "sectors" in question are the standard UNIX 512-byte
54301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// sectors, not any device- or filesystem-specific block size.  The
54401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// counters are incremented when the I/O completes.
54501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define SECTOR_SIZE 512
54601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
54701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// read ticks, write ticks
54801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// =======================
54901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
55001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// These values count the number of milliseconds that I/O requests have
55101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// waited on this block device.  If there are multiple I/O requests waiting,
55201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// these values will increase at a rate greater than 1000/second; for
55301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// example, if 60 read requests wait for an average of 30 ms, the read_ticks
55401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// field will increase by 60*30 = 1800.
55501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
55601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// in_flight
55701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// =========
55801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
55901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// This value counts the number of I/O requests that have been issued to
56001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// the device driver but have not yet completed.  It does not include I/O
56101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// requests that are in the queue but not yet issued to the device driver.
56201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
56301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// io_ticks
56401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// ========
56501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
56601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// This value counts the number of milliseconds during which the device has
56701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// had I/O requests queued.
56801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
56901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// time_in_queue
57001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// =============
57101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
57201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// This value counts the number of milliseconds that I/O requests have waited
57301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// on this block device.  If there are multiple I/O requests waiting, this
57401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// value will increase as the product of the number of milliseconds times the
57501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn// number of requests waiting (see "read ticks" above for an example).
57601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn#define S_TO_MS 1000
57701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn//
57801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn
579326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzynstatic int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
58001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn    unsigned long long fields[__STAT_NUMBER_FIELD];
581326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    bool z;
582326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    char *cp, *buffer = NULL;
583326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    size_t i = 0;
584326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    FILE *fp = fdopen(fd, "rb");
585326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    getline(&buffer, &i, fp);
586326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    fclose(fp);
587326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (!buffer) {
588326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return -errno;
589326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
590326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    i = strlen(buffer);
591326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    while ((i > 0) && (buffer[i - 1] == '\n')) {
592326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        buffer[--i] = '\0';
593326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
594326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (!*buffer) {
595326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        free(buffer);
596326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return 0;
597326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
598326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    z = true;
599326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
60001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        fields[i] = strtoull(cp, &cp, 10);
601326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        if (fields[i] != 0) {
602326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn            z = false;
603326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        }
604326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
605326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    if (z) { /* never accessed */
606326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        free(buffer);
607326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn        return 0;
608326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
609326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
610509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    if (!strncmp(path, BLK_DEV_SYS_DIR, sizeof(BLK_DEV_SYS_DIR) - 1)) {
611509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        path += sizeof(BLK_DEV_SYS_DIR) - 1;
612326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    }
6131dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang
6141dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang    printf("%-30s:%9s%9s%9s%9s%9s%9s%9s%9s%9s%9s%9s\n%-30s:\t%s\n", "Block-Dev",
6151dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang           "R-IOs", "R-merg", "R-sect", "R-wait", "W-IOs", "W-merg", "W-sect",
6161dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang           "W-wait", "in-fli", "activ", "T-wait", path, buffer);
617326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    free(buffer);
618326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
61901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn    if (fields[__STAT_IO_TICKS]) {
62001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        unsigned long read_perf = 0;
62101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        unsigned long read_ios = 0;
62201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        if (fields[__STAT_READ_TICKS]) {
62301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            unsigned long long divisor = fields[__STAT_READ_TICKS]
62401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                       * fields[__STAT_IO_TICKS];
62501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            read_perf = ((unsigned long long)SECTOR_SIZE
62601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_READ_SECTORS]
62701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
62801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                        / divisor;
62901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            read_ios = ((unsigned long long)S_TO_MS * fields[__STAT_READ_IOS]
63001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
63101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                        / divisor;
63201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        }
63301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn
63401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        unsigned long write_perf = 0;
63501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        unsigned long write_ios = 0;
63601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        if (fields[__STAT_WRITE_TICKS]) {
63701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            unsigned long long divisor = fields[__STAT_WRITE_TICKS]
63801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                       * fields[__STAT_IO_TICKS];
63901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            write_perf = ((unsigned long long)SECTOR_SIZE
64001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_WRITE_SECTORS]
64101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
64201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                        / divisor;
64301d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            write_ios = ((unsigned long long)S_TO_MS * fields[__STAT_WRITE_IOS]
64401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                           * fields[__STAT_IN_QUEUE] + (divisor >> 1))
64501d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                        / divisor;
64601d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        }
64701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn
64801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        unsigned queue = (fields[__STAT_IN_QUEUE]
64901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                             + (fields[__STAT_IO_TICKS] >> 1))
65001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn                                 / fields[__STAT_IO_TICKS];
65101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn
65201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        if (!write_perf && !write_ios) {
6531dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang            printf("%-30s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", path, read_perf, read_ios, queue);
65401d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        } else {
6551dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang            printf("%-30s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n", path, read_perf,
656d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme                   read_ios, write_perf, write_ios, queue);
65701d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        }
65801d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn
65901d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        /* bugreport timeout factor adjustment */
66001d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        if ((write_perf > 1) && (write_perf < worst_write_perf)) {
66101d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn            worst_write_perf = write_perf;
66201d6c3935ace93f208fa3d93802b286e7484cfaeMark Salyzyn        }
6638f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn    }
664326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn    return 0;
665326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn}
666326842fca4883f1256aa9ed019bb3206ee76fca7Mark Salyzyn
667be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chenstatic const long MINIMUM_LOGCAT_TIMEOUT_MS = 50000;
668be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen
669be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen/* timeout in ms to read a list of buffers */
670be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chenstatic unsigned long logcat_timeout(const std::vector<std::string>& buffers) {
671be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    unsigned long timeout_ms = 0;
672be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    for (const auto& buffer : buffers) {
673be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        log_id_t id = android_name_to_log_id(buffer.c_str());
674be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        unsigned long property_size = __android_logger_get_buffer_size(id);
675be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        /* Engineering margin is ten-fold our guess */
676be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        timeout_ms += 10 * (property_size + worst_write_perf) / worst_write_perf;
677be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    }
678be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    return timeout_ms > MINIMUM_LOGCAT_TIMEOUT_MS ? timeout_ms : MINIMUM_LOGCAT_TIMEOUT_MS;
6798f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn}
6808f37aa5011bf5d8c0a67126b92e3b435ffd4dca0Mark Salyzyn
6812b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Lemevoid Dumpstate::PrintHeader() const {
68296c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    std::string build, fingerprint, radio, bootloader, network;
68396c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    char date[80];
68496c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme
68596c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    build = android::base::GetProperty("ro.build.display.id", "(unknown)");
68696c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    fingerprint = android::base::GetProperty("ro.build.fingerprint", "(unknown)");
68796c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    radio = android::base::GetProperty("gsm.version.baseband", "(unknown)");
68896c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    bootloader = android::base::GetProperty("ro.bootloader", "(unknown)");
68996c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
690bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now_));
691f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
692d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
693d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== dumpstate: %s\n", date);
694d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
695f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
696d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("\n");
697d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Build: %s\n", build.c_str());
69896c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    // NOTE: fingerprint entry format is important for other tools.
699d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Build fingerprint: '%s'\n", fingerprint.c_str());
700d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Bootloader: %s\n", bootloader.c_str());
701d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Radio: %s\n", radio.c_str());
702d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Network: %s\n", network.c_str());
703f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
704d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Kernel: ");
705f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
706d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
7077709f8a5e62a67c6df06f68bddcc2a1036bd62bbFelipe Leme    printf("Uptime: ");
7087709f8a5e62a67c6df06f68bddcc2a1036bd62bbFelipe Leme    RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
7097709f8a5e62a67c6df06f68bddcc2a1036bd62bbFelipe Leme                   CommandOptions::WithTimeout(1).Always().Build());
710d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Bugreport format version: %s\n", version_.c_str());
711d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
712d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme           PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
713d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("\n");
71478f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme}
71578f2c86235d5882a8dc84c85a1c1864062e5f3afFelipe Leme
71624b66eed1acd08a975546b57198940f4de9250ebFelipe Leme// List of file extensions that can cause a zip file attachment to be rejected by some email
71724b66eed1acd08a975546b57198940f4de9250ebFelipe Leme// service providers.
71824b66eed1acd08a975546b57198940f4de9250ebFelipe Lemestatic const std::set<std::string> PROBLEMATIC_FILE_EXTENSIONS = {
71924b66eed1acd08a975546b57198940f4de9250ebFelipe Leme      ".ade", ".adp", ".bat", ".chm", ".cmd", ".com", ".cpl", ".exe", ".hta", ".ins", ".isp",
72024b66eed1acd08a975546b57198940f4de9250ebFelipe Leme      ".jar", ".jse", ".lib", ".lnk", ".mde", ".msc", ".msp", ".mst", ".pif", ".scr", ".sct",
72124b66eed1acd08a975546b57198940f4de9250ebFelipe Leme      ".shb", ".sys", ".vb",  ".vbe", ".vbs", ".vxd", ".wsc", ".wsf", ".wsh"
72224b66eed1acd08a975546b57198940f4de9250ebFelipe Leme};
72324b66eed1acd08a975546b57198940f4de9250ebFelipe Leme
724e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nairstatus_t Dumpstate::AddZipEntryFromFd(const std::string& entry_name, int fd,
725e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                                      std::chrono::milliseconds timeout = 0ms) {
7261d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!IsZipping()) {
7271d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGD("Not adding zip entry %s from fd because it's not a zipped bugreport\n",
7281d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme               entry_name.c_str());
729e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        return INVALID_OPERATION;
730111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme    }
73124b66eed1acd08a975546b57198940f4de9250ebFelipe Leme    std::string valid_name = entry_name;
73224b66eed1acd08a975546b57198940f4de9250ebFelipe Leme
73324b66eed1acd08a975546b57198940f4de9250ebFelipe Leme    // Rename extension if necessary.
734cb057c2e6bf23b43df49282c0db26b663e4535f7Chih-Hung Hsieh    size_t idx = entry_name.rfind('.');
73524b66eed1acd08a975546b57198940f4de9250ebFelipe Leme    if (idx != std::string::npos) {
73624b66eed1acd08a975546b57198940f4de9250ebFelipe Leme        std::string extension = entry_name.substr(idx);
73724b66eed1acd08a975546b57198940f4de9250ebFelipe Leme        std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
73824b66eed1acd08a975546b57198940f4de9250ebFelipe Leme        if (PROBLEMATIC_FILE_EXTENSIONS.count(extension) != 0) {
73924b66eed1acd08a975546b57198940f4de9250ebFelipe Leme            valid_name = entry_name + ".renamed";
74024b66eed1acd08a975546b57198940f4de9250ebFelipe Leme            MYLOGI("Renaming entry %s to %s\n", entry_name.c_str(), valid_name.c_str());
74124b66eed1acd08a975546b57198940f4de9250ebFelipe Leme        }
74224b66eed1acd08a975546b57198940f4de9250ebFelipe Leme    }
74324b66eed1acd08a975546b57198940f4de9250ebFelipe Leme
7446fe9db67f6c92d5fbf87d371da5cca412f672630Felipe Leme    // Logging statement  below is useful to time how long each entry takes, but it's too verbose.
7456fe9db67f6c92d5fbf87d371da5cca412f672630Felipe Leme    // MYLOGD("Adding zip entry %s\n", entry_name.c_str());
746c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    int32_t err = zip_writer_->StartEntryWithTime(valid_name.c_str(), ZipWriter::kCompress,
747c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme                                                  get_mtime(fd, ds.now_));
7481d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
749c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->StartEntryWithTime(%s): %s\n", valid_name.c_str(),
7501d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme               ZipWriter::ErrorCodeString(err));
751e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        return UNKNOWN_ERROR;
752e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
753e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    auto start = std::chrono::steady_clock::now();
754e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    auto end = start + timeout;
755e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    struct pollfd pfd = {fd, POLLIN};
756e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
757770410dcf2f72cf4e806442263e63719a0be0f5aFelipe Leme    std::vector<uint8_t> buffer(65536);
758e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    while (1) {
759e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (timeout.count() > 0) {
760e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            // lambda to recalculate the timeout.
761e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            auto time_left_ms = [end]() {
762e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                auto now = std::chrono::steady_clock::now();
763e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
764e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                return std::max(diff.count(), 0LL);
765e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            };
766e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
767e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
768e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            if (rc < 0) {
769e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                MYLOGE("Error in poll while adding from fd to zip entry %s:%s", entry_name.c_str(),
770e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                       strerror(errno));
771e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                return -errno;
772e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            } else if (rc == 0) {
773e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                MYLOGE("Timed out adding from fd to zip entry %s:%s Timeout:%lldms",
774e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                       entry_name.c_str(), strerror(errno), timeout.count());
775e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                return TIMED_OUT;
776e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            }
777e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
778e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
77922200401c000c556ff7ed6d100d4f57e18ebb24fZach Riggle        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), buffer.size()));
780e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        if (bytes_read == 0) {
781e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme            break;
782e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        } else if (bytes_read == -1) {
783cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno));
784e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            return -errno;
785e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        }
786c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        err = zip_writer_->WriteBytes(buffer.data(), bytes_read);
787e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        if (err) {
788c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme            MYLOGE("zip_writer_->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err));
789e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            return UNKNOWN_ERROR;
790e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        }
791e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
792e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
793c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    err = zip_writer_->FinishEntry();
7941d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
795c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
796e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        return UNKNOWN_ERROR;
797e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
798e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
799e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    return OK;
800e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
801e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
8021d486fe3847c831b9d57843cda209ed86853ee21Felipe Lemebool Dumpstate::AddZipEntry(const std::string& entry_name, const std::string& entry_path) {
8031d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    android::base::unique_fd fd(
8041d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
805aff684300a3b7d6984d3b3c1efddb810cd0205e7Andreas Gampe    if (fd == -1) {
806cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno));
807e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme        return false;
808e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme    }
809e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
810e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    return (AddZipEntryFromFd(entry_name, fd.get()) == OK);
811e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
812e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
813e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme/* adds a file to the existing zipped bugreport */
8144c2d66379753e2b7680811726424026b9e54b18aFelipe Lemestatic int _add_file_from_fd(const char* title __attribute__((unused)), const char* path, int fd) {
815e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    return (ds.AddZipEntryFromFd(ZIP_ROOT_DIR + path, fd) == OK) ? 0 : 1;
816e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
817e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
8181d486fe3847c831b9d57843cda209ed86853ee21Felipe Lemevoid Dumpstate::AddDir(const std::string& dir, bool recursive) {
8191d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!IsZipping()) {
8201d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGD("Not adding dir %s because it's not a zipped bugreport\n", dir.c_str());
821111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme        return;
822111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme    }
823678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    MYLOGD("Adding dir %s (recursive: %d)\n", dir.c_str(), recursive);
82446b85da716a32f285fe1222e9978beacc8697d09Felipe Leme    DurationReporter duration_reporter(dir, true);
825678727af1ae44fe40a6d70fb175f8acfdb5d83d9Felipe Leme    dump_files("", dir.c_str(), recursive ? skip_none : is_dir, _add_file_from_fd);
826e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme}
827e82a27d0c1e3f2cef6f13a1a9efff55638601752Felipe Leme
8281d486fe3847c831b9d57843cda209ed86853ee21Felipe Lemebool Dumpstate::AddTextZipEntry(const std::string& entry_name, const std::string& content) {
8291d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!IsZipping()) {
8301d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme        MYLOGD("Not adding text zip entry %s because it's not a zipped bugreport\n",
8311d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme               entry_name.c_str());
832111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme        return false;
833111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme    }
834cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme    MYLOGD("Adding zip text entry %s\n", entry_name.c_str());
835c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    int32_t err = zip_writer_->StartEntryWithTime(entry_name.c_str(), ZipWriter::kCompress, ds.now_);
8361d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
837c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->StartEntryWithTime(%s): %s\n", entry_name.c_str(),
8381d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme               ZipWriter::ErrorCodeString(err));
839809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme        return false;
840809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
841809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
842c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    err = zip_writer_->WriteBytes(content.c_str(), content.length());
8431d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
844c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->WriteBytes(%s): %s\n", entry_name.c_str(),
8451d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme               ZipWriter::ErrorCodeString(err));
846809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme        return false;
847809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
848809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
849c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    err = zip_writer_->FinishEntry();
8501d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
851c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
852809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme        return false;
853809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
854809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
855809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    return true;
856809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme}
857809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
8586ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Lemestatic void DoKmsg() {
8596ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    struct stat st;
8606ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    if (!stat(PSTORE_LAST_KMSG, &st)) {
8616ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
8626ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        DumpFile("LAST KMSG", PSTORE_LAST_KMSG);
8636ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) {
8646ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        DumpFile("LAST KMSG", ALT_PSTORE_LAST_KMSG);
8656ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    } else {
8666ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
8676ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        DumpFile("LAST KMSG", "/proc/last_kmsg");
8686ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    }
8696ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme}
8706ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
8714a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakoustatic void DoKernelLogcat() {
872be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    unsigned long timeout_ms = logcat_timeout({"kernel"});
8734a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    RunCommand(
8744a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        "KERNEL LOG",
8754a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        {"logcat", "-b", "kernel", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
8764a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
8774a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou}
8784a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou
8796ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Lemestatic void DoLogcat() {
8806921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair    unsigned long timeout_ms;
8816ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    // DumpFile("EVENT LOG TAGS", "/etc/event-log-tags");
8826ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    // calculate timeout
883be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    timeout_ms = logcat_timeout({"main", "system", "crash"});
884ae7376516dd9f57137408f11e5fdcc53a15d4d8bTony Mak    RunCommand("SYSTEM LOG",
8856921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair               {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
8866921f80f26cb779d2982d2e37e14aeadbc8230b7Vishnu Nair               CommandOptions::WithTimeoutInMs(timeout_ms).Build());
887be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    timeout_ms = logcat_timeout({"events"});
8884a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    RunCommand(
8894a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        "EVENT LOG",
8904a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
8914a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
892be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    timeout_ms = logcat_timeout({"stats"});
893be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    RunCommand(
894be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        "STATS LOG",
895be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        {"logcat", "-b", "stats", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
896be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
897be3bbc17db0fd09de2b2134a2a9c32ea7357db0eYao Chen    timeout_ms = logcat_timeout({"radio"});
8984a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    RunCommand(
8994a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        "RADIO LOG",
9004a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        {"logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
9014a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
9026ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
9036ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    RunCommand("LOG STATISTICS", {"logcat", "-b", "all", "-S"});
9046ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
9056ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
9064a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    RunCommand("LAST LOGCAT", {"logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable",
9074a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou                               "-v", "uid", "-d", "*:v"});
9086ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme}
9096ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
910a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran Cstatic void DumpIpTablesAsRoot() {
911b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("IPTABLES", {"iptables", "-L", "-nvx"});
912b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("IP6TABLES", {"ip6tables", "-L", "-nvx"});
91332af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline    RunCommand("IPTABLES NAT", {"iptables", "-t", "nat", "-L", "-nvx"});
914c0808155fd10d2d5c49bb4c8d4cafed8da28c182Felipe Leme    /* no ip6 nat */
91532af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline    RunCommand("IPTABLES MANGLE", {"iptables", "-t", "mangle", "-L", "-nvx"});
91632af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline    RunCommand("IP6TABLES MANGLE", {"ip6tables", "-t", "mangle", "-L", "-nvx"});
91732af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline    RunCommand("IPTABLES RAW", {"iptables", "-t", "raw", "-L", "-nvx"});
91832af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline    RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
919c0808155fd10d2d5c49bb4c8d4cafed8da28c182Felipe Leme}
920c0808155fd10d2d5c49bb4c8d4cafed8da28c182Felipe Leme
9218f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamathstatic void AddGlobalAnrTraceFile(const bool add_to_zip, const std::string& anr_traces_file,
9228f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                                  const std::string& anr_traces_dir) {
923e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    std::string dump_traces_dir;
924e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
925e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    if (dump_traces_path != nullptr) {
926e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        if (add_to_zip) {
927e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            dump_traces_dir = dirname(dump_traces_path);
928e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            MYLOGD("Adding ANR traces (directory %s) to the zip file\n", dump_traces_dir.c_str());
929e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            ds.AddDir(dump_traces_dir, true);
930e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        } else {
931e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n",
932e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme                   dump_traces_path);
933e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            ds.DumpFile("VM TRACES JUST NOW", dump_traces_path);
934e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        }
935e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    }
936e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
937e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
938e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // Make sure directory is not added twice.
939e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // TODO: this is an overzealous check because it's relying on dump_traces_path - which is
940e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // generated by dump_traces() -  and anr_traces_path - which is retrieved from a system
941e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // property - but in reality they're the same path (although the former could be nullptr).
942e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // Anyways, once dump_traces() is refactored as a private Dumpstate function, this logic should
943e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    // be revisited.
944e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    bool already_dumped = anr_traces_dir == dump_traces_dir;
945e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
9468f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    MYLOGD("AddGlobalAnrTraceFile(): dump_traces_dir=%s, anr_traces_dir=%s, already_dumped=%d\n",
947e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme           dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);
948e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
9496b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
9506b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        open(anr_traces_file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
9516b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath    if (fd.get() < 0) {
9528f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_file.c_str(), strerror(errno));
953e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    } else {
9548f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        if (add_to_zip) {
9558f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            if (!already_dumped) {
9568f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                MYLOGD("Adding dalvik ANR traces (directory %s) to the zip file\n",
9578f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                       anr_traces_dir.c_str());
9588f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                ds.AddDir(anr_traces_dir, true);
959e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            }
9608f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        } else {
9618f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            MYLOGD("Dumping last ANR traces (%s) to the main bugreport entry\n",
9628f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                   anr_traces_file.c_str());
9636b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath            dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_file.c_str(), fd.get());
9648f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
9658f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    }
9668f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath}
9678f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
9688f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamathstatic void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_dir) {
9698f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    MYLOGD("AddAnrTraceDir(): dump_traces_file=%s, anr_traces_dir=%s\n", dump_traces_path,
9708f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath           anr_traces_dir.c_str());
9718f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
9728f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // If we're here, dump_traces_path will always be a temporary file
9738f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // (created with mkostemp or similar) that contains dumps taken earlier
9748f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // on in the process.
9758f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (dump_traces_path != nullptr) {
9768f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        if (add_to_zip) {
9778f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            ds.AddZipEntry(ZIP_ROOT_DIR + anr_traces_dir + "/traces-just-now.txt", dump_traces_path);
9788f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        } else {
9798f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n",
9808f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                   dump_traces_path);
9818f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            ds.DumpFile("VM TRACES JUST NOW", dump_traces_path);
9828f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
9838f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
9848f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        const int ret = unlink(dump_traces_path);
9858f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        if (ret == -1) {
9868f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            MYLOGW("Error unlinking temporary trace path %s: %s\n", dump_traces_path,
9878f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                   strerror(errno));
9888f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        }
9898f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    }
9908f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
991bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    // Add a specific message for the first ANR Dump.
9925f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    if (ds.anr_data_.size() > 0) {
9935f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        AddDumps(ds.anr_data_.begin(), ds.anr_data_.begin() + 1,
994bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath                 "VM TRACES AT LAST ANR", add_to_zip);
995bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath
9966b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // The "last" ANR will always be included as separate entry in the zip file. In addition,
9976b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // it will be present in the body of the main entry if |add_to_zip| == false.
9986b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        //
9996b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath        // Historical ANRs are always included as separate entries in the bugreport zip file.
10005f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        AddDumps(ds.anr_data_.begin() + ((add_to_zip) ? 1 : 0), ds.anr_data_.end(),
10016b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath                 "HISTORICAL ANR", true /* add_to_zip */);
1002bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    } else {
10038f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        printf("*** NO ANRs to dump in %s\n\n", ANR_DIR.c_str());
10048f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    }
10058f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath}
10068f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
10078f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamathstatic void AddAnrTraceFiles() {
10088f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    const bool add_to_zip = ds.IsZipping() && ds.version_ == VERSION_SPLIT_ANR;
10098f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
10108f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    std::string anr_traces_file;
10118f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    std::string anr_traces_dir;
10128f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    bool is_global_trace_file = true;
10138f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
10148f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // First check whether the stack-trace-dir property is set. When it's set,
10158f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // each ANR trace will be written to a separate file and not to a global
10168f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // stack trace file.
10178f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    anr_traces_dir = android::base::GetProperty("dalvik.vm.stack-trace-dir", "");
10188f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (anr_traces_dir.empty()) {
10198f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        anr_traces_file = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
10208f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        if (!anr_traces_file.empty()) {
10218f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            anr_traces_dir = dirname(anr_traces_file.c_str());
1022e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        }
1023bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath    } else {
1024bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath        is_global_trace_file = false;
1025e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    }
1026e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
10278f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // We have neither configured a global trace file nor a trace directory,
10288f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // there will be nothing to dump.
10298f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (anr_traces_file.empty() && anr_traces_dir.empty()) {
10308f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
1031e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        return;
1032e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    }
1033e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
10348f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (is_global_trace_file) {
10358f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        AddGlobalAnrTraceFile(add_to_zip, anr_traces_file, anr_traces_dir);
10368f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    } else {
10378f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        AddAnrTraceDir(add_to_zip, anr_traces_dir);
10388f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    }
10398f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
1040e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    /* slow traces for slow operations */
1041e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    struct stat st;
10428f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (!anr_traces_dir.empty()) {
1043e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        int i = 0;
10448f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        while (true) {
10458f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            const std::string slow_trace_path =
10468f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath                anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
10478f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            if (stat(slow_trace_path.c_str(), &st)) {
1048e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme                // No traces file at this index, done with the files.
1049e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme                break;
1050e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            }
10518f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath            ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
1052e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme            i++;
1053e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme        }
1054e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    }
1055e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme}
1056e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme
1057509bb5d1764cdc44eef5166436dac3130a239d6dWei Wangstatic void DumpBlockStatFiles() {
1058509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    DurationReporter duration_reporter("DUMP BLOCK STAT");
1059509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang
10601dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang    std::unique_ptr<DIR, std::function<int(DIR*)>> dirptr(opendir(BLK_DEV_SYS_DIR), closedir);
10611dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang
10621dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang    if (dirptr == nullptr) {
1063509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        MYLOGE("Failed to open %s: %s\n", BLK_DEV_SYS_DIR, strerror(errno));
1064509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        return;
1065509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    }
1066509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang
1067509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    printf("------ DUMP BLOCK STAT ------\n\n");
10681dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang    while (struct dirent *d = readdir(dirptr.get())) {
1069509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        if ((d->d_name[0] == '.')
1070509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang         && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
1071509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang          || (d->d_name[1] == '\0'))) {
1072509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang            continue;
1073509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        }
1074509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        const std::string new_path =
1075509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang            android::base::StringPrintf("%s/%s", BLK_DEV_SYS_DIR, d->d_name);
1076509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        printf("------ BLOCK STAT (%s) ------\n", new_path.c_str());
1077509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        dump_files("", new_path.c_str(), skip_not_stat, dump_stat_from_fd);
1078509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang        printf("\n");
1079509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    }
10801dc1ef5af577d0cacc7b86a83d243d9750b0dd6dWei Wang     return;
1081509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang}
1082a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1083a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran Cstatic void DumpPacketStats() {
1084a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpFile("NETWORK DEV INFO", "/proc/net/dev");
1085a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpFile("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
1086a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpFile("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt");
1087a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpFile("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
1088a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpFile("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
1089a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C}
1090a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1091a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran Cstatic void DumpIpAddrAndRules() {
1092a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
1093a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("NETWORK INTERFACES", {"ip", "link"});
1094a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("IPv4 ADDRESSES", {"ip", "-4", "addr", "show"});
1095a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("IPv6 ADDRESSES", {"ip", "-6", "addr", "show"});
1096a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("IP RULES", {"ip", "rule", "show"});
1097a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"});
1098a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C}
1099a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
110064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nairstatic void RunDumpsysTextByPriority(const std::string& title, int priority,
110164afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                                     std::chrono::milliseconds timeout,
110264afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                                     std::chrono::milliseconds service_timeout) {
110364afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    auto start = std::chrono::steady_clock::now();
1104e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    sp<android::IServiceManager> sm = defaultServiceManager();
1105e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Dumpsys dumpsys(sm.get());
1106e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Vector<String16> args;
1107e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Dumpsys::setServiceArgs(args, /* asProto = */ false, priority);
1108e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ false);
1109e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    for (const String16& service : services) {
1110e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        std::string path(title);
1111e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        path.append(" - ").append(String8(service).c_str());
1112e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        DumpstateSectionReporter section_reporter(path, ds.listener_, ds.report_section_);
1113e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        size_t bytes_written = 0;
1114e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        status_t status = dumpsys.startDumpThread(service, args);
1115e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (status == OK) {
1116e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
1117e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            std::chrono::duration<double> elapsed_seconds;
1118e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            status = dumpsys.writeDump(STDOUT_FILENO, service, service_timeout,
1119e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                                       /* as_proto = */ false, elapsed_seconds, bytes_written);
1120e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            section_reporter.setSize(bytes_written);
1121e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            dumpsys.writeDumpFooter(STDOUT_FILENO, service, elapsed_seconds);
1122e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            bool dump_complete = (status == OK);
1123e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            dumpsys.stopDumpThread(dump_complete);
1124e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
1125e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        section_reporter.setStatus(status);
1126e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
1127e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        auto elapsed_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
1128e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            std::chrono::steady_clock::now() - start);
1129e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (elapsed_duration > timeout) {
1130e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            MYLOGE("*** command '%s' timed out after %llums\n", title.c_str(),
1131e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                   elapsed_duration.count());
1132e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            break;
1133e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
1134e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    }
1135e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair}
1136e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
113764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nairstatic void RunDumpsysText(const std::string& title, int priority,
113864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                           std::chrono::milliseconds timeout,
113964afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                           std::chrono::milliseconds service_timeout) {
114064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    DurationReporter duration_reporter(title);
114164afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str());
114264afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    fsync(STDOUT_FILENO);
114364afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysTextByPriority(title, priority, timeout, service_timeout);
114464afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair}
114564afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair
114664afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair/* Dump all services registered with Normal or Default priority. */
114764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nairstatic void RunDumpsysTextNormalPriority(const std::string& title,
114864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                                         std::chrono::milliseconds timeout,
114964afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                                         std::chrono::milliseconds service_timeout) {
115064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    DurationReporter duration_reporter(title);
115164afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str());
115264afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    fsync(STDOUT_FILENO);
115364afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, timeout,
115464afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                             service_timeout);
115564afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT, timeout,
115664afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                             service_timeout);
115764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair}
115864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair
115964afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nairstatic void RunDumpsysProto(const std::string& title, int priority,
116064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                            std::chrono::milliseconds timeout,
116164afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                            std::chrono::milliseconds service_timeout) {
11621e27b08c1c96926f88c782b047214e09f29d57d2Luis Hector Chavez    if (!ds.IsZipping()) {
11631e27b08c1c96926f88c782b047214e09f29d57d2Luis Hector Chavez        MYLOGD("Not dumping %s because it's not a zipped bugreport\n", title.c_str());
11641e27b08c1c96926f88c782b047214e09f29d57d2Luis Hector Chavez        return;
11651e27b08c1c96926f88c782b047214e09f29d57d2Luis Hector Chavez    }
1166e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    sp<android::IServiceManager> sm = defaultServiceManager();
1167e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Dumpsys dumpsys(sm.get());
1168e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Vector<String16> args;
1169e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Dumpsys::setServiceArgs(args, /* asProto = */ true, priority);
1170e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    DurationReporter duration_reporter(title);
1171e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
1172e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    auto start = std::chrono::steady_clock::now();
1173e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ true);
1174e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    for (const String16& service : services) {
1175e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        std::string path(kProtoPath);
1176e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        path.append(String8(service).c_str());
1177e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (priority == IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL) {
1178e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            path.append("_CRITICAL");
1179e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        } else if (priority == IServiceManager::DUMP_FLAG_PRIORITY_HIGH) {
1180e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            path.append("_HIGH");
1181e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
1182e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        path.append(kProtoExt);
1183e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        DumpstateSectionReporter section_reporter(path, ds.listener_, ds.report_section_);
1184e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        status_t status = dumpsys.startDumpThread(service, args);
1185e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (status == OK) {
1186e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout);
1187e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            bool dumpTerminated = (status == OK);
1188e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            dumpsys.stopDumpThread(dumpTerminated);
1189e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
1190e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        ZipWriter::FileEntry file_entry;
1191e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        ds.zip_writer_->GetLastEntry(&file_entry);
1192e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        section_reporter.setSize(file_entry.compressed_size);
1193e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        section_reporter.setStatus(status);
1194e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
1195e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        auto elapsed_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
1196e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            std::chrono::steady_clock::now() - start);
1197e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        if (elapsed_duration > timeout) {
1198e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            MYLOGE("*** command '%s' timed out after %llums\n", title.c_str(),
1199e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair                   elapsed_duration.count());
1200e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair            break;
1201e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair        }
1202e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair    }
1203e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair}
1204e97d6127dd73f8c9f4a60e33dd9a701ece47716dVishnu Nair
1205780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair// Runs dumpsys on services that must dump first and and will take less than 100ms to dump.
1206780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nairstatic void RunDumpsysCritical() {
120764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysText("DUMPSYS CRITICAL", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL,
120864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                   /* timeout= */ 5s, /* service_timeout= */ 500ms);
120964afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysProto("DUMPSYS CRITICAL PROTO", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL,
121064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                    /* timeout= */ 5s, /* service_timeout= */ 500ms);
1211780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair}
1212780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair
1213780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair// Runs dumpsys on services that must dump first but can take up to 250ms to dump.
1214780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nairstatic void RunDumpsysHigh() {
121564afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    // TODO meminfo takes ~10s, connectivity takes ~5sec to dump. They are both
121664afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    // high priority. Reduce timeout once they are able to dump in a shorter time or
121764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    // moved to a parallel task.
121864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysText("DUMPSYS HIGH", IServiceManager::DUMP_FLAG_PRIORITY_HIGH,
121964afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                   /* timeout= */ 90s, /* service_timeout= */ 30s);
122064afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysProto("DUMPSYS HIGH PROTO", IServiceManager::DUMP_FLAG_PRIORITY_HIGH,
122164afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                    /* timeout= */ 5s, /* service_timeout= */ 1s);
1222780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair}
1223780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair
1224780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair// Runs dumpsys on services that must dump but can take up to 10s to dump.
1225780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nairstatic void RunDumpsysNormal() {
122664afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysTextNormalPriority("DUMPSYS", /* timeout= */ 90s, /* service_timeout= */ 10s);
122764afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    RunDumpsysProto("DUMPSYS PROTO", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL,
122864afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair                    /* timeout= */ 90s, /* service_timeout= */ 10s);
1229780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair}
1230780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair
123144cd9480005ed5a5b1b3530f44335ba400055de3Steven Morelandstatic void DumpHals() {
123244cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    using android::sp;
123344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    using android::hidl::manager::V1_0::IServiceManager;
123444cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    using android::hardware::defaultServiceManager;
123544cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
123644cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    sp<IServiceManager> sm = defaultServiceManager();
123744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    if (sm == nullptr) {
123844cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        MYLOGE("Could not retrieve hwservicemanager to dump hals.\n");
123944cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        return;
124044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    }
124144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
124244cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    auto ret = sm->list([&](const auto& interfaces) {
124344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        for (const std::string& interface : interfaces) {
124444cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            std::string cleanName = interface;
124544cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            std::replace_if(cleanName.begin(),
124644cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                            cleanName.end(),
124744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                            [](char c) {
124844cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                                return !isalnum(c) &&
124944cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                                    std::string("@-_:.").find(c) == std::string::npos;
125044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                            }, '_');
125144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            const std::string path = kDumpstateBoardPath + "lshal_debug_" + cleanName;
125244cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
125344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            {
125444cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                auto fd = android::base::unique_fd(
125544cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    TEMP_FAILURE_RETRY(open(path.c_str(),
125644cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
125744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
125844cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                if (fd < 0) {
125944cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    MYLOGE("Could not open %s to dump additional hal information.\n", path.c_str());
126044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    continue;
126144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                }
126244cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                RunCommandToFd(fd,
126344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                        "",
1264c81cd3c115443fdd162446992e040ca45e7e4c51Steven Moreland                        {"lshal", "debug", "-E", interface},
126544cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                        CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
126644cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
126744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                bool empty = 0 == lseek(fd, 0, SEEK_END);
126844cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                if (!empty) {
126944cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                    ds.AddZipEntry("lshal-debug/" + cleanName + ".txt", path);
127044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland                }
127144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            }
127244cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
127344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland            unlink(path.c_str());
127444cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        }
127544cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    });
127644cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
127744cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    if (!ret.isOk()) {
127844cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        MYLOGE("Could not list hals from hwservicemanager.\n");
127944cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland    }
128044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland}
128144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland
1282bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Lemestatic void dumpstate() {
12839a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    DurationReporter duration_reporter("DUMPSTATE");
1284f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
12852db0f5f31c015b5a89b619f8c95a9bf95c09c75bArve Hjønnevåg    dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
1286b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("UPTIME", {"uptime"});
1287509bb5d1764cdc44eef5166436dac3130a239d6dWei Wang    DumpBlockStatFiles();
12888c8130eb68c89987a94db084608a4229bad06c18Mark Salyzyn    dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
1289b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("MEMORY INFO", "/proc/meminfo");
1290b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("CPU INFO", {"top", "-b", "-n", "1", "-H", "-s", "6", "-o",
129130dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme                            "pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name"});
1292f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    RunCommand("PROCRANK", {"procrank"}, AS_ROOT_20);
1293b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("VIRTUAL MEMORY STATS", "/proc/vmstat");
1294b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("VMALLOC INFO", "/proc/vmallocinfo");
1295b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("SLAB INFO", "/proc/slabinfo");
1296b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("ZONEINFO", "/proc/zoneinfo");
1297b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo");
1298b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BUDDYINFO", "/proc/buddyinfo");
1299b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("FRAGMENTATION INFO", "/d/extfrag/unusable_index");
1300b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme
1301b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("KERNEL WAKE SOURCES", "/d/wakeup_sources");
1302b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
1303b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("KERNEL SYNC", "/d/sync");
1304b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme
1305b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("PROCESSES AND THREADS",
1306591a72da3ec97e986f9149d0b0d851bf27f6665dYohei Yukawa               {"ps", "-A", "-T", "-Z", "-O", "pri,nice,rtprio,sched,pcy,time"});
1307f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    RunCommand("LIBRANK", {"librank"}, CommandOptions::AS_ROOT);
1308f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
130969ec3ac3e761042f0c5e1e708c161d2df3c6db2bAndreas Huber    if (ds.IsZipping()) {
131044cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        RunCommand("HARDWARE HALS", {"lshal"}, CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
131144cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        DumpHals();
131269ec3ac3e761042f0c5e1e708c161d2df3c6db2bAndreas Huber    } else {
131344cd9480005ed5a5b1b3530f44335ba400055de3Steven Moreland        RunCommand("HARDWARE HALS", {"lshal", "--debug"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
131469ec3ac3e761042f0c5e1e708c161d2df3c6db2bAndreas Huber    }
131581b429eba542f95877459bf6b860c55f35fea222Steven Moreland
1316b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("PRINTENV", {"printenv"});
131721b7c8d618777d6bf684e52b082c23f7e04b0688Elliott Hughes    RunCommand("NETSTAT", {"netstat", "-nW"});
1318e4eca58fe7daa5e2dce7fa2b615c541aef00bc67Felipe Leme    struct stat s;
1319e4eca58fe7daa5e2dce7fa2b615c541aef00bc67Felipe Leme    if (stat("/proc/modules", &s) != 0) {
1320e4eca58fe7daa5e2dce7fa2b615c541aef00bc67Felipe Leme        MYLOGD("Skipping 'lsmod' because /proc/modules does not exist\n");
1321e4eca58fe7daa5e2dce7fa2b615c541aef00bc67Felipe Leme    } else {
1322b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        RunCommand("LSMOD", {"lsmod"});
1323e4eca58fe7daa5e2dce7fa2b615c541aef00bc67Felipe Leme    }
13244db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
13254a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    if (__android_logger_property_get_bool(
13264a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou            "ro.logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE)) {
13274a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        DoKernelLogcat();
13284a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    } else {
13294a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou        do_dmesg();
13304a0a877c6d9b8aa2225a791329c2da0f7e8bdbe9Siarhei Vishniakou    }
1331f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1332f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    RunCommand("LIST OF OPEN FILES", {"lsof"}, CommandOptions::AS_ROOT);
13331dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
13341dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
1335a297c3258f6f7ea52cc2dcc42d62f85fda12a163Mark Salyzyn    for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)");
1336f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
13372ff8e87d906365a9b786ac6829b901ca2798bb68Ajay Panicker    /* Dump Bluetooth HCI logs */
13382ff8e87d906365a9b786ac6829b901ca2798bb68Ajay Panicker    ds.AddDir("/data/misc/bluetooth/logs", true);
1339d886ec496952a19bee202bc3d6f670009c3a0689Ajay Panicker
13409a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (!ds.do_early_screenshot_) {
1341cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGI("taking late screenshot\n");
1342bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme        ds.TakeScreenshot();
13435a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey    }
13445a93003d3f0d1808b6dcd9928041ec62ea7f67adJeff Sharkey
13456ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    DoLogcat();
1346ecc0763e6c96c418ea4ee6c993d58d16a58407b3Mark Salyzyn
1347e184f6610284ca80692d7e6789483375a7ca2f39Felipe Leme    AddAnrTraceFiles();
1348f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
13498f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // NOTE: tombstones are always added as separate entries in the zip archive
13508f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    // and are not interspersed with the main report.
13515f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    const bool tombstones_dumped = AddDumps(ds.tombstone_data_.begin(), ds.tombstone_data_.end(),
1352bd86372f09748b258f959cb7a1a04613038e59b0Narayan Kamath                                            "TOMBSTONE", true /* add_to_zip */);
13538f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath    if (!tombstones_dumped) {
13548f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath        printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR.c_str());
13557dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris    }
13567dc7f3221f26b771c266a26ec785eb74287922f1Christopher Ferris
1357a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpPacketStats();
1358f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
13596ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    DoKmsg();
13602262c16372570f57d3107d574abe2c80825d286eMark Salyzyn
1361a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpIpAddrAndRules();
13622b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran
13632b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran    dump_route_tables();
13642b3bba34aec65b612be8d1f52cd124d9c30955f9Sreeram Ramachandran
1365b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("ARP CACHE", {"ip", "-4", "neigh", "show"});
1366b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("IPv6 ND CACHE", {"ip", "-6", "neigh", "show"});
1367b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("MULTICAST ADDRESSES", {"ip", "maddr"});
1368f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1369780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair    RunDumpsysHigh();
13706afc38c45af45eb8f64793bca2903b3f4c55579bLorenzo Colitti
137123ccc625fd60891d20977abc5f2c35cbe46142acElliott Hughes    RunCommand("SYSTEM PROPERTIES", {"getprop"});
1372f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1373f334d669dcd9ce322dd5a997c3b5a392b9152d3bJin Qian    RunCommand("STORAGED IO INFO", {"storaged", "-u", "-p"});
1374f649a6ef3ca6358f605aea100c77a3f20f4af937ynwang
1375b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("FILESYSTEMS & FREE SPACE", {"df"});
1376f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1377b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunCommand("LAST RADIO LOG", {"parse_radio_log", "/proc/last_radio_log"});
1378f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1379f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* Binder state is expensive to look at as it uses a lot of memory. */
1380b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
1381b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
1382b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
1383b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BINDER STATS", "/sys/kernel/debug/binder/stats");
1384b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    DumpFile("BINDER STATE", "/sys/kernel/debug/binder/state");
1385f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
138636b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair    /* Add window and surface trace files. */
138736b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair    if (!PropertiesHelper::IsUserBuild()) {
138836b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair        ds.AddDir(WMTRACE_DATA_DIR, false);
138936b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair    }
139036b4cdb2ddec610e52ab60ae1f6497ae3739f496Vishnu Nair
13916f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    ds.DumpstateBoard();
1392f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
13937440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland    /* Migrate the ril_dumpstate to a device specific dumpstate? */
139496c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    int rilDumpstateTimeout = android::base::GetIntProperty("ril.dumpstate.timeout", 0);
139596c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme    if (rilDumpstateTimeout > 0) {
139630dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // su does not exist on user builds, so try running without it.
139730dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // This way any implementations of vril-dump that do not require
139830dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        // root can run on user builds.
139930dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme        CommandOptions::CommandOptionsBuilder options =
140096c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme            CommandOptions::WithTimeout(rilDumpstateTimeout);
1401f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme        if (!PropertiesHelper::IsUserBuild()) {
140230dbfa1c5fac2d8cbd5bc2e41616be9353c81733Felipe Leme            options.AsRoot();
1403f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
1404b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme        RunCommand("DUMP VENDOR RIL LOGS", {"vril-dump"}, options.Build());
1405f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1406f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1407d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1408d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Android Framework Services\n");
1409d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1410f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1411780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair    RunDumpsysNormal();
1412f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1413d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1414d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Checkins\n");
1415d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
141602bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn
1417b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
1418b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN MEMINFO", {"meminfo", "--checkin"});
1419b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN NETSTATS", {"netstats", "--checkin"});
1420b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN PROCSTATS", {"procstats", "-c"});
1421b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN USAGESTATS", {"usagestats", "-c"});
1422b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("CHECKIN PACKAGE", {"package", "--checkin"});
142302bea9786d2ecc4c04f35fd7d9b73d4dd2b73735Dianne Hackborn
1424d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1425d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Running Application Activities\n");
1426d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1427f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
14281434a5ccf5fa91f20f8f145ecdc4303a03cf3a17Winson Chung    RunDumpsys("APP ACTIVITIES", {"activity", "-v", "all"});
1429f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1430d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1431d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Running Application Services\n");
1432d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1433f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1434b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("APP SERVICES", {"activity", "service", "all"});
1435f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1436d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1437d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Running Application Providers\n");
1438d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1439f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1440b0f669de54ffe3ef59f3597faf2b4885793853cfFelipe Leme    RunDumpsys("APP PROVIDERS", {"activity", "provider", "all"});
1441f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
14428b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos    printf("========================================================\n");
14438b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos    printf("== Dropbox crashes\n");
14448b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos    printf("========================================================\n");
14458b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos
14468b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos    RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {"dropbox", "-p", "system_server_crash"});
14478b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos    RunDumpsys("DROPBOX SYSTEM APP CRASHES", {"dropbox", "-p", "system_app_crash"});
14488b397ab3d6ad2ff23897b3743fe51325e15ffaf6Adrian Roos
1449d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1450d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
1451d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme           ds.progress_->GetMax(), ds.progress_->GetInitialMax());
1452d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1453d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== dumpstate: done (id %d)\n", ds.id_);
1454d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1455f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
1456f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1457253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal// This method collects common dumpsys for telephony and wifi
1458253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawalstatic void DumpstateRadioCommon() {
1459a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpIpTablesAsRoot();
1460a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1461a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    if (!DropRootUser()) {
1462a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C        return;
1463a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    }
1464a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1465a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    do_dmesg();
1466a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DoLogcat();
1467a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpPacketStats();
1468a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DoKmsg();
1469a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    DumpIpAddrAndRules();
1470a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    dump_route_tables();
1471a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1472a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"},
1473a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C               CommandOptions::WithTimeout(10).Build());
1474253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal}
1475253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1476253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal// This method collects dumpsys for telephony debugging only
1477253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawalstatic void DumpstateTelephonyOnly() {
1478253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    DurationReporter duration_reporter("DUMPSTATE");
1479253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1480253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    DumpstateRadioCommon();
1481a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1482a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunCommand("SYSTEM PROPERTIES", {"getprop"});
1483a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1484a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1485a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("== Android Framework Services\n");
1486a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1487a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1488652cc80fcffda5a80b468b822cdddd69b28696a3Vishnu Nair    RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
1489652cc80fcffda5a80b468b822cdddd69b28696a3Vishnu Nair               SEC_TO_MSEC(10));
1490652cc80fcffda5a80b468b822cdddd69b28696a3Vishnu Nair    RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
1491652cc80fcffda5a80b468b822cdddd69b28696a3Vishnu Nair               SEC_TO_MSEC(10));
1492a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1493a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1494a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("== Running Application Services\n");
1495a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1496a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1497a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    RunDumpsys("TELEPHONY SERVICES", {"activity", "service", "TelephonyDebugService"});
1498a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1499a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1500963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran    printf("== Checkins\n");
1501963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran    printf("========================================================\n");
1502963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran
1503963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran    RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
1504963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran
1505963b04fa5c8f30e01e648bb1f1b37c0a8ac1a964Sooraj Sasindran    printf("========================================================\n");
1506a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("== dumpstate: done (id %d)\n", ds.id_);
1507a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C    printf("========================================================\n");
1508a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C}
1509a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C
1510253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal// This method collects dumpsys for wifi debugging only
1511253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawalstatic void DumpstateWifiOnly() {
1512253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    DurationReporter duration_reporter("DUMPSTATE");
1513253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1514253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    DumpstateRadioCommon();
1515253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1516253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("========================================================\n");
1517253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("== Android Framework Services\n");
1518253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("========================================================\n");
1519253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1520253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
1521253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal               SEC_TO_MSEC(10));
1522253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
1523253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal               SEC_TO_MSEC(10));
1524253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
1525253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("========================================================\n");
1526253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("== dumpstate: done (id %d)\n", ds.id_);
1527253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    printf("========================================================\n");
1528253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal}
1529253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal
15306f674aefab201fbf9141aabbb603bbfc84771927Felipe Lemevoid Dumpstate::DumpstateBoard() {
15316f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    DurationReporter duration_reporter("dumpstate_board()");
1532d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
1533d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("== Board\n");
1534d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("========================================================\n");
15356f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
153669d9221e3f2c3db256d8216f8f0d6316f7213c88Chris Phoenix    ::android::sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
15376f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    if (dumpstate_device == nullptr) {
15387440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        MYLOGE("No IDumpstateDevice implementation\n");
15396f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme        return;
15406f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    }
15416f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15426f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    if (!IsZipping()) {
15437440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        MYLOGD("Not dumping board info because it's not a zipped bugreport\n");
15446f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme        return;
15456f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    }
15466f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15479fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    std::string path[NUM_OF_DUMPS];
15489fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    android::base::unique_fd fd[NUM_OF_DUMPS];
15499fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    int numFds = 0;
15506f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15519fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    for (int i = 0; i < NUM_OF_DUMPS; i++) {
15529fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        path[i] = kDumpstateBoardPath + kDumpstateBoardFiles[i];
15539fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        MYLOGI("Calling IDumpstateDevice implementation using path %s\n", path[i].c_str());
15549fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song
15559fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        fd[i] = android::base::unique_fd(
15569fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            TEMP_FAILURE_RETRY(open(path[i].c_str(),
15579fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
15589fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
15599fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        if (fd[i] < 0) {
15609fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            MYLOGE("Could not open file %s: %s\n", path[i].c_str(), strerror(errno));
15619fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            return;
15629fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        } else {
15639fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            numFds++;
15649fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        }
15656f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    }
15666f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15679fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    native_handle_t *handle = native_handle_create(numFds, 0);
15686f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    if (handle == nullptr) {
15696f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme        MYLOGE("Could not create native_handle\n");
15706f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme        return;
15716f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    }
15729fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song
15739fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    for (int i = 0; i < numFds; i++) {
15749fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        handle->data[i] = fd[i].release();
15759fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    }
15766f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
1577f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    // TODO: need a timeout mechanism so dumpstate does not hang on device implementation call.
15787440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland    android::hardware::Return<void> status = dumpstate_device->dumpstateBoard(handle);
15797440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland    if (!status.isOk()) {
15807440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
15817440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        native_handle_close(handle);
15827440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        native_handle_delete(handle);
15837440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland        return;
15847440ddb786b7732478173fe142512dba4e2a8dfdSteven Moreland    }
15856f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15869fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    for (int i = 0; i < numFds; i++) {
15879fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        struct stat s;
15889fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        if (fstat(handle->data[i], &s) == -1) {
15899fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            MYLOGE("Failed to fstat %s: %d\n", kDumpstateBoardFiles[i].c_str(), errno);
15909fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        } else if (s.st_size > 0) {
15919fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            AddZipEntry(kDumpstateBoardFiles[i], path[i]);
15929fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        } else {
15939fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            MYLOGE("Ignoring empty %s\n", kDumpstateBoardFiles[i].c_str());
15949fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        }
15959fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    }
15969fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song
1597d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    printf("*** See dumpstate-board.txt entry ***\n");
15986f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
15996f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    native_handle_close(handle);
16006f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    native_handle_delete(handle);
16016f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
16029fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song    for (int i = 0; i < numFds; i++) {
16039fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        if (remove(path[i].c_str()) != 0) {
16049fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song            MYLOGE("Could not remove(%s): %s\n", path[i].c_str(), strerror(errno));
16059fbfad0b6dcda9a2b2c3913597aa24e4db7b3544Jie Song        }
16066f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme    }
16076f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme}
16086f674aefab201fbf9141aabbb603bbfc84771927Felipe Leme
16094a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Lemestatic void ShowUsageAndExit(int exitCode = 1) {
16104a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme    fprintf(stderr,
1611bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme            "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file] [-d] [-p] "
16124a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "[-z]] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]\n"
16134a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -h: display this help message\n"
16144a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -b: play sound file instead of vibrate, at beginning of job\n"
16154a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -e: play sound file instead of vibrate, at end of job\n"
16164a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -o: write to file (instead of stdout)\n"
16174a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -d: append date to filename (requires -o)\n"
16184a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -p: capture screenshot to filename.png (requires -o)\n"
16194a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -z: generate zipped file (requires -o)\n"
16204a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -s: write output to control socket (for init)\n"
162147f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa            "  -S: write file location to control socket (for init; requires -o and -z)\n"
16224a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -q: disable vibrate\n"
16234a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -B: send broadcast when finished (requires -o)\n"
16244a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -P: send broadcast when started and update system properties on "
16254a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "progress (requires -o and -B)\n"
16264a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "  -R: take bugreport in remote mode (requires -o, -z, -d and -B, "
16274a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            "shouldn't be used with -P)\n"
1628d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            "  -v: prints the dumpstate header and exit\n");
16294a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme    exit(exitCode);
16304a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme}
16314a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme
16324a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Lemestatic void ExitOnInvalidArgs() {
16334a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme    fprintf(stderr, "invalid combination of args\n");
16344a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme    ShowUsageAndExit();
1635f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
1636f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1637f87959e00732d7d737527f1248a71adea99ae29dWei Liustatic void register_sig_handler() {
1638558e1ef07fb6169a1501a9b8637387abef611f34Luis Hector Chavez    signal(SIGPIPE, SIG_IGN);
1639f87959e00732d7d737527f1248a71adea99ae29dWei Liu}
1640f87959e00732d7d737527f1248a71adea99ae29dWei Liu
16411d486fe3847c831b9d57843cda209ed86853ee21Felipe Lemebool Dumpstate::FinishZipFile() {
16429a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    std::string entry_name = base_name_ + "-" + name_ + ".txt";
16431d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    MYLOGD("Adding main entry (%s) from %s to .zip bugreport\n", entry_name.c_str(),
16449a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme           tmp_path_.c_str());
16455b9d3bf16bab50c8067bdc932dca1e7d952a035eFelipe Leme    // Final timestamp
16465b9d3bf16bab50c8067bdc932dca1e7d952a035eFelipe Leme    char date[80];
16475b9d3bf16bab50c8067bdc932dca1e7d952a035eFelipe Leme    time_t the_real_now_please_stand_up = time(nullptr);
16485b9d3bf16bab50c8067bdc932dca1e7d952a035eFelipe Leme    strftime(date, sizeof(date), "%Y/%m/%d %H:%M:%S", localtime(&the_real_now_please_stand_up));
16497447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    MYLOGD("dumpstate id %d finished around %s (%ld s)\n", ds.id_, date,
1650bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme           the_real_now_please_stand_up - ds.now_);
16515b9d3bf16bab50c8067bdc932dca1e7d952a035eFelipe Leme
16529a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (!ds.AddZipEntry(entry_name, tmp_path_)) {
1653cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGE("Failed to add text entry to .zip file\n");
16546e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        return false;
16556e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
16561d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (!AddTextZipEntry("main_entry.txt", entry_name)) {
1657cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGE("Failed to add main_entry.txt to .zip file\n");
1658111b9d06cc0fc72438782c9234f28675e5077ef4Felipe Leme        return false;
1659809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
16606e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
16610f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme    // Add log file (which contains stderr output) to zip...
16620f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme    fprintf(stderr, "dumpstate_log.txt entry on zip file logged up to here\n");
16639a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (!ds.AddZipEntry("dumpstate_log.txt", ds.log_path_.c_str())) {
16640f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme        MYLOGE("Failed to add dumpstate log to .zip file\n");
16650f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme        return false;
16660f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme    }
16670f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme    // ... and re-opens it for further logging.
16689a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()));
16690f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme    fprintf(stderr, "\n");
16700f3fb20cff288f2874c46c9f4102c6c9f273a0a3Felipe Leme
1671c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme    int32_t err = zip_writer_->Finish();
16721d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    if (err != 0) {
1673c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme        MYLOGE("zip_writer_->Finish(): %s\n", ZipWriter::ErrorCodeString(err));
16746e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        return false;
16756e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
16766e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
16771d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    // TODO: remove once FinishZipFile() is automatically handled by Dumpstate's destructor.
16781d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme    ds.zip_file.reset(nullptr);
16791d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme
1680e9d2c5414c86949f6de12c4291a2d8c34b2d0b34Felipe Leme    MYLOGD("Removing temporary file %s\n", tmp_path_.c_str())
1681e9d2c5414c86949f6de12c4291a2d8c34b2d0b34Felipe Leme    if (remove(tmp_path_.c_str()) != 0) {
1682e9d2c5414c86949f6de12c4291a2d8c34b2d0b34Felipe Leme        MYLOGE("Failed to remove temporary file (%s): %s\n", tmp_path_.c_str(), strerror(errno));
1683c4eee56dab06a7de1db18327f8d4831f89d1d640Felipe Leme    }
1684c4eee56dab06a7de1db18327f8d4831f89d1d640Felipe Leme
16856e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    return true;
16866e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme}
16876e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
1688cb057c2e6bf23b43df49282c0db26b663e4535f7Chih-Hung Hsiehstatic std::string SHA256_file_hash(const std::string& filepath) {
168927cd7b256eb08bf9dec7e4e8af8375711ab10225Andreas Gampe    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK
169027cd7b256eb08bf9dec7e4e8af8375711ab10225Andreas Gampe            | O_CLOEXEC | O_NOFOLLOW)));
1691aff684300a3b7d6984d3b3c1efddb810cd0205e7Andreas Gampe    if (fd == -1) {
1692cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme        MYLOGE("open(%s): %s\n", filepath.c_str(), strerror(errno));
16934db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        return NULL;
16944db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
16954db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
16964db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    SHA256_CTX ctx;
1697c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes    SHA256_Init(&ctx);
16984db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
16994db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    std::vector<uint8_t> buffer(65536);
17004db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    while (1) {
17014db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size()));
17024db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        if (bytes_read == 0) {
17034db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            break;
17044db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        } else if (bytes_read == -1) {
1705cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGE("read(%s): %s\n", filepath.c_str(), strerror(errno));
17064db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            return NULL;
17074db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski        }
17084db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
1709c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes        SHA256_Update(&ctx, buffer.data(), bytes_read);
17104db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
17114db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
1712c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes    uint8_t hash[SHA256_DIGEST_LENGTH];
1713c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes    SHA256_Final(hash, &ctx);
1714c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes
1715c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes    char hash_buffer[SHA256_DIGEST_LENGTH * 2 + 1];
1716c4dc141d1442794170421b9ee78ae00ce6b28307Elliott Hughes    for(size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
1717cbbdf73608bace91270622034e4813a2355b7bf1Michal Karpinski        sprintf(hash_buffer + (i * 2), "%02x", hash[i]);
17184db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
17194db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    hash_buffer[sizeof(hash_buffer) - 1] = 0;
17204db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    return std::string(hash_buffer);
17214db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski}
17224db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
1723a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Lemestatic void SendBroadcast(const std::string& action, const std::vector<std::string>& args) {
1724a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme    // clang-format off
1725a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme    std::vector<std::string> am = {"/system/bin/cmd", "activity", "broadcast", "--user", "0",
1726a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                    "--receiver-foreground", "--receiver-include-background", "-a", action};
1727a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme    // clang-format on
17288d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme
17298d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme    am.insert(am.end(), args.begin(), args.end());
17308d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme
17318d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme    RunCommand("", am,
17328d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme               CommandOptions::WithTimeout(20)
17338d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme                   .Log("Sending broadcast: '%s'\n")
17348d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme                   .Always()
17358d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme                   .DropRoot()
17368d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme                   .RedirectStderr()
17378d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme                   .Build());
17388d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme}
17398d2410eb937fdc27255b1129ed961463d64f847fFelipe Leme
174035b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Lemestatic void Vibrate(int duration_ms) {
174135b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme    // clang-format off
174235b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme    RunCommand("", {"cmd", "vibrator", "vibrate", std::to_string(duration_ms), "dumpstate"},
174335b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme               CommandOptions::WithTimeout(10)
174435b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme                   .Log("Vibrate: '%s'\n")
174535b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme                   .Always()
174635b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme                   .Build());
174735b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme    // clang-format on
174835b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme}
174935b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme
175020cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair/** Main entry point for dumpstate. */
175120cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nairint run_main(int argc, char* argv[]) {
1752f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int do_add_date = 0;
17536e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    int do_zip_file = 0;
17541f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    int do_vibrate = 1;
1755f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    char* use_outfile = 0;
1756f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int use_socket = 0;
17572628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    int use_control_socket = 0;
1758f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int do_fb = 0;
175927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey    int do_broadcast = 0;
17604db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    int is_remote_mode = 0;
1761d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    bool show_header_only = false;
176275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme    bool do_start_service = false;
17636ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    bool telephony_only = false;
1764253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    bool wifi_only = false;
176520cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair    int dup_stdout_fd;
176620cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair    int dup_stderr_fd;
17678fecfdda012928bc2fe6d0e66fd4a4c912946254Felipe Leme
1768f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    /* set as high priority, and protect from OOM killer */
1769f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    setpriority(PRIO_PROCESS, 0, -20);
17709c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang
1771d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    FILE* oom_adj = fopen("/proc/self/oom_score_adj", "we");
1772f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (oom_adj) {
17739c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang        fputs("-1000", oom_adj);
1774f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        fclose(oom_adj);
17759c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang    } else {
17769c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang        /* fallback to kernels <= 2.6.35 */
17779c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang        oom_adj = fopen("/proc/self/oom_adj", "we");
17789c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang        if (oom_adj) {
17799c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang            fputs("-17", oom_adj);
17809c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang            fclose(oom_adj);
17819c1f9bb7205e59d4bdc6f9e9601bc4b3ef210b3bWei Wang        }
1782f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1783f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
17841dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* parse arguments */
1785f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    int c;
17862628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
1787f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        switch (c) {
1788e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            // clang-format off
1789d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'd': do_add_date = 1;            break;
1790d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'z': do_zip_file = 1;            break;
1791d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'o': use_outfile = optarg;       break;
1792d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 's': use_socket = 1;             break;
1793d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'S': use_control_socket = 1;     break;
1794d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'v': show_header_only = true;    break;
1795d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'q': do_vibrate = 0;             break;
1796d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'p': do_fb = 1;                  break;
17979a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            case 'P': ds.update_progress_ = true; break;
1798d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'R': is_remote_mode = 1;         break;
1799d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'B': do_broadcast = 1;           break;
1800d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            case 'V':                             break; // compatibility no-op
18014a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            case 'h':
18024a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme                ShowUsageAndExit(0);
18034a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme                break;
18044a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme            default:
18054a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme                fprintf(stderr, "Invalid option: %c\n", c);
18064a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme                ShowUsageAndExit();
1807e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme                // clang-format on
1808f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
1809f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
1810f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
1811d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    // TODO: use helper function to convert argv into a string
1812d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    for (int i = 0; i < argc; i++) {
1813d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        ds.args_ += argv[i];
1814d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        if (i < argc - 1) {
1815d071c6802a03031b26de7b92a76d03849681149bFelipe Leme            ds.args_ += " ";
1816d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        }
1817d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    }
1818d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
1819d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    ds.extra_options_ = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
18209a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (!ds.extra_options_.empty()) {
18219ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme        // Framework uses a system property to override some command-line args.
18229ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme        // Currently, it contains the type of the requested bugreport.
18239a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (ds.extra_options_ == "bugreportplus") {
182475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme            // Currently, the dumpstate binder is only used by Shell to update progress.
182575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme            do_start_service = true;
18269a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.update_progress_ = true;
18279ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme            do_fb = 0;
18289a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        } else if (ds.extra_options_ == "bugreportremote") {
18299ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme            do_vibrate = 0;
18309ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme            is_remote_mode = 1;
18319ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme            do_fb = 0;
18329a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        } else if (ds.extra_options_ == "bugreportwear") {
1833446125176065d1d253583f455d1e708044004352lingfan            do_start_service = true;
18349a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.update_progress_ = true;
183546edde3cd8d4bb4eb3765ba5760591127f2e57fdAlain Vongsouvanh            do_zip_file = 1;
18366ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        } else if (ds.extra_options_ == "bugreporttelephony") {
18376ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            telephony_only = true;
1838253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal        } else if (ds.extra_options_ == "bugreportwifi") {
1839253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal            wifi_only = true;
1840253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal            do_zip_file = 1;
18419ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme        } else {
18429a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGE("Unknown extra option: %s\n", ds.extra_options_.c_str());
18439ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme        }
18449ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme        // Reset the property
184596c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme        android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
18469ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme    }
18479ce6aa4d22f6afee2c682cf2e40bf50575f3cc61Felipe Leme
1848b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla    ds.notification_title = android::base::GetProperty(PROPERTY_EXTRA_TITLE, "");
1849b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla    if (!ds.notification_title.empty()) {
1850b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        // Reset the property
1851b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        android::base::SetProperty(PROPERTY_EXTRA_TITLE, "");
1852b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla
1853b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        ds.notification_description = android::base::GetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
1854b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        if (!ds.notification_description.empty()) {
1855b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla            // Reset the property
1856b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla            android::base::SetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
1857b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        }
1858b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla        MYLOGD("notification (title:  %s, description: %s)\n",
1859b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla               ds.notification_title.c_str(), ds.notification_description.c_str());
1860b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla    }
1861b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla
18629a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if ((do_zip_file || do_add_date || ds.update_progress_ || do_broadcast) && !use_outfile) {
18634a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme        ExitOnInvalidArgs();
18646e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    }
18656e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
18662628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    if (use_control_socket && !do_zip_file) {
18674a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme        ExitOnInvalidArgs();
18682628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    }
18692628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme
18709a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (ds.update_progress_ && !do_broadcast) {
18714a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme        ExitOnInvalidArgs();
187271bbfc57974331dce79242ce806d92035fce06baFelipe Leme    }
18736e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme
18749a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (is_remote_mode && (ds.update_progress_ || !do_broadcast || !do_zip_file || !do_add_date)) {
18754a0db9fee04a5402b94cd31f0196334e110ebd05Felipe Leme        ExitOnInvalidArgs();
18764db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski    }
18774db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski
1878d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    if (ds.version_ == VERSION_DEFAULT) {
1879d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        ds.version_ = VERSION_CURRENT;
1880d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    }
1881d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
188264afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair    if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR) {
188364afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair        MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s')\n",
188464afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair               ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(),
188564afc024d760e31f3f41e0c5cb8fc543c9392ef1Vishnu Nair               VERSION_SPLIT_ANR.c_str());
1886d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        exit(1);
1887809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
1888809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
1889d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    if (show_header_only) {
1890d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        ds.PrintHeader();
1891d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        exit(0);
1892809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme    }
1893809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
18947447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    /* redirect output if needed */
18957447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    bool is_redirecting = !use_socket && use_outfile;
18967447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme
18977447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    // TODO: temporarily set progress until it's part of the Dumpstate constructor
18987447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    std::string stats_path =
18997447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme        is_redirecting ? android::base::StringPrintf("%s/dumpstate-stats.txt", dirname(use_outfile))
19007447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme                       : "";
19017447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    ds.progress_.reset(new Progress(stats_path));
19027447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme
1903d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    /* gets the sequential id */
19047447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
1905d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    ds.id_ = ++last_id;
1906d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
1907d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
1908d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    MYLOGI("begin\n");
1909d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
19106ae5c4f52b55943a7a84fb3cb47710effe788e11Felipe Leme    register_sig_handler();
1911d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
191275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme    if (do_start_service) {
191375876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme        MYLOGI("Starting 'dumpstate' service\n");
191475876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme        android::status_t ret;
191575876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme        if ((ret = android::os::DumpstateService::Start()) != android::OK) {
191675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme            MYLOGE("Unable to start DumpstateService: %d\n", ret);
191775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme        }
191875876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme    }
191975876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme
1920f029297f673ae06d219bd727a318a48b885db6fdFelipe Leme    if (PropertiesHelper::IsDryRun()) {
1921d071c6802a03031b26de7b92a76d03849681149bFelipe Leme        MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
1922d071c6802a03031b26de7b92a76d03849681149bFelipe Leme    }
1923d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
19247447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    MYLOGI("dumpstate info: id=%d, args='%s', extra_options= %s)\n", ds.id_, ds.args_.c_str(),
1925d071c6802a03031b26de7b92a76d03849681149bFelipe Leme           ds.extra_options_.c_str());
1926d071c6802a03031b26de7b92a76d03849681149bFelipe Leme
1927bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme    MYLOGI("bugreport format version: %s\n", ds.version_.c_str());
1928809d74e92c16cf694c929b8ca2b54515af13e9feFelipe Leme
19299a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    ds.do_early_screenshot_ = ds.update_progress_;
1930e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme
1931ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    // If we are going to use a socket, do it as early as possible
1932ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    // to avoid timeouts from bugreport.
1933ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    if (use_socket) {
1934ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris        redirect_to_socket(stdout, "dumpstate");
1935ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris    }
1936ed9354fc846895dc53397fbb5323bef00b3a3834Christopher Ferris
19372628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    if (use_control_socket) {
19382628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme        MYLOGD("Opening control socket\n");
19399a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        ds.control_socket_fd_ = open_socket("dumpstate");
19409a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        ds.update_progress_ = 1;
19412628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    }
19422628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme
194371bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
19449a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        ds.bugreport_dir_ = dirname(use_outfile);
1945f8124bd485e29fa013313426463dfe1647e69765Felipe Leme        std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
1946570e6ec1230c9e3458e0de57ebfe2aa2be043293Ian Pedowitz        std::string device_name = android::base::GetProperty("ro.product.name", "UNKNOWN_DEVICE");
1947f8124bd485e29fa013313426463dfe1647e69765Felipe Leme        ds.base_name_ = android::base::StringPrintf("%s-%s-%s", basename(use_outfile),
1948f8124bd485e29fa013313426463dfe1647e69765Felipe Leme                                                    device_name.c_str(), build_id.c_str());
194971bbfc57974331dce79242ce806d92035fce06baFelipe Leme        if (do_add_date) {
195071bbfc57974331dce79242ce806d92035fce06baFelipe Leme            char date[80];
1951bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme            strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
19522b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Leme            ds.name_ = date;
1953ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        } else {
19542b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Leme            ds.name_ = "undated";
195571bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
19566ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
19576ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        if (telephony_only) {
19586ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            ds.base_name_ += "-telephony";
1959253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal        } else if (wifi_only) {
1960253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal            ds.base_name_ += "-wifi";
19616ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        }
19626ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme
196371bbfc57974331dce79242ce806d92035fce06baFelipe Leme        if (do_fb) {
19649a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.screenshot_path_ = ds.GetPath(".png");
196571bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
19669a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        ds.tmp_path_ = ds.GetPath(".tmp");
196775876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme        ds.log_path_ = ds.GetPath("-dumpstate_log-" + std::to_string(ds.pid_) + ".txt");
1968e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme
1969e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme        MYLOGD(
1970e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Bugreport dir: %s\n"
1971e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Base name: %s\n"
1972e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Suffix: %s\n"
1973e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Log path: %s\n"
1974e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Temporary path: %s\n"
1975e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme            "Screenshot path: %s\n",
19769a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.bugreport_dir_.c_str(), ds.base_name_.c_str(), ds.name_.c_str(),
19779a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.log_path_.c_str(), ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
197871bbfc57974331dce79242ce806d92035fce06baFelipe Leme
19791e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        if (do_zip_file) {
19809a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.path_ = ds.GetPath(".zip");
19819a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGD("Creating initial .zip file (%s)\n", ds.path_.c_str());
19829a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            create_parent_dirs(ds.path_.c_str());
19839a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.zip_file.reset(fopen(ds.path_.c_str(), "wb"));
19841d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme            if (ds.zip_file == nullptr) {
19859a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                MYLOGE("fopen(%s, 'wb'): %s\n", ds.path_.c_str(), strerror(errno));
19861e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme                do_zip_file = 0;
19871e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            } else {
1988c6bc8bc4f05ad7d20e931944fb5042b578bc2e53Felipe Leme                ds.zip_writer_.reset(new ZipWriter(ds.zip_file.get()));
19891e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme            }
19901d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme            ds.AddTextZipEntry("version.txt", ds.version_);
19911e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        }
19921e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme
19939a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (ds.update_progress_) {
1994dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme            if (do_broadcast) {
1995dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme                // clang-format off
1996cfaa07ad3207cc2b64586f388ecad95d60082c88Christopher Tate
1997dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme                std::vector<std::string> am_args = {
1998a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                     "--receiver-permission", "android.permission.DUMP",
19992b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Leme                     "--es", "android.intent.extra.NAME", ds.name_,
2000e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme                     "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
200175876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme                     "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
20027447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme                     "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
2003dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme                };
2004dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme                // clang-format on
2005a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
2006dcd1f0da541304421648c77db287ebe56339a6beFelipe Leme            }
2007aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme            if (use_control_socket) {
20089a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                dprintf(ds.control_socket_fd_, "BEGIN:%s\n", ds.path_.c_str());
2009aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme            }
201071bbfc57974331dce79242ce806d92035fce06baFelipe Leme        }
201171bbfc57974331dce79242ce806d92035fce06baFelipe Leme    }
201271bbfc57974331dce79242ce806d92035fce06baFelipe Leme
2013f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    /* read /proc/cmdline before dropping root */
2014f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    FILE *cmdline = fopen("/proc/cmdline", "re");
2015f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    if (cmdline) {
2016f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
2017f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich        fclose(cmdline);
2018f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich    }
2019f3599b35c5f7f86cced0f3386a6c80e0b552f358Nick Kralevich
20201f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    if (do_vibrate) {
202135b8cf1902bba437eb9c3f14cb69cf403695ebe8Felipe Leme        Vibrate(150);
20221f794c442cc63f7962c21e8e712adeca338af63eJohn Michelau    }
2023f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
20249a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (do_fb && ds.do_early_screenshot_) {
20259a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (ds.screenshot_path_.empty()) {
20263634a1e3459cb609da709646107e246cafbc01f9Felipe Leme            // should not have happened
2027cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGE("INTERNAL ERROR: skipping early screenshot because path was not set\n");
20283634a1e3459cb609da709646107e246cafbc01f9Felipe Leme        } else {
2029cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGI("taking early screenshot\n");
2030bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme            ds.TakeScreenshot();
2031e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme        }
2032e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme    }
2033e338bf60701e5b955ab0a097f2631f2190218894Felipe Leme
20341e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    if (do_zip_file) {
20359a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (chown(ds.path_.c_str(), AID_SHELL, AID_SHELL)) {
20369a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGE("Unable to change ownership of zip file %s: %s\n", ds.path_.c_str(),
20371d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme                   strerror(errno));
20381e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme        }
20391e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme    }
20401e9edc619c6b1ca3998a26eaa4882b55ce801f12Felipe Leme
204171bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
204220cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair        TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
20439a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        redirect_to_file(stderr, const_cast<char*>(ds.log_path_.c_str()));
20449a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (chown(ds.log_path_.c_str(), AID_SHELL, AID_SHELL)) {
20459a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n",
20469a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                   ds.log_path_.c_str(), strerror(errno));
20476fe9db67f6c92d5fbf87d371da5cca412f672630Felipe Leme        }
204820cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair        TEMP_FAILURE_RETRY(dup_stdout_fd = dup(fileno(stdout)));
20496e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        /* TODO: rather than generating a text file now and zipping it later,
20506e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme           it would be more efficient to redirect stdout to the zip entry
20516e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme           directly, but the libziparchive doesn't support that option yet. */
20529a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        redirect_to_file(stdout, const_cast<char*>(ds.tmp_path_.c_str()));
20539a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (chown(ds.tmp_path_.c_str(), AID_SHELL, AID_SHELL)) {
20546fe9db67f6c92d5fbf87d371da5cca412f672630Felipe Leme            MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n",
20559a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                   ds.tmp_path_.c_str(), strerror(errno));
20566fe9db67f6c92d5fbf87d371da5cca412f672630Felipe Leme        }
2057f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
2058d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme
2059d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    // Don't buffer stdout
2060d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme    setvbuf(stdout, nullptr, _IONBF, 0);
2061d8b94e5e61ca744962400ebefa33c15c459571c4Felipe Leme
2062608385dd151e36a93f3e3f4a7514b1e720d20ae9Felipe Leme    // NOTE: there should be no stdout output until now, otherwise it would break the header.
2063608385dd151e36a93f3e3f4a7514b1e720d20ae9Felipe Leme    // In particular, DurationReport objects should be created passing 'title, NULL', so their
2064cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme    // duration is logged into MYLOG instead.
2065bbaf3c11c4723be0f6b56ef603e11b0baaa92429Felipe Leme    ds.PrintHeader();
2066f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
20676ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    if (telephony_only) {
2068a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C        DumpstateTelephonyOnly();
20696ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        ds.DumpstateBoard();
2070253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal    } else if (wifi_only) {
2071253dad4af7ed9df588d5b1403f7c95f9610c72efmukesh agrawal        DumpstateWifiOnly();
20726ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    } else {
20736ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // Dumps systrace right away, otherwise it will be filled with unnecessary events.
20746ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // First try to dump anrd trace if the daemon is running. Otherwise, dump
20756ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // the raw trace.
20766ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        if (!dump_anrd_trace()) {
20776ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            dump_systrace();
20786ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        }
207971a74ac75c8687195d27642fa0db31a796102c59Felipe Leme
20806ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // Invoking the following dumpsys calls before dump_traces() to try and
20816ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // keep the system stats as close to its initial state as possible.
2082780b1283e6d219e1ef3cb061f5096dcb359d88caVishnu Nair        RunDumpsysCritical();
2083fdf52d3697aa0396bd9d8883892937b99a6772a0Srinath Sridharan
20846ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
20856ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        dump_raft();
2086e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme
20876ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        /* collect stack traces from Dalvik and native processes (needs root) */
20886ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        dump_traces_path = dump_traces();
2089fdf52d3697aa0396bd9d8883892937b99a6772a0Srinath Sridharan
20906ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        /* Run some operations that require root. */
20915f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping());
20925f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez        ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping());
20938f788290f89c0782ca5cf2d1feaa81250295c5faNarayan Kamath
20946ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        ds.AddDir(RECOVERY_DIR, true);
20956ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        ds.AddDir(RECOVERY_DATA_DIR, true);
20966ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        ds.AddDir(LOGPERSIST_DATA_DIR, false);
20976ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        if (!PropertiesHelper::IsUserBuild()) {
20986ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            ds.AddDir(PROFILE_DATA_DIR_CUR, true);
20996ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            ds.AddDir(PROFILE_DATA_DIR_REF, true);
21006ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        }
21016ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        add_mountinfo();
2102a94c71732290dd6bba937548bbe748785dd43ab0Jayachandran C        DumpIpTablesAsRoot();
2103fdf52d3697aa0396bd9d8883892937b99a6772a0Srinath Sridharan
21046ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // Capture any IPSec policies in play.  No keys are exposed here.
21056ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        RunCommand("IP XFRM POLICY", {"ip", "xfrm", "policy"},
21066ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme                   CommandOptions::WithTimeout(10).Build());
210732af8c2aefd9a31e851c8f17168f19afcb5efb18Erik Kline
21086ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        // Run ss as root so we can see socket marks.
21096ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        RunCommand("DETAILED SOCKET STATE", {"ss", "-eionptu"},
21106ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme                   CommandOptions::WithTimeout(10).Build());
2111d3b809baff20a2ff7e41f4add801f71cce0665f7Lorenzo Colitti
21123cd671e868a3648a4ca00c3e0b063e983d34b702Jin Qian        // Run iotop as root to show top 100 IO threads
21133cd671e868a3648a4ca00c3e0b063e983d34b702Jin Qian        RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
21143cd671e868a3648a4ca00c3e0b063e983d34b702Jin Qian
21156ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        if (!DropRootUser()) {
21166ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme            return -1;
21176ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        }
2118fdf52d3697aa0396bd9d8883892937b99a6772a0Srinath Sridharan
21196ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme        dumpstate();
21206ec6ac46c457fb54752c7044647e77b4008ed2cfFelipe Leme    }
2121f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
212255b42a67f69767976ff16ab443b3e7142db693e1Felipe Leme    /* close output if needed */
212371bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (is_redirecting) {
212420cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair        TEMP_FAILURE_RETRY(dup2(dup_stdout_fd, fileno(stdout)));
2125f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
2126f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
21276e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    /* rename or zip the (now complete) .tmp file to its final location */
21286e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme    if (use_outfile) {
2129ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
2130ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        /* check if user changed the suffix using system properties */
213196c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme        std::string name = android::base::GetProperty(
213275876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme            android::base::StringPrintf("dumpstate.%d.name", ds.pid_), "");
2133ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        bool change_suffix= false;
213496c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme        if (!name.empty()) {
2135ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            /* must whitelist which characters are allowed, otherwise it could cross directories */
2136ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            std::regex valid_regex("^[-_a-zA-Z0-9]+$");
213796c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme            if (std::regex_match(name.c_str(), valid_regex)) {
2138ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                change_suffix = true;
2139ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            } else {
214096c2bbbf1ab3477f061f2b1b05482f5aec8c5dfaFelipe Leme                MYLOGE("invalid suffix provided by user: %s\n", name.c_str());
2141ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            }
2142ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        }
2143ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        if (change_suffix) {
21442b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Leme            MYLOGI("changing suffix from %s to %s\n", ds.name_.c_str(), name.c_str());
21452b9b06ca7c54a6d7b6b2188dbd884b445b052d34Felipe Leme            ds.name_ = name;
21469a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            if (!ds.screenshot_path_.empty()) {
21479a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                std::string new_screenshot_path = ds.GetPath(".png");
21489a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                if (rename(ds.screenshot_path_.c_str(), new_screenshot_path.c_str())) {
21499a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                    MYLOGE("rename(%s, %s): %s\n", ds.screenshot_path_.c_str(),
21509a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                           new_screenshot_path.c_str(), strerror(errno));
2151ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                } else {
21529a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                    ds.screenshot_path_ = new_screenshot_path;
2153ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme                }
2154ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme            }
2155ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme        }
2156ad5f6c475934ac6a658a203069a9f055540946e7Felipe Leme
21576e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        bool do_text_file = true;
21586e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        if (do_zip_file) {
21591d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme            if (!ds.FinishZipFile()) {
2160cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme                MYLOGE("Failed to finish zip file; sending text bugreport instead\n");
21616e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme                do_text_file = true;
21626e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            } else {
21636e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme                do_text_file = false;
21649127435ffbb081fe91a30169f394a57fd31fd05eFelipe Leme                // Since zip file is already created, it needs to be renamed.
21659a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                std::string new_path = ds.GetPath(".zip");
21669a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                if (ds.path_ != new_path) {
21679a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                    MYLOGD("Renaming zip file from %s to %s\n", ds.path_.c_str(), new_path.c_str());
21689a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                    if (rename(ds.path_.c_str(), new_path.c_str())) {
21699a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                        MYLOGE("rename(%s, %s): %s\n", ds.path_.c_str(), new_path.c_str(),
21701d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme                               strerror(errno));
21719127435ffbb081fe91a30169f394a57fd31fd05eFelipe Leme                    } else {
21729a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                        ds.path_ = new_path;
21739127435ffbb081fe91a30169f394a57fd31fd05eFelipe Leme                    }
21749127435ffbb081fe91a30169f394a57fd31fd05eFelipe Leme                }
21756e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            }
21766e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
21776e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        if (do_text_file) {
21789a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            ds.path_ = ds.GetPath(".txt");
21799a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGD("Generating .txt bugreport at %s from %s\n", ds.path_.c_str(),
21809a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                   ds.tmp_path_.c_str());
21819a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            if (rename(ds.tmp_path_.c_str(), ds.path_.c_str())) {
21829a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                MYLOGE("rename(%s, %s): %s\n", ds.tmp_path_.c_str(), ds.path_.c_str(),
21831d486fe3847c831b9d57843cda209ed86853ee21Felipe Leme                       strerror(errno));
21849a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                ds.path_.clear();
21856e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme            }
21866e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
21872628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme        if (use_control_socket) {
21882628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme            if (do_text_file) {
21899a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                dprintf(ds.control_socket_fd_,
2190e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme                        "FAIL:could not create zip file, check %s "
2191e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme                        "for more details\n",
21929a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                        ds.log_path_.c_str());
21932628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme            } else {
21949a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                dprintf(ds.control_socket_fd_, "OK:%s\n", ds.path_.c_str());
21952628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme            }
21962628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme        }
2197f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
2198f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
2199cc2a2fa64e22378d980ae0ae95c8865ebea05f69Felipe Leme    /* vibrate a few but shortly times to let user know it's finished */
220047f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa    if (do_vibrate) {
220147f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa        for (int i = 0; i < 3; i++) {
220247f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa            Vibrate(75);
220347f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa            usleep((75 + 50) * 1000);
220447f644e774a13c81bf8bda5166e65cd5c5171ef3Takuya Ogawa        }
2205cc2a2fa64e22378d980ae0ae95c8865ebea05f69Felipe Leme    }
2206cc2a2fa64e22378d980ae0ae95c8865ebea05f69Felipe Leme
22071dc94e315680b47fe430ef90f46c50a25c92fb6dJeff Brown    /* tell activity manager we're done */
220871bbfc57974331dce79242ce806d92035fce06baFelipe Leme    if (do_broadcast) {
22099a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        if (!ds.path_.empty()) {
22109a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme            MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
2211aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme            // clang-format off
2212cfaa07ad3207cc2b64586f388ecad95d60082c88Christopher Tate
221336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            std::vector<std::string> am_args = {
2214a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                 "--receiver-permission", "android.permission.DUMP",
2215e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme                 "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
221675876a2c0649b8cde36329ca0a1dc6e349af6493Felipe Leme                 "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
22177447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme                 "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
22189a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                 "--es", "android.intent.extra.BUGREPORT", ds.path_,
22199a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                 "--es", "android.intent.extra.DUMPSTATE_LOG", ds.log_path_
222036b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            };
2221aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme            // clang-format on
222236b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            if (do_fb) {
222336b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                am_args.push_back("--es");
222436b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme                am_args.push_back("android.intent.extra.SCREENSHOT");
22259a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                am_args.push_back(ds.screenshot_path_);
222636b3f6ff17e456dea81501006e33d5fdd1d3b480Felipe Leme            }
2227b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla            if (!ds.notification_title.empty()) {
2228b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                am_args.push_back("--es");
2229b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                am_args.push_back("android.intent.extra.TITLE");
2230b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                am_args.push_back(ds.notification_title);
2231b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                if (!ds.notification_description.empty()) {
2232b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                    am_args.push_back("--es");
2233b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                    am_args.push_back("android.intent.extra.DESCRIPTION");
2234b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                    am_args.push_back(ds.notification_description);
2235b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla                }
2236b53a1c9b4df27a7a66c9448778eace166a0ce14cNaveen Kalla            }
22374db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            if (is_remote_mode) {
22384db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                am_args.push_back("--es");
22394db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski                am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
22409a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme                am_args.push_back(SHA256_file_hash(ds.path_));
2241a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                SendBroadcast("com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED",
2242a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                              am_args);
22434db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            } else {
2244a4ef1f050ce4f4a9976057f1efa34a4ff5ec0ac8Felipe Leme                SendBroadcast("com.android.internal.intent.action.BUGREPORT_FINISHED", am_args);
22454db754fd7c13993d81d98157f10e8015422d1e3aMichal Karpinski            }
22466e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        } else {
2247cbce55d4fdbdd2e5a5515054c48d2116c5db2712Felipe Leme            MYLOGE("Skipping finished broadcast because bugreport could not be generated\n");
22486e01fa6f95fb20a2faab33561056d2e74cc097cbFelipe Leme        }
224927f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey    }
225027f9e6d849fce956c9b8f1ad5c3d9a954501a76bJeff Sharkey
22517447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    MYLOGD("Final progress: %d/%d (estimated %d)\n", ds.progress_->Get(), ds.progress_->GetMax(),
22527447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme           ds.progress_->GetInitialMax());
22537447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    ds.progress_->Save();
22547447d7c3d74b28f1a071b1d3503212cc8ad08d68Felipe Leme    MYLOGI("done (id %d)\n", ds.id_);
2255f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
2256107a05f72e711c92545d0be648ab79c4f858f372Felipe Leme    if (is_redirecting) {
225720cf5036c1f373c1acfbb95295f118b7ff6c2227Vishnu Nair        TEMP_FAILURE_RETRY(dup2(dup_stderr_fd, fileno(stderr)));
2258107a05f72e711c92545d0be648ab79c4f858f372Felipe Leme    }
2259107a05f72e711c92545d0be648ab79c4f858f372Felipe Leme
22609a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme    if (use_control_socket && ds.control_socket_fd_ != -1) {
2261e844a9d60a54c7dd6dbf0a8f44167b484324d08dFelipe Leme        MYLOGD("Closing control socket\n");
22629a523aed06ef962f67385ac88191b08dc91059f4Felipe Leme        close(ds.control_socket_fd_);
22632628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme    }
22642628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme
22655f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    ds.tombstone_data_.clear();
22665f6ee4a11de1de262cea6465c2f991834b2e4792Luis Hector Chavez    ds.anr_data_.clear();
22676b9516ced325e93880e9c8ef2793380866a1c579Narayan Kamath
2268f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return 0;
2269f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
2270