1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "dumpstate"
18*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_ALWAYS
19*38e8c45fSAndroid Build Coastguard Worker
20*38e8c45fSAndroid Build Coastguard Worker #include "dumpstate.h"
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker #include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <android-base/file.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <android-base/strings.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_manager.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_process.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <android/content/pm/IPackageManagerNative.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/dumpstate/1.1/IDumpstateDevice.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/dumpstate/1.1/types.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <android/hidl/manager/1.0/IServiceManager.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IIncidentCompanion.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <android_app_admin_flags.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <android_tracing.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <cutils/multiuser.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <cutils/native_handle.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <cutils/properties.h>
43*38e8c45fSAndroid Build Coastguard Worker #include <cutils/sockets.h>
44*38e8c45fSAndroid Build Coastguard Worker #include <cutils/trace.h>
45*38e8c45fSAndroid Build Coastguard Worker #include <debuggerd/client.h>
46*38e8c45fSAndroid Build Coastguard Worker #include <dirent.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <dumpsys.h>
48*38e8c45fSAndroid Build Coastguard Worker #include <dumputils/dump_utils.h>
49*38e8c45fSAndroid Build Coastguard Worker #include <errno.h>
50*38e8c45fSAndroid Build Coastguard Worker #include <fcntl.h>
51*38e8c45fSAndroid Build Coastguard Worker #include <hardware_legacy/power.h>
52*38e8c45fSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
53*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
54*38e8c45fSAndroid Build Coastguard Worker #include <libgen.h>
55*38e8c45fSAndroid Build Coastguard Worker #include <limits.h>
56*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
57*38e8c45fSAndroid Build Coastguard Worker #include <log/log_read.h>
58*38e8c45fSAndroid Build Coastguard Worker #include <math.h>
59*38e8c45fSAndroid Build Coastguard Worker #include <openssl/sha.h>
60*38e8c45fSAndroid Build Coastguard Worker #include <poll.h>
61*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
62*38e8c45fSAndroid Build Coastguard Worker #include <private/android_logger.h>
63*38e8c45fSAndroid Build Coastguard Worker #include <serviceutils/PriorityDumper.h>
64*38e8c45fSAndroid Build Coastguard Worker #include <signal.h>
65*38e8c45fSAndroid Build Coastguard Worker #include <stdarg.h>
66*38e8c45fSAndroid Build Coastguard Worker #include <stdbool.h>
67*38e8c45fSAndroid Build Coastguard Worker #include <stdio.h>
68*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
69*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
70*38e8c45fSAndroid Build Coastguard Worker #include <sys/capability.h>
71*38e8c45fSAndroid Build Coastguard Worker #include <sys/inotify.h>
72*38e8c45fSAndroid Build Coastguard Worker #include <sys/klog.h>
73*38e8c45fSAndroid Build Coastguard Worker #include <sys/mount.h>
74*38e8c45fSAndroid Build Coastguard Worker #include <sys/poll.h>
75*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
76*38e8c45fSAndroid Build Coastguard Worker #include <sys/resource.h>
77*38e8c45fSAndroid Build Coastguard Worker #include <sys/stat.h>
78*38e8c45fSAndroid Build Coastguard Worker #include <sys/time.h>
79*38e8c45fSAndroid Build Coastguard Worker #include <sys/wait.h>
80*38e8c45fSAndroid Build Coastguard Worker #include <time.h>
81*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
82*38e8c45fSAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
83*38e8c45fSAndroid Build Coastguard Worker #include <vintf/VintfObject.h>
84*38e8c45fSAndroid Build Coastguard Worker
85*38e8c45fSAndroid Build Coastguard Worker #include <chrono>
86*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
87*38e8c45fSAndroid Build Coastguard Worker #include <fstream>
88*38e8c45fSAndroid Build Coastguard Worker #include <functional>
89*38e8c45fSAndroid Build Coastguard Worker #include <future>
90*38e8c45fSAndroid Build Coastguard Worker #include <memory>
91*38e8c45fSAndroid Build Coastguard Worker #include <numeric>
92*38e8c45fSAndroid Build Coastguard Worker #include <regex>
93*38e8c45fSAndroid Build Coastguard Worker #include <set>
94*38e8c45fSAndroid Build Coastguard Worker #include <string>
95*38e8c45fSAndroid Build Coastguard Worker #include <utility>
96*38e8c45fSAndroid Build Coastguard Worker #include <vector>
97*38e8c45fSAndroid Build Coastguard Worker
98*38e8c45fSAndroid Build Coastguard Worker #include "DumpstateInternal.h"
99*38e8c45fSAndroid Build Coastguard Worker #include "DumpstateService.h"
100*38e8c45fSAndroid Build Coastguard Worker
101*38e8c45fSAndroid Build Coastguard Worker namespace dumpstate_hal_hidl_1_0 = android::hardware::dumpstate::V1_0;
102*38e8c45fSAndroid Build Coastguard Worker namespace dumpstate_hal_hidl = android::hardware::dumpstate::V1_1;
103*38e8c45fSAndroid Build Coastguard Worker namespace dumpstate_hal_aidl = aidl::android::hardware::dumpstate;
104*38e8c45fSAndroid Build Coastguard Worker
105*38e8c45fSAndroid Build Coastguard Worker using ::std::literals::chrono_literals::operator""ms;
106*38e8c45fSAndroid Build Coastguard Worker using ::std::literals::chrono_literals::operator""s;
107*38e8c45fSAndroid Build Coastguard Worker using ::std::placeholders::_1;
108*38e8c45fSAndroid Build Coastguard Worker
109*38e8c45fSAndroid Build Coastguard Worker // TODO: remove once moved to namespace
110*38e8c45fSAndroid Build Coastguard Worker using android::defaultServiceManager;
111*38e8c45fSAndroid Build Coastguard Worker using android::Dumpsys;
112*38e8c45fSAndroid Build Coastguard Worker using android::INVALID_OPERATION;
113*38e8c45fSAndroid Build Coastguard Worker using android::IServiceManager;
114*38e8c45fSAndroid Build Coastguard Worker using android::OK;
115*38e8c45fSAndroid Build Coastguard Worker using android::sp;
116*38e8c45fSAndroid Build Coastguard Worker using android::status_t;
117*38e8c45fSAndroid Build Coastguard Worker using android::String16;
118*38e8c45fSAndroid Build Coastguard Worker using android::String8;
119*38e8c45fSAndroid Build Coastguard Worker using android::TIMED_OUT;
120*38e8c45fSAndroid Build Coastguard Worker using android::UNKNOWN_ERROR;
121*38e8c45fSAndroid Build Coastguard Worker using android::Vector;
122*38e8c45fSAndroid Build Coastguard Worker using android::base::StringPrintf;
123*38e8c45fSAndroid Build Coastguard Worker using android::os::IDumpstateListener;
124*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::CommandOptions;
125*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::DumpFileToFd;
126*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::DumpPool;
127*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::PropertiesHelper;
128*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::TaskQueue;
129*38e8c45fSAndroid Build Coastguard Worker using android::os::dumpstate::WaitForTask;
130*38e8c45fSAndroid Build Coastguard Worker
131*38e8c45fSAndroid Build Coastguard Worker // Keep in sync with
132*38e8c45fSAndroid Build Coastguard Worker // frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
133*38e8c45fSAndroid Build Coastguard Worker static const int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
134*38e8c45fSAndroid Build Coastguard Worker
135*38e8c45fSAndroid Build Coastguard Worker /* Most simple commands have 10 as timeout, so 5 is a good estimate */
136*38e8c45fSAndroid Build Coastguard Worker static const int32_t WEIGHT_FILE = 5;
137*38e8c45fSAndroid Build Coastguard Worker
138*38e8c45fSAndroid Build Coastguard Worker // TODO: temporary variables and functions used during C++ refactoring
139*38e8c45fSAndroid Build Coastguard Worker static Dumpstate& ds = Dumpstate::GetInstance();
RunCommand(const std::string & title,const std::vector<std::string> & full_command,const CommandOptions & options=CommandOptions::DEFAULT,bool verbose_duration=false,int out_fd=STDOUT_FILENO)140*38e8c45fSAndroid Build Coastguard Worker static int RunCommand(const std::string& title, const std::vector<std::string>& full_command,
141*38e8c45fSAndroid Build Coastguard Worker const CommandOptions& options = CommandOptions::DEFAULT,
142*38e8c45fSAndroid Build Coastguard Worker bool verbose_duration = false, int out_fd = STDOUT_FILENO) {
143*38e8c45fSAndroid Build Coastguard Worker return ds.RunCommand(title, full_command, options, verbose_duration, out_fd);
144*38e8c45fSAndroid Build Coastguard Worker }
145*38e8c45fSAndroid Build Coastguard Worker
146*38e8c45fSAndroid Build Coastguard Worker // Reasonable value for max stats.
147*38e8c45fSAndroid Build Coastguard Worker static const int STATS_MAX_N_RUNS = 1000;
148*38e8c45fSAndroid Build Coastguard Worker static const long STATS_MAX_AVERAGE = 100000;
149*38e8c45fSAndroid Build Coastguard Worker
150*38e8c45fSAndroid Build Coastguard Worker CommandOptions Dumpstate::DEFAULT_DUMPSYS = CommandOptions::WithTimeout(30).Build();
151*38e8c45fSAndroid Build Coastguard Worker
152*38e8c45fSAndroid Build Coastguard Worker typedef Dumpstate::ConsentCallback::ConsentResult UserConsentResult;
153*38e8c45fSAndroid Build Coastguard Worker
154*38e8c45fSAndroid Build Coastguard Worker /* read before root is shed */
155*38e8c45fSAndroid Build Coastguard Worker static char cmdline_buf[16384] = "(unknown)";
156*38e8c45fSAndroid Build Coastguard Worker static const char *dump_traces_path = nullptr;
157*38e8c45fSAndroid Build Coastguard Worker static const uint64_t USER_CONSENT_TIMEOUT_MS = 30 * 1000;
158*38e8c45fSAndroid Build Coastguard Worker // Because telephony reports are significantly faster to collect (< 10 seconds vs. > 2 minutes),
159*38e8c45fSAndroid Build Coastguard Worker // it's often the case that they time out far too quickly for consent with such a hefty dialog for
160*38e8c45fSAndroid Build Coastguard Worker // the user to read. For telephony reports only, we increase the default timeout to 2 minutes to
161*38e8c45fSAndroid Build Coastguard Worker // roughly match full reports' durations.
162*38e8c45fSAndroid Build Coastguard Worker static const uint64_t TELEPHONY_REPORT_USER_CONSENT_TIMEOUT_MS = 2 * 60 * 1000;
163*38e8c45fSAndroid Build Coastguard Worker
164*38e8c45fSAndroid Build Coastguard Worker // TODO: variables and functions below should be part of dumpstate object
165*38e8c45fSAndroid Build Coastguard Worker
166*38e8c45fSAndroid Build Coastguard Worker static std::set<std::string> mount_points;
167*38e8c45fSAndroid Build Coastguard Worker void add_mountinfo();
168*38e8c45fSAndroid Build Coastguard Worker
169*38e8c45fSAndroid Build Coastguard Worker #define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
170*38e8c45fSAndroid Build Coastguard Worker #define ALT_PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops-0"
171*38e8c45fSAndroid Build Coastguard Worker #define BLK_DEV_SYS_DIR "/sys/block"
172*38e8c45fSAndroid Build Coastguard Worker
173*38e8c45fSAndroid Build Coastguard Worker #define AFLAGS "/system/bin/aflags"
174*38e8c45fSAndroid Build Coastguard Worker #define RECOVERY_DIR "/cache/recovery"
175*38e8c45fSAndroid Build Coastguard Worker #define RECOVERY_DATA_DIR "/data/misc/recovery"
176*38e8c45fSAndroid Build Coastguard Worker #define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
177*38e8c45fSAndroid Build Coastguard Worker #define UPDATE_ENGINE_PREF_DIR "/data/misc/update_engine/prefs"
178*38e8c45fSAndroid Build Coastguard Worker #define LOGPERSIST_DATA_DIR "/data/misc/logd"
179*38e8c45fSAndroid Build Coastguard Worker #define PREREBOOT_DATA_DIR "/data/misc/prereboot"
180*38e8c45fSAndroid Build Coastguard Worker #define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
181*38e8c45fSAndroid Build Coastguard Worker #define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
182*38e8c45fSAndroid Build Coastguard Worker #define XFRM_STAT_PROC_FILE "/proc/net/xfrm_stat"
183*38e8c45fSAndroid Build Coastguard Worker #define KERNEL_CONFIG "/proc/config.gz"
184*38e8c45fSAndroid Build Coastguard Worker #define WLUTIL "/vendor/xbin/wlutil"
185*38e8c45fSAndroid Build Coastguard Worker #define WMTRACE_DATA_DIR "/data/misc/wmtrace"
186*38e8c45fSAndroid Build Coastguard Worker #define OTA_METADATA_DIR "/metadata/ota"
187*38e8c45fSAndroid Build Coastguard Worker #define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log"
188*38e8c45fSAndroid Build Coastguard Worker #define LINKERCONFIG_DIR "/linkerconfig"
189*38e8c45fSAndroid Build Coastguard Worker #define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list"
190*38e8c45fSAndroid Build Coastguard Worker #define SYSTEM_TRACE_SNAPSHOT "/data/misc/perfetto-traces/bugreport/systrace.pftrace"
191*38e8c45fSAndroid Build Coastguard Worker #define CGROUPFS_DIR "/sys/fs/cgroup"
192*38e8c45fSAndroid Build Coastguard Worker #define SDK_EXT_INFO "/apex/com.android.sdkext/bin/derive_sdk"
193*38e8c45fSAndroid Build Coastguard Worker #define DROPBOX_DIR "/data/system/dropbox"
194*38e8c45fSAndroid Build Coastguard Worker #define PRINT_FLAGS "/system/bin/printflags"
195*38e8c45fSAndroid Build Coastguard Worker #define UWB_LOG_DIR "/data/misc/apexdata/com.android.uwb/log"
196*38e8c45fSAndroid Build Coastguard Worker
197*38e8c45fSAndroid Build Coastguard Worker // TODO(narayan): Since this information has to be kept in sync
198*38e8c45fSAndroid Build Coastguard Worker // with tombstoned, we should just put it in a common header.
199*38e8c45fSAndroid Build Coastguard Worker //
200*38e8c45fSAndroid Build Coastguard Worker // File: system/core/debuggerd/tombstoned/tombstoned.cpp
201*38e8c45fSAndroid Build Coastguard Worker static const std::string TOMBSTONE_DIR = "/data/tombstones/";
202*38e8c45fSAndroid Build Coastguard Worker static const std::string TOMBSTONE_FILE_PREFIX = "tombstone_";
203*38e8c45fSAndroid Build Coastguard Worker static const std::string ANR_DIR = "/data/anr/";
204*38e8c45fSAndroid Build Coastguard Worker static const std::string ANR_FILE_PREFIX = "anr_";
205*38e8c45fSAndroid Build Coastguard Worker static const std::string ANR_TRACE_FILE_PREFIX = "trace_";
206*38e8c45fSAndroid Build Coastguard Worker static const std::string SHUTDOWN_CHECKPOINTS_DIR = "/data/system/shutdown-checkpoints/";
207*38e8c45fSAndroid Build Coastguard Worker static const std::string SHUTDOWN_CHECKPOINTS_FILE_PREFIX = "checkpoints-";
208*38e8c45fSAndroid Build Coastguard Worker
209*38e8c45fSAndroid Build Coastguard Worker // File path to default screenshot image, that used when failed to capture the real screenshot.
210*38e8c45fSAndroid Build Coastguard Worker static const std::string DEFAULT_SCREENSHOT_PATH = "/system/etc/default_screenshot.png";
211*38e8c45fSAndroid Build Coastguard Worker
212*38e8c45fSAndroid Build Coastguard Worker // TODO: temporary variables and functions used during C++ refactoring
213*38e8c45fSAndroid Build Coastguard Worker
214*38e8c45fSAndroid Build Coastguard Worker #define RETURN_IF_USER_DENIED_CONSENT() \
215*38e8c45fSAndroid Build Coastguard Worker if (ds.IsUserConsentDenied()) { \
216*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Returning early as user denied consent to share bugreport with calling app."); \
217*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::USER_CONSENT_DENIED; \
218*38e8c45fSAndroid Build Coastguard Worker }
219*38e8c45fSAndroid Build Coastguard Worker
220*38e8c45fSAndroid Build Coastguard Worker // Runs func_ptr, but checks user consent before and after running it. Returns USER_CONSENT_DENIED
221*38e8c45fSAndroid Build Coastguard Worker // if consent is found to be denied.
222*38e8c45fSAndroid Build Coastguard Worker #define RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(func_ptr, ...) \
223*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT(); \
224*38e8c45fSAndroid Build Coastguard Worker func_ptr(__VA_ARGS__); \
225*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
226*38e8c45fSAndroid Build Coastguard Worker
227*38e8c45fSAndroid Build Coastguard Worker // Runs func_ptr, and logs a duration report after it's finished.
228*38e8c45fSAndroid Build Coastguard Worker #define RUN_SLOW_FUNCTION_AND_LOG(log_title, func_ptr, ...) \
229*38e8c45fSAndroid Build Coastguard Worker { \
230*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter_in_macro(log_title); \
231*38e8c45fSAndroid Build Coastguard Worker func_ptr(__VA_ARGS__); \
232*38e8c45fSAndroid Build Coastguard Worker }
233*38e8c45fSAndroid Build Coastguard Worker
234*38e8c45fSAndroid Build Coastguard Worker // Similar with RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK, an additional duration report
235*38e8c45fSAndroid Build Coastguard Worker // is output after a slow function is finished.
236*38e8c45fSAndroid Build Coastguard Worker #define RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(log_title, func_ptr, ...) \
237*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT(); \
238*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_AND_LOG(log_title, func_ptr, __VA_ARGS__); \
239*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
240*38e8c45fSAndroid Build Coastguard Worker
241*38e8c45fSAndroid Build Coastguard Worker #define WAIT_TASK_WITH_CONSENT_CHECK(future) \
242*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT(); \
243*38e8c45fSAndroid Build Coastguard Worker WaitForTask(future); \
244*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
245*38e8c45fSAndroid Build Coastguard Worker
246*38e8c45fSAndroid Build Coastguard Worker static const char* WAKE_LOCK_NAME = "dumpstate_wakelock";
247*38e8c45fSAndroid Build Coastguard Worker
248*38e8c45fSAndroid Build Coastguard Worker // Names of parallel tasks, they are used for the DumpPool to identify the dump
249*38e8c45fSAndroid Build Coastguard Worker // task and the log title of the duration report.
250*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_TRACES_TASK = "DUMP TRACES";
251*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_INCIDENT_REPORT_TASK = "INCIDENT REPORT";
252*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_NETSTATS_PROTO_TASK = "DUMP NETSTATS PROTO";
253*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_HALS_TASK = "DUMP HALS";
254*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_BOARD_TASK = "dumpstate_board()";
255*38e8c45fSAndroid Build Coastguard Worker static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS";
256*38e8c45fSAndroid Build Coastguard Worker static const std::string SERIALIZE_PERFETTO_TRACE_TASK = "SERIALIZE PERFETTO TRACE";
257*38e8c45fSAndroid Build Coastguard Worker
258*38e8c45fSAndroid Build Coastguard Worker namespace android {
259*38e8c45fSAndroid Build Coastguard Worker namespace os {
260*38e8c45fSAndroid Build Coastguard Worker namespace {
261*38e8c45fSAndroid Build Coastguard Worker
Open(std::string path,int flags,mode_t mode=0)262*38e8c45fSAndroid Build Coastguard Worker static int Open(std::string path, int flags, mode_t mode = 0) {
263*38e8c45fSAndroid Build Coastguard Worker int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
264*38e8c45fSAndroid Build Coastguard Worker if (fd == -1) {
265*38e8c45fSAndroid Build Coastguard Worker MYLOGE("open(%s, %s)\n", path.c_str(), strerror(errno));
266*38e8c45fSAndroid Build Coastguard Worker }
267*38e8c45fSAndroid Build Coastguard Worker return fd;
268*38e8c45fSAndroid Build Coastguard Worker }
269*38e8c45fSAndroid Build Coastguard Worker
OpenForWrite(std::string path)270*38e8c45fSAndroid Build Coastguard Worker static int OpenForWrite(std::string path) {
271*38e8c45fSAndroid Build Coastguard Worker return Open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
272*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
273*38e8c45fSAndroid Build Coastguard Worker }
274*38e8c45fSAndroid Build Coastguard Worker
OpenForRead(std::string path)275*38e8c45fSAndroid Build Coastguard Worker static int OpenForRead(std::string path) {
276*38e8c45fSAndroid Build Coastguard Worker return Open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
277*38e8c45fSAndroid Build Coastguard Worker }
278*38e8c45fSAndroid Build Coastguard Worker
CopyFile(int in_fd,int out_fd)279*38e8c45fSAndroid Build Coastguard Worker bool CopyFile(int in_fd, int out_fd) {
280*38e8c45fSAndroid Build Coastguard Worker char buf[4096];
281*38e8c45fSAndroid Build Coastguard Worker ssize_t byte_count;
282*38e8c45fSAndroid Build Coastguard Worker while ((byte_count = TEMP_FAILURE_RETRY(read(in_fd, buf, sizeof(buf)))) > 0) {
283*38e8c45fSAndroid Build Coastguard Worker if (!android::base::WriteFully(out_fd, buf, byte_count)) {
284*38e8c45fSAndroid Build Coastguard Worker return false;
285*38e8c45fSAndroid Build Coastguard Worker }
286*38e8c45fSAndroid Build Coastguard Worker }
287*38e8c45fSAndroid Build Coastguard Worker return (byte_count != -1);
288*38e8c45fSAndroid Build Coastguard Worker }
289*38e8c45fSAndroid Build Coastguard Worker
CopyFileToFd(const std::string & input_file,int out_fd)290*38e8c45fSAndroid Build Coastguard Worker static bool CopyFileToFd(const std::string& input_file, int out_fd) {
291*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Going to copy file (%s) to %d\n", input_file.c_str(), out_fd);
292*38e8c45fSAndroid Build Coastguard Worker
293*38e8c45fSAndroid Build Coastguard Worker // Obtain a handle to the source file.
294*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd in_fd(OpenForRead(input_file));
295*38e8c45fSAndroid Build Coastguard Worker if (out_fd != -1 && in_fd.get() != -1) {
296*38e8c45fSAndroid Build Coastguard Worker if (CopyFile(in_fd.get(), out_fd)) {
297*38e8c45fSAndroid Build Coastguard Worker return true;
298*38e8c45fSAndroid Build Coastguard Worker }
299*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to copy file: %s\n", strerror(errno));
300*38e8c45fSAndroid Build Coastguard Worker }
301*38e8c45fSAndroid Build Coastguard Worker return false;
302*38e8c45fSAndroid Build Coastguard Worker }
303*38e8c45fSAndroid Build Coastguard Worker
UnlinkAndLogOnError(const std::string & file)304*38e8c45fSAndroid Build Coastguard Worker static bool UnlinkAndLogOnError(const std::string& file) {
305*38e8c45fSAndroid Build Coastguard Worker if (file.empty()) {
306*38e8c45fSAndroid Build Coastguard Worker return false;
307*38e8c45fSAndroid Build Coastguard Worker }
308*38e8c45fSAndroid Build Coastguard Worker if (unlink(file.c_str())) {
309*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to unlink file (%s): %s\n", file.c_str(), strerror(errno));
310*38e8c45fSAndroid Build Coastguard Worker return false;
311*38e8c45fSAndroid Build Coastguard Worker }
312*38e8c45fSAndroid Build Coastguard Worker return true;
313*38e8c45fSAndroid Build Coastguard Worker }
314*38e8c45fSAndroid Build Coastguard Worker
GetModuleMetadataVersion()315*38e8c45fSAndroid Build Coastguard Worker int64_t GetModuleMetadataVersion() {
316*38e8c45fSAndroid Build Coastguard Worker auto binder = defaultServiceManager()->getService(android::String16("package_native"));
317*38e8c45fSAndroid Build Coastguard Worker if (binder == nullptr) {
318*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to retrieve package_native service");
319*38e8c45fSAndroid Build Coastguard Worker return 0L;
320*38e8c45fSAndroid Build Coastguard Worker }
321*38e8c45fSAndroid Build Coastguard Worker auto package_service = android::interface_cast<content::pm::IPackageManagerNative>(binder);
322*38e8c45fSAndroid Build Coastguard Worker std::string package_name;
323*38e8c45fSAndroid Build Coastguard Worker auto status = package_service->getModuleMetadataPackageName(&package_name);
324*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
325*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to retrieve module metadata package name: %s", status.toString8().c_str());
326*38e8c45fSAndroid Build Coastguard Worker return 0L;
327*38e8c45fSAndroid Build Coastguard Worker }
328*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Module metadata package name: %s\n", package_name.c_str());
329*38e8c45fSAndroid Build Coastguard Worker int64_t version_code;
330*38e8c45fSAndroid Build Coastguard Worker status = package_service->getVersionCodeForPackage(android::String16(package_name.c_str()),
331*38e8c45fSAndroid Build Coastguard Worker &version_code);
332*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
333*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to retrieve module metadata version: %s", status.toString8().c_str());
334*38e8c45fSAndroid Build Coastguard Worker return 0L;
335*38e8c45fSAndroid Build Coastguard Worker }
336*38e8c45fSAndroid Build Coastguard Worker return version_code;
337*38e8c45fSAndroid Build Coastguard Worker }
338*38e8c45fSAndroid Build Coastguard Worker
PathExists(const std::string & path)339*38e8c45fSAndroid Build Coastguard Worker static bool PathExists(const std::string& path) {
340*38e8c45fSAndroid Build Coastguard Worker struct stat sb;
341*38e8c45fSAndroid Build Coastguard Worker return stat(path.c_str(), &sb) == 0;
342*38e8c45fSAndroid Build Coastguard Worker }
343*38e8c45fSAndroid Build Coastguard Worker
CopyFileToFile(const std::string & input_file,const std::string & output_file)344*38e8c45fSAndroid Build Coastguard Worker static bool CopyFileToFile(const std::string& input_file, const std::string& output_file) {
345*38e8c45fSAndroid Build Coastguard Worker if (input_file == output_file) {
346*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Skipping copying bugreport file since the destination is the same (%s)\n",
347*38e8c45fSAndroid Build Coastguard Worker output_file.c_str());
348*38e8c45fSAndroid Build Coastguard Worker return false;
349*38e8c45fSAndroid Build Coastguard Worker }
350*38e8c45fSAndroid Build Coastguard Worker else if (PathExists(output_file)) {
351*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Cannot overwrite an existing file (%s)\n", output_file.c_str());
352*38e8c45fSAndroid Build Coastguard Worker return false;
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker
355*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Going to copy bugreport file (%s) to %s\n", input_file.c_str(), output_file.c_str());
356*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd out_fd(OpenForWrite(output_file));
357*38e8c45fSAndroid Build Coastguard Worker return CopyFileToFd(input_file, out_fd.get());
358*38e8c45fSAndroid Build Coastguard Worker }
359*38e8c45fSAndroid Build Coastguard Worker
360*38e8c45fSAndroid Build Coastguard Worker } // namespace
361*38e8c45fSAndroid Build Coastguard Worker } // namespace os
362*38e8c45fSAndroid Build Coastguard Worker } // namespace android
363*38e8c45fSAndroid Build Coastguard Worker
RunDumpsys(const std::string & title,const std::vector<std::string> & dumpsysArgs,const CommandOptions & options=Dumpstate::DEFAULT_DUMPSYS,long dumpsysTimeoutMs=0,int out_fd=STDOUT_FILENO)364*38e8c45fSAndroid Build Coastguard Worker static void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs,
365*38e8c45fSAndroid Build Coastguard Worker const CommandOptions& options = Dumpstate::DEFAULT_DUMPSYS,
366*38e8c45fSAndroid Build Coastguard Worker long dumpsysTimeoutMs = 0, int out_fd = STDOUT_FILENO) {
367*38e8c45fSAndroid Build Coastguard Worker return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeoutMs, out_fd);
368*38e8c45fSAndroid Build Coastguard Worker }
RunDumpsys(const std::string & title,const std::vector<std::string> & dumpsysArgs,int out_fd)369*38e8c45fSAndroid Build Coastguard Worker static void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs,
370*38e8c45fSAndroid Build Coastguard Worker int out_fd) {
371*38e8c45fSAndroid Build Coastguard Worker return ds.RunDumpsys(title, dumpsysArgs, Dumpstate::DEFAULT_DUMPSYS, 0, out_fd);
372*38e8c45fSAndroid Build Coastguard Worker }
DumpFile(const std::string & title,const std::string & path)373*38e8c45fSAndroid Build Coastguard Worker static int DumpFile(const std::string& title, const std::string& path) {
374*38e8c45fSAndroid Build Coastguard Worker return ds.DumpFile(title, path);
375*38e8c45fSAndroid Build Coastguard Worker }
376*38e8c45fSAndroid Build Coastguard Worker
377*38e8c45fSAndroid Build Coastguard Worker // Relative directory (inside the zip) for all files copied as-is into the bugreport.
378*38e8c45fSAndroid Build Coastguard Worker static const std::string ZIP_ROOT_DIR = "FS";
379*38e8c45fSAndroid Build Coastguard Worker
380*38e8c45fSAndroid Build Coastguard Worker static const std::string kProtoPath = "proto/";
381*38e8c45fSAndroid Build Coastguard Worker static const std::string kProtoExt = ".proto";
382*38e8c45fSAndroid Build Coastguard Worker static const std::string kDumpstateBoardFiles[] = {
383*38e8c45fSAndroid Build Coastguard Worker "dumpstate_board.txt",
384*38e8c45fSAndroid Build Coastguard Worker "dumpstate_board.bin"
385*38e8c45fSAndroid Build Coastguard Worker };
386*38e8c45fSAndroid Build Coastguard Worker static const int NUM_OF_DUMPS = arraysize(kDumpstateBoardFiles);
387*38e8c45fSAndroid Build Coastguard Worker
388*38e8c45fSAndroid Build Coastguard Worker static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
389*38e8c45fSAndroid Build Coastguard Worker static constexpr char PROPERTY_VERSION[] = "dumpstate.version";
390*38e8c45fSAndroid Build Coastguard Worker
391*38e8c45fSAndroid Build Coastguard Worker static const CommandOptions AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot().Build();
392*38e8c45fSAndroid Build Coastguard Worker
393*38e8c45fSAndroid Build Coastguard Worker /*
394*38e8c45fSAndroid Build Coastguard Worker * Returns a vector of dump fds under |dir_path| with a given |file_prefix|.
395*38e8c45fSAndroid Build Coastguard Worker * The returned vector is sorted by the mtimes of the dumps with descending
396*38e8c45fSAndroid Build Coastguard Worker * order.
397*38e8c45fSAndroid Build Coastguard Worker */
GetDumpFds(const std::string & dir_path,const std::string & file_prefix)398*38e8c45fSAndroid Build Coastguard Worker static std::vector<DumpData> GetDumpFds(const std::string& dir_path,
399*38e8c45fSAndroid Build Coastguard Worker const std::string& file_prefix) {
400*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir);
401*38e8c45fSAndroid Build Coastguard Worker
402*38e8c45fSAndroid Build Coastguard Worker if (dump_dir == nullptr) {
403*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Unable to open directory %s: %s\n", dir_path.c_str(), strerror(errno));
404*38e8c45fSAndroid Build Coastguard Worker return std::vector<DumpData>();
405*38e8c45fSAndroid Build Coastguard Worker }
406*38e8c45fSAndroid Build Coastguard Worker
407*38e8c45fSAndroid Build Coastguard Worker std::vector<DumpData> dump_data;
408*38e8c45fSAndroid Build Coastguard Worker struct dirent* entry = nullptr;
409*38e8c45fSAndroid Build Coastguard Worker while ((entry = readdir(dump_dir.get()))) {
410*38e8c45fSAndroid Build Coastguard Worker if (entry->d_type != DT_REG) {
411*38e8c45fSAndroid Build Coastguard Worker continue;
412*38e8c45fSAndroid Build Coastguard Worker }
413*38e8c45fSAndroid Build Coastguard Worker
414*38e8c45fSAndroid Build Coastguard Worker const std::string base_name(entry->d_name);
415*38e8c45fSAndroid Build Coastguard Worker if (base_name.find(file_prefix) != 0) {
416*38e8c45fSAndroid Build Coastguard Worker continue;
417*38e8c45fSAndroid Build Coastguard Worker }
418*38e8c45fSAndroid Build Coastguard Worker
419*38e8c45fSAndroid Build Coastguard Worker const std::string abs_path = dir_path + base_name;
420*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(
421*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(open(abs_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
422*38e8c45fSAndroid Build Coastguard Worker if (fd == -1) {
423*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Unable to open dump file %s: %s\n", abs_path.c_str(), strerror(errno));
424*38e8c45fSAndroid Build Coastguard Worker break;
425*38e8c45fSAndroid Build Coastguard Worker }
426*38e8c45fSAndroid Build Coastguard Worker
427*38e8c45fSAndroid Build Coastguard Worker struct stat st = {};
428*38e8c45fSAndroid Build Coastguard Worker if (fstat(fd, &st) == -1) {
429*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Unable to stat dump file %s: %s\n", abs_path.c_str(), strerror(errno));
430*38e8c45fSAndroid Build Coastguard Worker continue;
431*38e8c45fSAndroid Build Coastguard Worker }
432*38e8c45fSAndroid Build Coastguard Worker
433*38e8c45fSAndroid Build Coastguard Worker dump_data.emplace_back(DumpData{abs_path, std::move(fd), st.st_mtime});
434*38e8c45fSAndroid Build Coastguard Worker }
435*38e8c45fSAndroid Build Coastguard Worker if (!dump_data.empty()) {
436*38e8c45fSAndroid Build Coastguard Worker std::sort(dump_data.begin(), dump_data.end(),
437*38e8c45fSAndroid Build Coastguard Worker [](const auto& a, const auto& b) { return a.mtime > b.mtime; });
438*38e8c45fSAndroid Build Coastguard Worker }
439*38e8c45fSAndroid Build Coastguard Worker
440*38e8c45fSAndroid Build Coastguard Worker return dump_data;
441*38e8c45fSAndroid Build Coastguard Worker }
442*38e8c45fSAndroid Build Coastguard Worker
AddDumps(const std::vector<DumpData>::const_iterator start,const std::vector<DumpData>::const_iterator end,const char * type_name,const bool add_to_zip)443*38e8c45fSAndroid Build Coastguard Worker static bool AddDumps(const std::vector<DumpData>::const_iterator start,
444*38e8c45fSAndroid Build Coastguard Worker const std::vector<DumpData>::const_iterator end,
445*38e8c45fSAndroid Build Coastguard Worker const char* type_name, const bool add_to_zip) {
446*38e8c45fSAndroid Build Coastguard Worker bool dumped = false;
447*38e8c45fSAndroid Build Coastguard Worker for (auto it = start; it != end; ++it) {
448*38e8c45fSAndroid Build Coastguard Worker const std::string& name = it->name;
449*38e8c45fSAndroid Build Coastguard Worker const int fd = it->fd;
450*38e8c45fSAndroid Build Coastguard Worker dumped = true;
451*38e8c45fSAndroid Build Coastguard Worker
452*38e8c45fSAndroid Build Coastguard Worker // Seek to the beginning of the file before dumping any data. A given
453*38e8c45fSAndroid Build Coastguard Worker // DumpData entry might be dumped multiple times in the report.
454*38e8c45fSAndroid Build Coastguard Worker //
455*38e8c45fSAndroid Build Coastguard Worker // For example, the most recent ANR entry is dumped to the body of the
456*38e8c45fSAndroid Build Coastguard Worker // main entry and it also shows up as a separate entry in the bugreport
457*38e8c45fSAndroid Build Coastguard Worker // ZIP file.
458*38e8c45fSAndroid Build Coastguard Worker if (lseek(fd, 0, SEEK_SET) != static_cast<off_t>(0)) {
459*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to add %s to zip file, lseek failed: %s\n", name.c_str(),
460*38e8c45fSAndroid Build Coastguard Worker strerror(errno));
461*38e8c45fSAndroid Build Coastguard Worker }
462*38e8c45fSAndroid Build Coastguard Worker
463*38e8c45fSAndroid Build Coastguard Worker if (add_to_zip) {
464*38e8c45fSAndroid Build Coastguard Worker if (ds.AddZipEntryFromFd(ZIP_ROOT_DIR + name, fd, /* timeout = */ 0ms) != OK) {
465*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to add %s to zip file, addZipEntryFromFd failed\n", name.c_str());
466*38e8c45fSAndroid Build Coastguard Worker }
467*38e8c45fSAndroid Build Coastguard Worker } else {
468*38e8c45fSAndroid Build Coastguard Worker dump_file_from_fd(type_name, name.c_str(), fd);
469*38e8c45fSAndroid Build Coastguard Worker }
470*38e8c45fSAndroid Build Coastguard Worker }
471*38e8c45fSAndroid Build Coastguard Worker
472*38e8c45fSAndroid Build Coastguard Worker return dumped;
473*38e8c45fSAndroid Build Coastguard Worker }
474*38e8c45fSAndroid Build Coastguard Worker
475*38e8c45fSAndroid Build Coastguard Worker // for_each_pid() callback to get mount info about a process.
do_mountinfo(int pid,const char * name)476*38e8c45fSAndroid Build Coastguard Worker void do_mountinfo(int pid, const char* name __attribute__((unused))) {
477*38e8c45fSAndroid Build Coastguard Worker char path[PATH_MAX];
478*38e8c45fSAndroid Build Coastguard Worker
479*38e8c45fSAndroid Build Coastguard Worker // Gets the the content of the /proc/PID/ns/mnt link, so only unique mount points
480*38e8c45fSAndroid Build Coastguard Worker // are added.
481*38e8c45fSAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
482*38e8c45fSAndroid Build Coastguard Worker char linkname[PATH_MAX];
483*38e8c45fSAndroid Build Coastguard Worker ssize_t r = readlink(path, linkname, PATH_MAX);
484*38e8c45fSAndroid Build Coastguard Worker if (r == -1) {
485*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to read link for %s: %s\n", path, strerror(errno));
486*38e8c45fSAndroid Build Coastguard Worker return;
487*38e8c45fSAndroid Build Coastguard Worker }
488*38e8c45fSAndroid Build Coastguard Worker linkname[r] = '\0';
489*38e8c45fSAndroid Build Coastguard Worker
490*38e8c45fSAndroid Build Coastguard Worker if (mount_points.find(linkname) == mount_points.end()) {
491*38e8c45fSAndroid Build Coastguard Worker // First time this mount point was found: add it
492*38e8c45fSAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/proc/%d/mountinfo", pid);
493*38e8c45fSAndroid Build Coastguard Worker if (ds.AddZipEntry(ZIP_ROOT_DIR + path, path)) {
494*38e8c45fSAndroid Build Coastguard Worker mount_points.insert(linkname);
495*38e8c45fSAndroid Build Coastguard Worker } else {
496*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to add mountinfo %s to zip file\n", path);
497*38e8c45fSAndroid Build Coastguard Worker }
498*38e8c45fSAndroid Build Coastguard Worker }
499*38e8c45fSAndroid Build Coastguard Worker }
500*38e8c45fSAndroid Build Coastguard Worker
add_mountinfo()501*38e8c45fSAndroid Build Coastguard Worker void add_mountinfo() {
502*38e8c45fSAndroid Build Coastguard Worker std::string title = "MOUNT INFO";
503*38e8c45fSAndroid Build Coastguard Worker mount_points.clear();
504*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title, true);
505*38e8c45fSAndroid Build Coastguard Worker for_each_pid(do_mountinfo, nullptr);
506*38e8c45fSAndroid Build Coastguard Worker MYLOGD("%s: %d entries added to zip file\n", title.c_str(), (int)mount_points.size());
507*38e8c45fSAndroid Build Coastguard Worker }
508*38e8c45fSAndroid Build Coastguard Worker
dump_dev_files(const char * title,const char * driverpath,const char * filename)509*38e8c45fSAndroid Build Coastguard Worker static void dump_dev_files(const char *title, const char *driverpath, const char *filename)
510*38e8c45fSAndroid Build Coastguard Worker {
511*38e8c45fSAndroid Build Coastguard Worker DIR *d;
512*38e8c45fSAndroid Build Coastguard Worker struct dirent *de;
513*38e8c45fSAndroid Build Coastguard Worker char path[PATH_MAX];
514*38e8c45fSAndroid Build Coastguard Worker
515*38e8c45fSAndroid Build Coastguard Worker d = opendir(driverpath);
516*38e8c45fSAndroid Build Coastguard Worker if (d == nullptr) {
517*38e8c45fSAndroid Build Coastguard Worker return;
518*38e8c45fSAndroid Build Coastguard Worker }
519*38e8c45fSAndroid Build Coastguard Worker
520*38e8c45fSAndroid Build Coastguard Worker while ((de = readdir(d))) {
521*38e8c45fSAndroid Build Coastguard Worker if (de->d_type != DT_LNK) {
522*38e8c45fSAndroid Build Coastguard Worker continue;
523*38e8c45fSAndroid Build Coastguard Worker }
524*38e8c45fSAndroid Build Coastguard Worker snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
525*38e8c45fSAndroid Build Coastguard Worker DumpFile(title, path);
526*38e8c45fSAndroid Build Coastguard Worker }
527*38e8c45fSAndroid Build Coastguard Worker
528*38e8c45fSAndroid Build Coastguard Worker closedir(d);
529*38e8c45fSAndroid Build Coastguard Worker }
530*38e8c45fSAndroid Build Coastguard Worker
skip_not_stat(const char * path)531*38e8c45fSAndroid Build Coastguard Worker static bool skip_not_stat(const char *path) {
532*38e8c45fSAndroid Build Coastguard Worker static const char stat[] = "/stat";
533*38e8c45fSAndroid Build Coastguard Worker size_t len = strlen(path);
534*38e8c45fSAndroid Build Coastguard Worker if (path[len - 1] == '/') { /* Directory? */
535*38e8c45fSAndroid Build Coastguard Worker return false;
536*38e8c45fSAndroid Build Coastguard Worker }
537*38e8c45fSAndroid Build Coastguard Worker return strcmp(path + len - sizeof(stat) + 1, stat); /* .../stat? */
538*38e8c45fSAndroid Build Coastguard Worker }
539*38e8c45fSAndroid Build Coastguard Worker
skip_wtf_strictmode(const char * path)540*38e8c45fSAndroid Build Coastguard Worker static bool skip_wtf_strictmode(const char *path) {
541*38e8c45fSAndroid Build Coastguard Worker if (strstr(path, "_wtf")) {
542*38e8c45fSAndroid Build Coastguard Worker return true;
543*38e8c45fSAndroid Build Coastguard Worker } else if (strstr(path, "_strictmode")) {
544*38e8c45fSAndroid Build Coastguard Worker return true;
545*38e8c45fSAndroid Build Coastguard Worker }
546*38e8c45fSAndroid Build Coastguard Worker return false;
547*38e8c45fSAndroid Build Coastguard Worker }
548*38e8c45fSAndroid Build Coastguard Worker
skip_none(const char * path)549*38e8c45fSAndroid Build Coastguard Worker static bool skip_none(const char* path __attribute__((unused))) {
550*38e8c45fSAndroid Build Coastguard Worker return false;
551*38e8c45fSAndroid Build Coastguard Worker }
552*38e8c45fSAndroid Build Coastguard Worker
553*38e8c45fSAndroid Build Coastguard Worker unsigned long worst_write_perf = 20000; /* in KB/s */
554*38e8c45fSAndroid Build Coastguard Worker
555*38e8c45fSAndroid Build Coastguard Worker //
556*38e8c45fSAndroid Build Coastguard Worker // stat offsets
557*38e8c45fSAndroid Build Coastguard Worker // Name units description
558*38e8c45fSAndroid Build Coastguard Worker // ---- ----- -----------
559*38e8c45fSAndroid Build Coastguard Worker // read I/Os requests number of read I/Os processed
560*38e8c45fSAndroid Build Coastguard Worker #define __STAT_READ_IOS 0
561*38e8c45fSAndroid Build Coastguard Worker // read merges requests number of read I/Os merged with in-queue I/O
562*38e8c45fSAndroid Build Coastguard Worker #define __STAT_READ_MERGES 1
563*38e8c45fSAndroid Build Coastguard Worker // read sectors sectors number of sectors read
564*38e8c45fSAndroid Build Coastguard Worker #define __STAT_READ_SECTORS 2
565*38e8c45fSAndroid Build Coastguard Worker // read ticks milliseconds total wait time for read requests
566*38e8c45fSAndroid Build Coastguard Worker #define __STAT_READ_TICKS 3
567*38e8c45fSAndroid Build Coastguard Worker // write I/Os requests number of write I/Os processed
568*38e8c45fSAndroid Build Coastguard Worker #define __STAT_WRITE_IOS 4
569*38e8c45fSAndroid Build Coastguard Worker // write merges requests number of write I/Os merged with in-queue I/O
570*38e8c45fSAndroid Build Coastguard Worker #define __STAT_WRITE_MERGES 5
571*38e8c45fSAndroid Build Coastguard Worker // write sectors sectors number of sectors written
572*38e8c45fSAndroid Build Coastguard Worker #define __STAT_WRITE_SECTORS 6
573*38e8c45fSAndroid Build Coastguard Worker // write ticks milliseconds total wait time for write requests
574*38e8c45fSAndroid Build Coastguard Worker #define __STAT_WRITE_TICKS 7
575*38e8c45fSAndroid Build Coastguard Worker // in_flight requests number of I/Os currently in flight
576*38e8c45fSAndroid Build Coastguard Worker #define __STAT_IN_FLIGHT 8
577*38e8c45fSAndroid Build Coastguard Worker // io_ticks milliseconds total time this block device has been active
578*38e8c45fSAndroid Build Coastguard Worker #define __STAT_IO_TICKS 9
579*38e8c45fSAndroid Build Coastguard Worker // time_in_queue milliseconds total wait time for all requests
580*38e8c45fSAndroid Build Coastguard Worker #define __STAT_IN_QUEUE 10
581*38e8c45fSAndroid Build Coastguard Worker #define __STAT_NUMBER_FIELD 11
582*38e8c45fSAndroid Build Coastguard Worker //
583*38e8c45fSAndroid Build Coastguard Worker // read I/Os, write I/Os
584*38e8c45fSAndroid Build Coastguard Worker // =====================
585*38e8c45fSAndroid Build Coastguard Worker //
586*38e8c45fSAndroid Build Coastguard Worker // These values increment when an I/O request completes.
587*38e8c45fSAndroid Build Coastguard Worker //
588*38e8c45fSAndroid Build Coastguard Worker // read merges, write merges
589*38e8c45fSAndroid Build Coastguard Worker // =========================
590*38e8c45fSAndroid Build Coastguard Worker //
591*38e8c45fSAndroid Build Coastguard Worker // These values increment when an I/O request is merged with an
592*38e8c45fSAndroid Build Coastguard Worker // already-queued I/O request.
593*38e8c45fSAndroid Build Coastguard Worker //
594*38e8c45fSAndroid Build Coastguard Worker // read sectors, write sectors
595*38e8c45fSAndroid Build Coastguard Worker // ===========================
596*38e8c45fSAndroid Build Coastguard Worker //
597*38e8c45fSAndroid Build Coastguard Worker // These values count the number of sectors read from or written to this
598*38e8c45fSAndroid Build Coastguard Worker // block device. The "sectors" in question are the standard UNIX 512-byte
599*38e8c45fSAndroid Build Coastguard Worker // sectors, not any device- or filesystem-specific block size. The
600*38e8c45fSAndroid Build Coastguard Worker // counters are incremented when the I/O completes.
601*38e8c45fSAndroid Build Coastguard Worker #define SECTOR_SIZE 512
602*38e8c45fSAndroid Build Coastguard Worker //
603*38e8c45fSAndroid Build Coastguard Worker // read ticks, write ticks
604*38e8c45fSAndroid Build Coastguard Worker // =======================
605*38e8c45fSAndroid Build Coastguard Worker //
606*38e8c45fSAndroid Build Coastguard Worker // These values count the number of milliseconds that I/O requests have
607*38e8c45fSAndroid Build Coastguard Worker // waited on this block device. If there are multiple I/O requests waiting,
608*38e8c45fSAndroid Build Coastguard Worker // these values will increase at a rate greater than 1000/second; for
609*38e8c45fSAndroid Build Coastguard Worker // example, if 60 read requests wait for an average of 30 ms, the read_ticks
610*38e8c45fSAndroid Build Coastguard Worker // field will increase by 60*30 = 1800.
611*38e8c45fSAndroid Build Coastguard Worker //
612*38e8c45fSAndroid Build Coastguard Worker // in_flight
613*38e8c45fSAndroid Build Coastguard Worker // =========
614*38e8c45fSAndroid Build Coastguard Worker //
615*38e8c45fSAndroid Build Coastguard Worker // This value counts the number of I/O requests that have been issued to
616*38e8c45fSAndroid Build Coastguard Worker // the device driver but have not yet completed. It does not include I/O
617*38e8c45fSAndroid Build Coastguard Worker // requests that are in the queue but not yet issued to the device driver.
618*38e8c45fSAndroid Build Coastguard Worker //
619*38e8c45fSAndroid Build Coastguard Worker // io_ticks
620*38e8c45fSAndroid Build Coastguard Worker // ========
621*38e8c45fSAndroid Build Coastguard Worker //
622*38e8c45fSAndroid Build Coastguard Worker // This value counts the number of milliseconds during which the device has
623*38e8c45fSAndroid Build Coastguard Worker // had I/O requests queued.
624*38e8c45fSAndroid Build Coastguard Worker //
625*38e8c45fSAndroid Build Coastguard Worker // time_in_queue
626*38e8c45fSAndroid Build Coastguard Worker // =============
627*38e8c45fSAndroid Build Coastguard Worker //
628*38e8c45fSAndroid Build Coastguard Worker // This value counts the number of milliseconds that I/O requests have waited
629*38e8c45fSAndroid Build Coastguard Worker // on this block device. If there are multiple I/O requests waiting, this
630*38e8c45fSAndroid Build Coastguard Worker // value will increase as the product of the number of milliseconds times the
631*38e8c45fSAndroid Build Coastguard Worker // number of requests waiting (see "read ticks" above for an example).
632*38e8c45fSAndroid Build Coastguard Worker #define S_TO_MS 1000
633*38e8c45fSAndroid Build Coastguard Worker //
634*38e8c45fSAndroid Build Coastguard Worker
dump_stat_from_fd(const char * title __unused,const char * path,int fd)635*38e8c45fSAndroid Build Coastguard Worker static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
636*38e8c45fSAndroid Build Coastguard Worker unsigned long long fields[__STAT_NUMBER_FIELD];
637*38e8c45fSAndroid Build Coastguard Worker bool z;
638*38e8c45fSAndroid Build Coastguard Worker char *cp, *buffer = nullptr;
639*38e8c45fSAndroid Build Coastguard Worker size_t i = 0;
640*38e8c45fSAndroid Build Coastguard Worker FILE *fp = fdopen(dup(fd), "rb");
641*38e8c45fSAndroid Build Coastguard Worker getline(&buffer, &i, fp);
642*38e8c45fSAndroid Build Coastguard Worker fclose(fp);
643*38e8c45fSAndroid Build Coastguard Worker if (!buffer) {
644*38e8c45fSAndroid Build Coastguard Worker return -errno;
645*38e8c45fSAndroid Build Coastguard Worker }
646*38e8c45fSAndroid Build Coastguard Worker i = strlen(buffer);
647*38e8c45fSAndroid Build Coastguard Worker while ((i > 0) && (buffer[i - 1] == '\n')) {
648*38e8c45fSAndroid Build Coastguard Worker buffer[--i] = '\0';
649*38e8c45fSAndroid Build Coastguard Worker }
650*38e8c45fSAndroid Build Coastguard Worker if (!*buffer) {
651*38e8c45fSAndroid Build Coastguard Worker free(buffer);
652*38e8c45fSAndroid Build Coastguard Worker return 0;
653*38e8c45fSAndroid Build Coastguard Worker }
654*38e8c45fSAndroid Build Coastguard Worker z = true;
655*38e8c45fSAndroid Build Coastguard Worker for (cp = buffer, i = 0; i < (sizeof(fields) / sizeof(fields[0])); ++i) {
656*38e8c45fSAndroid Build Coastguard Worker fields[i] = strtoull(cp, &cp, 10);
657*38e8c45fSAndroid Build Coastguard Worker if (fields[i] != 0) {
658*38e8c45fSAndroid Build Coastguard Worker z = false;
659*38e8c45fSAndroid Build Coastguard Worker }
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker if (z) { /* never accessed */
662*38e8c45fSAndroid Build Coastguard Worker free(buffer);
663*38e8c45fSAndroid Build Coastguard Worker return 0;
664*38e8c45fSAndroid Build Coastguard Worker }
665*38e8c45fSAndroid Build Coastguard Worker
666*38e8c45fSAndroid Build Coastguard Worker if (!strncmp(path, BLK_DEV_SYS_DIR, sizeof(BLK_DEV_SYS_DIR) - 1)) {
667*38e8c45fSAndroid Build Coastguard Worker path += sizeof(BLK_DEV_SYS_DIR) - 1;
668*38e8c45fSAndroid Build Coastguard Worker }
669*38e8c45fSAndroid Build Coastguard Worker
670*38e8c45fSAndroid Build Coastguard Worker printf("%-30s:%9s%9s%9s%9s%9s%9s%9s%9s%9s%9s%9s\n%-30s:\t%s\n", "Block-Dev",
671*38e8c45fSAndroid Build Coastguard Worker "R-IOs", "R-merg", "R-sect", "R-wait", "W-IOs", "W-merg", "W-sect",
672*38e8c45fSAndroid Build Coastguard Worker "W-wait", "in-fli", "activ", "T-wait", path, buffer);
673*38e8c45fSAndroid Build Coastguard Worker free(buffer);
674*38e8c45fSAndroid Build Coastguard Worker
675*38e8c45fSAndroid Build Coastguard Worker if (fields[__STAT_IO_TICKS]) {
676*38e8c45fSAndroid Build Coastguard Worker unsigned long read_perf = 0;
677*38e8c45fSAndroid Build Coastguard Worker unsigned long read_ios = 0;
678*38e8c45fSAndroid Build Coastguard Worker if (fields[__STAT_READ_TICKS]) {
679*38e8c45fSAndroid Build Coastguard Worker unsigned long long divisor = fields[__STAT_READ_TICKS]
680*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IO_TICKS];
681*38e8c45fSAndroid Build Coastguard Worker read_perf = ((unsigned long long)SECTOR_SIZE
682*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_READ_SECTORS]
683*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IN_QUEUE] + (divisor >> 1))
684*38e8c45fSAndroid Build Coastguard Worker / divisor;
685*38e8c45fSAndroid Build Coastguard Worker read_ios = ((unsigned long long)S_TO_MS * fields[__STAT_READ_IOS]
686*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IN_QUEUE] + (divisor >> 1))
687*38e8c45fSAndroid Build Coastguard Worker / divisor;
688*38e8c45fSAndroid Build Coastguard Worker }
689*38e8c45fSAndroid Build Coastguard Worker
690*38e8c45fSAndroid Build Coastguard Worker unsigned long write_perf = 0;
691*38e8c45fSAndroid Build Coastguard Worker unsigned long write_ios = 0;
692*38e8c45fSAndroid Build Coastguard Worker if (fields[__STAT_WRITE_TICKS]) {
693*38e8c45fSAndroid Build Coastguard Worker unsigned long long divisor = fields[__STAT_WRITE_TICKS]
694*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IO_TICKS];
695*38e8c45fSAndroid Build Coastguard Worker write_perf = ((unsigned long long)SECTOR_SIZE
696*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_WRITE_SECTORS]
697*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IN_QUEUE] + (divisor >> 1))
698*38e8c45fSAndroid Build Coastguard Worker / divisor;
699*38e8c45fSAndroid Build Coastguard Worker write_ios = ((unsigned long long)S_TO_MS * fields[__STAT_WRITE_IOS]
700*38e8c45fSAndroid Build Coastguard Worker * fields[__STAT_IN_QUEUE] + (divisor >> 1))
701*38e8c45fSAndroid Build Coastguard Worker / divisor;
702*38e8c45fSAndroid Build Coastguard Worker }
703*38e8c45fSAndroid Build Coastguard Worker
704*38e8c45fSAndroid Build Coastguard Worker unsigned queue = (fields[__STAT_IN_QUEUE]
705*38e8c45fSAndroid Build Coastguard Worker + (fields[__STAT_IO_TICKS] >> 1))
706*38e8c45fSAndroid Build Coastguard Worker / fields[__STAT_IO_TICKS];
707*38e8c45fSAndroid Build Coastguard Worker
708*38e8c45fSAndroid Build Coastguard Worker if (!write_perf && !write_ios) {
709*38e8c45fSAndroid Build Coastguard Worker printf("%-30s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", path, read_perf, read_ios, queue);
710*38e8c45fSAndroid Build Coastguard Worker } else {
711*38e8c45fSAndroid Build Coastguard Worker printf("%-30s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n", path, read_perf,
712*38e8c45fSAndroid Build Coastguard Worker read_ios, write_perf, write_ios, queue);
713*38e8c45fSAndroid Build Coastguard Worker }
714*38e8c45fSAndroid Build Coastguard Worker
715*38e8c45fSAndroid Build Coastguard Worker /* bugreport timeout factor adjustment */
716*38e8c45fSAndroid Build Coastguard Worker if ((write_perf > 1) && (write_perf < worst_write_perf)) {
717*38e8c45fSAndroid Build Coastguard Worker worst_write_perf = write_perf;
718*38e8c45fSAndroid Build Coastguard Worker }
719*38e8c45fSAndroid Build Coastguard Worker }
720*38e8c45fSAndroid Build Coastguard Worker return 0;
721*38e8c45fSAndroid Build Coastguard Worker }
722*38e8c45fSAndroid Build Coastguard Worker
723*38e8c45fSAndroid Build Coastguard Worker static const long MINIMUM_LOGCAT_TIMEOUT_MS = 50000;
724*38e8c45fSAndroid Build Coastguard Worker
725*38e8c45fSAndroid Build Coastguard Worker // Returns the actual readable size of the given buffer or -1 on error.
logcat_buffer_readable_size(const std::string & buffer)726*38e8c45fSAndroid Build Coastguard Worker static long logcat_buffer_readable_size(const std::string& buffer) {
727*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{
728*38e8c45fSAndroid Build Coastguard Worker android_logger_list_alloc(0, 0, 0), &android_logger_list_free};
729*38e8c45fSAndroid Build Coastguard Worker auto logger = android_logger_open(logger_list.get(), android_name_to_log_id(buffer.c_str()));
730*38e8c45fSAndroid Build Coastguard Worker
731*38e8c45fSAndroid Build Coastguard Worker return android_logger_get_log_readable_size(logger);
732*38e8c45fSAndroid Build Coastguard Worker }
733*38e8c45fSAndroid Build Coastguard Worker
734*38e8c45fSAndroid Build Coastguard Worker // Returns timeout in ms to read a list of buffers.
logcat_timeout(const std::vector<std::string> & buffers)735*38e8c45fSAndroid Build Coastguard Worker static unsigned long logcat_timeout(const std::vector<std::string>& buffers) {
736*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms = 0;
737*38e8c45fSAndroid Build Coastguard Worker for (const auto& buffer : buffers) {
738*38e8c45fSAndroid Build Coastguard Worker long readable_size = logcat_buffer_readable_size(buffer);
739*38e8c45fSAndroid Build Coastguard Worker if (readable_size > 0) {
740*38e8c45fSAndroid Build Coastguard Worker // Engineering margin is ten-fold our guess.
741*38e8c45fSAndroid Build Coastguard Worker timeout_ms += 10 * (readable_size + worst_write_perf) / worst_write_perf;
742*38e8c45fSAndroid Build Coastguard Worker }
743*38e8c45fSAndroid Build Coastguard Worker }
744*38e8c45fSAndroid Build Coastguard Worker return timeout_ms > MINIMUM_LOGCAT_TIMEOUT_MS ? timeout_ms : MINIMUM_LOGCAT_TIMEOUT_MS;
745*38e8c45fSAndroid Build Coastguard Worker }
746*38e8c45fSAndroid Build Coastguard Worker
747*38e8c45fSAndroid Build Coastguard Worker // Opens a socket and returns its file descriptor.
748*38e8c45fSAndroid Build Coastguard Worker static int open_socket(const char* service);
749*38e8c45fSAndroid Build Coastguard Worker
ConsentCallback()750*38e8c45fSAndroid Build Coastguard Worker Dumpstate::ConsentCallback::ConsentCallback() : result_(UNAVAILABLE), start_time_(Nanotime()) {
751*38e8c45fSAndroid Build Coastguard Worker }
752*38e8c45fSAndroid Build Coastguard Worker
onReportApproved()753*38e8c45fSAndroid Build Coastguard Worker android::binder::Status Dumpstate::ConsentCallback::onReportApproved() {
754*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(lock_);
755*38e8c45fSAndroid Build Coastguard Worker result_ = APPROVED;
756*38e8c45fSAndroid Build Coastguard Worker MYLOGD("User approved consent to share bugreport\n");
757*38e8c45fSAndroid Build Coastguard Worker
758*38e8c45fSAndroid Build Coastguard Worker // Maybe copy screenshot so calling app can display the screenshot to the user as soon as
759*38e8c45fSAndroid Build Coastguard Worker // consent is granted.
760*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->is_screenshot_copied) {
761*38e8c45fSAndroid Build Coastguard Worker return android::binder::Status::ok();
762*38e8c45fSAndroid Build Coastguard Worker }
763*38e8c45fSAndroid Build Coastguard Worker
764*38e8c45fSAndroid Build Coastguard Worker if (!ds.options_->do_screenshot || ds.options_->screenshot_fd.get() == -1 ||
765*38e8c45fSAndroid Build Coastguard Worker !ds.do_early_screenshot_) {
766*38e8c45fSAndroid Build Coastguard Worker return android::binder::Status::ok();
767*38e8c45fSAndroid Build Coastguard Worker }
768*38e8c45fSAndroid Build Coastguard Worker
769*38e8c45fSAndroid Build Coastguard Worker bool copy_succeeded = android::os::CopyFileToFd(ds.screenshot_path_,
770*38e8c45fSAndroid Build Coastguard Worker ds.options_->screenshot_fd.get());
771*38e8c45fSAndroid Build Coastguard Worker if (copy_succeeded) {
772*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(ds.screenshot_path_);
773*38e8c45fSAndroid Build Coastguard Worker } else {
774*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to copy screenshot to a permanent file.\n");
775*38e8c45fSAndroid Build Coastguard Worker copy_succeeded = android::os::CopyFileToFd(DEFAULT_SCREENSHOT_PATH,
776*38e8c45fSAndroid Build Coastguard Worker ds.options_->screenshot_fd.get());
777*38e8c45fSAndroid Build Coastguard Worker }
778*38e8c45fSAndroid Build Coastguard Worker ds.options_->is_screenshot_copied = copy_succeeded;
779*38e8c45fSAndroid Build Coastguard Worker return android::binder::Status::ok();
780*38e8c45fSAndroid Build Coastguard Worker }
781*38e8c45fSAndroid Build Coastguard Worker
onReportDenied()782*38e8c45fSAndroid Build Coastguard Worker android::binder::Status Dumpstate::ConsentCallback::onReportDenied() {
783*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(lock_);
784*38e8c45fSAndroid Build Coastguard Worker result_ = DENIED;
785*38e8c45fSAndroid Build Coastguard Worker MYLOGW("User denied consent to share bugreport\n");
786*38e8c45fSAndroid Build Coastguard Worker return android::binder::Status::ok();
787*38e8c45fSAndroid Build Coastguard Worker }
788*38e8c45fSAndroid Build Coastguard Worker
getResult()789*38e8c45fSAndroid Build Coastguard Worker UserConsentResult Dumpstate::ConsentCallback::getResult() {
790*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(lock_);
791*38e8c45fSAndroid Build Coastguard Worker return result_;
792*38e8c45fSAndroid Build Coastguard Worker }
793*38e8c45fSAndroid Build Coastguard Worker
getElapsedTimeMs() const794*38e8c45fSAndroid Build Coastguard Worker uint64_t Dumpstate::ConsentCallback::getElapsedTimeMs() const {
795*38e8c45fSAndroid Build Coastguard Worker return (Nanotime() - start_time_) / NANOS_PER_MILLI;
796*38e8c45fSAndroid Build Coastguard Worker }
797*38e8c45fSAndroid Build Coastguard Worker
PrintHeader() const798*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::PrintHeader() const {
799*38e8c45fSAndroid Build Coastguard Worker std::string build, fingerprint, radio, bootloader, network, sdkversion;
800*38e8c45fSAndroid Build Coastguard Worker char date[80];
801*38e8c45fSAndroid Build Coastguard Worker
802*38e8c45fSAndroid Build Coastguard Worker build = android::base::GetProperty("ro.build.display.id", "(unknown)");
803*38e8c45fSAndroid Build Coastguard Worker fingerprint = android::base::GetProperty("ro.build.fingerprint", "(unknown)");
804*38e8c45fSAndroid Build Coastguard Worker radio = android::base::GetProperty("gsm.version.baseband", "(unknown)");
805*38e8c45fSAndroid Build Coastguard Worker bootloader = android::base::GetProperty("ro.bootloader", "(unknown)");
806*38e8c45fSAndroid Build Coastguard Worker network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
807*38e8c45fSAndroid Build Coastguard Worker sdkversion = android::base::GetProperty("ro.build.version.sdk", "(unknown)");
808*38e8c45fSAndroid Build Coastguard Worker strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now_));
809*38e8c45fSAndroid Build Coastguard Worker
810*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
811*38e8c45fSAndroid Build Coastguard Worker printf("== dumpstate: %s\n", date);
812*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
813*38e8c45fSAndroid Build Coastguard Worker
814*38e8c45fSAndroid Build Coastguard Worker printf("\n");
815*38e8c45fSAndroid Build Coastguard Worker printf("Build: %s\n", build.c_str());
816*38e8c45fSAndroid Build Coastguard Worker // NOTE: fingerprint entry format is important for other tools.
817*38e8c45fSAndroid Build Coastguard Worker printf("Build fingerprint: '%s'\n", fingerprint.c_str());
818*38e8c45fSAndroid Build Coastguard Worker printf("Bootloader: %s\n", bootloader.c_str());
819*38e8c45fSAndroid Build Coastguard Worker printf("Radio: %s\n", radio.c_str());
820*38e8c45fSAndroid Build Coastguard Worker printf("Network: %s\n", network.c_str());
821*38e8c45fSAndroid Build Coastguard Worker int64_t module_metadata_version = android::os::GetModuleMetadataVersion();
822*38e8c45fSAndroid Build Coastguard Worker if (module_metadata_version != 0) {
823*38e8c45fSAndroid Build Coastguard Worker printf("Module Metadata version: %" PRId64 "\n", module_metadata_version);
824*38e8c45fSAndroid Build Coastguard Worker }
825*38e8c45fSAndroid Build Coastguard Worker printf("Android SDK version: %s\n", sdkversion.c_str());
826*38e8c45fSAndroid Build Coastguard Worker printf("SDK extensions: ");
827*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(STDOUT_FILENO, "", {SDK_EXT_INFO, "--header"},
828*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(1).Always().DropRoot().Build());
829*38e8c45fSAndroid Build Coastguard Worker
830*38e8c45fSAndroid Build Coastguard Worker printf("Kernel: ");
831*38e8c45fSAndroid Build Coastguard Worker DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
832*38e8c45fSAndroid Build Coastguard Worker printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
833*38e8c45fSAndroid Build Coastguard Worker printf("Bootconfig: ");
834*38e8c45fSAndroid Build Coastguard Worker DumpFileToFd(STDOUT_FILENO, "", "/proc/bootconfig");
835*38e8c45fSAndroid Build Coastguard Worker printf("Uptime: ");
836*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(STDOUT_FILENO, "", {"uptime", "-p"},
837*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(1).Always().Build());
838*38e8c45fSAndroid Build Coastguard Worker printf("Bugreport format version: %s\n", version_.c_str());
839*38e8c45fSAndroid Build Coastguard Worker printf(
840*38e8c45fSAndroid Build Coastguard Worker "Dumpstate info: id=%d pid=%d dry_run=%d parallel_run=%d strict_run=%d args=%s "
841*38e8c45fSAndroid Build Coastguard Worker "bugreport_mode=%s\n",
842*38e8c45fSAndroid Build Coastguard Worker id_, pid_, PropertiesHelper::IsDryRun(), PropertiesHelper::IsParallelRun(),
843*38e8c45fSAndroid Build Coastguard Worker PropertiesHelper::IsStrictRun(), options_->args.c_str(),
844*38e8c45fSAndroid Build Coastguard Worker options_->bugreport_mode_string.c_str());
845*38e8c45fSAndroid Build Coastguard Worker printf("\n");
846*38e8c45fSAndroid Build Coastguard Worker }
847*38e8c45fSAndroid Build Coastguard Worker
848*38e8c45fSAndroid Build Coastguard Worker // List of file extensions that can cause a zip file attachment to be rejected by some email
849*38e8c45fSAndroid Build Coastguard Worker // service providers.
850*38e8c45fSAndroid Build Coastguard Worker static const std::set<std::string> PROBLEMATIC_FILE_EXTENSIONS = {
851*38e8c45fSAndroid Build Coastguard Worker ".ade", ".adp", ".bat", ".chm", ".cmd", ".com", ".cpl", ".exe", ".hta", ".ins", ".isp",
852*38e8c45fSAndroid Build Coastguard Worker ".jar", ".jse", ".lib", ".lnk", ".mde", ".msc", ".msp", ".mst", ".pif", ".scr", ".sct",
853*38e8c45fSAndroid Build Coastguard Worker ".shb", ".sys", ".vb", ".vbe", ".vbs", ".vxd", ".wsc", ".wsf", ".wsh"
854*38e8c45fSAndroid Build Coastguard Worker };
855*38e8c45fSAndroid Build Coastguard Worker
AddZipEntryFromFd(const std::string & entry_name,int fd,std::chrono::milliseconds timeout=0ms)856*38e8c45fSAndroid Build Coastguard Worker status_t Dumpstate::AddZipEntryFromFd(const std::string& entry_name, int fd,
857*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout = 0ms) {
858*38e8c45fSAndroid Build Coastguard Worker std::string valid_name = entry_name;
859*38e8c45fSAndroid Build Coastguard Worker
860*38e8c45fSAndroid Build Coastguard Worker // Rename extension if necessary.
861*38e8c45fSAndroid Build Coastguard Worker size_t idx = entry_name.rfind('.');
862*38e8c45fSAndroid Build Coastguard Worker if (idx != std::string::npos) {
863*38e8c45fSAndroid Build Coastguard Worker std::string extension = entry_name.substr(idx);
864*38e8c45fSAndroid Build Coastguard Worker std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
865*38e8c45fSAndroid Build Coastguard Worker if (PROBLEMATIC_FILE_EXTENSIONS.count(extension) != 0) {
866*38e8c45fSAndroid Build Coastguard Worker valid_name = entry_name + ".renamed";
867*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Renaming entry %s to %s\n", entry_name.c_str(), valid_name.c_str());
868*38e8c45fSAndroid Build Coastguard Worker }
869*38e8c45fSAndroid Build Coastguard Worker }
870*38e8c45fSAndroid Build Coastguard Worker
871*38e8c45fSAndroid Build Coastguard Worker // Logging statement below is useful to time how long each entry takes, but it's too verbose.
872*38e8c45fSAndroid Build Coastguard Worker // MYLOGD("Adding zip entry %s\n", entry_name.c_str());
873*38e8c45fSAndroid Build Coastguard Worker size_t flags = ZipWriter::kCompress | ZipWriter::kDefaultCompression;
874*38e8c45fSAndroid Build Coastguard Worker int32_t err = zip_writer_->StartEntryWithTime(valid_name.c_str(), flags,
875*38e8c45fSAndroid Build Coastguard Worker get_mtime(fd, ds.now_));
876*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
877*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->StartEntryWithTime(%s): %s\n", valid_name.c_str(),
878*38e8c45fSAndroid Build Coastguard Worker ZipWriter::ErrorCodeString(err));
879*38e8c45fSAndroid Build Coastguard Worker return UNKNOWN_ERROR;
880*38e8c45fSAndroid Build Coastguard Worker }
881*38e8c45fSAndroid Build Coastguard Worker bool finished_entry = false;
882*38e8c45fSAndroid Build Coastguard Worker auto finish_entry = [this, &finished_entry] {
883*38e8c45fSAndroid Build Coastguard Worker if (!finished_entry) {
884*38e8c45fSAndroid Build Coastguard Worker // This should only be called when we're going to return an earlier error,
885*38e8c45fSAndroid Build Coastguard Worker // which would've been logged. This may imply the file is already corrupt
886*38e8c45fSAndroid Build Coastguard Worker // and any further logging from FinishEntry is more likely to mislead than
887*38e8c45fSAndroid Build Coastguard Worker // not.
888*38e8c45fSAndroid Build Coastguard Worker this->zip_writer_->FinishEntry();
889*38e8c45fSAndroid Build Coastguard Worker }
890*38e8c45fSAndroid Build Coastguard Worker };
891*38e8c45fSAndroid Build Coastguard Worker auto scope_guard = android::base::make_scope_guard(finish_entry);
892*38e8c45fSAndroid Build Coastguard Worker auto start = std::chrono::steady_clock::now();
893*38e8c45fSAndroid Build Coastguard Worker auto end = start + timeout;
894*38e8c45fSAndroid Build Coastguard Worker struct pollfd pfd = {fd, POLLIN};
895*38e8c45fSAndroid Build Coastguard Worker
896*38e8c45fSAndroid Build Coastguard Worker std::vector<uint8_t> buffer(65536);
897*38e8c45fSAndroid Build Coastguard Worker while (1) {
898*38e8c45fSAndroid Build Coastguard Worker if (timeout.count() > 0) {
899*38e8c45fSAndroid Build Coastguard Worker // lambda to recalculate the timeout.
900*38e8c45fSAndroid Build Coastguard Worker auto time_left_ms = [end]() {
901*38e8c45fSAndroid Build Coastguard Worker auto now = std::chrono::steady_clock::now();
902*38e8c45fSAndroid Build Coastguard Worker auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
903*38e8c45fSAndroid Build Coastguard Worker return std::max(diff.count(), 0LL);
904*38e8c45fSAndroid Build Coastguard Worker };
905*38e8c45fSAndroid Build Coastguard Worker
906*38e8c45fSAndroid Build Coastguard Worker int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
907*38e8c45fSAndroid Build Coastguard Worker if (rc < 0) {
908*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Error in poll while adding from fd to zip entry %s:%s\n",
909*38e8c45fSAndroid Build Coastguard Worker entry_name.c_str(), strerror(errno));
910*38e8c45fSAndroid Build Coastguard Worker return -errno;
911*38e8c45fSAndroid Build Coastguard Worker } else if (rc == 0) {
912*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Timed out adding from fd to zip entry %s:%s Timeout:%lldms\n",
913*38e8c45fSAndroid Build Coastguard Worker entry_name.c_str(), strerror(errno), timeout.count());
914*38e8c45fSAndroid Build Coastguard Worker return TIMED_OUT;
915*38e8c45fSAndroid Build Coastguard Worker }
916*38e8c45fSAndroid Build Coastguard Worker }
917*38e8c45fSAndroid Build Coastguard Worker
918*38e8c45fSAndroid Build Coastguard Worker ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), buffer.size()));
919*38e8c45fSAndroid Build Coastguard Worker if (bytes_read == 0) {
920*38e8c45fSAndroid Build Coastguard Worker break;
921*38e8c45fSAndroid Build Coastguard Worker } else if (bytes_read == -1) {
922*38e8c45fSAndroid Build Coastguard Worker MYLOGE("read(%s): %s\n", entry_name.c_str(), strerror(errno));
923*38e8c45fSAndroid Build Coastguard Worker return -errno;
924*38e8c45fSAndroid Build Coastguard Worker }
925*38e8c45fSAndroid Build Coastguard Worker err = zip_writer_->WriteBytes(buffer.data(), bytes_read);
926*38e8c45fSAndroid Build Coastguard Worker if (err) {
927*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->WriteBytes(): %s\n", ZipWriter::ErrorCodeString(err));
928*38e8c45fSAndroid Build Coastguard Worker return UNKNOWN_ERROR;
929*38e8c45fSAndroid Build Coastguard Worker }
930*38e8c45fSAndroid Build Coastguard Worker }
931*38e8c45fSAndroid Build Coastguard Worker
932*38e8c45fSAndroid Build Coastguard Worker err = zip_writer_->FinishEntry();
933*38e8c45fSAndroid Build Coastguard Worker finished_entry = true;
934*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
935*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
936*38e8c45fSAndroid Build Coastguard Worker return UNKNOWN_ERROR;
937*38e8c45fSAndroid Build Coastguard Worker }
938*38e8c45fSAndroid Build Coastguard Worker
939*38e8c45fSAndroid Build Coastguard Worker return OK;
940*38e8c45fSAndroid Build Coastguard Worker }
941*38e8c45fSAndroid Build Coastguard Worker
AddZipEntry(const std::string & entry_name,const std::string & entry_path)942*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::AddZipEntry(const std::string& entry_name, const std::string& entry_path) {
943*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(
944*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(open(entry_path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
945*38e8c45fSAndroid Build Coastguard Worker if (fd == -1) {
946*38e8c45fSAndroid Build Coastguard Worker MYLOGE("open(%s): %s\n", entry_path.c_str(), strerror(errno));
947*38e8c45fSAndroid Build Coastguard Worker return false;
948*38e8c45fSAndroid Build Coastguard Worker }
949*38e8c45fSAndroid Build Coastguard Worker
950*38e8c45fSAndroid Build Coastguard Worker return (AddZipEntryFromFd(entry_name, fd.get()) == OK);
951*38e8c45fSAndroid Build Coastguard Worker }
952*38e8c45fSAndroid Build Coastguard Worker
953*38e8c45fSAndroid Build Coastguard Worker /* adds a file to the existing zipped bugreport */
_add_file_from_fd(const char * title,const char * path,int fd)954*38e8c45fSAndroid Build Coastguard Worker static int _add_file_from_fd(const char* title __attribute__((unused)), const char* path, int fd) {
955*38e8c45fSAndroid Build Coastguard Worker return (ds.AddZipEntryFromFd(ZIP_ROOT_DIR + path, fd) == OK) ? 0 : 1;
956*38e8c45fSAndroid Build Coastguard Worker }
957*38e8c45fSAndroid Build Coastguard Worker
AddDir(const std::string & dir,bool recursive)958*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::AddDir(const std::string& dir, bool recursive) {
959*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Adding dir %s (recursive: %d)\n", dir.c_str(), recursive);
960*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(dir, true);
961*38e8c45fSAndroid Build Coastguard Worker dump_files("", dir.c_str(), recursive ? skip_none : is_dir, _add_file_from_fd);
962*38e8c45fSAndroid Build Coastguard Worker }
963*38e8c45fSAndroid Build Coastguard Worker
AddTextZipEntry(const std::string & entry_name,const std::string & content)964*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::AddTextZipEntry(const std::string& entry_name, const std::string& content) {
965*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Adding zip text entry %s\n", entry_name.c_str());
966*38e8c45fSAndroid Build Coastguard Worker size_t flags = ZipWriter::kCompress | ZipWriter::kDefaultCompression;
967*38e8c45fSAndroid Build Coastguard Worker int32_t err = zip_writer_->StartEntryWithTime(entry_name.c_str(), flags, ds.now_);
968*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
969*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->StartEntryWithTime(%s): %s\n", entry_name.c_str(),
970*38e8c45fSAndroid Build Coastguard Worker ZipWriter::ErrorCodeString(err));
971*38e8c45fSAndroid Build Coastguard Worker return false;
972*38e8c45fSAndroid Build Coastguard Worker }
973*38e8c45fSAndroid Build Coastguard Worker
974*38e8c45fSAndroid Build Coastguard Worker err = zip_writer_->WriteBytes(content.c_str(), content.length());
975*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
976*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->WriteBytes(%s): %s\n", entry_name.c_str(),
977*38e8c45fSAndroid Build Coastguard Worker ZipWriter::ErrorCodeString(err));
978*38e8c45fSAndroid Build Coastguard Worker return false;
979*38e8c45fSAndroid Build Coastguard Worker }
980*38e8c45fSAndroid Build Coastguard Worker
981*38e8c45fSAndroid Build Coastguard Worker err = zip_writer_->FinishEntry();
982*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
983*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->FinishEntry(): %s\n", ZipWriter::ErrorCodeString(err));
984*38e8c45fSAndroid Build Coastguard Worker return false;
985*38e8c45fSAndroid Build Coastguard Worker }
986*38e8c45fSAndroid Build Coastguard Worker
987*38e8c45fSAndroid Build Coastguard Worker return true;
988*38e8c45fSAndroid Build Coastguard Worker }
989*38e8c45fSAndroid Build Coastguard Worker
DoKmsg()990*38e8c45fSAndroid Build Coastguard Worker static void DoKmsg() {
991*38e8c45fSAndroid Build Coastguard Worker struct stat st;
992*38e8c45fSAndroid Build Coastguard Worker if (!stat(PSTORE_LAST_KMSG, &st)) {
993*38e8c45fSAndroid Build Coastguard Worker /* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
994*38e8c45fSAndroid Build Coastguard Worker DumpFile("LAST KMSG", PSTORE_LAST_KMSG);
995*38e8c45fSAndroid Build Coastguard Worker } else if (!stat(ALT_PSTORE_LAST_KMSG, &st)) {
996*38e8c45fSAndroid Build Coastguard Worker DumpFile("LAST KMSG", ALT_PSTORE_LAST_KMSG);
997*38e8c45fSAndroid Build Coastguard Worker } else {
998*38e8c45fSAndroid Build Coastguard Worker /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
999*38e8c45fSAndroid Build Coastguard Worker DumpFile("LAST KMSG", "/proc/last_kmsg");
1000*38e8c45fSAndroid Build Coastguard Worker }
1001*38e8c45fSAndroid Build Coastguard Worker }
1002*38e8c45fSAndroid Build Coastguard Worker
DoKernelLogcat()1003*38e8c45fSAndroid Build Coastguard Worker static void DoKernelLogcat() {
1004*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms = logcat_timeout({"kernel"});
1005*38e8c45fSAndroid Build Coastguard Worker RunCommand(
1006*38e8c45fSAndroid Build Coastguard Worker "KERNEL LOG",
1007*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-b", "kernel", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1008*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build());
1009*38e8c45fSAndroid Build Coastguard Worker }
1010*38e8c45fSAndroid Build Coastguard Worker
DoSystemLogcat(time_t since)1011*38e8c45fSAndroid Build Coastguard Worker static void DoSystemLogcat(time_t since) {
1012*38e8c45fSAndroid Build Coastguard Worker char since_str[80];
1013*38e8c45fSAndroid Build Coastguard Worker strftime(since_str, sizeof(since_str), "%Y-%m-%d %H:%M:%S.000", localtime(&since));
1014*38e8c45fSAndroid Build Coastguard Worker
1015*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms = logcat_timeout({"main", "system", "crash"});
1016*38e8c45fSAndroid Build Coastguard Worker RunCommand("SYSTEM LOG",
1017*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v", "-T",
1018*38e8c45fSAndroid Build Coastguard Worker since_str},
1019*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build());
1020*38e8c45fSAndroid Build Coastguard Worker }
1021*38e8c45fSAndroid Build Coastguard Worker
DoRadioLogcat()1022*38e8c45fSAndroid Build Coastguard Worker static void DoRadioLogcat() {
1023*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms = logcat_timeout({"radio"});
1024*38e8c45fSAndroid Build Coastguard Worker RunCommand(
1025*38e8c45fSAndroid Build Coastguard Worker "RADIO LOG",
1026*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1027*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build(), true /* verbose_duration */);
1028*38e8c45fSAndroid Build Coastguard Worker }
1029*38e8c45fSAndroid Build Coastguard Worker
DoLogcat()1030*38e8c45fSAndroid Build Coastguard Worker static void DoLogcat() {
1031*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms;
1032*38e8c45fSAndroid Build Coastguard Worker // DumpFile("EVENT LOG TAGS", "/etc/event-log-tags");
1033*38e8c45fSAndroid Build Coastguard Worker // calculate timeout
1034*38e8c45fSAndroid Build Coastguard Worker timeout_ms = logcat_timeout({"main", "system", "crash"});
1035*38e8c45fSAndroid Build Coastguard Worker RunCommand("SYSTEM LOG",
1036*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1037*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build());
1038*38e8c45fSAndroid Build Coastguard Worker timeout_ms = logcat_timeout({"events"});
1039*38e8c45fSAndroid Build Coastguard Worker RunCommand(
1040*38e8c45fSAndroid Build Coastguard Worker "EVENT LOG",
1041*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1042*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build(), true /* verbose_duration */);
1043*38e8c45fSAndroid Build Coastguard Worker timeout_ms = logcat_timeout({"stats"});
1044*38e8c45fSAndroid Build Coastguard Worker RunCommand(
1045*38e8c45fSAndroid Build Coastguard Worker "STATS LOG",
1046*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-b", "stats", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1047*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build(), true /* verbose_duration */);
1048*38e8c45fSAndroid Build Coastguard Worker DoRadioLogcat();
1049*38e8c45fSAndroid Build Coastguard Worker
1050*38e8c45fSAndroid Build Coastguard Worker /* kernels must set CONFIG_PSTORE_PMSG, slice up pstore with device tree */
1051*38e8c45fSAndroid Build Coastguard Worker RunCommand("LAST LOGCAT", {"logcat", "-L", "-b", "all", "-v", "threadtime", "-v", "printable",
1052*38e8c45fSAndroid Build Coastguard Worker "-v", "uid", "-d", "*:v"});
1053*38e8c45fSAndroid Build Coastguard Worker }
1054*38e8c45fSAndroid Build Coastguard Worker
DumpIncidentReport()1055*38e8c45fSAndroid Build Coastguard Worker static void DumpIncidentReport() {
1056*38e8c45fSAndroid Build Coastguard Worker const std::string path = ds.bugreport_internal_dir_ + "/tmp_incident_report";
1057*38e8c45fSAndroid Build Coastguard Worker auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(),
1058*38e8c45fSAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1059*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
1060*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
1061*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open %s to dump incident report.\n", path.c_str());
1062*38e8c45fSAndroid Build Coastguard Worker return;
1063*38e8c45fSAndroid Build Coastguard Worker }
1064*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(fd, "", {"incident", "-u"},
1065*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(PropertiesHelper::IsStrictRun() ? 20 : 120).Build());
1066*38e8c45fSAndroid Build Coastguard Worker bool empty = 0 == lseek(fd, 0, SEEK_END);
1067*38e8c45fSAndroid Build Coastguard Worker if (!empty) {
1068*38e8c45fSAndroid Build Coastguard Worker // Use a different name from "incident.proto"
1069*38e8c45fSAndroid Build Coastguard Worker // /proto/incident.proto is reserved for incident service dump
1070*38e8c45fSAndroid Build Coastguard Worker // i.e. metadata for debugging.
1071*38e8c45fSAndroid Build Coastguard Worker ds.EnqueueAddZipEntryAndCleanupIfNeeded(kProtoPath + "incident_report" + kProtoExt,
1072*38e8c45fSAndroid Build Coastguard Worker path);
1073*38e8c45fSAndroid Build Coastguard Worker } else {
1074*38e8c45fSAndroid Build Coastguard Worker unlink(path.c_str());
1075*38e8c45fSAndroid Build Coastguard Worker }
1076*38e8c45fSAndroid Build Coastguard Worker }
1077*38e8c45fSAndroid Build Coastguard Worker
DumpNetstatsProto()1078*38e8c45fSAndroid Build Coastguard Worker static void DumpNetstatsProto() {
1079*38e8c45fSAndroid Build Coastguard Worker const std::string path = ds.bugreport_internal_dir_ + "/tmp_netstats_proto";
1080*38e8c45fSAndroid Build Coastguard Worker auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(),
1081*38e8c45fSAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1082*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
1083*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
1084*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open %s to dump netstats proto.\n", path.c_str());
1085*38e8c45fSAndroid Build Coastguard Worker return;
1086*38e8c45fSAndroid Build Coastguard Worker }
1087*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(fd, "", {"dumpsys", "netstats", "--proto"},
1088*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(5).Build());
1089*38e8c45fSAndroid Build Coastguard Worker bool empty = 0 == lseek(fd, 0, SEEK_END);
1090*38e8c45fSAndroid Build Coastguard Worker if (!empty) {
1091*38e8c45fSAndroid Build Coastguard Worker ds.EnqueueAddZipEntryAndCleanupIfNeeded(kProtoPath + "netstats" + kProtoExt,
1092*38e8c45fSAndroid Build Coastguard Worker path);
1093*38e8c45fSAndroid Build Coastguard Worker } else {
1094*38e8c45fSAndroid Build Coastguard Worker unlink(path.c_str());
1095*38e8c45fSAndroid Build Coastguard Worker }
1096*38e8c45fSAndroid Build Coastguard Worker }
1097*38e8c45fSAndroid Build Coastguard Worker
MaybeAddSystemTraceToZip()1098*38e8c45fSAndroid Build Coastguard Worker static void MaybeAddSystemTraceToZip() {
1099*38e8c45fSAndroid Build Coastguard Worker // This function copies into the .zip the system trace that was snapshotted
1100*38e8c45fSAndroid Build Coastguard Worker // by the early call to MaybeSnapshotSystemTraceAsync(), if any background
1101*38e8c45fSAndroid Build Coastguard Worker // tracing was happening.
1102*38e8c45fSAndroid Build Coastguard Worker bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0;
1103*38e8c45fSAndroid Build Coastguard Worker if (!system_trace_exists) {
1104*38e8c45fSAndroid Build Coastguard Worker // No background trace was happening at the time MaybeSnapshotSystemTraceAsync() was invoked
1105*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsUserBuild()) {
1106*38e8c45fSAndroid Build Coastguard Worker MYLOGI(
1107*38e8c45fSAndroid Build Coastguard Worker "No system traces found. Check for previously uploaded traces by looking for "
1108*38e8c45fSAndroid Build Coastguard Worker "go/trace-uuid in logcat")
1109*38e8c45fSAndroid Build Coastguard Worker }
1110*38e8c45fSAndroid Build Coastguard Worker return;
1111*38e8c45fSAndroid Build Coastguard Worker }
1112*38e8c45fSAndroid Build Coastguard Worker ds.AddZipEntry(
1113*38e8c45fSAndroid Build Coastguard Worker ZIP_ROOT_DIR + SYSTEM_TRACE_SNAPSHOT,
1114*38e8c45fSAndroid Build Coastguard Worker SYSTEM_TRACE_SNAPSHOT);
1115*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(SYSTEM_TRACE_SNAPSHOT);
1116*38e8c45fSAndroid Build Coastguard Worker }
1117*38e8c45fSAndroid Build Coastguard Worker
DumpVisibleWindowViews()1118*38e8c45fSAndroid Build Coastguard Worker static void DumpVisibleWindowViews() {
1119*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("VISIBLE WINDOW VIEWS");
1120*38e8c45fSAndroid Build Coastguard Worker const std::string path = ds.bugreport_internal_dir_ + "/tmp_visible_window_views";
1121*38e8c45fSAndroid Build Coastguard Worker auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(),
1122*38e8c45fSAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1123*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
1124*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
1125*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open %s to dump visible views.\n", path.c_str());
1126*38e8c45fSAndroid Build Coastguard Worker return;
1127*38e8c45fSAndroid Build Coastguard Worker }
1128*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(fd, "", {"cmd", "window", "dump-visible-window-views"},
1129*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Build());
1130*38e8c45fSAndroid Build Coastguard Worker bool empty = 0 == lseek(fd, 0, SEEK_END);
1131*38e8c45fSAndroid Build Coastguard Worker if (!empty) {
1132*38e8c45fSAndroid Build Coastguard Worker ds.AddZipEntry("visible_windows.zip", path);
1133*38e8c45fSAndroid Build Coastguard Worker } else {
1134*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Failed to dump visible windows\n");
1135*38e8c45fSAndroid Build Coastguard Worker }
1136*38e8c45fSAndroid Build Coastguard Worker unlink(path.c_str());
1137*38e8c45fSAndroid Build Coastguard Worker }
1138*38e8c45fSAndroid Build Coastguard Worker
DumpIpTablesAsRoot()1139*38e8c45fSAndroid Build Coastguard Worker static void DumpIpTablesAsRoot() {
1140*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPTABLES", {"iptables", "-L", "-nvx"});
1141*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP6TABLES", {"ip6tables", "-L", "-nvx"});
1142*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPTABLES NAT", {"iptables", "-t", "nat", "-L", "-nvx"});
1143*38e8c45fSAndroid Build Coastguard Worker /* no ip6 nat */
1144*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPTABLES MANGLE", {"iptables", "-t", "mangle", "-L", "-nvx"});
1145*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP6TABLES MANGLE", {"ip6tables", "-t", "mangle", "-L", "-nvx"});
1146*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPTABLES RAW", {"iptables", "-t", "raw", "-L", "-nvx"});
1147*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
1148*38e8c45fSAndroid Build Coastguard Worker }
1149*38e8c45fSAndroid Build Coastguard Worker
DumpShutdownCheckpoints()1150*38e8c45fSAndroid Build Coastguard Worker static void DumpShutdownCheckpoints() {
1151*38e8c45fSAndroid Build Coastguard Worker const bool shutdown_checkpoints_dumped = AddDumps(
1152*38e8c45fSAndroid Build Coastguard Worker ds.shutdown_checkpoints_.begin(), ds.shutdown_checkpoints_.end(),
1153*38e8c45fSAndroid Build Coastguard Worker "SHUTDOWN CHECKPOINTS", false /* add_to_zip */);
1154*38e8c45fSAndroid Build Coastguard Worker if (!shutdown_checkpoints_dumped) {
1155*38e8c45fSAndroid Build Coastguard Worker printf("*** NO SHUTDOWN CHECKPOINTS to dump in %s\n\n",
1156*38e8c45fSAndroid Build Coastguard Worker SHUTDOWN_CHECKPOINTS_DIR.c_str());
1157*38e8c45fSAndroid Build Coastguard Worker }
1158*38e8c45fSAndroid Build Coastguard Worker }
1159*38e8c45fSAndroid Build Coastguard Worker
DumpDynamicPartitionInfo()1160*38e8c45fSAndroid Build Coastguard Worker static void DumpDynamicPartitionInfo() {
1161*38e8c45fSAndroid Build Coastguard Worker if (!::android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
1162*38e8c45fSAndroid Build Coastguard Worker return;
1163*38e8c45fSAndroid Build Coastguard Worker }
1164*38e8c45fSAndroid Build Coastguard Worker
1165*38e8c45fSAndroid Build Coastguard Worker RunCommand("LPDUMP", {"lpdump", "--all"});
1166*38e8c45fSAndroid Build Coastguard Worker RunCommand("DEVICE-MAPPER", {"gsid", "dump-device-mapper"});
1167*38e8c45fSAndroid Build Coastguard Worker }
1168*38e8c45fSAndroid Build Coastguard Worker
AddAnrTraceDir(const std::string & anr_traces_dir)1169*38e8c45fSAndroid Build Coastguard Worker static void AddAnrTraceDir(const std::string& anr_traces_dir) {
1170*38e8c45fSAndroid Build Coastguard Worker MYLOGD("AddAnrTraceDir(): dump_traces_file=%s, anr_traces_dir=%s\n", dump_traces_path,
1171*38e8c45fSAndroid Build Coastguard Worker anr_traces_dir.c_str());
1172*38e8c45fSAndroid Build Coastguard Worker
1173*38e8c45fSAndroid Build Coastguard Worker // If we're here, dump_traces_path will always be a temporary file
1174*38e8c45fSAndroid Build Coastguard Worker // (created with mkostemp or similar) that contains dumps taken earlier
1175*38e8c45fSAndroid Build Coastguard Worker // on in the process.
1176*38e8c45fSAndroid Build Coastguard Worker if (dump_traces_path != nullptr) {
1177*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n",
1178*38e8c45fSAndroid Build Coastguard Worker dump_traces_path);
1179*38e8c45fSAndroid Build Coastguard Worker ds.DumpFile("VM TRACES JUST NOW", dump_traces_path);
1180*38e8c45fSAndroid Build Coastguard Worker
1181*38e8c45fSAndroid Build Coastguard Worker const int ret = unlink(dump_traces_path);
1182*38e8c45fSAndroid Build Coastguard Worker if (ret == -1) {
1183*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Error unlinking temporary trace path %s: %s\n", dump_traces_path,
1184*38e8c45fSAndroid Build Coastguard Worker strerror(errno));
1185*38e8c45fSAndroid Build Coastguard Worker }
1186*38e8c45fSAndroid Build Coastguard Worker }
1187*38e8c45fSAndroid Build Coastguard Worker
1188*38e8c45fSAndroid Build Coastguard Worker // Add a specific message for the first ANR Dump.
1189*38e8c45fSAndroid Build Coastguard Worker if (ds.anr_data_.size() > 0) {
1190*38e8c45fSAndroid Build Coastguard Worker // The "last" ANR will always be present in the body of the main entry.
1191*38e8c45fSAndroid Build Coastguard Worker AddDumps(ds.anr_data_.begin(), ds.anr_data_.begin() + 1,
1192*38e8c45fSAndroid Build Coastguard Worker "VM TRACES AT LAST ANR", false /* add_to_zip */);
1193*38e8c45fSAndroid Build Coastguard Worker
1194*38e8c45fSAndroid Build Coastguard Worker // Historical ANRs are always included as separate entries in the bugreport zip file.
1195*38e8c45fSAndroid Build Coastguard Worker AddDumps(ds.anr_data_.begin(), ds.anr_data_.end(),
1196*38e8c45fSAndroid Build Coastguard Worker "HISTORICAL ANR", true /* add_to_zip */);
1197*38e8c45fSAndroid Build Coastguard Worker } else {
1198*38e8c45fSAndroid Build Coastguard Worker printf("*** NO ANRs to dump in %s\n\n", ANR_DIR.c_str());
1199*38e8c45fSAndroid Build Coastguard Worker }
1200*38e8c45fSAndroid Build Coastguard Worker
1201*38e8c45fSAndroid Build Coastguard Worker // Add Java anr traces (such as generated by the Finalizer Watchdog).
1202*38e8c45fSAndroid Build Coastguard Worker AddDumps(ds.anr_trace_data_.begin(), ds.anr_trace_data_.end(), "JAVA ANR TRACES",
1203*38e8c45fSAndroid Build Coastguard Worker true /* add_to_zip */);
1204*38e8c45fSAndroid Build Coastguard Worker }
1205*38e8c45fSAndroid Build Coastguard Worker
AddAnrTraceFiles()1206*38e8c45fSAndroid Build Coastguard Worker static void AddAnrTraceFiles() {
1207*38e8c45fSAndroid Build Coastguard Worker std::string anr_traces_dir = "/data/anr";
1208*38e8c45fSAndroid Build Coastguard Worker
1209*38e8c45fSAndroid Build Coastguard Worker AddAnrTraceDir(anr_traces_dir);
1210*38e8c45fSAndroid Build Coastguard Worker
1211*38e8c45fSAndroid Build Coastguard Worker RunCommand("ANR FILES", {"ls", "-lt", ANR_DIR});
1212*38e8c45fSAndroid Build Coastguard Worker
1213*38e8c45fSAndroid Build Coastguard Worker // Slow traces for slow operations.
1214*38e8c45fSAndroid Build Coastguard Worker struct stat st;
1215*38e8c45fSAndroid Build Coastguard Worker int i = 0;
1216*38e8c45fSAndroid Build Coastguard Worker while (true) {
1217*38e8c45fSAndroid Build Coastguard Worker const std::string slow_trace_path =
1218*38e8c45fSAndroid Build Coastguard Worker anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
1219*38e8c45fSAndroid Build Coastguard Worker if (stat(slow_trace_path.c_str(), &st)) {
1220*38e8c45fSAndroid Build Coastguard Worker // No traces file at this index, done with the files.
1221*38e8c45fSAndroid Build Coastguard Worker break;
1222*38e8c45fSAndroid Build Coastguard Worker }
1223*38e8c45fSAndroid Build Coastguard Worker ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
1224*38e8c45fSAndroid Build Coastguard Worker i++;
1225*38e8c45fSAndroid Build Coastguard Worker }
1226*38e8c45fSAndroid Build Coastguard Worker }
1227*38e8c45fSAndroid Build Coastguard Worker
DumpBlockStatFiles()1228*38e8c45fSAndroid Build Coastguard Worker static void DumpBlockStatFiles() {
1229*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMP BLOCK STAT");
1230*38e8c45fSAndroid Build Coastguard Worker
1231*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<DIR, std::function<int(DIR*)>> dirptr(opendir(BLK_DEV_SYS_DIR), closedir);
1232*38e8c45fSAndroid Build Coastguard Worker
1233*38e8c45fSAndroid Build Coastguard Worker if (dirptr == nullptr) {
1234*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to open %s: %s\n", BLK_DEV_SYS_DIR, strerror(errno));
1235*38e8c45fSAndroid Build Coastguard Worker return;
1236*38e8c45fSAndroid Build Coastguard Worker }
1237*38e8c45fSAndroid Build Coastguard Worker
1238*38e8c45fSAndroid Build Coastguard Worker printf("------ DUMP BLOCK STAT ------\n\n");
1239*38e8c45fSAndroid Build Coastguard Worker while (struct dirent *d = readdir(dirptr.get())) {
1240*38e8c45fSAndroid Build Coastguard Worker if ((d->d_name[0] == '.')
1241*38e8c45fSAndroid Build Coastguard Worker && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
1242*38e8c45fSAndroid Build Coastguard Worker || (d->d_name[1] == '\0'))) {
1243*38e8c45fSAndroid Build Coastguard Worker continue;
1244*38e8c45fSAndroid Build Coastguard Worker }
1245*38e8c45fSAndroid Build Coastguard Worker const std::string new_path =
1246*38e8c45fSAndroid Build Coastguard Worker android::base::StringPrintf("%s/%s", BLK_DEV_SYS_DIR, d->d_name);
1247*38e8c45fSAndroid Build Coastguard Worker printf("------ BLOCK STAT (%s) ------\n", new_path.c_str());
1248*38e8c45fSAndroid Build Coastguard Worker dump_files("", new_path.c_str(), skip_not_stat, dump_stat_from_fd);
1249*38e8c45fSAndroid Build Coastguard Worker printf("\n");
1250*38e8c45fSAndroid Build Coastguard Worker }
1251*38e8c45fSAndroid Build Coastguard Worker return;
1252*38e8c45fSAndroid Build Coastguard Worker }
1253*38e8c45fSAndroid Build Coastguard Worker
DumpPacketStats()1254*38e8c45fSAndroid Build Coastguard Worker static void DumpPacketStats() {
1255*38e8c45fSAndroid Build Coastguard Worker DumpFile("NETWORK DEV INFO", "/proc/net/dev");
1256*38e8c45fSAndroid Build Coastguard Worker }
1257*38e8c45fSAndroid Build Coastguard Worker
DumpIpAddrAndRules()1258*38e8c45fSAndroid Build Coastguard Worker static void DumpIpAddrAndRules() {
1259*38e8c45fSAndroid Build Coastguard Worker /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
1260*38e8c45fSAndroid Build Coastguard Worker RunCommand("NETWORK INTERFACES", {"ip", "-s", "link"});
1261*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPv4 ADDRESSES", {"ip", "-4", "addr", "show"});
1262*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPv6 ADDRESSES", {"ip", "-6", "addr", "show"});
1263*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP RULES", {"ip", "rule", "show"});
1264*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"});
1265*38e8c45fSAndroid Build Coastguard Worker }
1266*38e8c45fSAndroid Build Coastguard Worker
RunDumpsysTextByPriority(const std::string & title,int priority,std::chrono::milliseconds timeout,std::chrono::milliseconds service_timeout)1267*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysTextByPriority(const std::string& title, int priority,
1268*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout,
1269*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds service_timeout) {
1270*38e8c45fSAndroid Build Coastguard Worker auto start = std::chrono::steady_clock::now();
1271*38e8c45fSAndroid Build Coastguard Worker sp<android::IServiceManager> sm = defaultServiceManager();
1272*38e8c45fSAndroid Build Coastguard Worker Dumpsys dumpsys(sm.get());
1273*38e8c45fSAndroid Build Coastguard Worker Vector<String16> args;
1274*38e8c45fSAndroid Build Coastguard Worker Dumpsys::setServiceArgs(args, /* asProto = */ false, priority);
1275*38e8c45fSAndroid Build Coastguard Worker Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ false);
1276*38e8c45fSAndroid Build Coastguard Worker for (const String16& service : services) {
1277*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1278*38e8c45fSAndroid Build Coastguard Worker std::string path(title);
1279*38e8c45fSAndroid Build Coastguard Worker path.append(" - ").append(String8(service).c_str());
1280*38e8c45fSAndroid Build Coastguard Worker size_t bytes_written = 0;
1281*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) {
1282*38e8c45fSAndroid Build Coastguard Worker dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
1283*38e8c45fSAndroid Build Coastguard Worker dumpsys.writeDumpFooter(STDOUT_FILENO, service, std::chrono::milliseconds(1));
1284*38e8c45fSAndroid Build Coastguard Worker } else {
1285*38e8c45fSAndroid Build Coastguard Worker status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP | Dumpsys::TYPE_PID |
1286*38e8c45fSAndroid Build Coastguard Worker Dumpsys::TYPE_CLIENTS | Dumpsys::TYPE_THREAD,
1287*38e8c45fSAndroid Build Coastguard Worker service, args);
1288*38e8c45fSAndroid Build Coastguard Worker if (status == OK) {
1289*38e8c45fSAndroid Build Coastguard Worker dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
1290*38e8c45fSAndroid Build Coastguard Worker std::chrono::duration<double> elapsed_seconds;
1291*38e8c45fSAndroid Build Coastguard Worker if (priority == IServiceManager::DUMP_FLAG_PRIORITY_HIGH &&
1292*38e8c45fSAndroid Build Coastguard Worker service == String16("meminfo")) {
1293*38e8c45fSAndroid Build Coastguard Worker // Use a longer timeout for meminfo, since 30s is not always enough.
1294*38e8c45fSAndroid Build Coastguard Worker status = dumpsys.writeDump(STDOUT_FILENO, service, 60s,
1295*38e8c45fSAndroid Build Coastguard Worker /* as_proto = */ false, elapsed_seconds,
1296*38e8c45fSAndroid Build Coastguard Worker bytes_written);
1297*38e8c45fSAndroid Build Coastguard Worker } else {
1298*38e8c45fSAndroid Build Coastguard Worker status = dumpsys.writeDump(STDOUT_FILENO, service, service_timeout,
1299*38e8c45fSAndroid Build Coastguard Worker /* as_proto = */ false, elapsed_seconds,
1300*38e8c45fSAndroid Build Coastguard Worker bytes_written);
1301*38e8c45fSAndroid Build Coastguard Worker }
1302*38e8c45fSAndroid Build Coastguard Worker dumpsys.writeDumpFooter(STDOUT_FILENO, service, elapsed_seconds);
1303*38e8c45fSAndroid Build Coastguard Worker bool dump_complete = (status == OK);
1304*38e8c45fSAndroid Build Coastguard Worker dumpsys.stopDumpThread(dump_complete);
1305*38e8c45fSAndroid Build Coastguard Worker } else {
1306*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to start dump thread for service: %s, status: %d",
1307*38e8c45fSAndroid Build Coastguard Worker String8(service).c_str(), status);
1308*38e8c45fSAndroid Build Coastguard Worker }
1309*38e8c45fSAndroid Build Coastguard Worker }
1310*38e8c45fSAndroid Build Coastguard Worker
1311*38e8c45fSAndroid Build Coastguard Worker auto elapsed_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
1312*38e8c45fSAndroid Build Coastguard Worker std::chrono::steady_clock::now() - start);
1313*38e8c45fSAndroid Build Coastguard Worker if (elapsed_duration > timeout) {
1314*38e8c45fSAndroid Build Coastguard Worker MYLOGE("*** command '%s' timed out after %llums\n", title.c_str(),
1315*38e8c45fSAndroid Build Coastguard Worker elapsed_duration.count());
1316*38e8c45fSAndroid Build Coastguard Worker break;
1317*38e8c45fSAndroid Build Coastguard Worker }
1318*38e8c45fSAndroid Build Coastguard Worker }
1319*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::OK;
1320*38e8c45fSAndroid Build Coastguard Worker }
1321*38e8c45fSAndroid Build Coastguard Worker
RunDumpsysText(const std::string & title,int priority,std::chrono::milliseconds timeout,std::chrono::milliseconds service_timeout)1322*38e8c45fSAndroid Build Coastguard Worker static void RunDumpsysText(const std::string& title, int priority,
1323*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout,
1324*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds service_timeout) {
1325*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
1326*38e8c45fSAndroid Build Coastguard Worker dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str());
1327*38e8c45fSAndroid Build Coastguard Worker fsync(STDOUT_FILENO);
1328*38e8c45fSAndroid Build Coastguard Worker RunDumpsysTextByPriority(title, priority, timeout, service_timeout);
1329*38e8c45fSAndroid Build Coastguard Worker }
1330*38e8c45fSAndroid Build Coastguard Worker
1331*38e8c45fSAndroid Build Coastguard Worker /* Dump all services registered with Normal or Default priority. */
RunDumpsysTextNormalPriority(const std::string & title,std::chrono::milliseconds timeout,std::chrono::milliseconds service_timeout)1332*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysTextNormalPriority(const std::string& title,
1333*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout,
1334*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds service_timeout) {
1335*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
1336*38e8c45fSAndroid Build Coastguard Worker dprintf(STDOUT_FILENO, "------ %s (/system/bin/dumpsys) ------\n", title.c_str());
1337*38e8c45fSAndroid Build Coastguard Worker fsync(STDOUT_FILENO);
1338*38e8c45fSAndroid Build Coastguard Worker RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL, timeout,
1339*38e8c45fSAndroid Build Coastguard Worker service_timeout);
1340*38e8c45fSAndroid Build Coastguard Worker
1341*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1342*38e8c45fSAndroid Build Coastguard Worker
1343*38e8c45fSAndroid Build Coastguard Worker return RunDumpsysTextByPriority(title, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT, timeout,
1344*38e8c45fSAndroid Build Coastguard Worker service_timeout);
1345*38e8c45fSAndroid Build Coastguard Worker }
1346*38e8c45fSAndroid Build Coastguard Worker
RunDumpsysProto(const std::string & title,int priority,std::chrono::milliseconds timeout,std::chrono::milliseconds service_timeout)1347*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priority,
1348*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds timeout,
1349*38e8c45fSAndroid Build Coastguard Worker std::chrono::milliseconds service_timeout) {
1350*38e8c45fSAndroid Build Coastguard Worker sp<android::IServiceManager> sm = defaultServiceManager();
1351*38e8c45fSAndroid Build Coastguard Worker Dumpsys dumpsys(sm.get());
1352*38e8c45fSAndroid Build Coastguard Worker Vector<String16> args;
1353*38e8c45fSAndroid Build Coastguard Worker Dumpsys::setServiceArgs(args, /* asProto = */ true, priority);
1354*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
1355*38e8c45fSAndroid Build Coastguard Worker
1356*38e8c45fSAndroid Build Coastguard Worker auto start = std::chrono::steady_clock::now();
1357*38e8c45fSAndroid Build Coastguard Worker Vector<String16> services = dumpsys.listServices(priority, /* supports_proto = */ true);
1358*38e8c45fSAndroid Build Coastguard Worker for (const String16& service : services) {
1359*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1360*38e8c45fSAndroid Build Coastguard Worker std::string path(kProtoPath);
1361*38e8c45fSAndroid Build Coastguard Worker path.append(String8(service).c_str());
1362*38e8c45fSAndroid Build Coastguard Worker if (priority == IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL) {
1363*38e8c45fSAndroid Build Coastguard Worker path.append("_CRITICAL");
1364*38e8c45fSAndroid Build Coastguard Worker } else if (priority == IServiceManager::DUMP_FLAG_PRIORITY_HIGH) {
1365*38e8c45fSAndroid Build Coastguard Worker path.append("_HIGH");
1366*38e8c45fSAndroid Build Coastguard Worker }
1367*38e8c45fSAndroid Build Coastguard Worker path.append(kProtoExt);
1368*38e8c45fSAndroid Build Coastguard Worker status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP, service, args);
1369*38e8c45fSAndroid Build Coastguard Worker if (status == OK) {
1370*38e8c45fSAndroid Build Coastguard Worker status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout);
1371*38e8c45fSAndroid Build Coastguard Worker bool dumpTerminated = (status == OK);
1372*38e8c45fSAndroid Build Coastguard Worker dumpsys.stopDumpThread(dumpTerminated);
1373*38e8c45fSAndroid Build Coastguard Worker }
1374*38e8c45fSAndroid Build Coastguard Worker ZipWriter::FileEntry file_entry;
1375*38e8c45fSAndroid Build Coastguard Worker ds.zip_writer_->GetLastEntry(&file_entry);
1376*38e8c45fSAndroid Build Coastguard Worker
1377*38e8c45fSAndroid Build Coastguard Worker auto elapsed_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
1378*38e8c45fSAndroid Build Coastguard Worker std::chrono::steady_clock::now() - start);
1379*38e8c45fSAndroid Build Coastguard Worker if (elapsed_duration > timeout) {
1380*38e8c45fSAndroid Build Coastguard Worker MYLOGE("*** command '%s' timed out after %llums\n", title.c_str(),
1381*38e8c45fSAndroid Build Coastguard Worker elapsed_duration.count());
1382*38e8c45fSAndroid Build Coastguard Worker break;
1383*38e8c45fSAndroid Build Coastguard Worker }
1384*38e8c45fSAndroid Build Coastguard Worker }
1385*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::OK;
1386*38e8c45fSAndroid Build Coastguard Worker }
1387*38e8c45fSAndroid Build Coastguard Worker
1388*38e8c45fSAndroid Build Coastguard Worker // Runs dumpsys on services that must dump first and will take less than 100ms to dump.
RunDumpsysCritical()1389*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysCritical() {
1390*38e8c45fSAndroid Build Coastguard Worker RunDumpsysText("DUMPSYS CRITICAL", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL,
1391*38e8c45fSAndroid Build Coastguard Worker /* timeout= */ 5s, /* service_timeout= */ 500ms);
1392*38e8c45fSAndroid Build Coastguard Worker
1393*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1394*38e8c45fSAndroid Build Coastguard Worker
1395*38e8c45fSAndroid Build Coastguard Worker return RunDumpsysProto("DUMPSYS CRITICAL PROTO", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL,
1396*38e8c45fSAndroid Build Coastguard Worker /* timeout= */ 5s, /* service_timeout= */ 500ms);
1397*38e8c45fSAndroid Build Coastguard Worker }
1398*38e8c45fSAndroid Build Coastguard Worker
1399*38e8c45fSAndroid Build Coastguard Worker // Runs dumpsys on services that must dump first but can take up to 250ms to dump.
RunDumpsysHigh()1400*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysHigh() {
1401*38e8c45fSAndroid Build Coastguard Worker // TODO meminfo takes ~10s, connectivity takes ~5sec to dump. They are both
1402*38e8c45fSAndroid Build Coastguard Worker // high priority. Reduce timeout once they are able to dump in a shorter time or
1403*38e8c45fSAndroid Build Coastguard Worker // moved to a parallel task.
1404*38e8c45fSAndroid Build Coastguard Worker RunDumpsysText("DUMPSYS HIGH", IServiceManager::DUMP_FLAG_PRIORITY_HIGH,
1405*38e8c45fSAndroid Build Coastguard Worker /* timeout= */ 90s, /* service_timeout= */ 30s);
1406*38e8c45fSAndroid Build Coastguard Worker
1407*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1408*38e8c45fSAndroid Build Coastguard Worker
1409*38e8c45fSAndroid Build Coastguard Worker return RunDumpsysProto("DUMPSYS HIGH PROTO", IServiceManager::DUMP_FLAG_PRIORITY_HIGH,
1410*38e8c45fSAndroid Build Coastguard Worker /* timeout= */ 5s, /* service_timeout= */ 1s);
1411*38e8c45fSAndroid Build Coastguard Worker }
1412*38e8c45fSAndroid Build Coastguard Worker
1413*38e8c45fSAndroid Build Coastguard Worker // Runs dumpsys on services that must dump but can take up to 10s to dump.
RunDumpsysNormal()1414*38e8c45fSAndroid Build Coastguard Worker static Dumpstate::RunStatus RunDumpsysNormal() {
1415*38e8c45fSAndroid Build Coastguard Worker RunDumpsysTextNormalPriority("DUMPSYS", /* timeout= */ 90s, /* service_timeout= */ 10s);
1416*38e8c45fSAndroid Build Coastguard Worker
1417*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1418*38e8c45fSAndroid Build Coastguard Worker
1419*38e8c45fSAndroid Build Coastguard Worker return RunDumpsysProto("DUMPSYS PROTO", IServiceManager::DUMP_FLAG_PRIORITY_NORMAL,
1420*38e8c45fSAndroid Build Coastguard Worker /* timeout= */ 90s, /* service_timeout= */ 10s);
1421*38e8c45fSAndroid Build Coastguard Worker }
1422*38e8c45fSAndroid Build Coastguard Worker
1423*38e8c45fSAndroid Build Coastguard Worker /*
1424*38e8c45fSAndroid Build Coastguard Worker * |out_fd| A fd to support the DumpPool to output results to a temporary file.
1425*38e8c45fSAndroid Build Coastguard Worker * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO
1426*38e8c45fSAndroid Build Coastguard Worker * if it's not running in the parallel task.
1427*38e8c45fSAndroid Build Coastguard Worker */
DumpHals(int out_fd=STDOUT_FILENO)1428*38e8c45fSAndroid Build Coastguard Worker static void DumpHals(int out_fd = STDOUT_FILENO) {
1429*38e8c45fSAndroid Build Coastguard Worker RunCommand("HARDWARE HALS", {"lshal", "--all", "--types=all"},
1430*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).AsRootIfAvailable().Build(),
1431*38e8c45fSAndroid Build Coastguard Worker false, out_fd);
1432*38e8c45fSAndroid Build Coastguard Worker
1433*38e8c45fSAndroid Build Coastguard Worker using android::hidl::manager::V1_0::IServiceManager;
1434*38e8c45fSAndroid Build Coastguard Worker using android::hardware::defaultServiceManager;
1435*38e8c45fSAndroid Build Coastguard Worker
1436*38e8c45fSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
1437*38e8c45fSAndroid Build Coastguard Worker if (sm == nullptr) {
1438*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not retrieve hwservicemanager to dump hals.\n");
1439*38e8c45fSAndroid Build Coastguard Worker return;
1440*38e8c45fSAndroid Build Coastguard Worker }
1441*38e8c45fSAndroid Build Coastguard Worker
1442*38e8c45fSAndroid Build Coastguard Worker auto ret = sm->list([&](const auto& interfaces) {
1443*38e8c45fSAndroid Build Coastguard Worker for (const std::string& interface : interfaces) {
1444*38e8c45fSAndroid Build Coastguard Worker std::string cleanName = interface;
1445*38e8c45fSAndroid Build Coastguard Worker std::replace_if(
1446*38e8c45fSAndroid Build Coastguard Worker cleanName.begin(), cleanName.end(),
1447*38e8c45fSAndroid Build Coastguard Worker [](char c) {
1448*38e8c45fSAndroid Build Coastguard Worker return !isalnum(c) && std::string("@-_.").find(c) == std::string::npos;
1449*38e8c45fSAndroid Build Coastguard Worker },
1450*38e8c45fSAndroid Build Coastguard Worker '_');
1451*38e8c45fSAndroid Build Coastguard Worker const std::string path = ds.bugreport_internal_dir_ + "/lshal_debug_" + cleanName;
1452*38e8c45fSAndroid Build Coastguard Worker
1453*38e8c45fSAndroid Build Coastguard Worker bool empty = false;
1454*38e8c45fSAndroid Build Coastguard Worker {
1455*38e8c45fSAndroid Build Coastguard Worker auto fd = android::base::unique_fd(
1456*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(open(path.c_str(),
1457*38e8c45fSAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
1458*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
1459*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
1460*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open %s to dump additional hal information.\n", path.c_str());
1461*38e8c45fSAndroid Build Coastguard Worker continue;
1462*38e8c45fSAndroid Build Coastguard Worker }
1463*38e8c45fSAndroid Build Coastguard Worker RunCommandToFd(fd,
1464*38e8c45fSAndroid Build Coastguard Worker "",
1465*38e8c45fSAndroid Build Coastguard Worker {"lshal", "debug", "-E", interface},
1466*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
1467*38e8c45fSAndroid Build Coastguard Worker
1468*38e8c45fSAndroid Build Coastguard Worker empty = 0 == lseek(fd, 0, SEEK_END);
1469*38e8c45fSAndroid Build Coastguard Worker }
1470*38e8c45fSAndroid Build Coastguard Worker if (!empty) {
1471*38e8c45fSAndroid Build Coastguard Worker ds.EnqueueAddZipEntryAndCleanupIfNeeded("lshal-debug/" + cleanName + ".txt",
1472*38e8c45fSAndroid Build Coastguard Worker path);
1473*38e8c45fSAndroid Build Coastguard Worker } else {
1474*38e8c45fSAndroid Build Coastguard Worker unlink(path.c_str());
1475*38e8c45fSAndroid Build Coastguard Worker }
1476*38e8c45fSAndroid Build Coastguard Worker }
1477*38e8c45fSAndroid Build Coastguard Worker });
1478*38e8c45fSAndroid Build Coastguard Worker
1479*38e8c45fSAndroid Build Coastguard Worker if (!ret.isOk()) {
1480*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not list hals from hwservicemanager.\n");
1481*38e8c45fSAndroid Build Coastguard Worker }
1482*38e8c45fSAndroid Build Coastguard Worker }
1483*38e8c45fSAndroid Build Coastguard Worker
1484*38e8c45fSAndroid Build Coastguard Worker // Dump all of the files that make up the vendor interface.
1485*38e8c45fSAndroid Build Coastguard Worker // See the files listed in dumpFileList() for the latest list of files.
DumpVintf()1486*38e8c45fSAndroid Build Coastguard Worker static void DumpVintf() {
1487*38e8c45fSAndroid Build Coastguard Worker
1488*38e8c45fSAndroid Build Coastguard Worker const std::string sku = android::base::GetProperty("ro.boot.product.hardware.sku", "");
1489*38e8c45fSAndroid Build Coastguard Worker const auto vintfFiles = android::vintf::details::dumpFileList(sku);
1490*38e8c45fSAndroid Build Coastguard Worker for (const auto vintfFile : vintfFiles) {
1491*38e8c45fSAndroid Build Coastguard Worker struct stat st;
1492*38e8c45fSAndroid Build Coastguard Worker if (stat(vintfFile.c_str(), &st) == 0) {
1493*38e8c45fSAndroid Build Coastguard Worker if (S_ISDIR(st.st_mode)) {
1494*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(vintfFile, true /* recursive */);
1495*38e8c45fSAndroid Build Coastguard Worker } else {
1496*38e8c45fSAndroid Build Coastguard Worker ds.EnqueueAddZipEntryAndCleanupIfNeeded(ZIP_ROOT_DIR + vintfFile,
1497*38e8c45fSAndroid Build Coastguard Worker vintfFile);
1498*38e8c45fSAndroid Build Coastguard Worker }
1499*38e8c45fSAndroid Build Coastguard Worker }
1500*38e8c45fSAndroid Build Coastguard Worker }
1501*38e8c45fSAndroid Build Coastguard Worker }
1502*38e8c45fSAndroid Build Coastguard Worker
DumpExternalFragmentationInfo()1503*38e8c45fSAndroid Build Coastguard Worker static void DumpExternalFragmentationInfo() {
1504*38e8c45fSAndroid Build Coastguard Worker struct stat st;
1505*38e8c45fSAndroid Build Coastguard Worker if (stat("/proc/buddyinfo", &st) != 0) {
1506*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to dump external fragmentation info\n");
1507*38e8c45fSAndroid Build Coastguard Worker return;
1508*38e8c45fSAndroid Build Coastguard Worker }
1509*38e8c45fSAndroid Build Coastguard Worker
1510*38e8c45fSAndroid Build Coastguard Worker printf("------ EXTERNAL FRAGMENTATION INFO ------\n");
1511*38e8c45fSAndroid Build Coastguard Worker std::ifstream ifs("/proc/buddyinfo");
1512*38e8c45fSAndroid Build Coastguard Worker auto unusable_index_regex = std::regex{"Node\\s+([0-9]+),\\s+zone\\s+(\\S+)\\s+(.*)"};
1513*38e8c45fSAndroid Build Coastguard Worker for (std::string line; std::getline(ifs, line);) {
1514*38e8c45fSAndroid Build Coastguard Worker std::smatch match_results;
1515*38e8c45fSAndroid Build Coastguard Worker if (std::regex_match(line, match_results, unusable_index_regex)) {
1516*38e8c45fSAndroid Build Coastguard Worker std::stringstream free_pages(std::string{match_results[3]});
1517*38e8c45fSAndroid Build Coastguard Worker std::vector<int> free_pages_per_order(std::istream_iterator<int>{free_pages},
1518*38e8c45fSAndroid Build Coastguard Worker std::istream_iterator<int>());
1519*38e8c45fSAndroid Build Coastguard Worker
1520*38e8c45fSAndroid Build Coastguard Worker int total_free_pages = 0;
1521*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < free_pages_per_order.size(); i++) {
1522*38e8c45fSAndroid Build Coastguard Worker total_free_pages += (free_pages_per_order[i] * std::pow(2, i));
1523*38e8c45fSAndroid Build Coastguard Worker }
1524*38e8c45fSAndroid Build Coastguard Worker
1525*38e8c45fSAndroid Build Coastguard Worker printf("Node %s, zone %8s", match_results[1].str().c_str(),
1526*38e8c45fSAndroid Build Coastguard Worker match_results[2].str().c_str());
1527*38e8c45fSAndroid Build Coastguard Worker
1528*38e8c45fSAndroid Build Coastguard Worker int usable_free_pages = total_free_pages;
1529*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < free_pages_per_order.size(); i++) {
1530*38e8c45fSAndroid Build Coastguard Worker auto unusable_index = (total_free_pages - usable_free_pages) /
1531*38e8c45fSAndroid Build Coastguard Worker static_cast<double>(total_free_pages);
1532*38e8c45fSAndroid Build Coastguard Worker printf(" %5.3f", unusable_index);
1533*38e8c45fSAndroid Build Coastguard Worker usable_free_pages -= (free_pages_per_order[i] * std::pow(2, i));
1534*38e8c45fSAndroid Build Coastguard Worker }
1535*38e8c45fSAndroid Build Coastguard Worker
1536*38e8c45fSAndroid Build Coastguard Worker printf("\n");
1537*38e8c45fSAndroid Build Coastguard Worker }
1538*38e8c45fSAndroid Build Coastguard Worker }
1539*38e8c45fSAndroid Build Coastguard Worker printf("\n");
1540*38e8c45fSAndroid Build Coastguard Worker }
1541*38e8c45fSAndroid Build Coastguard Worker
DumpstateLimitedOnly()1542*38e8c45fSAndroid Build Coastguard Worker static void DumpstateLimitedOnly() {
1543*38e8c45fSAndroid Build Coastguard Worker // Trimmed-down version of dumpstate to only include a allowlisted
1544*38e8c45fSAndroid Build Coastguard Worker // set of logs (system log, event log, and system server / system app
1545*38e8c45fSAndroid Build Coastguard Worker // crashes, and networking logs). See b/136273873 and b/138459828
1546*38e8c45fSAndroid Build Coastguard Worker // for context.
1547*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMPSTATE");
1548*38e8c45fSAndroid Build Coastguard Worker unsigned long timeout_ms;
1549*38e8c45fSAndroid Build Coastguard Worker // calculate timeout
1550*38e8c45fSAndroid Build Coastguard Worker timeout_ms = logcat_timeout({"main", "system", "crash"});
1551*38e8c45fSAndroid Build Coastguard Worker RunCommand("SYSTEM LOG",
1552*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1553*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build());
1554*38e8c45fSAndroid Build Coastguard Worker timeout_ms = logcat_timeout({"events"});
1555*38e8c45fSAndroid Build Coastguard Worker RunCommand(
1556*38e8c45fSAndroid Build Coastguard Worker "EVENT LOG",
1557*38e8c45fSAndroid Build Coastguard Worker {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
1558*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeoutInMs(timeout_ms).Build());
1559*38e8c45fSAndroid Build Coastguard Worker
1560*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1561*38e8c45fSAndroid Build Coastguard Worker printf("== Networking Service\n");
1562*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1563*38e8c45fSAndroid Build Coastguard Worker
1564*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS NETWORK_SERVICE_LIMITED", {"wifi", "-a"},
1565*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
1566*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS CONNECTIVITY REQUESTS", {"connectivity", "requests"},
1567*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
1568*38e8c45fSAndroid Build Coastguard Worker
1569*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1570*38e8c45fSAndroid Build Coastguard Worker printf("== Networking Policy\n");
1571*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1572*38e8c45fSAndroid Build Coastguard Worker
1573*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS NETWORK POLICY", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(),
1574*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
1575*38e8c45fSAndroid Build Coastguard Worker
1576*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1577*38e8c45fSAndroid Build Coastguard Worker printf("== Dropbox crashes\n");
1578*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1579*38e8c45fSAndroid Build Coastguard Worker
1580*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {"dropbox", "-p", "system_server_crash"});
1581*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DROPBOX SYSTEM APP CRASHES", {"dropbox", "-p", "system_app_crash"});
1582*38e8c45fSAndroid Build Coastguard Worker
1583*38e8c45fSAndroid Build Coastguard Worker
1584*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1585*38e8c45fSAndroid Build Coastguard Worker printf("== ANR Traces\n");
1586*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1587*38e8c45fSAndroid Build Coastguard Worker
1588*38e8c45fSAndroid Build Coastguard Worker ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX);
1589*38e8c45fSAndroid Build Coastguard Worker AddAnrTraceFiles();
1590*38e8c45fSAndroid Build Coastguard Worker
1591*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1592*38e8c45fSAndroid Build Coastguard Worker printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
1593*38e8c45fSAndroid Build Coastguard Worker ds.progress_->GetMax(), ds.progress_->GetInitialMax());
1594*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1595*38e8c45fSAndroid Build Coastguard Worker printf("== dumpstate: done (id %d)\n", ds.id_);
1596*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1597*38e8c45fSAndroid Build Coastguard Worker }
1598*38e8c45fSAndroid Build Coastguard Worker
1599*38e8c45fSAndroid Build Coastguard Worker /*
1600*38e8c45fSAndroid Build Coastguard Worker * |out_fd| A fd to support the DumpPool to output results to a temporary file.
1601*38e8c45fSAndroid Build Coastguard Worker * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO
1602*38e8c45fSAndroid Build Coastguard Worker * if it's not running in the parallel task.
1603*38e8c45fSAndroid Build Coastguard Worker */
DumpCheckins(int out_fd=STDOUT_FILENO)1604*38e8c45fSAndroid Build Coastguard Worker static void DumpCheckins(int out_fd = STDOUT_FILENO) {
1605*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1606*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Checkins\n");
1607*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1608*38e8c45fSAndroid Build Coastguard Worker
1609*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"}, out_fd);
1610*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN NETSTATS", {"netstats", "--checkin"}, out_fd);
1611*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN PROCSTATS", {"procstats", "-c"}, out_fd);
1612*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN USAGESTATS", {"usagestats", "-c"}, out_fd);
1613*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN PACKAGE", {"package", "--checkin"}, out_fd);
1614*38e8c45fSAndroid Build Coastguard Worker }
1615*38e8c45fSAndroid Build Coastguard Worker
1616*38e8c45fSAndroid Build Coastguard Worker /*
1617*38e8c45fSAndroid Build Coastguard Worker * Runs dumpsys on activity service to dump all application activities, services
1618*38e8c45fSAndroid Build Coastguard Worker * and providers in the device.
1619*38e8c45fSAndroid Build Coastguard Worker *
1620*38e8c45fSAndroid Build Coastguard Worker * |out_fd| A fd to support the DumpPool to output results to a temporary file.
1621*38e8c45fSAndroid Build Coastguard Worker * Dumpstate can pick up later and output to the bugreport. Using STDOUT_FILENO
1622*38e8c45fSAndroid Build Coastguard Worker * if it's not running in the parallel task.
1623*38e8c45fSAndroid Build Coastguard Worker */
DumpAppInfos(int out_fd=STDOUT_FILENO)1624*38e8c45fSAndroid Build Coastguard Worker static void DumpAppInfos(int out_fd = STDOUT_FILENO) {
1625*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1626*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Running Application Activities\n");
1627*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1628*38e8c45fSAndroid Build Coastguard Worker
1629*38e8c45fSAndroid Build Coastguard Worker // The following dumpsys internally collects output from running apps, so it can take a long
1630*38e8c45fSAndroid Build Coastguard Worker // time. So let's extend the timeout.
1631*38e8c45fSAndroid Build Coastguard Worker
1632*38e8c45fSAndroid Build Coastguard Worker const CommandOptions DUMPSYS_COMPONENTS_OPTIONS = CommandOptions::WithTimeout(60).Build();
1633*38e8c45fSAndroid Build Coastguard Worker
1634*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP ACTIVITIES", {"activity", "-v", "all"}, DUMPSYS_COMPONENTS_OPTIONS, 0, out_fd);
1635*38e8c45fSAndroid Build Coastguard Worker
1636*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1637*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Running Application Services (platform)\n");
1638*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1639*38e8c45fSAndroid Build Coastguard Worker
1640*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP SERVICES PLATFORM", {"activity", "service", "all-platform-non-critical"},
1641*38e8c45fSAndroid Build Coastguard Worker DUMPSYS_COMPONENTS_OPTIONS, 0, out_fd);
1642*38e8c45fSAndroid Build Coastguard Worker
1643*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1644*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Running Application Services (non-platform)\n");
1645*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1646*38e8c45fSAndroid Build Coastguard Worker
1647*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP SERVICES NON-PLATFORM", {"activity", "service", "all-non-platform"},
1648*38e8c45fSAndroid Build Coastguard Worker DUMPSYS_COMPONENTS_OPTIONS, 0, out_fd);
1649*38e8c45fSAndroid Build Coastguard Worker
1650*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1651*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Running Application Providers (platform)\n");
1652*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1653*38e8c45fSAndroid Build Coastguard Worker
1654*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP PROVIDERS PLATFORM", {"activity", "provider", "all-platform"},
1655*38e8c45fSAndroid Build Coastguard Worker DUMPSYS_COMPONENTS_OPTIONS, 0, out_fd);
1656*38e8c45fSAndroid Build Coastguard Worker
1657*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1658*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Running Application Providers (non-platform)\n");
1659*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
1660*38e8c45fSAndroid Build Coastguard Worker
1661*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP PROVIDERS NON-PLATFORM", {"activity", "provider", "all-non-platform"},
1662*38e8c45fSAndroid Build Coastguard Worker DUMPSYS_COMPONENTS_OPTIONS, 0, out_fd);
1663*38e8c45fSAndroid Build Coastguard Worker }
1664*38e8c45fSAndroid Build Coastguard Worker
1665*38e8c45fSAndroid Build Coastguard Worker // Dumps various things. Returns early with status USER_CONSENT_DENIED if user denies consent
1666*38e8c45fSAndroid Build Coastguard Worker // via the consent they are shown. Ignores other errors that occur while running various
1667*38e8c45fSAndroid Build Coastguard Worker // commands. The consent checking is currently done around long running tasks, which happen to
1668*38e8c45fSAndroid Build Coastguard Worker // be distributed fairly evenly throughout the function.
dumpstate()1669*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::dumpstate() {
1670*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMPSTATE");
1671*38e8c45fSAndroid Build Coastguard Worker
1672*38e8c45fSAndroid Build Coastguard Worker // Enqueue slow functions into the thread pool, if the parallel run is enabled.
1673*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins,
1674*38e8c45fSAndroid Build Coastguard Worker dump_netstats_report;
1675*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1676*38e8c45fSAndroid Build Coastguard Worker // Pool was shutdown in DumpstateDefaultAfterCritical method in order to
1677*38e8c45fSAndroid Build Coastguard Worker // drop root user. Restarts it.
1678*38e8c45fSAndroid Build Coastguard Worker ds.dump_pool_->start(/* thread_counts = */3);
1679*38e8c45fSAndroid Build Coastguard Worker
1680*38e8c45fSAndroid Build Coastguard Worker dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1);
1681*38e8c45fSAndroid Build Coastguard Worker dump_incident_report = ds.dump_pool_->enqueueTask(
1682*38e8c45fSAndroid Build Coastguard Worker DUMP_INCIDENT_REPORT_TASK, &DumpIncidentReport);
1683*38e8c45fSAndroid Build Coastguard Worker dump_netstats_report = ds.dump_pool_->enqueueTask(
1684*38e8c45fSAndroid Build Coastguard Worker DUMP_NETSTATS_PROTO_TASK, &DumpNetstatsProto);
1685*38e8c45fSAndroid Build Coastguard Worker dump_board = ds.dump_pool_->enqueueTaskWithFd(
1686*38e8c45fSAndroid Build Coastguard Worker DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1);
1687*38e8c45fSAndroid Build Coastguard Worker dump_checkins = ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1);
1688*38e8c45fSAndroid Build Coastguard Worker }
1689*38e8c45fSAndroid Build Coastguard Worker
1690*38e8c45fSAndroid Build Coastguard Worker // Dump various things. Note that anything that takes "long" (i.e. several seconds) should
1691*38e8c45fSAndroid Build Coastguard Worker // check intermittently (if it's intrerruptable like a foreach on pids) and/or should be wrapped
1692*38e8c45fSAndroid Build Coastguard Worker // in a consent check (via RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK).
1693*38e8c45fSAndroid Build Coastguard Worker dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
1694*38e8c45fSAndroid Build Coastguard Worker RunCommand("UPTIME", {"uptime"});
1695*38e8c45fSAndroid Build Coastguard Worker DumpBlockStatFiles();
1696*38e8c45fSAndroid Build Coastguard Worker DumpFile("MEMORY INFO", "/proc/meminfo");
1697*38e8c45fSAndroid Build Coastguard Worker RunCommand("CPU INFO", {"top", "-b", "-n", "1", "-H", "-s", "6", "-o",
1698*38e8c45fSAndroid Build Coastguard Worker "pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name"});
1699*38e8c45fSAndroid Build Coastguard Worker
1700*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(RunCommand, "BUGREPORT_PROCDUMP", {"bugreport_procdump"},
1701*38e8c45fSAndroid Build Coastguard Worker CommandOptions::AS_ROOT);
1702*38e8c45fSAndroid Build Coastguard Worker
1703*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(DumpVisibleWindowViews);
1704*38e8c45fSAndroid Build Coastguard Worker
1705*38e8c45fSAndroid Build Coastguard Worker DumpFile("VIRTUAL MEMORY STATS", "/proc/vmstat");
1706*38e8c45fSAndroid Build Coastguard Worker DumpFile("VMALLOC INFO", "/proc/vmallocinfo");
1707*38e8c45fSAndroid Build Coastguard Worker DumpFile("SLAB INFO", "/proc/slabinfo");
1708*38e8c45fSAndroid Build Coastguard Worker DumpFile("ZONEINFO", "/proc/zoneinfo");
1709*38e8c45fSAndroid Build Coastguard Worker DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo");
1710*38e8c45fSAndroid Build Coastguard Worker DumpFile("BUDDYINFO", "/proc/buddyinfo");
1711*38e8c45fSAndroid Build Coastguard Worker DumpExternalFragmentationInfo();
1712*38e8c45fSAndroid Build Coastguard Worker
1713*38e8c45fSAndroid Build Coastguard Worker DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
1714*38e8c45fSAndroid Build Coastguard Worker
1715*38e8c45fSAndroid Build Coastguard Worker RunCommand("PROCESSES AND THREADS",
1716*38e8c45fSAndroid Build Coastguard Worker {"ps", "-A", "-T", "-Z", "-O", "pri,nice,rtprio,sched,pcy,time"});
1717*38e8c45fSAndroid Build Coastguard Worker
1718*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1719*38e8c45fSAndroid Build Coastguard Worker WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_hals));
1720*38e8c45fSAndroid Build Coastguard Worker } else {
1721*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_HALS_TASK, DumpHals);
1722*38e8c45fSAndroid Build Coastguard Worker }
1723*38e8c45fSAndroid Build Coastguard Worker
1724*38e8c45fSAndroid Build Coastguard Worker RunCommand("PRINTENV", {"printenv"});
1725*38e8c45fSAndroid Build Coastguard Worker RunCommand("NETSTAT", {"netstat", "-nW"});
1726*38e8c45fSAndroid Build Coastguard Worker struct stat s;
1727*38e8c45fSAndroid Build Coastguard Worker if (stat("/proc/modules", &s) != 0) {
1728*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Skipping 'lsmod' because /proc/modules does not exist\n");
1729*38e8c45fSAndroid Build Coastguard Worker } else {
1730*38e8c45fSAndroid Build Coastguard Worker RunCommand("LSMOD", {"lsmod"});
1731*38e8c45fSAndroid Build Coastguard Worker RunCommand("MODULES INFO",
1732*38e8c45fSAndroid Build Coastguard Worker {"sh", "-c", "cat /proc/modules | cut -d' ' -f1 | "
1733*38e8c45fSAndroid Build Coastguard Worker " while read MOD ; do echo modinfo:$MOD ; modinfo $MOD ; "
1734*38e8c45fSAndroid Build Coastguard Worker "done"}, CommandOptions::AS_ROOT);
1735*38e8c45fSAndroid Build Coastguard Worker }
1736*38e8c45fSAndroid Build Coastguard Worker
1737*38e8c45fSAndroid Build Coastguard Worker if (android::base::GetBoolProperty("ro.logd.kernel", false)) {
1738*38e8c45fSAndroid Build Coastguard Worker DoKernelLogcat();
1739*38e8c45fSAndroid Build Coastguard Worker } else {
1740*38e8c45fSAndroid Build Coastguard Worker do_dmesg();
1741*38e8c45fSAndroid Build Coastguard Worker }
1742*38e8c45fSAndroid Build Coastguard Worker
1743*38e8c45fSAndroid Build Coastguard Worker DumpVintf();
1744*38e8c45fSAndroid Build Coastguard Worker
1745*38e8c45fSAndroid Build Coastguard Worker RunCommand("LIST OF OPEN FILES", {"lsof"}, CommandOptions::AS_ROOT);
1746*38e8c45fSAndroid Build Coastguard Worker
1747*38e8c45fSAndroid Build Coastguard Worker for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
1748*38e8c45fSAndroid Build Coastguard Worker for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)");
1749*38e8c45fSAndroid Build Coastguard Worker
1750*38e8c45fSAndroid Build Coastguard Worker /* Dump Nfc NCI logs */
1751*38e8c45fSAndroid Build Coastguard Worker ds.AddDir("/data/misc/nfc/logs", true);
1752*38e8c45fSAndroid Build Coastguard Worker
1753*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->do_screenshot && !ds.do_early_screenshot_) {
1754*38e8c45fSAndroid Build Coastguard Worker MYLOGI("taking late screenshot\n");
1755*38e8c45fSAndroid Build Coastguard Worker ds.TakeScreenshot();
1756*38e8c45fSAndroid Build Coastguard Worker }
1757*38e8c45fSAndroid Build Coastguard Worker
1758*38e8c45fSAndroid Build Coastguard Worker AddAnrTraceFiles();
1759*38e8c45fSAndroid Build Coastguard Worker
1760*38e8c45fSAndroid Build Coastguard Worker MaybeAddSystemTraceToZip();
1761*38e8c45fSAndroid Build Coastguard Worker
1762*38e8c45fSAndroid Build Coastguard Worker // NOTE: tombstones are always added as separate entries in the zip archive
1763*38e8c45fSAndroid Build Coastguard Worker // and are not interspersed with the main report.
1764*38e8c45fSAndroid Build Coastguard Worker const bool tombstones_dumped = AddDumps(ds.tombstone_data_.begin(), ds.tombstone_data_.end(),
1765*38e8c45fSAndroid Build Coastguard Worker "TOMBSTONE", true /* add_to_zip */);
1766*38e8c45fSAndroid Build Coastguard Worker if (!tombstones_dumped) {
1767*38e8c45fSAndroid Build Coastguard Worker printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR.c_str());
1768*38e8c45fSAndroid Build Coastguard Worker }
1769*38e8c45fSAndroid Build Coastguard Worker
1770*38e8c45fSAndroid Build Coastguard Worker DumpPacketStats();
1771*38e8c45fSAndroid Build Coastguard Worker
1772*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("EBPF MAP STATS", {"connectivity", "trafficcontroller"});
1773*38e8c45fSAndroid Build Coastguard Worker
1774*38e8c45fSAndroid Build Coastguard Worker DoKmsg();
1775*38e8c45fSAndroid Build Coastguard Worker
1776*38e8c45fSAndroid Build Coastguard Worker DumpShutdownCheckpoints();
1777*38e8c45fSAndroid Build Coastguard Worker
1778*38e8c45fSAndroid Build Coastguard Worker DumpIpAddrAndRules();
1779*38e8c45fSAndroid Build Coastguard Worker
1780*38e8c45fSAndroid Build Coastguard Worker dump_route_tables();
1781*38e8c45fSAndroid Build Coastguard Worker
1782*38e8c45fSAndroid Build Coastguard Worker RunCommand("ARP CACHE", {"ip", "-4", "neigh", "show"});
1783*38e8c45fSAndroid Build Coastguard Worker RunCommand("IPv6 ND CACHE", {"ip", "-6", "neigh", "show"});
1784*38e8c45fSAndroid Build Coastguard Worker RunCommand("MULTICAST ADDRESSES", {"ip", "maddr"});
1785*38e8c45fSAndroid Build Coastguard Worker
1786*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(RunDumpsysHigh);
1787*38e8c45fSAndroid Build Coastguard Worker
1788*38e8c45fSAndroid Build Coastguard Worker // The dump mechanism in connectivity is refactored due to modularization work. Connectivity can
1789*38e8c45fSAndroid Build Coastguard Worker // only register with a default priority(NORMAL priority). Dumpstate has to call connectivity
1790*38e8c45fSAndroid Build Coastguard Worker // dump with priority parameters to dump high priority information.
1791*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("SERVICE HIGH connectivity", {"connectivity", "--dump-priority", "HIGH"},
1792*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Build());
1793*38e8c45fSAndroid Build Coastguard Worker
1794*38e8c45fSAndroid Build Coastguard Worker RunCommand("SYSTEM PROPERTIES", {"getprop"});
1795*38e8c45fSAndroid Build Coastguard Worker
1796*38e8c45fSAndroid Build Coastguard Worker DumpFile("SYSTEM BUILD-TIME RELEASE FLAGS", "/system/etc/build_flags.json");
1797*38e8c45fSAndroid Build Coastguard Worker DumpFile("SYSTEM_EXT BUILD-TIME RELEASE FLAGS", "/system_ext/etc/build_flags.json");
1798*38e8c45fSAndroid Build Coastguard Worker DumpFile("PRODUCT BUILD-TIME RELEASE FLAGS", "/product/etc/build_flags.json");
1799*38e8c45fSAndroid Build Coastguard Worker DumpFile("VENDOR BUILD-TIME RELEASE FLAGS", "/vendor/etc/build_flags.json");
1800*38e8c45fSAndroid Build Coastguard Worker
1801*38e8c45fSAndroid Build Coastguard Worker RunCommand("ACONFIG FLAGS", {PRINT_FLAGS},
1802*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().DropRoot().Build());
1803*38e8c45fSAndroid Build Coastguard Worker RunCommand("ACONFIG FLAGS DUMP", {AFLAGS, "list"},
1804*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build());
1805*38e8c45fSAndroid Build Coastguard Worker RunCommand("WHICH ACONFIG FLAG STORAGE", {AFLAGS, "which-backing"},
1806*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build());
1807*38e8c45fSAndroid Build Coastguard Worker
1808*38e8c45fSAndroid Build Coastguard Worker RunCommand("STORAGED IO INFO", {"storaged", "-u", "-p"});
1809*38e8c45fSAndroid Build Coastguard Worker
1810*38e8c45fSAndroid Build Coastguard Worker RunCommand("FILESYSTEMS & FREE SPACE", {"df"});
1811*38e8c45fSAndroid Build Coastguard Worker
1812*38e8c45fSAndroid Build Coastguard Worker /* Binder state is expensive to look at as it uses a lot of memory. */
1813*38e8c45fSAndroid Build Coastguard Worker std::string binder_logs_dir = access("/dev/binderfs/binder_logs", R_OK) ?
1814*38e8c45fSAndroid Build Coastguard Worker "/sys/kernel/debug/binder" : "/dev/binderfs/binder_logs";
1815*38e8c45fSAndroid Build Coastguard Worker
1816*38e8c45fSAndroid Build Coastguard Worker DumpFile("BINDER FAILED TRANSACTION LOG", binder_logs_dir + "/failed_transaction_log");
1817*38e8c45fSAndroid Build Coastguard Worker DumpFile("BINDER TRANSACTION LOG", binder_logs_dir + "/transaction_log");
1818*38e8c45fSAndroid Build Coastguard Worker DumpFile("BINDER TRANSACTIONS", binder_logs_dir + "/transactions");
1819*38e8c45fSAndroid Build Coastguard Worker DumpFile("BINDER STATS", binder_logs_dir + "/stats");
1820*38e8c45fSAndroid Build Coastguard Worker DumpFile("BINDER STATE", binder_logs_dir + "/state");
1821*38e8c45fSAndroid Build Coastguard Worker
1822*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(SNAPSHOTCTL_LOG_DIR, false);
1823*38e8c45fSAndroid Build Coastguard Worker
1824*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1825*38e8c45fSAndroid Build Coastguard Worker WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_board));
1826*38e8c45fSAndroid Build Coastguard Worker } else {
1827*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_BOARD_TASK, ds.DumpstateBoard);
1828*38e8c45fSAndroid Build Coastguard Worker }
1829*38e8c45fSAndroid Build Coastguard Worker
1830*38e8c45fSAndroid Build Coastguard Worker /* Migrate the ril_dumpstate to a device specific dumpstate? */
1831*38e8c45fSAndroid Build Coastguard Worker int rilDumpstateTimeout = android::base::GetIntProperty("ril.dumpstate.timeout", 0);
1832*38e8c45fSAndroid Build Coastguard Worker if (rilDumpstateTimeout > 0) {
1833*38e8c45fSAndroid Build Coastguard Worker // su does not exist on user builds, so try running without it.
1834*38e8c45fSAndroid Build Coastguard Worker // This way any implementations of vril-dump that do not require
1835*38e8c45fSAndroid Build Coastguard Worker // root can run on user builds.
1836*38e8c45fSAndroid Build Coastguard Worker CommandOptions::CommandOptionsBuilder options =
1837*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(rilDumpstateTimeout);
1838*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsUserBuild()) {
1839*38e8c45fSAndroid Build Coastguard Worker options.AsRoot();
1840*38e8c45fSAndroid Build Coastguard Worker }
1841*38e8c45fSAndroid Build Coastguard Worker RunCommand("DUMP VENDOR RIL LOGS", {"vril-dump"}, options.Build());
1842*38e8c45fSAndroid Build Coastguard Worker }
1843*38e8c45fSAndroid Build Coastguard Worker
1844*38e8c45fSAndroid Build Coastguard Worker /* Dump USB information */
1845*38e8c45fSAndroid Build Coastguard Worker RunCommand("typec_connector_class", {"typec_connector_class"},
1846*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
1847*38e8c45fSAndroid Build Coastguard Worker RunCommand("lsusb", {"lsusb"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
1848*38e8c45fSAndroid Build Coastguard Worker
1849*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1850*38e8c45fSAndroid Build Coastguard Worker printf("== Android Framework Services\n");
1851*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1852*38e8c45fSAndroid Build Coastguard Worker
1853*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(RunDumpsysNormal);
1854*38e8c45fSAndroid Build Coastguard Worker
1855*38e8c45fSAndroid Build Coastguard Worker /* Dump Bluetooth HCI logs after getting bluetooth_manager dumpsys */
1856*38e8c45fSAndroid Build Coastguard Worker ds.AddDir("/data/misc/bluetooth/logs", true);
1857*38e8c45fSAndroid Build Coastguard Worker
1858*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1859*38e8c45fSAndroid Build Coastguard Worker WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_checkins));
1860*38e8c45fSAndroid Build Coastguard Worker } else {
1861*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_CHECKINS_TASK, DumpCheckins);
1862*38e8c45fSAndroid Build Coastguard Worker }
1863*38e8c45fSAndroid Build Coastguard Worker
1864*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK(DumpAppInfos);
1865*38e8c45fSAndroid Build Coastguard Worker
1866*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1867*38e8c45fSAndroid Build Coastguard Worker printf("== Dropbox crashes\n");
1868*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1869*38e8c45fSAndroid Build Coastguard Worker
1870*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {"dropbox", "-p", "system_server_crash"});
1871*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DROPBOX SYSTEM APP CRASHES", {"dropbox", "-p", "system_app_crash"});
1872*38e8c45fSAndroid Build Coastguard Worker
1873*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1874*38e8c45fSAndroid Build Coastguard Worker printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
1875*38e8c45fSAndroid Build Coastguard Worker ds.progress_->GetMax(), ds.progress_->GetInitialMax());
1876*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1877*38e8c45fSAndroid Build Coastguard Worker printf("== dumpstate: done (id %d)\n", ds.id_);
1878*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1879*38e8c45fSAndroid Build Coastguard Worker
1880*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1881*38e8c45fSAndroid Build Coastguard Worker printf("== Obtaining statsd metadata\n");
1882*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
1883*38e8c45fSAndroid Build Coastguard Worker // This differs from the usual dumpsys stats, which is the stats report data.
1884*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("STATSDSTATS", {"stats", "--metadata"});
1885*38e8c45fSAndroid Build Coastguard Worker
1886*38e8c45fSAndroid Build Coastguard Worker // Add linker configuration directory
1887*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(LINKERCONFIG_DIR, true);
1888*38e8c45fSAndroid Build Coastguard Worker
1889*38e8c45fSAndroid Build Coastguard Worker /* Dump frozen cgroupfs */
1890*38e8c45fSAndroid Build Coastguard Worker dump_frozen_cgroupfs();
1891*38e8c45fSAndroid Build Coastguard Worker
1892*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1893*38e8c45fSAndroid Build Coastguard Worker WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_netstats_report));
1894*38e8c45fSAndroid Build Coastguard Worker } else {
1895*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_NETSTATS_PROTO_TASK,
1896*38e8c45fSAndroid Build Coastguard Worker DumpNetstatsProto);
1897*38e8c45fSAndroid Build Coastguard Worker }
1898*38e8c45fSAndroid Build Coastguard Worker
1899*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
1900*38e8c45fSAndroid Build Coastguard Worker WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_incident_report));
1901*38e8c45fSAndroid Build Coastguard Worker } else {
1902*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_INCIDENT_REPORT_TASK,
1903*38e8c45fSAndroid Build Coastguard Worker DumpIncidentReport);
1904*38e8c45fSAndroid Build Coastguard Worker }
1905*38e8c45fSAndroid Build Coastguard Worker
1906*38e8c45fSAndroid Build Coastguard Worker MaybeAddUiTracesToZip();
1907*38e8c45fSAndroid Build Coastguard Worker
1908*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::OK;
1909*38e8c45fSAndroid Build Coastguard Worker }
1910*38e8c45fSAndroid Build Coastguard Worker
1911*38e8c45fSAndroid Build Coastguard Worker /*
1912*38e8c45fSAndroid Build Coastguard Worker * Dumps state for the default case; drops root after it's no longer necessary.
1913*38e8c45fSAndroid Build Coastguard Worker *
1914*38e8c45fSAndroid Build Coastguard Worker * Returns RunStatus::OK if everything went fine.
1915*38e8c45fSAndroid Build Coastguard Worker * Returns RunStatus::ERROR if there was an error.
1916*38e8c45fSAndroid Build Coastguard Worker * Returns RunStatus::USER_DENIED_CONSENT if user explicitly denied consent to sharing the bugreport
1917*38e8c45fSAndroid Build Coastguard Worker * with the caller.
1918*38e8c45fSAndroid Build Coastguard Worker */
DumpstateDefaultAfterCritical()1919*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::DumpstateDefaultAfterCritical() {
1920*38e8c45fSAndroid Build Coastguard Worker // Capture first logcat early on; useful to take a snapshot before dumpstate logs take over the
1921*38e8c45fSAndroid Build Coastguard Worker // buffer.
1922*38e8c45fSAndroid Build Coastguard Worker DoLogcat();
1923*38e8c45fSAndroid Build Coastguard Worker // Capture timestamp after first logcat to use in next logcat
1924*38e8c45fSAndroid Build Coastguard Worker time_t logcat_ts = time(nullptr);
1925*38e8c45fSAndroid Build Coastguard Worker
1926*38e8c45fSAndroid Build Coastguard Worker /* collect stack traces from Dalvik and native processes (needs root) */
1927*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> dump_traces;
1928*38e8c45fSAndroid Build Coastguard Worker if (dump_pool_) {
1929*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
1930*38e8c45fSAndroid Build Coastguard Worker // One thread is enough since we only need to enqueue DumpTraces here.
1931*38e8c45fSAndroid Build Coastguard Worker dump_pool_->start(/* thread_counts = */1);
1932*38e8c45fSAndroid Build Coastguard Worker
1933*38e8c45fSAndroid Build Coastguard Worker // DumpTraces takes long time, post it to the another thread in the
1934*38e8c45fSAndroid Build Coastguard Worker // pool, if pool is available
1935*38e8c45fSAndroid Build Coastguard Worker dump_traces = dump_pool_->enqueueTask(
1936*38e8c45fSAndroid Build Coastguard Worker DUMP_TRACES_TASK, &Dumpstate::DumpTraces, &ds, &dump_traces_path);
1937*38e8c45fSAndroid Build Coastguard Worker } else {
1938*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_TRACES_TASK, ds.DumpTraces,
1939*38e8c45fSAndroid Build Coastguard Worker &dump_traces_path);
1940*38e8c45fSAndroid Build Coastguard Worker }
1941*38e8c45fSAndroid Build Coastguard Worker
1942*38e8c45fSAndroid Build Coastguard Worker /* Run some operations that require root. */
1943*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsDryRun()) {
1944*38e8c45fSAndroid Build Coastguard Worker ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX);
1945*38e8c45fSAndroid Build Coastguard Worker ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX);
1946*38e8c45fSAndroid Build Coastguard Worker ds.anr_trace_data_ = GetDumpFds(ANR_DIR, ANR_TRACE_FILE_PREFIX);
1947*38e8c45fSAndroid Build Coastguard Worker ds.shutdown_checkpoints_ = GetDumpFds(
1948*38e8c45fSAndroid Build Coastguard Worker SHUTDOWN_CHECKPOINTS_DIR, SHUTDOWN_CHECKPOINTS_FILE_PREFIX);
1949*38e8c45fSAndroid Build Coastguard Worker }
1950*38e8c45fSAndroid Build Coastguard Worker
1951*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(RECOVERY_DIR, true);
1952*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(RECOVERY_DATA_DIR, true);
1953*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(UPDATE_ENGINE_LOG_DIR, true);
1954*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(UPDATE_ENGINE_PREF_DIR, true);
1955*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(LOGPERSIST_DATA_DIR, false);
1956*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsUserBuild()) {
1957*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(PROFILE_DATA_DIR_CUR, true);
1958*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(PROFILE_DATA_DIR_REF, true);
1959*38e8c45fSAndroid Build Coastguard Worker ds.AddZipEntry(ZIP_ROOT_DIR + PACKAGE_DEX_USE_LIST, PACKAGE_DEX_USE_LIST);
1960*38e8c45fSAndroid Build Coastguard Worker }
1961*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(PREREBOOT_DATA_DIR, false);
1962*38e8c45fSAndroid Build Coastguard Worker add_mountinfo();
1963*38e8c45fSAndroid Build Coastguard Worker for (const char* path : {"/proc/cpuinfo", "/proc/meminfo"}) {
1964*38e8c45fSAndroid Build Coastguard Worker ds.AddZipEntry(ZIP_ROOT_DIR + path, path);
1965*38e8c45fSAndroid Build Coastguard Worker }
1966*38e8c45fSAndroid Build Coastguard Worker DumpIpTablesAsRoot();
1967*38e8c45fSAndroid Build Coastguard Worker DumpDynamicPartitionInfo();
1968*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(OTA_METADATA_DIR, true);
1969*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsUserBuild()) {
1970*38e8c45fSAndroid Build Coastguard Worker // Include dropbox entry files inside ZIP, but exclude
1971*38e8c45fSAndroid Build Coastguard Worker // noisy WTF and StrictMode entries
1972*38e8c45fSAndroid Build Coastguard Worker dump_files("", DROPBOX_DIR, skip_wtf_strictmode, _add_file_from_fd);
1973*38e8c45fSAndroid Build Coastguard Worker }
1974*38e8c45fSAndroid Build Coastguard Worker
1975*38e8c45fSAndroid Build Coastguard Worker // Capture any IPSec policies in play. No keys are exposed here.
1976*38e8c45fSAndroid Build Coastguard Worker RunCommand("IP XFRM POLICY", {"ip", "xfrm", "policy"}, CommandOptions::WithTimeout(10).Build());
1977*38e8c45fSAndroid Build Coastguard Worker
1978*38e8c45fSAndroid Build Coastguard Worker // Dump IPsec stats. No keys are exposed here.
1979*38e8c45fSAndroid Build Coastguard Worker DumpFile("XFRM STATS", XFRM_STAT_PROC_FILE);
1980*38e8c45fSAndroid Build Coastguard Worker
1981*38e8c45fSAndroid Build Coastguard Worker // Run ss as root so we can see socket marks.
1982*38e8c45fSAndroid Build Coastguard Worker RunCommand("DETAILED SOCKET STATE", {"ss", "-eionptu"}, CommandOptions::WithTimeout(10).Build());
1983*38e8c45fSAndroid Build Coastguard Worker
1984*38e8c45fSAndroid Build Coastguard Worker // Run iotop as root to show top 100 IO threads
1985*38e8c45fSAndroid Build Coastguard Worker RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
1986*38e8c45fSAndroid Build Coastguard Worker
1987*38e8c45fSAndroid Build Coastguard Worker // Gather shared memory buffer info if the product implements it
1988*38e8c45fSAndroid Build Coastguard Worker RunCommand("Dmabuf dump", {"dmabuf_dump"});
1989*38e8c45fSAndroid Build Coastguard Worker RunCommand("Dmabuf per-buffer/per-exporter/per-device stats", {"dmabuf_dump", "-b"});
1990*38e8c45fSAndroid Build Coastguard Worker
1991*38e8c45fSAndroid Build Coastguard Worker DumpFile("PSI cpu", "/proc/pressure/cpu");
1992*38e8c45fSAndroid Build Coastguard Worker DumpFile("PSI memory", "/proc/pressure/memory");
1993*38e8c45fSAndroid Build Coastguard Worker DumpFile("PSI io", "/proc/pressure/io");
1994*38e8c45fSAndroid Build Coastguard Worker
1995*38e8c45fSAndroid Build Coastguard Worker ds.AddZipEntry(ZIP_ROOT_DIR + KERNEL_CONFIG, KERNEL_CONFIG);
1996*38e8c45fSAndroid Build Coastguard Worker
1997*38e8c45fSAndroid Build Coastguard Worker RunCommand("SDK EXTENSIONS", {SDK_EXT_INFO, "--dump"},
1998*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().DropRoot().Build());
1999*38e8c45fSAndroid Build Coastguard Worker
2000*38e8c45fSAndroid Build Coastguard Worker // Dump UWB UCI logs here because apexdata requires root access
2001*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(UWB_LOG_DIR, true);
2002*38e8c45fSAndroid Build Coastguard Worker
2003*38e8c45fSAndroid Build Coastguard Worker if (dump_pool_) {
2004*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
2005*38e8c45fSAndroid Build Coastguard Worker WaitForTask(std::move(dump_traces));
2006*38e8c45fSAndroid Build Coastguard Worker
2007*38e8c45fSAndroid Build Coastguard Worker // Current running thread in the pool is the root user also. Delete
2008*38e8c45fSAndroid Build Coastguard Worker // the pool and make a new one later to ensure none of threads in the pool are root.
2009*38e8c45fSAndroid Build Coastguard Worker dump_pool_ = std::make_unique<DumpPool>(bugreport_internal_dir_);
2010*38e8c45fSAndroid Build Coastguard Worker }
2011*38e8c45fSAndroid Build Coastguard Worker if (!DropRootUser()) {
2012*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::ERROR;
2013*38e8c45fSAndroid Build Coastguard Worker }
2014*38e8c45fSAndroid Build Coastguard Worker
2015*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
2016*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = dumpstate();
2017*38e8c45fSAndroid Build Coastguard Worker // Capture logcat since the last time we did it.
2018*38e8c45fSAndroid Build Coastguard Worker DoSystemLogcat(logcat_ts);
2019*38e8c45fSAndroid Build Coastguard Worker return status;
2020*38e8c45fSAndroid Build Coastguard Worker }
2021*38e8c45fSAndroid Build Coastguard Worker
2022*38e8c45fSAndroid Build Coastguard Worker // Common states for telephony and wifi which are needed to be collected before
2023*38e8c45fSAndroid Build Coastguard Worker // dumpstate drop the root user.
DumpstateRadioAsRoot()2024*38e8c45fSAndroid Build Coastguard Worker static void DumpstateRadioAsRoot() {
2025*38e8c45fSAndroid Build Coastguard Worker DumpIpTablesAsRoot();
2026*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(LOGPERSIST_DATA_DIR, false);
2027*38e8c45fSAndroid Build Coastguard Worker }
2028*38e8c45fSAndroid Build Coastguard Worker
2029*38e8c45fSAndroid Build Coastguard Worker // This method collects common dumpsys for telephony and wifi. Typically, wifi
2030*38e8c45fSAndroid Build Coastguard Worker // reports are fine to include all information, but telephony reports on user
2031*38e8c45fSAndroid Build Coastguard Worker // builds need to strip some content (see DumpstateTelephonyOnly).
DumpstateRadioCommon(bool include_sensitive_info=true)2032*38e8c45fSAndroid Build Coastguard Worker static void DumpstateRadioCommon(bool include_sensitive_info = true) {
2033*38e8c45fSAndroid Build Coastguard Worker // We need to be picky about some stuff for telephony reports on user builds.
2034*38e8c45fSAndroid Build Coastguard Worker if (!include_sensitive_info) {
2035*38e8c45fSAndroid Build Coastguard Worker // Only dump the radio log buffer (other buffers and dumps contain too much unrelated info).
2036*38e8c45fSAndroid Build Coastguard Worker DoRadioLogcat();
2037*38e8c45fSAndroid Build Coastguard Worker } else {
2038*38e8c45fSAndroid Build Coastguard Worker // DumpHals takes long time, post it to the another thread in the pool,
2039*38e8c45fSAndroid Build Coastguard Worker // if pool is available.
2040*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> dump_hals;
2041*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
2042*38e8c45fSAndroid Build Coastguard Worker dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1);
2043*38e8c45fSAndroid Build Coastguard Worker }
2044*38e8c45fSAndroid Build Coastguard Worker // Contains various system properties and process startup info.
2045*38e8c45fSAndroid Build Coastguard Worker do_dmesg();
2046*38e8c45fSAndroid Build Coastguard Worker // Logs other than the radio buffer may contain package/component names and potential PII.
2047*38e8c45fSAndroid Build Coastguard Worker DoLogcat();
2048*38e8c45fSAndroid Build Coastguard Worker // Too broad for connectivity problems.
2049*38e8c45fSAndroid Build Coastguard Worker DoKmsg();
2050*38e8c45fSAndroid Build Coastguard Worker // DumpHals contains unrelated hardware info (camera, NFC, biometrics, ...).
2051*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
2052*38e8c45fSAndroid Build Coastguard Worker WaitForTask(std::move(dump_hals));
2053*38e8c45fSAndroid Build Coastguard Worker } else {
2054*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_AND_LOG(DUMP_HALS_TASK, DumpHals);
2055*38e8c45fSAndroid Build Coastguard Worker }
2056*38e8c45fSAndroid Build Coastguard Worker }
2057*38e8c45fSAndroid Build Coastguard Worker
2058*38e8c45fSAndroid Build Coastguard Worker DumpPacketStats();
2059*38e8c45fSAndroid Build Coastguard Worker DumpIpAddrAndRules();
2060*38e8c45fSAndroid Build Coastguard Worker dump_route_tables();
2061*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"},
2062*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Build());
2063*38e8c45fSAndroid Build Coastguard Worker }
2064*38e8c45fSAndroid Build Coastguard Worker
2065*38e8c45fSAndroid Build Coastguard Worker // We use "telephony" here for legacy reasons, though this now really means "connectivity" (cellular
2066*38e8c45fSAndroid Build Coastguard Worker // + wifi + networking). This method collects dumpsys for connectivity debugging only. General rules
2067*38e8c45fSAndroid Build Coastguard Worker // for what can be included on user builds: all reported information MUST directly relate to
2068*38e8c45fSAndroid Build Coastguard Worker // connectivity debugging or customer support and MUST NOT contain unrelated personally identifiable
2069*38e8c45fSAndroid Build Coastguard Worker // information. This information MUST NOT identify user-installed packages (UIDs are OK, package
2070*38e8c45fSAndroid Build Coastguard Worker // names are not), and MUST NOT contain logs of user application traffic.
2071*38e8c45fSAndroid Build Coastguard Worker // TODO(b/148168577) rename this and other related fields/methods to "connectivity" instead.
DumpstateTelephonyOnly(const std::string & calling_package)2072*38e8c45fSAndroid Build Coastguard Worker static void DumpstateTelephonyOnly(const std::string& calling_package) {
2073*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMPSTATE");
2074*38e8c45fSAndroid Build Coastguard Worker
2075*38e8c45fSAndroid Build Coastguard Worker const CommandOptions DUMPSYS_COMPONENTS_OPTIONS = CommandOptions::WithTimeout(60).Build();
2076*38e8c45fSAndroid Build Coastguard Worker
2077*38e8c45fSAndroid Build Coastguard Worker const bool include_sensitive_info = !PropertiesHelper::IsUserBuild();
2078*38e8c45fSAndroid Build Coastguard Worker
2079*38e8c45fSAndroid Build Coastguard Worker DumpstateRadioAsRoot();
2080*38e8c45fSAndroid Build Coastguard Worker if (!DropRootUser()) {
2081*38e8c45fSAndroid Build Coastguard Worker return;
2082*38e8c45fSAndroid Build Coastguard Worker }
2083*38e8c45fSAndroid Build Coastguard Worker
2084*38e8c45fSAndroid Build Coastguard Worker // Starts thread pool after the root user is dropped, and two additional threads
2085*38e8c45fSAndroid Build Coastguard Worker // are created for DumpHals in the DumpstateRadioCommon and DumpstateBoard.
2086*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> dump_board;
2087*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
2088*38e8c45fSAndroid Build Coastguard Worker ds.dump_pool_->start(/*thread_counts =*/2);
2089*38e8c45fSAndroid Build Coastguard Worker
2090*38e8c45fSAndroid Build Coastguard Worker // DumpstateBoard takes long time, post it to the another thread in the pool,
2091*38e8c45fSAndroid Build Coastguard Worker // if pool is available.
2092*38e8c45fSAndroid Build Coastguard Worker dump_board = ds.dump_pool_->enqueueTaskWithFd(
2093*38e8c45fSAndroid Build Coastguard Worker DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1);
2094*38e8c45fSAndroid Build Coastguard Worker }
2095*38e8c45fSAndroid Build Coastguard Worker
2096*38e8c45fSAndroid Build Coastguard Worker DumpstateRadioCommon(include_sensitive_info);
2097*38e8c45fSAndroid Build Coastguard Worker
2098*38e8c45fSAndroid Build Coastguard Worker if (include_sensitive_info) {
2099*38e8c45fSAndroid Build Coastguard Worker // Contains too much unrelated PII, and given the unstructured nature of sysprops, we can't
2100*38e8c45fSAndroid Build Coastguard Worker // really cherrypick all of the connectivity-related ones. Apps generally have no business
2101*38e8c45fSAndroid Build Coastguard Worker // reading these anyway, and there should be APIs to supply the info in a more app-friendly
2102*38e8c45fSAndroid Build Coastguard Worker // way.
2103*38e8c45fSAndroid Build Coastguard Worker RunCommand("SYSTEM PROPERTIES", {"getprop"});
2104*38e8c45fSAndroid Build Coastguard Worker }
2105*38e8c45fSAndroid Build Coastguard Worker
2106*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2107*38e8c45fSAndroid Build Coastguard Worker printf("== Android Framework Services\n");
2108*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2109*38e8c45fSAndroid Build Coastguard Worker
2110*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
2111*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2112*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"vcn_management"}, CommandOptions::WithTimeout(90).Build(),
2113*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2114*38e8c45fSAndroid Build Coastguard Worker if (include_sensitive_info) {
2115*38e8c45fSAndroid Build Coastguard Worker // Carrier apps' services will be dumped below in dumpsys activity service all-non-platform.
2116*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
2117*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2118*38e8c45fSAndroid Build Coastguard Worker } else {
2119*38e8c45fSAndroid Build Coastguard Worker // If the caller is a carrier app and has a carrier service, dump it here since we aren't
2120*38e8c45fSAndroid Build Coastguard Worker // running dumpsys activity service all-non-platform below. Due to the increased output, we
2121*38e8c45fSAndroid Build Coastguard Worker // give a higher timeout as well.
2122*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"carrier_config", "--requesting-package", calling_package},
2123*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(30));
2124*38e8c45fSAndroid Build Coastguard Worker }
2125*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
2126*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
2127*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"network_management"}, CommandOptions::WithTimeout(90).Build(),
2128*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2129*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"telephony.registry"}, CommandOptions::WithTimeout(90).Build(),
2130*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2131*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"isub"}, CommandOptions::WithTimeout(90).Build(),
2132*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2133*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"telecom"}, CommandOptions::WithTimeout(90).Build(),
2134*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2135*38e8c45fSAndroid Build Coastguard Worker if (include_sensitive_info) {
2136*38e8c45fSAndroid Build Coastguard Worker // Contains raw IP addresses, omit from reports on user builds.
2137*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"netd"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
2138*38e8c45fSAndroid Build Coastguard Worker // Contains raw destination IP/MAC addresses, omit from reports on user builds.
2139*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"connmetrics"}, CommandOptions::WithTimeout(90).Build(),
2140*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2141*38e8c45fSAndroid Build Coastguard Worker // Contains package/component names, omit from reports on user builds.
2142*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("BATTERYSTATS", {"batterystats"}, CommandOptions::WithTimeout(90).Build(),
2143*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2144*38e8c45fSAndroid Build Coastguard Worker // Contains package names, but should be relatively simple to remove them (also contains
2145*38e8c45fSAndroid Build Coastguard Worker // UIDs already), omit from reports on user builds.
2146*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("BATTERYSTATS", {"deviceidle"}, CommandOptions::WithTimeout(90).Build(),
2147*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2148*38e8c45fSAndroid Build Coastguard Worker }
2149*38e8c45fSAndroid Build Coastguard Worker
2150*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2151*38e8c45fSAndroid Build Coastguard Worker printf("== Running Application Services\n");
2152*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2153*38e8c45fSAndroid Build Coastguard Worker
2154*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("TELEPHONY SERVICES", {"activity", "service", "TelephonyDebugService"});
2155*38e8c45fSAndroid Build Coastguard Worker
2156*38e8c45fSAndroid Build Coastguard Worker if (include_sensitive_info) {
2157*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2158*38e8c45fSAndroid Build Coastguard Worker printf("== Running Application Services (non-platform)\n");
2159*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2160*38e8c45fSAndroid Build Coastguard Worker
2161*38e8c45fSAndroid Build Coastguard Worker // Contains package/component names and potential PII, omit from reports on user builds.
2162*38e8c45fSAndroid Build Coastguard Worker // To get dumps of the active CarrierService(s) on user builds, we supply an argument to the
2163*38e8c45fSAndroid Build Coastguard Worker // carrier_config dumpsys instead.
2164*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("APP SERVICES NON-PLATFORM", {"activity", "service", "all-non-platform"},
2165*38e8c45fSAndroid Build Coastguard Worker DUMPSYS_COMPONENTS_OPTIONS);
2166*38e8c45fSAndroid Build Coastguard Worker
2167*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2168*38e8c45fSAndroid Build Coastguard Worker printf("== Checkins\n");
2169*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2170*38e8c45fSAndroid Build Coastguard Worker
2171*38e8c45fSAndroid Build Coastguard Worker // Contains package/component names, omit from reports on user builds.
2172*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
2173*38e8c45fSAndroid Build Coastguard Worker }
2174*38e8c45fSAndroid Build Coastguard Worker
2175*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2176*38e8c45fSAndroid Build Coastguard Worker printf("== dumpstate: done (id %d)\n", ds.id_);
2177*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2178*38e8c45fSAndroid Build Coastguard Worker
2179*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
2180*38e8c45fSAndroid Build Coastguard Worker WaitForTask(std::move(dump_board));
2181*38e8c45fSAndroid Build Coastguard Worker } else {
2182*38e8c45fSAndroid Build Coastguard Worker RUN_SLOW_FUNCTION_AND_LOG(DUMP_BOARD_TASK, ds.DumpstateBoard);
2183*38e8c45fSAndroid Build Coastguard Worker }
2184*38e8c45fSAndroid Build Coastguard Worker }
2185*38e8c45fSAndroid Build Coastguard Worker
2186*38e8c45fSAndroid Build Coastguard Worker // This method collects dumpsys for wifi debugging only
DumpstateWifiOnly()2187*38e8c45fSAndroid Build Coastguard Worker static void DumpstateWifiOnly() {
2188*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMPSTATE");
2189*38e8c45fSAndroid Build Coastguard Worker
2190*38e8c45fSAndroid Build Coastguard Worker DumpstateRadioAsRoot();
2191*38e8c45fSAndroid Build Coastguard Worker if (!DropRootUser()) {
2192*38e8c45fSAndroid Build Coastguard Worker return;
2193*38e8c45fSAndroid Build Coastguard Worker }
2194*38e8c45fSAndroid Build Coastguard Worker
2195*38e8c45fSAndroid Build Coastguard Worker // Starts thread pool after the root user is dropped. Only one additional
2196*38e8c45fSAndroid Build Coastguard Worker // thread is needed for DumpHals in the DumpstateRadioCommon.
2197*38e8c45fSAndroid Build Coastguard Worker if (ds.dump_pool_) {
2198*38e8c45fSAndroid Build Coastguard Worker ds.dump_pool_->start(/*thread_counts =*/1);
2199*38e8c45fSAndroid Build Coastguard Worker }
2200*38e8c45fSAndroid Build Coastguard Worker
2201*38e8c45fSAndroid Build Coastguard Worker DumpstateRadioCommon();
2202*38e8c45fSAndroid Build Coastguard Worker
2203*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2204*38e8c45fSAndroid Build Coastguard Worker printf("== Android Framework Services\n");
2205*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2206*38e8c45fSAndroid Build Coastguard Worker
2207*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
2208*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2209*38e8c45fSAndroid Build Coastguard Worker RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
2210*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(10));
2211*38e8c45fSAndroid Build Coastguard Worker
2212*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2213*38e8c45fSAndroid Build Coastguard Worker printf("== dumpstate: done (id %d)\n", ds.id_);
2214*38e8c45fSAndroid Build Coastguard Worker printf("========================================================\n");
2215*38e8c45fSAndroid Build Coastguard Worker }
2216*38e8c45fSAndroid Build Coastguard Worker
2217*38e8c45fSAndroid Build Coastguard Worker // Collects a lightweight dumpstate to be used for debugging onboarding related flows.
DumpstateOnboardingOnly()2218*38e8c45fSAndroid Build Coastguard Worker static void DumpstateOnboardingOnly() {
2219*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(LOGPERSIST_DATA_DIR, false);
2220*38e8c45fSAndroid Build Coastguard Worker }
2221*38e8c45fSAndroid Build Coastguard Worker
GetTimestamp(const timespec & ts)2222*38e8c45fSAndroid Build Coastguard Worker static std::string GetTimestamp(const timespec& ts) {
2223*38e8c45fSAndroid Build Coastguard Worker tm tm;
2224*38e8c45fSAndroid Build Coastguard Worker localtime_r(&ts.tv_sec, &tm);
2225*38e8c45fSAndroid Build Coastguard Worker
2226*38e8c45fSAndroid Build Coastguard Worker // Reserve enough space for the entire time string, includes the space
2227*38e8c45fSAndroid Build Coastguard Worker // for the '\0' to make the calculations below easier by using size for
2228*38e8c45fSAndroid Build Coastguard Worker // the total string size.
2229*38e8c45fSAndroid Build Coastguard Worker std::string str(sizeof("1970-01-01 00:00:00.123456789+0830"), '\0');
2230*38e8c45fSAndroid Build Coastguard Worker size_t n = strftime(str.data(), str.size(), "%F %H:%M", &tm);
2231*38e8c45fSAndroid Build Coastguard Worker if (n == 0) {
2232*38e8c45fSAndroid Build Coastguard Worker return "TIMESTAMP FAILURE";
2233*38e8c45fSAndroid Build Coastguard Worker }
2234*38e8c45fSAndroid Build Coastguard Worker int num_chars = snprintf(&str[n], str.size() - n, ":%02d.%09ld", tm.tm_sec, ts.tv_nsec);
2235*38e8c45fSAndroid Build Coastguard Worker if (num_chars > str.size() - n) {
2236*38e8c45fSAndroid Build Coastguard Worker return "TIMESTAMP FAILURE";
2237*38e8c45fSAndroid Build Coastguard Worker }
2238*38e8c45fSAndroid Build Coastguard Worker n += static_cast<size_t>(num_chars);
2239*38e8c45fSAndroid Build Coastguard Worker if (strftime(&str[n], str.size() - n, "%z", &tm) == 0) {
2240*38e8c45fSAndroid Build Coastguard Worker return "TIMESTAMP FAILURE";
2241*38e8c45fSAndroid Build Coastguard Worker }
2242*38e8c45fSAndroid Build Coastguard Worker return str;
2243*38e8c45fSAndroid Build Coastguard Worker }
2244*38e8c45fSAndroid Build Coastguard Worker
GetCmdline(pid_t pid)2245*38e8c45fSAndroid Build Coastguard Worker static std::string GetCmdline(pid_t pid) {
2246*38e8c45fSAndroid Build Coastguard Worker std::string cmdline;
2247*38e8c45fSAndroid Build Coastguard Worker if (!android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid),
2248*38e8c45fSAndroid Build Coastguard Worker &cmdline)) {
2249*38e8c45fSAndroid Build Coastguard Worker return "UNKNOWN";
2250*38e8c45fSAndroid Build Coastguard Worker }
2251*38e8c45fSAndroid Build Coastguard Worker // There are '\0' terminators between arguments, convert them to spaces.
2252*38e8c45fSAndroid Build Coastguard Worker // But start by skipping all trailing '\0' values.
2253*38e8c45fSAndroid Build Coastguard Worker size_t cur = cmdline.size() - 1;
2254*38e8c45fSAndroid Build Coastguard Worker while (cur != 0 && cmdline[cur] == '\0') {
2255*38e8c45fSAndroid Build Coastguard Worker cur--;
2256*38e8c45fSAndroid Build Coastguard Worker }
2257*38e8c45fSAndroid Build Coastguard Worker if (cur == 0) {
2258*38e8c45fSAndroid Build Coastguard Worker return "UNKNOWN";
2259*38e8c45fSAndroid Build Coastguard Worker }
2260*38e8c45fSAndroid Build Coastguard Worker while ((cur = cmdline.rfind('\0', cur)) != std::string::npos) {
2261*38e8c45fSAndroid Build Coastguard Worker cmdline[cur] = ' ';
2262*38e8c45fSAndroid Build Coastguard Worker }
2263*38e8c45fSAndroid Build Coastguard Worker return cmdline;
2264*38e8c45fSAndroid Build Coastguard Worker }
2265*38e8c45fSAndroid Build Coastguard Worker
DumpPidHeader(int fd,pid_t pid,const timespec & ts)2266*38e8c45fSAndroid Build Coastguard Worker static void DumpPidHeader(int fd, pid_t pid, const timespec& ts) {
2267*38e8c45fSAndroid Build Coastguard Worker // For consistency, the header to this message matches the one
2268*38e8c45fSAndroid Build Coastguard Worker // dumped by debuggerd.
2269*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "\n----- pid %d at %s -----\n", pid, GetTimestamp(ts).c_str());
2270*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "Cmd line: %s\n", GetCmdline(pid).c_str());
2271*38e8c45fSAndroid Build Coastguard Worker }
2272*38e8c45fSAndroid Build Coastguard Worker
DumpPidFooter(int fd,pid_t pid)2273*38e8c45fSAndroid Build Coastguard Worker static void DumpPidFooter(int fd, pid_t pid) {
2274*38e8c45fSAndroid Build Coastguard Worker // For consistency, the footer to this message matches the one
2275*38e8c45fSAndroid Build Coastguard Worker // dumped by debuggerd.
2276*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "----- end %d -----\n", pid);
2277*38e8c45fSAndroid Build Coastguard Worker }
2278*38e8c45fSAndroid Build Coastguard Worker
DumpBacktrace(int fd,pid_t pid,bool is_java_process)2279*38e8c45fSAndroid Build Coastguard Worker static bool DumpBacktrace(int fd, pid_t pid, bool is_java_process) {
2280*38e8c45fSAndroid Build Coastguard Worker int ret = dump_backtrace_to_file_timeout(
2281*38e8c45fSAndroid Build Coastguard Worker pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace, 3, fd);
2282*38e8c45fSAndroid Build Coastguard Worker if (ret == -1 && is_java_process) {
2283*38e8c45fSAndroid Build Coastguard Worker // Tried to unwind as a java process, try a native unwind.
2284*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "Java unwind failed for pid %d, trying a native unwind.\n", pid);
2285*38e8c45fSAndroid Build Coastguard Worker ret = dump_backtrace_to_file_timeout(pid, kDebuggerdNativeBacktrace, 3, fd);
2286*38e8c45fSAndroid Build Coastguard Worker }
2287*38e8c45fSAndroid Build Coastguard Worker return ret != -1;
2288*38e8c45fSAndroid Build Coastguard Worker }
2289*38e8c45fSAndroid Build Coastguard Worker
DumpTraces(const char ** path)2290*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::DumpTraces(const char** path) {
2291*38e8c45fSAndroid Build Coastguard Worker const std::string temp_file_pattern = ds.bugreport_internal_dir_ + "/dumptrace_XXXXXX";
2292*38e8c45fSAndroid Build Coastguard Worker const size_t buf_size = temp_file_pattern.length() + 1;
2293*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
2294*38e8c45fSAndroid Build Coastguard Worker memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);
2295*38e8c45fSAndroid Build Coastguard Worker
2296*38e8c45fSAndroid Build Coastguard Worker // Create a new, empty file to receive all trace dumps.
2297*38e8c45fSAndroid Build Coastguard Worker //
2298*38e8c45fSAndroid Build Coastguard Worker // TODO: This can be simplified once we remove support for the old style
2299*38e8c45fSAndroid Build Coastguard Worker // dumps. We can have a file descriptor passed in to dump_traces instead
2300*38e8c45fSAndroid Build Coastguard Worker // of creating a file, closing it and then reopening it again.
2301*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(mkostemp(file_name_buf.get(), O_APPEND | O_CLOEXEC));
2302*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
2303*38e8c45fSAndroid Build Coastguard Worker MYLOGE("mkostemp on pattern %s: %s\n", file_name_buf.get(), strerror(errno));
2304*38e8c45fSAndroid Build Coastguard Worker return RunStatus::OK;
2305*38e8c45fSAndroid Build Coastguard Worker }
2306*38e8c45fSAndroid Build Coastguard Worker
2307*38e8c45fSAndroid Build Coastguard Worker // Nobody should have access to this temporary file except dumpstate, but we
2308*38e8c45fSAndroid Build Coastguard Worker // temporarily grant 'read' to 'others' here because this file is created
2309*38e8c45fSAndroid Build Coastguard Worker // when tombstoned is still running as root, but dumped after dropping. This
2310*38e8c45fSAndroid Build Coastguard Worker // can go away once support for old style dumping has.
2311*38e8c45fSAndroid Build Coastguard Worker const int chmod_ret = fchmod(fd, 0666);
2312*38e8c45fSAndroid Build Coastguard Worker if (chmod_ret < 0) {
2313*38e8c45fSAndroid Build Coastguard Worker MYLOGE("fchmod on %s failed: %s\n", file_name_buf.get(), strerror(errno));
2314*38e8c45fSAndroid Build Coastguard Worker return RunStatus::OK;
2315*38e8c45fSAndroid Build Coastguard Worker }
2316*38e8c45fSAndroid Build Coastguard Worker
2317*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
2318*38e8c45fSAndroid Build Coastguard Worker if (proc.get() == nullptr) {
2319*38e8c45fSAndroid Build Coastguard Worker MYLOGE("opendir /proc failed: %s\n", strerror(errno));
2320*38e8c45fSAndroid Build Coastguard Worker return RunStatus::OK;
2321*38e8c45fSAndroid Build Coastguard Worker }
2322*38e8c45fSAndroid Build Coastguard Worker
2323*38e8c45fSAndroid Build Coastguard Worker // Number of times process dumping has timed out. If we encounter too many
2324*38e8c45fSAndroid Build Coastguard Worker // failures, we'll give up.
2325*38e8c45fSAndroid Build Coastguard Worker int timeout_failures = 0;
2326*38e8c45fSAndroid Build Coastguard Worker bool dalvik_found = false;
2327*38e8c45fSAndroid Build Coastguard Worker
2328*38e8c45fSAndroid Build Coastguard Worker const std::set<int> hal_pids = get_interesting_pids();
2329*38e8c45fSAndroid Build Coastguard Worker
2330*38e8c45fSAndroid Build Coastguard Worker struct dirent* d;
2331*38e8c45fSAndroid Build Coastguard Worker while ((d = readdir(proc.get()))) {
2332*38e8c45fSAndroid Build Coastguard Worker RETURN_IF_USER_DENIED_CONSENT();
2333*38e8c45fSAndroid Build Coastguard Worker int pid = atoi(d->d_name);
2334*38e8c45fSAndroid Build Coastguard Worker if (pid <= 0) {
2335*38e8c45fSAndroid Build Coastguard Worker continue;
2336*38e8c45fSAndroid Build Coastguard Worker }
2337*38e8c45fSAndroid Build Coastguard Worker
2338*38e8c45fSAndroid Build Coastguard Worker const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
2339*38e8c45fSAndroid Build Coastguard Worker std::string exe;
2340*38e8c45fSAndroid Build Coastguard Worker if (!android::base::Readlink(link_name, &exe)) {
2341*38e8c45fSAndroid Build Coastguard Worker continue;
2342*38e8c45fSAndroid Build Coastguard Worker }
2343*38e8c45fSAndroid Build Coastguard Worker
2344*38e8c45fSAndroid Build Coastguard Worker bool is_java_process;
2345*38e8c45fSAndroid Build Coastguard Worker if (exe == "/system/bin/app_process32" || exe == "/system/bin/app_process64") {
2346*38e8c45fSAndroid Build Coastguard Worker // Don't bother dumping backtraces for the zygote.
2347*38e8c45fSAndroid Build Coastguard Worker if (IsZygote(pid)) {
2348*38e8c45fSAndroid Build Coastguard Worker continue;
2349*38e8c45fSAndroid Build Coastguard Worker }
2350*38e8c45fSAndroid Build Coastguard Worker
2351*38e8c45fSAndroid Build Coastguard Worker dalvik_found = true;
2352*38e8c45fSAndroid Build Coastguard Worker is_java_process = true;
2353*38e8c45fSAndroid Build Coastguard Worker } else if (should_dump_native_traces(exe.c_str()) || hal_pids.find(pid) != hal_pids.end()) {
2354*38e8c45fSAndroid Build Coastguard Worker is_java_process = false;
2355*38e8c45fSAndroid Build Coastguard Worker } else {
2356*38e8c45fSAndroid Build Coastguard Worker // Probably a native process we don't care about, continue.
2357*38e8c45fSAndroid Build Coastguard Worker continue;
2358*38e8c45fSAndroid Build Coastguard Worker }
2359*38e8c45fSAndroid Build Coastguard Worker
2360*38e8c45fSAndroid Build Coastguard Worker // If 3 backtrace dumps fail in a row, consider debuggerd dead.
2361*38e8c45fSAndroid Build Coastguard Worker if (timeout_failures == 3) {
2362*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "ERROR: Too many stack dump failures, exiting.\n");
2363*38e8c45fSAndroid Build Coastguard Worker break;
2364*38e8c45fSAndroid Build Coastguard Worker }
2365*38e8c45fSAndroid Build Coastguard Worker
2366*38e8c45fSAndroid Build Coastguard Worker timespec start_timespec;
2367*38e8c45fSAndroid Build Coastguard Worker clock_gettime(CLOCK_REALTIME, &start_timespec);
2368*38e8c45fSAndroid Build Coastguard Worker if (IsCached(pid)) {
2369*38e8c45fSAndroid Build Coastguard Worker DumpPidHeader(fd, pid, start_timespec);
2370*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "Process is cached, skipping backtrace due to high chance of timeout.\n");
2371*38e8c45fSAndroid Build Coastguard Worker DumpPidFooter(fd, pid);
2372*38e8c45fSAndroid Build Coastguard Worker continue;
2373*38e8c45fSAndroid Build Coastguard Worker }
2374*38e8c45fSAndroid Build Coastguard Worker
2375*38e8c45fSAndroid Build Coastguard Worker const uint64_t start = Nanotime();
2376*38e8c45fSAndroid Build Coastguard Worker if (!DumpBacktrace(fd, pid, is_java_process)) {
2377*38e8c45fSAndroid Build Coastguard Worker if (IsCached(pid)) {
2378*38e8c45fSAndroid Build Coastguard Worker DumpPidHeader(fd, pid, start_timespec);
2379*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "Backtrace failed, but process has become cached.\n");
2380*38e8c45fSAndroid Build Coastguard Worker DumpPidFooter(fd, pid);
2381*38e8c45fSAndroid Build Coastguard Worker continue;
2382*38e8c45fSAndroid Build Coastguard Worker }
2383*38e8c45fSAndroid Build Coastguard Worker
2384*38e8c45fSAndroid Build Coastguard Worker DumpPidHeader(fd, pid, start_timespec);
2385*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "Backtrace gathering failed, likely due to a timeout.\n");
2386*38e8c45fSAndroid Build Coastguard Worker DumpPidFooter(fd, pid);
2387*38e8c45fSAndroid Build Coastguard Worker
2388*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "\n[dump %s stack %d: %.3fs elapsed]\n",
2389*38e8c45fSAndroid Build Coastguard Worker is_java_process ? "dalvik" : "native", pid,
2390*38e8c45fSAndroid Build Coastguard Worker (float)(Nanotime() - start) / NANOS_PER_SEC);
2391*38e8c45fSAndroid Build Coastguard Worker timeout_failures++;
2392*38e8c45fSAndroid Build Coastguard Worker continue;
2393*38e8c45fSAndroid Build Coastguard Worker }
2394*38e8c45fSAndroid Build Coastguard Worker
2395*38e8c45fSAndroid Build Coastguard Worker // We've successfully dumped stack traces, reset the failure count
2396*38e8c45fSAndroid Build Coastguard Worker // and write a summary of the elapsed time to the file and continue with the
2397*38e8c45fSAndroid Build Coastguard Worker // next process.
2398*38e8c45fSAndroid Build Coastguard Worker timeout_failures = 0;
2399*38e8c45fSAndroid Build Coastguard Worker
2400*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "[dump %s stack %d: %.3fs elapsed]\n", is_java_process ? "dalvik" : "native",
2401*38e8c45fSAndroid Build Coastguard Worker pid, (float)(Nanotime() - start) / NANOS_PER_SEC);
2402*38e8c45fSAndroid Build Coastguard Worker }
2403*38e8c45fSAndroid Build Coastguard Worker
2404*38e8c45fSAndroid Build Coastguard Worker if (!dalvik_found) {
2405*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
2406*38e8c45fSAndroid Build Coastguard Worker }
2407*38e8c45fSAndroid Build Coastguard Worker
2408*38e8c45fSAndroid Build Coastguard Worker *path = file_name_buf.release();
2409*38e8c45fSAndroid Build Coastguard Worker return RunStatus::OK;
2410*38e8c45fSAndroid Build Coastguard Worker }
2411*38e8c45fSAndroid Build Coastguard Worker
GetDumpstateHalModeHidl(const Dumpstate::BugreportMode bugreport_mode)2412*38e8c45fSAndroid Build Coastguard Worker static dumpstate_hal_hidl::DumpstateMode GetDumpstateHalModeHidl(
2413*38e8c45fSAndroid Build Coastguard Worker const Dumpstate::BugreportMode bugreport_mode) {
2414*38e8c45fSAndroid Build Coastguard Worker switch (bugreport_mode) {
2415*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_FULL:
2416*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::FULL;
2417*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
2418*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::INTERACTIVE;
2419*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
2420*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::REMOTE;
2421*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WEAR:
2422*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::WEAR;
2423*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
2424*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::CONNECTIVITY;
2425*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WIFI:
2426*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::WIFI;
2427*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_ONBOARDING:
2428*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
2429*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::DEFAULT;
2430*38e8c45fSAndroid Build Coastguard Worker }
2431*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_hidl::DumpstateMode::DEFAULT;
2432*38e8c45fSAndroid Build Coastguard Worker }
2433*38e8c45fSAndroid Build Coastguard Worker
GetDumpstateHalModeAidl(const Dumpstate::BugreportMode bugreport_mode)2434*38e8c45fSAndroid Build Coastguard Worker static dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode GetDumpstateHalModeAidl(
2435*38e8c45fSAndroid Build Coastguard Worker const Dumpstate::BugreportMode bugreport_mode) {
2436*38e8c45fSAndroid Build Coastguard Worker switch (bugreport_mode) {
2437*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_FULL:
2438*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::FULL;
2439*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
2440*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::INTERACTIVE;
2441*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
2442*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::REMOTE;
2443*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WEAR:
2444*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::WEAR;
2445*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
2446*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::CONNECTIVITY;
2447*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WIFI:
2448*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::WIFI;
2449*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_ONBOARDING:
2450*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
2451*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::DEFAULT;
2452*38e8c45fSAndroid Build Coastguard Worker }
2453*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::DEFAULT;
2454*38e8c45fSAndroid Build Coastguard Worker }
2455*38e8c45fSAndroid Build Coastguard Worker
DoDumpstateBoardHidl(const sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_1_0,const std::vector<::ndk::ScopedFileDescriptor> & dumpstate_fds,const Dumpstate::BugreportMode bugreport_mode,const size_t timeout_sec)2456*38e8c45fSAndroid Build Coastguard Worker static void DoDumpstateBoardHidl(
2457*38e8c45fSAndroid Build Coastguard Worker const sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_1_0,
2458*38e8c45fSAndroid Build Coastguard Worker const std::vector<::ndk::ScopedFileDescriptor>& dumpstate_fds,
2459*38e8c45fSAndroid Build Coastguard Worker const Dumpstate::BugreportMode bugreport_mode,
2460*38e8c45fSAndroid Build Coastguard Worker const size_t timeout_sec) {
2461*38e8c45fSAndroid Build Coastguard Worker
2462*38e8c45fSAndroid Build Coastguard Worker using ScopedNativeHandle =
2463*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
2464*38e8c45fSAndroid Build Coastguard Worker ScopedNativeHandle handle(native_handle_create(static_cast<int>(dumpstate_fds.size()), 0),
2465*38e8c45fSAndroid Build Coastguard Worker [](native_handle_t* handle) {
2466*38e8c45fSAndroid Build Coastguard Worker // we don't close file handle's here
2467*38e8c45fSAndroid Build Coastguard Worker // via native_handle_close(handle)
2468*38e8c45fSAndroid Build Coastguard Worker // instead we let dumpstate_fds close the file handles when
2469*38e8c45fSAndroid Build Coastguard Worker // dumpstate_fds gets destroyed
2470*38e8c45fSAndroid Build Coastguard Worker native_handle_delete(handle);
2471*38e8c45fSAndroid Build Coastguard Worker });
2472*38e8c45fSAndroid Build Coastguard Worker if (handle == nullptr) {
2473*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not create native_handle for dumpstate HAL\n");
2474*38e8c45fSAndroid Build Coastguard Worker return;
2475*38e8c45fSAndroid Build Coastguard Worker }
2476*38e8c45fSAndroid Build Coastguard Worker
2477*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < dumpstate_fds.size(); i++) {
2478*38e8c45fSAndroid Build Coastguard Worker handle.get()->data[i] = dumpstate_fds[i].get();
2479*38e8c45fSAndroid Build Coastguard Worker }
2480*38e8c45fSAndroid Build Coastguard Worker
2481*38e8c45fSAndroid Build Coastguard Worker // Prefer version 1.1 if available. New devices launching with R are no longer allowed to
2482*38e8c45fSAndroid Build Coastguard Worker // implement just 1.0.
2483*38e8c45fSAndroid Build Coastguard Worker const char* descriptor_to_kill;
2484*38e8c45fSAndroid Build Coastguard Worker using DumpstateBoardTask = std::packaged_task<bool()>;
2485*38e8c45fSAndroid Build Coastguard Worker DumpstateBoardTask dumpstate_board_task;
2486*38e8c45fSAndroid Build Coastguard Worker sp<dumpstate_hal_hidl::IDumpstateDevice> dumpstate_hal(
2487*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_hidl::IDumpstateDevice::castFrom(dumpstate_hal_1_0));
2488*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal != nullptr) {
2489*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Using IDumpstateDevice v1.1 HIDL HAL");
2490*38e8c45fSAndroid Build Coastguard Worker
2491*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_hidl::DumpstateMode dumpstate_hal_mode =
2492*38e8c45fSAndroid Build Coastguard Worker GetDumpstateHalModeHidl(bugreport_mode);
2493*38e8c45fSAndroid Build Coastguard Worker
2494*38e8c45fSAndroid Build Coastguard Worker descriptor_to_kill = dumpstate_hal_hidl::IDumpstateDevice::descriptor;
2495*38e8c45fSAndroid Build Coastguard Worker dumpstate_board_task =
2496*38e8c45fSAndroid Build Coastguard Worker DumpstateBoardTask([timeout_sec, dumpstate_hal_mode, dumpstate_hal, &handle]() -> bool {
2497*38e8c45fSAndroid Build Coastguard Worker ::android::hardware::Return<dumpstate_hal_hidl::DumpstateStatus> status =
2498*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal->dumpstateBoard_1_1(handle.get(), dumpstate_hal_mode,
2499*38e8c45fSAndroid Build Coastguard Worker SEC_TO_MSEC(timeout_sec));
2500*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
2501*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
2502*38e8c45fSAndroid Build Coastguard Worker return false;
2503*38e8c45fSAndroid Build Coastguard Worker } else if (status != dumpstate_hal_hidl::DumpstateStatus::OK) {
2504*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard failed with DumpstateStatus::%s\n",
2505*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_hidl::toString(status).c_str());
2506*38e8c45fSAndroid Build Coastguard Worker return false;
2507*38e8c45fSAndroid Build Coastguard Worker }
2508*38e8c45fSAndroid Build Coastguard Worker return true;
2509*38e8c45fSAndroid Build Coastguard Worker });
2510*38e8c45fSAndroid Build Coastguard Worker } else {
2511*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Using IDumpstateDevice v1.0 HIDL HAL");
2512*38e8c45fSAndroid Build Coastguard Worker
2513*38e8c45fSAndroid Build Coastguard Worker descriptor_to_kill = dumpstate_hal_hidl_1_0::IDumpstateDevice::descriptor;
2514*38e8c45fSAndroid Build Coastguard Worker dumpstate_board_task = DumpstateBoardTask([dumpstate_hal_1_0, &handle]() -> bool {
2515*38e8c45fSAndroid Build Coastguard Worker ::android::hardware::Return<void> status =
2516*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_1_0->dumpstateBoard(handle.get());
2517*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
2518*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
2519*38e8c45fSAndroid Build Coastguard Worker return false;
2520*38e8c45fSAndroid Build Coastguard Worker }
2521*38e8c45fSAndroid Build Coastguard Worker return true;
2522*38e8c45fSAndroid Build Coastguard Worker });
2523*38e8c45fSAndroid Build Coastguard Worker }
2524*38e8c45fSAndroid Build Coastguard Worker auto result = dumpstate_board_task.get_future();
2525*38e8c45fSAndroid Build Coastguard Worker std::thread(std::move(dumpstate_board_task)).detach();
2526*38e8c45fSAndroid Build Coastguard Worker
2527*38e8c45fSAndroid Build Coastguard Worker if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
2528*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate HAL\n", timeout_sec);
2529*38e8c45fSAndroid Build Coastguard Worker if (!android::base::SetProperty(
2530*38e8c45fSAndroid Build Coastguard Worker "ctl.interface_restart",
2531*38e8c45fSAndroid Build Coastguard Worker android::base::StringPrintf("%s/default", descriptor_to_kill))) {
2532*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Couldn't restart dumpstate HAL\n");
2533*38e8c45fSAndroid Build Coastguard Worker }
2534*38e8c45fSAndroid Build Coastguard Worker }
2535*38e8c45fSAndroid Build Coastguard Worker // Wait some time for init to kill dumpstate vendor HAL
2536*38e8c45fSAndroid Build Coastguard Worker constexpr size_t killing_timeout_sec = 10;
2537*38e8c45fSAndroid Build Coastguard Worker if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
2538*38e8c45fSAndroid Build Coastguard Worker MYLOGE(
2539*38e8c45fSAndroid Build Coastguard Worker "killing dumpstateBoard timed out after %zus, continue and "
2540*38e8c45fSAndroid Build Coastguard Worker "there might be racing in content\n",
2541*38e8c45fSAndroid Build Coastguard Worker killing_timeout_sec);
2542*38e8c45fSAndroid Build Coastguard Worker }
2543*38e8c45fSAndroid Build Coastguard Worker }
2544*38e8c45fSAndroid Build Coastguard Worker
DoDumpstateBoardAidl(const std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> dumpstate_hal,const std::vector<::ndk::ScopedFileDescriptor> & dumpstate_fds,const Dumpstate::BugreportMode bugreport_mode,const size_t timeout_sec)2545*38e8c45fSAndroid Build Coastguard Worker static void DoDumpstateBoardAidl(
2546*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> dumpstate_hal,
2547*38e8c45fSAndroid Build Coastguard Worker const std::vector<::ndk::ScopedFileDescriptor>& dumpstate_fds,
2548*38e8c45fSAndroid Build Coastguard Worker const Dumpstate::BugreportMode bugreport_mode, const size_t timeout_sec) {
2549*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Using IDumpstateDevice AIDL HAL");
2550*38e8c45fSAndroid Build Coastguard Worker
2551*38e8c45fSAndroid Build Coastguard Worker const char* descriptor_to_kill;
2552*38e8c45fSAndroid Build Coastguard Worker using DumpstateBoardTask = std::packaged_task<bool()>;
2553*38e8c45fSAndroid Build Coastguard Worker DumpstateBoardTask dumpstate_board_task;
2554*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode dumpstate_hal_mode =
2555*38e8c45fSAndroid Build Coastguard Worker GetDumpstateHalModeAidl(bugreport_mode);
2556*38e8c45fSAndroid Build Coastguard Worker
2557*38e8c45fSAndroid Build Coastguard Worker descriptor_to_kill = dumpstate_hal_aidl::IDumpstateDevice::descriptor;
2558*38e8c45fSAndroid Build Coastguard Worker dumpstate_board_task = DumpstateBoardTask([dumpstate_hal, &dumpstate_fds, dumpstate_hal_mode,
2559*38e8c45fSAndroid Build Coastguard Worker timeout_sec]() -> bool {
2560*38e8c45fSAndroid Build Coastguard Worker auto status = dumpstate_hal->dumpstateBoard(dumpstate_fds, dumpstate_hal_mode, timeout_sec);
2561*38e8c45fSAndroid Build Coastguard Worker
2562*38e8c45fSAndroid Build Coastguard Worker if (!status.isOk()) {
2563*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard failed: %s\n", status.getDescription().c_str());
2564*38e8c45fSAndroid Build Coastguard Worker return false;
2565*38e8c45fSAndroid Build Coastguard Worker }
2566*38e8c45fSAndroid Build Coastguard Worker return true;
2567*38e8c45fSAndroid Build Coastguard Worker });
2568*38e8c45fSAndroid Build Coastguard Worker auto result = dumpstate_board_task.get_future();
2569*38e8c45fSAndroid Build Coastguard Worker std::thread(std::move(dumpstate_board_task)).detach();
2570*38e8c45fSAndroid Build Coastguard Worker
2571*38e8c45fSAndroid Build Coastguard Worker if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
2572*38e8c45fSAndroid Build Coastguard Worker MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate HAL\n", timeout_sec);
2573*38e8c45fSAndroid Build Coastguard Worker if (!android::base::SetProperty(
2574*38e8c45fSAndroid Build Coastguard Worker "ctl.interface_restart",
2575*38e8c45fSAndroid Build Coastguard Worker android::base::StringPrintf("%s/default", descriptor_to_kill))) {
2576*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Couldn't restart dumpstate HAL\n");
2577*38e8c45fSAndroid Build Coastguard Worker }
2578*38e8c45fSAndroid Build Coastguard Worker }
2579*38e8c45fSAndroid Build Coastguard Worker // Wait some time for init to kill dumpstate vendor HAL
2580*38e8c45fSAndroid Build Coastguard Worker constexpr size_t killing_timeout_sec = 10;
2581*38e8c45fSAndroid Build Coastguard Worker if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
2582*38e8c45fSAndroid Build Coastguard Worker MYLOGE(
2583*38e8c45fSAndroid Build Coastguard Worker "killing dumpstateBoard timed out after %zus, continue and "
2584*38e8c45fSAndroid Build Coastguard Worker "there might be racing in content\n",
2585*38e8c45fSAndroid Build Coastguard Worker killing_timeout_sec);
2586*38e8c45fSAndroid Build Coastguard Worker }
2587*38e8c45fSAndroid Build Coastguard Worker }
2588*38e8c45fSAndroid Build Coastguard Worker
GetDumpstateBoardAidlService()2589*38e8c45fSAndroid Build Coastguard Worker static std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> GetDumpstateBoardAidlService() {
2590*38e8c45fSAndroid Build Coastguard Worker const std::string aidl_instance_name =
2591*38e8c45fSAndroid Build Coastguard Worker std::string(dumpstate_hal_aidl::IDumpstateDevice::descriptor) + "/default";
2592*38e8c45fSAndroid Build Coastguard Worker
2593*38e8c45fSAndroid Build Coastguard Worker if (!AServiceManager_isDeclared(aidl_instance_name.c_str())) {
2594*38e8c45fSAndroid Build Coastguard Worker return nullptr;
2595*38e8c45fSAndroid Build Coastguard Worker }
2596*38e8c45fSAndroid Build Coastguard Worker
2597*38e8c45fSAndroid Build Coastguard Worker ndk::SpAIBinder dumpstateBinder(AServiceManager_waitForService(aidl_instance_name.c_str()));
2598*38e8c45fSAndroid Build Coastguard Worker
2599*38e8c45fSAndroid Build Coastguard Worker return dumpstate_hal_aidl::IDumpstateDevice::fromBinder(dumpstateBinder);
2600*38e8c45fSAndroid Build Coastguard Worker }
2601*38e8c45fSAndroid Build Coastguard Worker
DumpstateBoard(int out_fd)2602*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::DumpstateBoard(int out_fd) {
2603*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
2604*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "== Board\n");
2605*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "========================================================\n");
2606*38e8c45fSAndroid Build Coastguard Worker
2607*38e8c45fSAndroid Build Coastguard Worker /*
2608*38e8c45fSAndroid Build Coastguard Worker * mount debugfs for non-user builds with ro.product.debugfs_restrictions.enabled
2609*38e8c45fSAndroid Build Coastguard Worker * set to true and unmount it after invoking dumpstateBoard_* methods.
2610*38e8c45fSAndroid Build Coastguard Worker * This is to enable debug builds to not have debugfs mounted during runtime.
2611*38e8c45fSAndroid Build Coastguard Worker * It will also ensure that debugfs is only accessed by the dumpstate HAL.
2612*38e8c45fSAndroid Build Coastguard Worker */
2613*38e8c45fSAndroid Build Coastguard Worker auto mount_debugfs =
2614*38e8c45fSAndroid Build Coastguard Worker android::base::GetBoolProperty("ro.product.debugfs_restrictions.enabled", false);
2615*38e8c45fSAndroid Build Coastguard Worker if (mount_debugfs) {
2616*38e8c45fSAndroid Build Coastguard Worker RunCommand("mount debugfs", {"mount", "-t", "debugfs", "debugfs", "/sys/kernel/debug"},
2617*38e8c45fSAndroid Build Coastguard Worker AS_ROOT_20);
2618*38e8c45fSAndroid Build Coastguard Worker RunCommand("chmod debugfs", {"chmod", "0755", "/sys/kernel/debug"}, AS_ROOT_20);
2619*38e8c45fSAndroid Build Coastguard Worker }
2620*38e8c45fSAndroid Build Coastguard Worker
2621*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> paths;
2622*38e8c45fSAndroid Build Coastguard Worker std::vector<android::base::ScopeGuard<std::function<void()>>> remover;
2623*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < NUM_OF_DUMPS; i++) {
2624*38e8c45fSAndroid Build Coastguard Worker paths.emplace_back(StringPrintf("%s/%s", ds.bugreport_internal_dir_.c_str(),
2625*38e8c45fSAndroid Build Coastguard Worker kDumpstateBoardFiles[i].c_str()));
2626*38e8c45fSAndroid Build Coastguard Worker remover.emplace_back(android::base::make_scope_guard(
2627*38e8c45fSAndroid Build Coastguard Worker std::bind([](std::string path) { android::os::UnlinkAndLogOnError(path); }, paths[i])));
2628*38e8c45fSAndroid Build Coastguard Worker }
2629*38e8c45fSAndroid Build Coastguard Worker
2630*38e8c45fSAndroid Build Coastguard Worker // get dumpstate HAL AIDL implementation
2631*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> dumpstate_hal_handle_aidl(
2632*38e8c45fSAndroid Build Coastguard Worker GetDumpstateBoardAidlService());
2633*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal_handle_aidl == nullptr) {
2634*38e8c45fSAndroid Build Coastguard Worker MYLOGI("No IDumpstateDevice AIDL implementation\n");
2635*38e8c45fSAndroid Build Coastguard Worker }
2636*38e8c45fSAndroid Build Coastguard Worker
2637*38e8c45fSAndroid Build Coastguard Worker // get dumpstate HAL HIDL implementation, only if AIDL HAL implementation not found
2638*38e8c45fSAndroid Build Coastguard Worker sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_handle_hidl_1_0 = nullptr;
2639*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal_handle_aidl == nullptr) {
2640*38e8c45fSAndroid Build Coastguard Worker dumpstate_hal_handle_hidl_1_0 = dumpstate_hal_hidl_1_0::IDumpstateDevice::getService();
2641*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal_handle_hidl_1_0 == nullptr) {
2642*38e8c45fSAndroid Build Coastguard Worker MYLOGI("No IDumpstateDevice HIDL implementation\n");
2643*38e8c45fSAndroid Build Coastguard Worker }
2644*38e8c45fSAndroid Build Coastguard Worker }
2645*38e8c45fSAndroid Build Coastguard Worker
2646*38e8c45fSAndroid Build Coastguard Worker // if neither HIDL nor AIDL implementation found, then return
2647*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal_handle_hidl_1_0 == nullptr && dumpstate_hal_handle_aidl == nullptr) {
2648*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not find IDumpstateDevice implementation\n");
2649*38e8c45fSAndroid Build Coastguard Worker return;
2650*38e8c45fSAndroid Build Coastguard Worker }
2651*38e8c45fSAndroid Build Coastguard Worker
2652*38e8c45fSAndroid Build Coastguard Worker // this is used to hold the file descriptors and when this variable goes out of scope
2653*38e8c45fSAndroid Build Coastguard Worker // the file descriptors are closed
2654*38e8c45fSAndroid Build Coastguard Worker std::vector<::ndk::ScopedFileDescriptor> dumpstate_fds;
2655*38e8c45fSAndroid Build Coastguard Worker
2656*38e8c45fSAndroid Build Coastguard Worker // TODO(128270426): Check for consent in between?
2657*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < paths.size(); i++) {
2658*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());
2659*38e8c45fSAndroid Build Coastguard Worker
2660*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(TEMP_FAILURE_RETRY(
2661*38e8c45fSAndroid Build Coastguard Worker open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
2662*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
2663*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
2664*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
2665*38e8c45fSAndroid Build Coastguard Worker return;
2666*38e8c45fSAndroid Build Coastguard Worker }
2667*38e8c45fSAndroid Build Coastguard Worker
2668*38e8c45fSAndroid Build Coastguard Worker dumpstate_fds.emplace_back(fd.release());
2669*38e8c45fSAndroid Build Coastguard Worker // we call fd.release() here to make sure "fd" does not get closed
2670*38e8c45fSAndroid Build Coastguard Worker // after "fd" goes out of scope after this block.
2671*38e8c45fSAndroid Build Coastguard Worker // "fd" will be closed when "dumpstate_fds" goes out of scope
2672*38e8c45fSAndroid Build Coastguard Worker // i.e. when we exit this function
2673*38e8c45fSAndroid Build Coastguard Worker }
2674*38e8c45fSAndroid Build Coastguard Worker
2675*38e8c45fSAndroid Build Coastguard Worker // Given that bugreport is required to diagnose failures, it's better to set an arbitrary amount
2676*38e8c45fSAndroid Build Coastguard Worker // of timeout for IDumpstateDevice than to block the rest of bugreport. In the timeout case, we
2677*38e8c45fSAndroid Build Coastguard Worker // will kill the HAL and grab whatever it dumped in time.
2678*38e8c45fSAndroid Build Coastguard Worker constexpr size_t timeout_sec = 45;
2679*38e8c45fSAndroid Build Coastguard Worker
2680*38e8c45fSAndroid Build Coastguard Worker if (dumpstate_hal_handle_aidl != nullptr) {
2681*38e8c45fSAndroid Build Coastguard Worker DoDumpstateBoardAidl(dumpstate_hal_handle_aidl, dumpstate_fds, options_->bugreport_mode,
2682*38e8c45fSAndroid Build Coastguard Worker timeout_sec);
2683*38e8c45fSAndroid Build Coastguard Worker } else if (dumpstate_hal_handle_hidl_1_0 != nullptr) {
2684*38e8c45fSAndroid Build Coastguard Worker // run HIDL HAL only if AIDL HAL not found
2685*38e8c45fSAndroid Build Coastguard Worker DoDumpstateBoardHidl(dumpstate_hal_handle_hidl_1_0, dumpstate_fds, options_->bugreport_mode,
2686*38e8c45fSAndroid Build Coastguard Worker timeout_sec);
2687*38e8c45fSAndroid Build Coastguard Worker }
2688*38e8c45fSAndroid Build Coastguard Worker
2689*38e8c45fSAndroid Build Coastguard Worker if (mount_debugfs) {
2690*38e8c45fSAndroid Build Coastguard Worker auto keep_debugfs_mounted =
2691*38e8c45fSAndroid Build Coastguard Worker android::base::GetProperty("persist.dbg.keep_debugfs_mounted", "");
2692*38e8c45fSAndroid Build Coastguard Worker if (keep_debugfs_mounted.empty())
2693*38e8c45fSAndroid Build Coastguard Worker RunCommand("unmount debugfs", {"umount", "/sys/kernel/debug"}, AS_ROOT_20);
2694*38e8c45fSAndroid Build Coastguard Worker }
2695*38e8c45fSAndroid Build Coastguard Worker
2696*38e8c45fSAndroid Build Coastguard Worker auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
2697*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < paths.size(); i++) {
2698*38e8c45fSAndroid Build Coastguard Worker struct stat s;
2699*38e8c45fSAndroid Build Coastguard Worker if (fstat(dumpstate_fds[i].get(), &s) == -1) {
2700*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(), strerror(errno));
2701*38e8c45fSAndroid Build Coastguard Worker file_sizes[i] = -1;
2702*38e8c45fSAndroid Build Coastguard Worker continue;
2703*38e8c45fSAndroid Build Coastguard Worker }
2704*38e8c45fSAndroid Build Coastguard Worker file_sizes[i] = s.st_size;
2705*38e8c45fSAndroid Build Coastguard Worker }
2706*38e8c45fSAndroid Build Coastguard Worker
2707*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < paths.size(); i++) {
2708*38e8c45fSAndroid Build Coastguard Worker if (file_sizes[i] == -1) {
2709*38e8c45fSAndroid Build Coastguard Worker continue;
2710*38e8c45fSAndroid Build Coastguard Worker }
2711*38e8c45fSAndroid Build Coastguard Worker if (file_sizes[i] == 0) {
2712*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Ignoring empty %s\n", kDumpstateBoardFiles[i].c_str());
2713*38e8c45fSAndroid Build Coastguard Worker continue;
2714*38e8c45fSAndroid Build Coastguard Worker }
2715*38e8c45fSAndroid Build Coastguard Worker remover[i].Disable();
2716*38e8c45fSAndroid Build Coastguard Worker EnqueueAddZipEntryAndCleanupIfNeeded(kDumpstateBoardFiles[i], paths[i]);
2717*38e8c45fSAndroid Build Coastguard Worker dprintf(out_fd, "*** See %s entry ***\n", kDumpstateBoardFiles[i].c_str());
2718*38e8c45fSAndroid Build Coastguard Worker }
2719*38e8c45fSAndroid Build Coastguard Worker }
2720*38e8c45fSAndroid Build Coastguard Worker
ShowUsage()2721*38e8c45fSAndroid Build Coastguard Worker static void ShowUsage() {
2722*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr,
2723*38e8c45fSAndroid Build Coastguard Worker "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o directory] [-p] "
2724*38e8c45fSAndroid Build Coastguard Worker "[-s] [-S] [-q] [-P] [-R] [-L] [-V version]\n"
2725*38e8c45fSAndroid Build Coastguard Worker " -h: display this help message\n"
2726*38e8c45fSAndroid Build Coastguard Worker " -b: play sound file instead of vibrate, at beginning of job\n"
2727*38e8c45fSAndroid Build Coastguard Worker " -e: play sound file instead of vibrate, at end of job\n"
2728*38e8c45fSAndroid Build Coastguard Worker " -o: write to custom directory (only in limited mode)\n"
2729*38e8c45fSAndroid Build Coastguard Worker " -p: capture screenshot to filename.png\n"
2730*38e8c45fSAndroid Build Coastguard Worker " -s: write zipped file to control socket (for init)\n"
2731*38e8c45fSAndroid Build Coastguard Worker " -S: write file location to control socket (for init)\n"
2732*38e8c45fSAndroid Build Coastguard Worker " -q: disable vibrate\n"
2733*38e8c45fSAndroid Build Coastguard Worker " -P: send broadcast when started and do progress updates\n"
2734*38e8c45fSAndroid Build Coastguard Worker " -R: take bugreport in remote mode (shouldn't be used with -P)\n"
2735*38e8c45fSAndroid Build Coastguard Worker " -w: start binder service and make it wait for a call to startBugreport\n"
2736*38e8c45fSAndroid Build Coastguard Worker " -L: output limited information that is safe for submission in feedback reports\n"
2737*38e8c45fSAndroid Build Coastguard Worker " -v: prints the dumpstate header and exit\n");
2738*38e8c45fSAndroid Build Coastguard Worker }
2739*38e8c45fSAndroid Build Coastguard Worker
register_sig_handler()2740*38e8c45fSAndroid Build Coastguard Worker static void register_sig_handler() {
2741*38e8c45fSAndroid Build Coastguard Worker signal(SIGPIPE, SIG_IGN);
2742*38e8c45fSAndroid Build Coastguard Worker }
2743*38e8c45fSAndroid Build Coastguard Worker
FinishZipFile()2744*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::FinishZipFile() {
2745*38e8c45fSAndroid Build Coastguard Worker // Runs all enqueued adding zip entry and cleanup tasks before finishing the zip file.
2746*38e8c45fSAndroid Build Coastguard Worker if (zip_entry_tasks_) {
2747*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_->run(/* do_cancel = */false);
2748*38e8c45fSAndroid Build Coastguard Worker }
2749*38e8c45fSAndroid Build Coastguard Worker
2750*38e8c45fSAndroid Build Coastguard Worker std::string entry_name = base_name_ + "-" + name_ + ".txt";
2751*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Adding main entry (%s) from %s to .zip bugreport\n", entry_name.c_str(),
2752*38e8c45fSAndroid Build Coastguard Worker tmp_path_.c_str());
2753*38e8c45fSAndroid Build Coastguard Worker // Final timestamp
2754*38e8c45fSAndroid Build Coastguard Worker char date[80];
2755*38e8c45fSAndroid Build Coastguard Worker time_t the_real_now_please_stand_up = time(nullptr);
2756*38e8c45fSAndroid Build Coastguard Worker strftime(date, sizeof(date), "%Y/%m/%d %H:%M:%S", localtime(&the_real_now_please_stand_up));
2757*38e8c45fSAndroid Build Coastguard Worker MYLOGD("dumpstate id %d finished around %s (%ld s)\n", ds.id_, date,
2758*38e8c45fSAndroid Build Coastguard Worker the_real_now_please_stand_up - ds.now_);
2759*38e8c45fSAndroid Build Coastguard Worker
2760*38e8c45fSAndroid Build Coastguard Worker if (!ds.AddZipEntry(entry_name, tmp_path_)) {
2761*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to add text entry to .zip file\n");
2762*38e8c45fSAndroid Build Coastguard Worker return false;
2763*38e8c45fSAndroid Build Coastguard Worker }
2764*38e8c45fSAndroid Build Coastguard Worker if (!AddTextZipEntry("main_entry.txt", entry_name)) {
2765*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to add main_entry.txt to .zip file\n");
2766*38e8c45fSAndroid Build Coastguard Worker return false;
2767*38e8c45fSAndroid Build Coastguard Worker }
2768*38e8c45fSAndroid Build Coastguard Worker
2769*38e8c45fSAndroid Build Coastguard Worker // Add log file (which contains stderr output) to zip...
2770*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "dumpstate_log.txt entry on zip file logged up to here\n");
2771*38e8c45fSAndroid Build Coastguard Worker if (!ds.AddZipEntry("dumpstate_log.txt", ds.log_path_.c_str())) {
2772*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to add dumpstate log to .zip file\n");
2773*38e8c45fSAndroid Build Coastguard Worker return false;
2774*38e8c45fSAndroid Build Coastguard Worker }
2775*38e8c45fSAndroid Build Coastguard Worker // TODO: Should truncate the existing file.
2776*38e8c45fSAndroid Build Coastguard Worker // ... and re-open it for further logging.
2777*38e8c45fSAndroid Build Coastguard Worker if (!redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()))) {
2778*38e8c45fSAndroid Build Coastguard Worker return false;
2779*38e8c45fSAndroid Build Coastguard Worker }
2780*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "\n");
2781*38e8c45fSAndroid Build Coastguard Worker
2782*38e8c45fSAndroid Build Coastguard Worker int32_t err = zip_writer_->Finish();
2783*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
2784*38e8c45fSAndroid Build Coastguard Worker MYLOGE("zip_writer_->Finish(): %s\n", ZipWriter::ErrorCodeString(err));
2785*38e8c45fSAndroid Build Coastguard Worker return false;
2786*38e8c45fSAndroid Build Coastguard Worker }
2787*38e8c45fSAndroid Build Coastguard Worker
2788*38e8c45fSAndroid Build Coastguard Worker // TODO: remove once FinishZipFile() is automatically handled by Dumpstate's destructor.
2789*38e8c45fSAndroid Build Coastguard Worker ds.zip_file.reset(nullptr);
2790*38e8c45fSAndroid Build Coastguard Worker
2791*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Removing temporary file %s\n", tmp_path_.c_str())
2792*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(tmp_path_);
2793*38e8c45fSAndroid Build Coastguard Worker
2794*38e8c45fSAndroid Build Coastguard Worker return true;
2795*38e8c45fSAndroid Build Coastguard Worker }
2796*38e8c45fSAndroid Build Coastguard Worker
SendBroadcast(const std::string & action,const std::vector<std::string> & args,int32_t user_id)2797*38e8c45fSAndroid Build Coastguard Worker static void SendBroadcast(const std::string& action,
2798*38e8c45fSAndroid Build Coastguard Worker const std::vector<std::string>& args,
2799*38e8c45fSAndroid Build Coastguard Worker int32_t user_id) {
2800*38e8c45fSAndroid Build Coastguard Worker // clang-format off
2801*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> am = {"/system/bin/cmd", "activity", "broadcast", "--user",
2802*38e8c45fSAndroid Build Coastguard Worker std::to_string(user_id), "--receiver-foreground",
2803*38e8c45fSAndroid Build Coastguard Worker "--receiver-include-background", "-a", action};
2804*38e8c45fSAndroid Build Coastguard Worker // clang-format on
2805*38e8c45fSAndroid Build Coastguard Worker
2806*38e8c45fSAndroid Build Coastguard Worker am.insert(am.end(), args.begin(), args.end());
2807*38e8c45fSAndroid Build Coastguard Worker
2808*38e8c45fSAndroid Build Coastguard Worker RunCommand("", am,
2809*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(20)
2810*38e8c45fSAndroid Build Coastguard Worker .Log("Sending broadcast: '%s'\n")
2811*38e8c45fSAndroid Build Coastguard Worker .Always()
2812*38e8c45fSAndroid Build Coastguard Worker .DropRoot()
2813*38e8c45fSAndroid Build Coastguard Worker .RedirectStderr()
2814*38e8c45fSAndroid Build Coastguard Worker .Build());
2815*38e8c45fSAndroid Build Coastguard Worker }
2816*38e8c45fSAndroid Build Coastguard Worker
Vibrate(int duration_ms)2817*38e8c45fSAndroid Build Coastguard Worker static void Vibrate(int duration_ms) {
2818*38e8c45fSAndroid Build Coastguard Worker // clang-format off
2819*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> args = {"cmd", "vibrator_manager", "synced", "-f", "-d", "dumpstate",
2820*38e8c45fSAndroid Build Coastguard Worker "oneshot", std::to_string(duration_ms)};
2821*38e8c45fSAndroid Build Coastguard Worker RunCommand("", args,
2822*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10)
2823*38e8c45fSAndroid Build Coastguard Worker .Log("Vibrate: '%s'\n")
2824*38e8c45fSAndroid Build Coastguard Worker .Always()
2825*38e8c45fSAndroid Build Coastguard Worker .Build());
2826*38e8c45fSAndroid Build Coastguard Worker // clang-format on
2827*38e8c45fSAndroid Build Coastguard Worker }
2828*38e8c45fSAndroid Build Coastguard Worker
MaybeResolveSymlink(std::string * path)2829*38e8c45fSAndroid Build Coastguard Worker static void MaybeResolveSymlink(std::string* path) {
2830*38e8c45fSAndroid Build Coastguard Worker std::string resolved_path;
2831*38e8c45fSAndroid Build Coastguard Worker if (android::base::Readlink(*path, &resolved_path)) {
2832*38e8c45fSAndroid Build Coastguard Worker *path = resolved_path;
2833*38e8c45fSAndroid Build Coastguard Worker }
2834*38e8c45fSAndroid Build Coastguard Worker }
2835*38e8c45fSAndroid Build Coastguard Worker
2836*38e8c45fSAndroid Build Coastguard Worker /*
2837*38e8c45fSAndroid Build Coastguard Worker * Prepares state like filename, screenshot path, etc in Dumpstate. Also initializes ZipWriter
2838*38e8c45fSAndroid Build Coastguard Worker * and adds the version file. Return false if zip_file could not be open to write.
2839*38e8c45fSAndroid Build Coastguard Worker */
PrepareToWriteToFile()2840*38e8c45fSAndroid Build Coastguard Worker static bool PrepareToWriteToFile() {
2841*38e8c45fSAndroid Build Coastguard Worker MaybeResolveSymlink(&ds.bugreport_internal_dir_);
2842*38e8c45fSAndroid Build Coastguard Worker
2843*38e8c45fSAndroid Build Coastguard Worker std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
2844*38e8c45fSAndroid Build Coastguard Worker std::string device_name = android::base::GetProperty("ro.product.name", "UNKNOWN_DEVICE");
2845*38e8c45fSAndroid Build Coastguard Worker ds.base_name_ = StringPrintf("bugreport-%s-%s", device_name.c_str(), build_id.c_str());
2846*38e8c45fSAndroid Build Coastguard Worker char date[80];
2847*38e8c45fSAndroid Build Coastguard Worker strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
2848*38e8c45fSAndroid Build Coastguard Worker ds.name_ = date;
2849*38e8c45fSAndroid Build Coastguard Worker
2850*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->telephony_only) {
2851*38e8c45fSAndroid Build Coastguard Worker ds.base_name_ += "-telephony";
2852*38e8c45fSAndroid Build Coastguard Worker } else if (ds.options_->wifi_only) {
2853*38e8c45fSAndroid Build Coastguard Worker ds.base_name_ += "-wifi";
2854*38e8c45fSAndroid Build Coastguard Worker }
2855*38e8c45fSAndroid Build Coastguard Worker
2856*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->do_screenshot) {
2857*38e8c45fSAndroid Build Coastguard Worker ds.screenshot_path_ = ds.GetPath(ds.CalledByApi() ? "-png.tmp" : ".png");
2858*38e8c45fSAndroid Build Coastguard Worker }
2859*38e8c45fSAndroid Build Coastguard Worker ds.tmp_path_ = ds.GetPath(".tmp");
2860*38e8c45fSAndroid Build Coastguard Worker ds.log_path_ = ds.GetPath("-dumpstate_log-" + std::to_string(ds.pid_) + ".txt");
2861*38e8c45fSAndroid Build Coastguard Worker
2862*38e8c45fSAndroid Build Coastguard Worker std::string destination = ds.CalledByApi()
2863*38e8c45fSAndroid Build Coastguard Worker ? StringPrintf("[fd:%d]", ds.options_->bugreport_fd.get())
2864*38e8c45fSAndroid Build Coastguard Worker : ds.bugreport_internal_dir_.c_str();
2865*38e8c45fSAndroid Build Coastguard Worker MYLOGD(
2866*38e8c45fSAndroid Build Coastguard Worker "Bugreport dir: [%s] "
2867*38e8c45fSAndroid Build Coastguard Worker "Base name: [%s] "
2868*38e8c45fSAndroid Build Coastguard Worker "Suffix: [%s] "
2869*38e8c45fSAndroid Build Coastguard Worker "Log path: [%s] "
2870*38e8c45fSAndroid Build Coastguard Worker "Temporary path: [%s] "
2871*38e8c45fSAndroid Build Coastguard Worker "Screenshot path: [%s]\n",
2872*38e8c45fSAndroid Build Coastguard Worker destination.c_str(), ds.base_name_.c_str(), ds.name_.c_str(), ds.log_path_.c_str(),
2873*38e8c45fSAndroid Build Coastguard Worker ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
2874*38e8c45fSAndroid Build Coastguard Worker
2875*38e8c45fSAndroid Build Coastguard Worker ds.path_ = ds.GetPath(ds.CalledByApi() ? "-zip.tmp" : ".zip");
2876*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Creating initial .zip file (%s)\n", ds.path_.c_str());
2877*38e8c45fSAndroid Build Coastguard Worker create_parent_dirs(ds.path_.c_str());
2878*38e8c45fSAndroid Build Coastguard Worker ds.zip_file.reset(fopen(ds.path_.c_str(), "wb"));
2879*38e8c45fSAndroid Build Coastguard Worker if (ds.zip_file == nullptr) {
2880*38e8c45fSAndroid Build Coastguard Worker MYLOGE("fopen(%s, 'wb'): %s\n", ds.path_.c_str(), strerror(errno));
2881*38e8c45fSAndroid Build Coastguard Worker return false;
2882*38e8c45fSAndroid Build Coastguard Worker }
2883*38e8c45fSAndroid Build Coastguard Worker ds.zip_writer_.reset(new ZipWriter(ds.zip_file.get()));
2884*38e8c45fSAndroid Build Coastguard Worker ds.AddTextZipEntry("version.txt", ds.version_);
2885*38e8c45fSAndroid Build Coastguard Worker return true;
2886*38e8c45fSAndroid Build Coastguard Worker }
2887*38e8c45fSAndroid Build Coastguard Worker
2888*38e8c45fSAndroid Build Coastguard Worker /*
2889*38e8c45fSAndroid Build Coastguard Worker * Finalizes writing to the file by zipping the tmp file to the final location,
2890*38e8c45fSAndroid Build Coastguard Worker * printing zipped file status, etc.
2891*38e8c45fSAndroid Build Coastguard Worker */
FinalizeFile()2892*38e8c45fSAndroid Build Coastguard Worker static void FinalizeFile() {
2893*38e8c45fSAndroid Build Coastguard Worker bool do_text_file = !ds.FinishZipFile();
2894*38e8c45fSAndroid Build Coastguard Worker if (do_text_file) {
2895*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to finish zip file; sending text bugreport instead\n");
2896*38e8c45fSAndroid Build Coastguard Worker }
2897*38e8c45fSAndroid Build Coastguard Worker
2898*38e8c45fSAndroid Build Coastguard Worker std::string final_path = ds.path_;
2899*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->OutputToCustomFile()) {
2900*38e8c45fSAndroid Build Coastguard Worker final_path = ds.GetPath(ds.options_->out_dir, ".zip");
2901*38e8c45fSAndroid Build Coastguard Worker android::os::CopyFileToFile(ds.path_, final_path);
2902*38e8c45fSAndroid Build Coastguard Worker }
2903*38e8c45fSAndroid Build Coastguard Worker
2904*38e8c45fSAndroid Build Coastguard Worker if (ds.options_->stream_to_socket) {
2905*38e8c45fSAndroid Build Coastguard Worker android::os::CopyFileToFd(ds.path_, ds.control_socket_fd_);
2906*38e8c45fSAndroid Build Coastguard Worker } else if (ds.options_->progress_updates_to_socket) {
2907*38e8c45fSAndroid Build Coastguard Worker if (do_text_file) {
2908*38e8c45fSAndroid Build Coastguard Worker dprintf(ds.control_socket_fd_,
2909*38e8c45fSAndroid Build Coastguard Worker "FAIL:could not create zip file, check %s "
2910*38e8c45fSAndroid Build Coastguard Worker "for more details\n",
2911*38e8c45fSAndroid Build Coastguard Worker ds.log_path_.c_str());
2912*38e8c45fSAndroid Build Coastguard Worker } else {
2913*38e8c45fSAndroid Build Coastguard Worker dprintf(ds.control_socket_fd_, "OK:%s\n", final_path.c_str());
2914*38e8c45fSAndroid Build Coastguard Worker }
2915*38e8c45fSAndroid Build Coastguard Worker }
2916*38e8c45fSAndroid Build Coastguard Worker }
2917*38e8c45fSAndroid Build Coastguard Worker
2918*38e8c45fSAndroid Build Coastguard Worker
ModeToString(Dumpstate::BugreportMode mode)2919*38e8c45fSAndroid Build Coastguard Worker static inline const char* ModeToString(Dumpstate::BugreportMode mode) {
2920*38e8c45fSAndroid Build Coastguard Worker switch (mode) {
2921*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_FULL:
2922*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_FULL";
2923*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
2924*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_INTERACTIVE";
2925*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
2926*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_REMOTE";
2927*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WEAR:
2928*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_WEAR";
2929*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
2930*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_TELEPHONY";
2931*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WIFI:
2932*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_WIFI";
2933*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_ONBOARDING:
2934*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_ONBOARDING";
2935*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
2936*38e8c45fSAndroid Build Coastguard Worker return "BUGREPORT_DEFAULT";
2937*38e8c45fSAndroid Build Coastguard Worker }
2938*38e8c45fSAndroid Build Coastguard Worker }
2939*38e8c45fSAndroid Build Coastguard Worker
IsConsentlessBugreportAllowed(const Dumpstate::DumpOptions & options)2940*38e8c45fSAndroid Build Coastguard Worker static bool IsConsentlessBugreportAllowed(const Dumpstate::DumpOptions& options) {
2941*38e8c45fSAndroid Build Coastguard Worker // only BUGREPORT_TELEPHONY does not allow using consentless bugreport
2942*38e8c45fSAndroid Build Coastguard Worker return !options.telephony_only;
2943*38e8c45fSAndroid Build Coastguard Worker }
2944*38e8c45fSAndroid Build Coastguard Worker
SetOptionsFromMode(Dumpstate::BugreportMode mode,Dumpstate::DumpOptions * options,bool is_screenshot_requested)2945*38e8c45fSAndroid Build Coastguard Worker static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options,
2946*38e8c45fSAndroid Build Coastguard Worker bool is_screenshot_requested) {
2947*38e8c45fSAndroid Build Coastguard Worker // Modify com.android.shell.BugreportProgressService#isDefaultScreenshotRequired as well for
2948*38e8c45fSAndroid Build Coastguard Worker // default system screenshots.
2949*38e8c45fSAndroid Build Coastguard Worker options->bugreport_mode = mode;
2950*38e8c45fSAndroid Build Coastguard Worker options->bugreport_mode_string = ModeToString(mode);
2951*38e8c45fSAndroid Build Coastguard Worker switch (mode) {
2952*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_FULL:
2953*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = is_screenshot_requested;
2954*38e8c45fSAndroid Build Coastguard Worker break;
2955*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
2956*38e8c45fSAndroid Build Coastguard Worker // Currently, the dumpstate binder is only used by Shell to update progress.
2957*38e8c45fSAndroid Build Coastguard Worker options->do_progress_updates = true;
2958*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = is_screenshot_requested;
2959*38e8c45fSAndroid Build Coastguard Worker break;
2960*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
2961*38e8c45fSAndroid Build Coastguard Worker options->do_vibrate = false;
2962*38e8c45fSAndroid Build Coastguard Worker options->is_remote_mode = true;
2963*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = false;
2964*38e8c45fSAndroid Build Coastguard Worker break;
2965*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WEAR:
2966*38e8c45fSAndroid Build Coastguard Worker options->do_vibrate = false;
2967*38e8c45fSAndroid Build Coastguard Worker options->do_progress_updates = true;
2968*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = is_screenshot_requested;
2969*38e8c45fSAndroid Build Coastguard Worker break;
2970*38e8c45fSAndroid Build Coastguard Worker // TODO(b/148168577) rename TELEPHONY everywhere to CONNECTIVITY.
2971*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
2972*38e8c45fSAndroid Build Coastguard Worker options->telephony_only = true;
2973*38e8c45fSAndroid Build Coastguard Worker options->do_progress_updates = true;
2974*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = false;
2975*38e8c45fSAndroid Build Coastguard Worker break;
2976*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_WIFI:
2977*38e8c45fSAndroid Build Coastguard Worker options->wifi_only = true;
2978*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = false;
2979*38e8c45fSAndroid Build Coastguard Worker break;
2980*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_ONBOARDING:
2981*38e8c45fSAndroid Build Coastguard Worker options->onboarding_only = true;
2982*38e8c45fSAndroid Build Coastguard Worker options->do_screenshot = false;
2983*38e8c45fSAndroid Build Coastguard Worker break;
2984*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
2985*38e8c45fSAndroid Build Coastguard Worker break;
2986*38e8c45fSAndroid Build Coastguard Worker }
2987*38e8c45fSAndroid Build Coastguard Worker }
2988*38e8c45fSAndroid Build Coastguard Worker
LogDumpOptions(const Dumpstate::DumpOptions & options)2989*38e8c45fSAndroid Build Coastguard Worker static void LogDumpOptions(const Dumpstate::DumpOptions& options) {
2990*38e8c45fSAndroid Build Coastguard Worker MYLOGI(
2991*38e8c45fSAndroid Build Coastguard Worker "do_vibrate: %d stream_to_socket: %d progress_updates_to_socket: %d do_screenshot: %d "
2992*38e8c45fSAndroid Build Coastguard Worker "is_remote_mode: %d show_header_only: %d telephony_only: %d "
2993*38e8c45fSAndroid Build Coastguard Worker "wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s "
2994*38e8c45fSAndroid Build Coastguard Worker "limited_only: %d args: %s\n",
2995*38e8c45fSAndroid Build Coastguard Worker options.do_vibrate, options.stream_to_socket, options.progress_updates_to_socket,
2996*38e8c45fSAndroid Build Coastguard Worker options.do_screenshot, options.is_remote_mode, options.show_header_only,
2997*38e8c45fSAndroid Build Coastguard Worker options.telephony_only, options.wifi_only,
2998*38e8c45fSAndroid Build Coastguard Worker options.do_progress_updates, options.bugreport_fd.get(),
2999*38e8c45fSAndroid Build Coastguard Worker options.bugreport_mode_string.c_str(),
3000*38e8c45fSAndroid Build Coastguard Worker options.limited_only, options.args.c_str());
3001*38e8c45fSAndroid Build Coastguard Worker }
3002*38e8c45fSAndroid Build Coastguard Worker
Initialize(BugreportMode bugreport_mode,int bugreport_flags,const android::base::unique_fd & bugreport_fd_in,const android::base::unique_fd & screenshot_fd_in,bool is_screenshot_requested,bool skip_user_consent)3003*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
3004*38e8c45fSAndroid Build Coastguard Worker int bugreport_flags,
3005*38e8c45fSAndroid Build Coastguard Worker const android::base::unique_fd& bugreport_fd_in,
3006*38e8c45fSAndroid Build Coastguard Worker const android::base::unique_fd& screenshot_fd_in,
3007*38e8c45fSAndroid Build Coastguard Worker bool is_screenshot_requested,
3008*38e8c45fSAndroid Build Coastguard Worker bool skip_user_consent) {
3009*38e8c45fSAndroid Build Coastguard Worker this->use_predumped_ui_data = bugreport_flags & BugreportFlag::BUGREPORT_USE_PREDUMPED_UI_DATA;
3010*38e8c45fSAndroid Build Coastguard Worker this->is_consent_deferred = bugreport_flags & BugreportFlag::BUGREPORT_FLAG_DEFER_CONSENT;
3011*38e8c45fSAndroid Build Coastguard Worker this->skip_user_consent = skip_user_consent;
3012*38e8c45fSAndroid Build Coastguard Worker // Duplicate the fds because the passed in fds don't outlive the binder transaction.
3013*38e8c45fSAndroid Build Coastguard Worker bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0));
3014*38e8c45fSAndroid Build Coastguard Worker screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0));
3015*38e8c45fSAndroid Build Coastguard Worker
3016*38e8c45fSAndroid Build Coastguard Worker SetOptionsFromMode(bugreport_mode, this, is_screenshot_requested);
3017*38e8c45fSAndroid Build Coastguard Worker }
3018*38e8c45fSAndroid Build Coastguard Worker
Initialize(int argc,char * argv[])3019*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) {
3020*38e8c45fSAndroid Build Coastguard Worker RunStatus status = RunStatus::OK;
3021*38e8c45fSAndroid Build Coastguard Worker int c;
3022*38e8c45fSAndroid Build Coastguard Worker while ((c = getopt(argc, argv, "dho:svqzpLPBRSV:w")) != -1) {
3023*38e8c45fSAndroid Build Coastguard Worker switch (c) {
3024*38e8c45fSAndroid Build Coastguard Worker // clang-format off
3025*38e8c45fSAndroid Build Coastguard Worker case 'o': out_dir = optarg; break;
3026*38e8c45fSAndroid Build Coastguard Worker case 's': stream_to_socket = true; break;
3027*38e8c45fSAndroid Build Coastguard Worker case 'S': progress_updates_to_socket = true; break;
3028*38e8c45fSAndroid Build Coastguard Worker case 'v': show_header_only = true; break;
3029*38e8c45fSAndroid Build Coastguard Worker case 'q': do_vibrate = false; break;
3030*38e8c45fSAndroid Build Coastguard Worker case 'p': do_screenshot = true; break;
3031*38e8c45fSAndroid Build Coastguard Worker case 'P': do_progress_updates = true; break;
3032*38e8c45fSAndroid Build Coastguard Worker case 'R': is_remote_mode = true; break;
3033*38e8c45fSAndroid Build Coastguard Worker case 'L': limited_only = true; break;
3034*38e8c45fSAndroid Build Coastguard Worker case 'V':
3035*38e8c45fSAndroid Build Coastguard Worker case 'd':
3036*38e8c45fSAndroid Build Coastguard Worker case 'z':
3037*38e8c45fSAndroid Build Coastguard Worker // compatibility no-op
3038*38e8c45fSAndroid Build Coastguard Worker break;
3039*38e8c45fSAndroid Build Coastguard Worker case 'w':
3040*38e8c45fSAndroid Build Coastguard Worker // This was already processed
3041*38e8c45fSAndroid Build Coastguard Worker break;
3042*38e8c45fSAndroid Build Coastguard Worker case 'h':
3043*38e8c45fSAndroid Build Coastguard Worker status = RunStatus::HELP;
3044*38e8c45fSAndroid Build Coastguard Worker break;
3045*38e8c45fSAndroid Build Coastguard Worker default:
3046*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Invalid option: %c\n", c);
3047*38e8c45fSAndroid Build Coastguard Worker status = RunStatus::INVALID_INPUT;
3048*38e8c45fSAndroid Build Coastguard Worker break;
3049*38e8c45fSAndroid Build Coastguard Worker // clang-format on
3050*38e8c45fSAndroid Build Coastguard Worker }
3051*38e8c45fSAndroid Build Coastguard Worker }
3052*38e8c45fSAndroid Build Coastguard Worker
3053*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < argc; i++) {
3054*38e8c45fSAndroid Build Coastguard Worker args += argv[i];
3055*38e8c45fSAndroid Build Coastguard Worker if (i < argc - 1) {
3056*38e8c45fSAndroid Build Coastguard Worker args += " ";
3057*38e8c45fSAndroid Build Coastguard Worker }
3058*38e8c45fSAndroid Build Coastguard Worker }
3059*38e8c45fSAndroid Build Coastguard Worker
3060*38e8c45fSAndroid Build Coastguard Worker // Reset next index used by getopt so this can be called multiple times, for eg, in tests.
3061*38e8c45fSAndroid Build Coastguard Worker optind = 1;
3062*38e8c45fSAndroid Build Coastguard Worker
3063*38e8c45fSAndroid Build Coastguard Worker return status;
3064*38e8c45fSAndroid Build Coastguard Worker }
3065*38e8c45fSAndroid Build Coastguard Worker
ValidateOptions() const3066*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::DumpOptions::ValidateOptions() const {
3067*38e8c45fSAndroid Build Coastguard Worker if (bugreport_fd.get() != -1 && stream_to_socket) {
3068*38e8c45fSAndroid Build Coastguard Worker return false;
3069*38e8c45fSAndroid Build Coastguard Worker }
3070*38e8c45fSAndroid Build Coastguard Worker
3071*38e8c45fSAndroid Build Coastguard Worker if ((progress_updates_to_socket || do_progress_updates) && stream_to_socket) {
3072*38e8c45fSAndroid Build Coastguard Worker return false;
3073*38e8c45fSAndroid Build Coastguard Worker }
3074*38e8c45fSAndroid Build Coastguard Worker
3075*38e8c45fSAndroid Build Coastguard Worker if (is_remote_mode && (do_progress_updates || stream_to_socket)) {
3076*38e8c45fSAndroid Build Coastguard Worker return false;
3077*38e8c45fSAndroid Build Coastguard Worker }
3078*38e8c45fSAndroid Build Coastguard Worker return true;
3079*38e8c45fSAndroid Build Coastguard Worker }
3080*38e8c45fSAndroid Build Coastguard Worker
SetOptions(std::unique_ptr<DumpOptions> options)3081*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::SetOptions(std::unique_ptr<DumpOptions> options) {
3082*38e8c45fSAndroid Build Coastguard Worker options_ = std::move(options);
3083*38e8c45fSAndroid Build Coastguard Worker }
3084*38e8c45fSAndroid Build Coastguard Worker
Initialize()3085*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::Initialize() {
3086*38e8c45fSAndroid Build Coastguard Worker /* gets the sequential id */
3087*38e8c45fSAndroid Build Coastguard Worker uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
3088*38e8c45fSAndroid Build Coastguard Worker id_ = ++last_id;
3089*38e8c45fSAndroid Build Coastguard Worker android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
3090*38e8c45fSAndroid Build Coastguard Worker }
3091*38e8c45fSAndroid Build Coastguard Worker
Run(int32_t calling_uid,const std::string & calling_package)3092*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::Run(int32_t calling_uid, const std::string& calling_package) {
3093*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = RunInternal(calling_uid, calling_package);
3094*38e8c45fSAndroid Build Coastguard Worker HandleRunStatus(status);
3095*38e8c45fSAndroid Build Coastguard Worker return status;
3096*38e8c45fSAndroid Build Coastguard Worker }
3097*38e8c45fSAndroid Build Coastguard Worker
Retrieve(int32_t calling_uid,const std::string & calling_package,const bool keep_bugreport_on_retrieval,const bool skip_user_consent)3098*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package,
3099*38e8c45fSAndroid Build Coastguard Worker const bool keep_bugreport_on_retrieval,
3100*38e8c45fSAndroid Build Coastguard Worker const bool skip_user_consent) {
3101*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package,
3102*38e8c45fSAndroid Build Coastguard Worker keep_bugreport_on_retrieval,
3103*38e8c45fSAndroid Build Coastguard Worker skip_user_consent);
3104*38e8c45fSAndroid Build Coastguard Worker HandleRunStatus(status);
3105*38e8c45fSAndroid Build Coastguard Worker return status;
3106*38e8c45fSAndroid Build Coastguard Worker }
3107*38e8c45fSAndroid Build Coastguard Worker
RetrieveInternal(int32_t calling_uid,const std::string & calling_package,const bool keep_bugreport_on_retrieval,const bool skip_user_consent)3108*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::RetrieveInternal(int32_t calling_uid,
3109*38e8c45fSAndroid Build Coastguard Worker const std::string& calling_package,
3110*38e8c45fSAndroid Build Coastguard Worker const bool keep_bugreport_on_retrieval,
3111*38e8c45fSAndroid Build Coastguard Worker const bool skip_user_consent) {
3112*38e8c45fSAndroid Build Coastguard Worker if (!android::app::admin::flags::onboarding_consentless_bugreports() || !skip_user_consent) {
3113*38e8c45fSAndroid Build Coastguard Worker consent_callback_ = new ConsentCallback();
3114*38e8c45fSAndroid Build Coastguard Worker const String16 incidentcompanion("incidentcompanion");
3115*38e8c45fSAndroid Build Coastguard Worker sp<android::IBinder> ics(
3116*38e8c45fSAndroid Build Coastguard Worker defaultServiceManager()->checkService(incidentcompanion));
3117*38e8c45fSAndroid Build Coastguard Worker android::String16 package(calling_package.c_str());
3118*38e8c45fSAndroid Build Coastguard Worker if (ics != nullptr) {
3119*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Checking user consent via incidentcompanion service\n");
3120*38e8c45fSAndroid Build Coastguard Worker
3121*38e8c45fSAndroid Build Coastguard Worker android::interface_cast<android::os::IIncidentCompanion>(ics)->authorizeReport(
3122*38e8c45fSAndroid Build Coastguard Worker calling_uid, package, String16(), String16(),
3123*38e8c45fSAndroid Build Coastguard Worker 0x1 /* FLAG_CONFIRMATION_DIALOG */, consent_callback_.get());
3124*38e8c45fSAndroid Build Coastguard Worker } else {
3125*38e8c45fSAndroid Build Coastguard Worker MYLOGD(
3126*38e8c45fSAndroid Build Coastguard Worker "Unable to check user consent; incidentcompanion service unavailable\n");
3127*38e8c45fSAndroid Build Coastguard Worker return RunStatus::USER_CONSENT_TIMED_OUT;
3128*38e8c45fSAndroid Build Coastguard Worker }
3129*38e8c45fSAndroid Build Coastguard Worker UserConsentResult consent_result = consent_callback_->getResult();
3130*38e8c45fSAndroid Build Coastguard Worker int timeout_ms = 30 * 1000;
3131*38e8c45fSAndroid Build Coastguard Worker while (consent_result == UserConsentResult::UNAVAILABLE &&
3132*38e8c45fSAndroid Build Coastguard Worker consent_callback_->getElapsedTimeMs() < timeout_ms) {
3133*38e8c45fSAndroid Build Coastguard Worker sleep(1);
3134*38e8c45fSAndroid Build Coastguard Worker consent_result = consent_callback_->getResult();
3135*38e8c45fSAndroid Build Coastguard Worker }
3136*38e8c45fSAndroid Build Coastguard Worker if (consent_result == UserConsentResult::DENIED) {
3137*38e8c45fSAndroid Build Coastguard Worker return RunStatus::USER_CONSENT_DENIED;
3138*38e8c45fSAndroid Build Coastguard Worker }
3139*38e8c45fSAndroid Build Coastguard Worker if (consent_result == UserConsentResult::UNAVAILABLE) {
3140*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Canceling user consent request via incidentcompanion service\n");
3141*38e8c45fSAndroid Build Coastguard Worker android::interface_cast<android::os::IIncidentCompanion>(ics)->cancelAuthorization(
3142*38e8c45fSAndroid Build Coastguard Worker consent_callback_.get());
3143*38e8c45fSAndroid Build Coastguard Worker return RunStatus::USER_CONSENT_TIMED_OUT;
3144*38e8c45fSAndroid Build Coastguard Worker }
3145*38e8c45fSAndroid Build Coastguard Worker }
3146*38e8c45fSAndroid Build Coastguard Worker
3147*38e8c45fSAndroid Build Coastguard Worker bool copy_succeeded =
3148*38e8c45fSAndroid Build Coastguard Worker android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
3149*38e8c45fSAndroid Build Coastguard Worker
3150*38e8c45fSAndroid Build Coastguard Worker if (copy_succeeded && (!android::app::admin::flags::onboarding_bugreport_v2_enabled()
3151*38e8c45fSAndroid Build Coastguard Worker || !keep_bugreport_on_retrieval)) {
3152*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(path_);
3153*38e8c45fSAndroid Build Coastguard Worker }
3154*38e8c45fSAndroid Build Coastguard Worker
3155*38e8c45fSAndroid Build Coastguard Worker return copy_succeeded ? Dumpstate::RunStatus::OK
3156*38e8c45fSAndroid Build Coastguard Worker : Dumpstate::RunStatus::ERROR;
3157*38e8c45fSAndroid Build Coastguard Worker }
3158*38e8c45fSAndroid Build Coastguard Worker
HandleRunStatus(Dumpstate::RunStatus status)3159*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::HandleRunStatus(Dumpstate::RunStatus status) {
3160*38e8c45fSAndroid Build Coastguard Worker if (listener_ != nullptr) {
3161*38e8c45fSAndroid Build Coastguard Worker switch (status) {
3162*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::OK:
3163*38e8c45fSAndroid Build Coastguard Worker listener_->onFinished(path_.c_str());
3164*38e8c45fSAndroid Build Coastguard Worker break;
3165*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::HELP:
3166*38e8c45fSAndroid Build Coastguard Worker break;
3167*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::INVALID_INPUT:
3168*38e8c45fSAndroid Build Coastguard Worker listener_->onError(IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT);
3169*38e8c45fSAndroid Build Coastguard Worker break;
3170*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::ERROR:
3171*38e8c45fSAndroid Build Coastguard Worker listener_->onError(IDumpstateListener::BUGREPORT_ERROR_RUNTIME_ERROR);
3172*38e8c45fSAndroid Build Coastguard Worker break;
3173*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::USER_CONSENT_DENIED:
3174*38e8c45fSAndroid Build Coastguard Worker listener_->onError(IDumpstateListener::BUGREPORT_ERROR_USER_DENIED_CONSENT);
3175*38e8c45fSAndroid Build Coastguard Worker break;
3176*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT:
3177*38e8c45fSAndroid Build Coastguard Worker listener_->onError(IDumpstateListener::BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
3178*38e8c45fSAndroid Build Coastguard Worker break;
3179*38e8c45fSAndroid Build Coastguard Worker }
3180*38e8c45fSAndroid Build Coastguard Worker }
3181*38e8c45fSAndroid Build Coastguard Worker }
Cancel()3182*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::Cancel() {
3183*38e8c45fSAndroid Build Coastguard Worker CleanupTmpFiles();
3184*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(log_path_);
3185*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < NUM_OF_DUMPS; i++) {
3186*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(ds.bugreport_internal_dir_ + "/" +
3187*38e8c45fSAndroid Build Coastguard Worker kDumpstateBoardFiles[i]);
3188*38e8c45fSAndroid Build Coastguard Worker }
3189*38e8c45fSAndroid Build Coastguard Worker tombstone_data_.clear();
3190*38e8c45fSAndroid Build Coastguard Worker anr_data_.clear();
3191*38e8c45fSAndroid Build Coastguard Worker anr_trace_data_.clear();
3192*38e8c45fSAndroid Build Coastguard Worker shutdown_checkpoints_.clear();
3193*38e8c45fSAndroid Build Coastguard Worker
3194*38e8c45fSAndroid Build Coastguard Worker // Instead of shutdown the pool, we delete temporary files directly since
3195*38e8c45fSAndroid Build Coastguard Worker // shutdown blocking the call.
3196*38e8c45fSAndroid Build Coastguard Worker if (dump_pool_) {
3197*38e8c45fSAndroid Build Coastguard Worker dump_pool_->deleteTempFiles();
3198*38e8c45fSAndroid Build Coastguard Worker }
3199*38e8c45fSAndroid Build Coastguard Worker if (zip_entry_tasks_) {
3200*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_->run(/*do_cancel =*/ true);
3201*38e8c45fSAndroid Build Coastguard Worker }
3202*38e8c45fSAndroid Build Coastguard Worker }
3203*38e8c45fSAndroid Build Coastguard Worker
PreDumpUiData()3204*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::PreDumpUiData() {
3205*38e8c45fSAndroid Build Coastguard Worker auto snapshot_system_trace = MaybeSnapshotSystemTraceAsync();
3206*38e8c45fSAndroid Build Coastguard Worker MaybeSnapshotUiTraces();
3207*38e8c45fSAndroid Build Coastguard Worker MaybeWaitForSnapshotSystemTrace(std::move(snapshot_system_trace));
3208*38e8c45fSAndroid Build Coastguard Worker }
3209*38e8c45fSAndroid Build Coastguard Worker
3210*38e8c45fSAndroid Build Coastguard Worker /*
3211*38e8c45fSAndroid Build Coastguard Worker * Dumps relevant information to a bugreport based on the given options.
3212*38e8c45fSAndroid Build Coastguard Worker *
3213*38e8c45fSAndroid Build Coastguard Worker * The bugreport can be dumped to a file or streamed to a socket.
3214*38e8c45fSAndroid Build Coastguard Worker *
3215*38e8c45fSAndroid Build Coastguard Worker * How dumping to file works:
3216*38e8c45fSAndroid Build Coastguard Worker * stdout is redirected to a temporary file. This will later become the main bugreport entry.
3217*38e8c45fSAndroid Build Coastguard Worker * stderr is redirected a log file.
3218*38e8c45fSAndroid Build Coastguard Worker *
3219*38e8c45fSAndroid Build Coastguard Worker * The temporary bugreport is then populated via printfs, dumping contents of files and
3220*38e8c45fSAndroid Build Coastguard Worker * output of commands to stdout.
3221*38e8c45fSAndroid Build Coastguard Worker *
3222*38e8c45fSAndroid Build Coastguard Worker * A bunch of other files and dumps are added to the zip archive.
3223*38e8c45fSAndroid Build Coastguard Worker *
3224*38e8c45fSAndroid Build Coastguard Worker * The temporary bugreport file and the log file also get added to the archive.
3225*38e8c45fSAndroid Build Coastguard Worker *
3226*38e8c45fSAndroid Build Coastguard Worker * Bugreports are first generated in a local directory and later copied to the caller's fd
3227*38e8c45fSAndroid Build Coastguard Worker * or directory if supplied.
3228*38e8c45fSAndroid Build Coastguard Worker */
RunInternal(int32_t calling_uid,const std::string & calling_package)3229*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid,
3230*38e8c45fSAndroid Build Coastguard Worker const std::string& calling_package) {
3231*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("RUN INTERNAL", /* logcat_only = */true);
3232*38e8c45fSAndroid Build Coastguard Worker LogDumpOptions(*options_);
3233*38e8c45fSAndroid Build Coastguard Worker if (!options_->ValidateOptions()) {
3234*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Invalid options specified\n");
3235*38e8c45fSAndroid Build Coastguard Worker return RunStatus::INVALID_INPUT;
3236*38e8c45fSAndroid Build Coastguard Worker }
3237*38e8c45fSAndroid Build Coastguard Worker /* set as high priority, and protect from OOM killer */
3238*38e8c45fSAndroid Build Coastguard Worker setpriority(PRIO_PROCESS, 0, -20);
3239*38e8c45fSAndroid Build Coastguard Worker
3240*38e8c45fSAndroid Build Coastguard Worker FILE* oom_adj = fopen("/proc/self/oom_score_adj", "we");
3241*38e8c45fSAndroid Build Coastguard Worker if (oom_adj) {
3242*38e8c45fSAndroid Build Coastguard Worker fputs("-1000", oom_adj);
3243*38e8c45fSAndroid Build Coastguard Worker fclose(oom_adj);
3244*38e8c45fSAndroid Build Coastguard Worker } else {
3245*38e8c45fSAndroid Build Coastguard Worker /* fallback to kernels <= 2.6.35 */
3246*38e8c45fSAndroid Build Coastguard Worker oom_adj = fopen("/proc/self/oom_adj", "we");
3247*38e8c45fSAndroid Build Coastguard Worker if (oom_adj) {
3248*38e8c45fSAndroid Build Coastguard Worker fputs("-17", oom_adj);
3249*38e8c45fSAndroid Build Coastguard Worker fclose(oom_adj);
3250*38e8c45fSAndroid Build Coastguard Worker }
3251*38e8c45fSAndroid Build Coastguard Worker }
3252*38e8c45fSAndroid Build Coastguard Worker
3253*38e8c45fSAndroid Build Coastguard Worker if (version_ == VERSION_DEFAULT) {
3254*38e8c45fSAndroid Build Coastguard Worker version_ = VERSION_CURRENT;
3255*38e8c45fSAndroid Build Coastguard Worker }
3256*38e8c45fSAndroid Build Coastguard Worker
3257*38e8c45fSAndroid Build Coastguard Worker if (version_ != VERSION_CURRENT) {
3258*38e8c45fSAndroid Build Coastguard Worker MYLOGE("invalid version requested ('%s'); supported values are: ('%s', '%s')\n",
3259*38e8c45fSAndroid Build Coastguard Worker version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str());
3260*38e8c45fSAndroid Build Coastguard Worker return RunStatus::INVALID_INPUT;
3261*38e8c45fSAndroid Build Coastguard Worker }
3262*38e8c45fSAndroid Build Coastguard Worker
3263*38e8c45fSAndroid Build Coastguard Worker if (options_->show_header_only) {
3264*38e8c45fSAndroid Build Coastguard Worker PrintHeader();
3265*38e8c45fSAndroid Build Coastguard Worker return RunStatus::OK;
3266*38e8c45fSAndroid Build Coastguard Worker }
3267*38e8c45fSAndroid Build Coastguard Worker
3268*38e8c45fSAndroid Build Coastguard Worker MYLOGD("dumpstate calling_uid = %d ; calling package = %s \n",
3269*38e8c45fSAndroid Build Coastguard Worker calling_uid, calling_package.c_str());
3270*38e8c45fSAndroid Build Coastguard Worker
3271*38e8c45fSAndroid Build Coastguard Worker // TODO: temporarily set progress until it's part of the Dumpstate constructor
3272*38e8c45fSAndroid Build Coastguard Worker std::string stats_path =
3273*38e8c45fSAndroid Build Coastguard Worker android::base::StringPrintf("%s/dumpstate-stats.txt", bugreport_internal_dir_.c_str());
3274*38e8c45fSAndroid Build Coastguard Worker progress_.reset(new Progress(stats_path));
3275*38e8c45fSAndroid Build Coastguard Worker
3276*38e8c45fSAndroid Build Coastguard Worker if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
3277*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to acquire wake lock: %s\n", strerror(errno));
3278*38e8c45fSAndroid Build Coastguard Worker } else {
3279*38e8c45fSAndroid Build Coastguard Worker // Wake lock will be released automatically on process death
3280*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Wake lock acquired.\n");
3281*38e8c45fSAndroid Build Coastguard Worker }
3282*38e8c45fSAndroid Build Coastguard Worker
3283*38e8c45fSAndroid Build Coastguard Worker register_sig_handler();
3284*38e8c45fSAndroid Build Coastguard Worker
3285*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) {
3286*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
3287*38e8c45fSAndroid Build Coastguard Worker }
3288*38e8c45fSAndroid Build Coastguard Worker
3289*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsStrictRun()) {
3290*38e8c45fSAndroid Build Coastguard Worker MYLOGI(
3291*38e8c45fSAndroid Build Coastguard Worker "Running on strict-run mode, which has shorter timeouts "
3292*38e8c45fSAndroid Build Coastguard Worker "(to disable, call 'setprop dumpstate.strict_run false')\n");
3293*38e8c45fSAndroid Build Coastguard Worker }
3294*38e8c45fSAndroid Build Coastguard Worker
3295*38e8c45fSAndroid Build Coastguard Worker MYLOGI("dumpstate info: id=%d, args='%s', bugreport_mode= %s bugreport format version: %s\n",
3296*38e8c45fSAndroid Build Coastguard Worker id_, options_->args.c_str(), options_->bugreport_mode_string.c_str(), version_.c_str());
3297*38e8c45fSAndroid Build Coastguard Worker
3298*38e8c45fSAndroid Build Coastguard Worker do_early_screenshot_ = options_->do_progress_updates;
3299*38e8c45fSAndroid Build Coastguard Worker
3300*38e8c45fSAndroid Build Coastguard Worker // If we are going to use a socket, do it as early as possible
3301*38e8c45fSAndroid Build Coastguard Worker // to avoid timeouts from bugreport.
3302*38e8c45fSAndroid Build Coastguard Worker if (options_->stream_to_socket || options_->progress_updates_to_socket) {
3303*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Opening control socket\n");
3304*38e8c45fSAndroid Build Coastguard Worker control_socket_fd_ = open_socket_fn_("dumpstate");
3305*38e8c45fSAndroid Build Coastguard Worker if (control_socket_fd_ == -1) {
3306*38e8c45fSAndroid Build Coastguard Worker return ERROR;
3307*38e8c45fSAndroid Build Coastguard Worker }
3308*38e8c45fSAndroid Build Coastguard Worker if (options_->progress_updates_to_socket) {
3309*38e8c45fSAndroid Build Coastguard Worker options_->do_progress_updates = 1;
3310*38e8c45fSAndroid Build Coastguard Worker }
3311*38e8c45fSAndroid Build Coastguard Worker }
3312*38e8c45fSAndroid Build Coastguard Worker
3313*38e8c45fSAndroid Build Coastguard Worker if (!PrepareToWriteToFile()) {
3314*38e8c45fSAndroid Build Coastguard Worker return ERROR;
3315*38e8c45fSAndroid Build Coastguard Worker }
3316*38e8c45fSAndroid Build Coastguard Worker
3317*38e8c45fSAndroid Build Coastguard Worker // Interactive, wear & telephony modes are default to true.
3318*38e8c45fSAndroid Build Coastguard Worker // and may enable from cli option or when using control socket
3319*38e8c45fSAndroid Build Coastguard Worker if (options_->do_progress_updates) {
3320*38e8c45fSAndroid Build Coastguard Worker // clang-format off
3321*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> am_args = {
3322*38e8c45fSAndroid Build Coastguard Worker "--receiver-permission", "android.permission.DUMP",
3323*38e8c45fSAndroid Build Coastguard Worker };
3324*38e8c45fSAndroid Build Coastguard Worker // clang-format on
3325*38e8c45fSAndroid Build Coastguard Worker // Send STARTED broadcast for apps that listen to bugreport generation events
3326*38e8c45fSAndroid Build Coastguard Worker SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED",
3327*38e8c45fSAndroid Build Coastguard Worker am_args, multiuser_get_user_id(calling_uid));
3328*38e8c45fSAndroid Build Coastguard Worker if (options_->progress_updates_to_socket) {
3329*38e8c45fSAndroid Build Coastguard Worker dprintf(control_socket_fd_, "BEGIN:%s\n", path_.c_str());
3330*38e8c45fSAndroid Build Coastguard Worker }
3331*38e8c45fSAndroid Build Coastguard Worker }
3332*38e8c45fSAndroid Build Coastguard Worker
3333*38e8c45fSAndroid Build Coastguard Worker /* read /proc/cmdline before dropping root */
3334*38e8c45fSAndroid Build Coastguard Worker FILE *cmdline = fopen("/proc/cmdline", "re");
3335*38e8c45fSAndroid Build Coastguard Worker if (cmdline) {
3336*38e8c45fSAndroid Build Coastguard Worker fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
3337*38e8c45fSAndroid Build Coastguard Worker fclose(cmdline);
3338*38e8c45fSAndroid Build Coastguard Worker }
3339*38e8c45fSAndroid Build Coastguard Worker
3340*38e8c45fSAndroid Build Coastguard Worker if (options_->do_vibrate) {
3341*38e8c45fSAndroid Build Coastguard Worker Vibrate(150);
3342*38e8c45fSAndroid Build Coastguard Worker }
3343*38e8c45fSAndroid Build Coastguard Worker
3344*38e8c45fSAndroid Build Coastguard Worker if (zip_file != nullptr) {
3345*38e8c45fSAndroid Build Coastguard Worker if (chown(path_.c_str(), AID_SHELL, AID_SHELL)) {
3346*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to change ownership of zip file %s: %s\n", path_.c_str(),
3347*38e8c45fSAndroid Build Coastguard Worker strerror(errno));
3348*38e8c45fSAndroid Build Coastguard Worker }
3349*38e8c45fSAndroid Build Coastguard Worker }
3350*38e8c45fSAndroid Build Coastguard Worker
3351*38e8c45fSAndroid Build Coastguard Worker int dup_stdout_fd;
3352*38e8c45fSAndroid Build Coastguard Worker int dup_stderr_fd;
3353*38e8c45fSAndroid Build Coastguard Worker // Redirect stderr to log_path_ for debugging.
3354*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
3355*38e8c45fSAndroid Build Coastguard Worker if (!redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()))) {
3356*38e8c45fSAndroid Build Coastguard Worker return ERROR;
3357*38e8c45fSAndroid Build Coastguard Worker }
3358*38e8c45fSAndroid Build Coastguard Worker if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) {
3359*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(),
3360*38e8c45fSAndroid Build Coastguard Worker strerror(errno));
3361*38e8c45fSAndroid Build Coastguard Worker }
3362*38e8c45fSAndroid Build Coastguard Worker
3363*38e8c45fSAndroid Build Coastguard Worker // Redirect stdout to tmp_path_. This is the main bugreport entry and will be
3364*38e8c45fSAndroid Build Coastguard Worker // moved into zip file later, if zipping.
3365*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(dup_stdout_fd = dup(fileno(stdout)));
3366*38e8c45fSAndroid Build Coastguard Worker // TODO: why not write to a file instead of stdout to overcome this problem?
3367*38e8c45fSAndroid Build Coastguard Worker /* TODO: rather than generating a text file now and zipping it later,
3368*38e8c45fSAndroid Build Coastguard Worker it would be more efficient to redirect stdout to the zip entry
3369*38e8c45fSAndroid Build Coastguard Worker directly, but the libziparchive doesn't support that option yet. */
3370*38e8c45fSAndroid Build Coastguard Worker if (!redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str()))) {
3371*38e8c45fSAndroid Build Coastguard Worker return ERROR;
3372*38e8c45fSAndroid Build Coastguard Worker }
3373*38e8c45fSAndroid Build Coastguard Worker if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) {
3374*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n",
3375*38e8c45fSAndroid Build Coastguard Worker tmp_path_.c_str(), strerror(errno));
3376*38e8c45fSAndroid Build Coastguard Worker }
3377*38e8c45fSAndroid Build Coastguard Worker
3378*38e8c45fSAndroid Build Coastguard Worker // Don't buffer stdout
3379*38e8c45fSAndroid Build Coastguard Worker setvbuf(stdout, nullptr, _IONBF, 0);
3380*38e8c45fSAndroid Build Coastguard Worker
3381*38e8c45fSAndroid Build Coastguard Worker // Enable the parallel run if the client requests to output to a file.
3382*38e8c45fSAndroid Build Coastguard Worker EnableParallelRunIfNeeded();
3383*38e8c45fSAndroid Build Coastguard Worker // Using scope guard to make sure the dump pool can be shut down correctly.
3384*38e8c45fSAndroid Build Coastguard Worker auto scope_guard_to_shutdown_pool = android::base::make_scope_guard([=]() {
3385*38e8c45fSAndroid Build Coastguard Worker ShutdownDumpPool();
3386*38e8c45fSAndroid Build Coastguard Worker });
3387*38e8c45fSAndroid Build Coastguard Worker
3388*38e8c45fSAndroid Build Coastguard Worker // NOTE: there should be no stdout output until now, otherwise it would break the header.
3389*38e8c45fSAndroid Build Coastguard Worker // In particular, DurationReport objects should be created passing 'title, NULL', so their
3390*38e8c45fSAndroid Build Coastguard Worker // duration is logged into MYLOG instead.
3391*38e8c45fSAndroid Build Coastguard Worker PrintHeader();
3392*38e8c45fSAndroid Build Coastguard Worker
3393*38e8c45fSAndroid Build Coastguard Worker bool system_trace_exists = access(SYSTEM_TRACE_SNAPSHOT, F_OK) == 0;
3394*38e8c45fSAndroid Build Coastguard Worker if (options_->use_predumped_ui_data && !system_trace_exists) {
3395*38e8c45fSAndroid Build Coastguard Worker MYLOGW("Ignoring 'use predumped data' flag because no predumped data is available");
3396*38e8c45fSAndroid Build Coastguard Worker options_->use_predumped_ui_data = false;
3397*38e8c45fSAndroid Build Coastguard Worker }
3398*38e8c45fSAndroid Build Coastguard Worker
3399*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> snapshot_system_trace;
3400*38e8c45fSAndroid Build Coastguard Worker
3401*38e8c45fSAndroid Build Coastguard Worker bool is_dumpstate_restricted =
3402*38e8c45fSAndroid Build Coastguard Worker options_->telephony_only || options_->wifi_only || options_->limited_only;
3403*38e8c45fSAndroid Build Coastguard Worker if (!is_dumpstate_restricted) {
3404*38e8c45fSAndroid Build Coastguard Worker // Snapshot the system trace now (if running) to avoid that dumpstate's
3405*38e8c45fSAndroid Build Coastguard Worker // own activity pushes out interesting data from the trace ring buffer.
3406*38e8c45fSAndroid Build Coastguard Worker // The trace file is added to the zip by MaybeAddSystemTraceToZip().
3407*38e8c45fSAndroid Build Coastguard Worker snapshot_system_trace = MaybeSnapshotSystemTraceAsync();
3408*38e8c45fSAndroid Build Coastguard Worker
3409*38e8c45fSAndroid Build Coastguard Worker // Invoke critical dumpsys to preserve system state, before doing anything else.
3410*38e8c45fSAndroid Build Coastguard Worker RunDumpsysCritical();
3411*38e8c45fSAndroid Build Coastguard Worker
3412*38e8c45fSAndroid Build Coastguard Worker // Snapshot the UI traces now (if running).
3413*38e8c45fSAndroid Build Coastguard Worker // The trace files will be added to bugreport later.
3414*38e8c45fSAndroid Build Coastguard Worker MaybeSnapshotUiTraces();
3415*38e8c45fSAndroid Build Coastguard Worker }
3416*38e8c45fSAndroid Build Coastguard Worker
3417*38e8c45fSAndroid Build Coastguard Worker MaybeTakeEarlyScreenshot();
3418*38e8c45fSAndroid Build Coastguard Worker MaybeWaitForSnapshotSystemTrace(std::move(snapshot_system_trace));
3419*38e8c45fSAndroid Build Coastguard Worker onUiIntensiveBugreportDumpsFinished(calling_uid);
3420*38e8c45fSAndroid Build Coastguard Worker MaybeCheckUserConsent(calling_uid, calling_package);
3421*38e8c45fSAndroid Build Coastguard Worker if (options_->telephony_only) {
3422*38e8c45fSAndroid Build Coastguard Worker DumpstateTelephonyOnly(calling_package);
3423*38e8c45fSAndroid Build Coastguard Worker } else if (options_->wifi_only) {
3424*38e8c45fSAndroid Build Coastguard Worker DumpstateWifiOnly();
3425*38e8c45fSAndroid Build Coastguard Worker } else if (options_->limited_only) {
3426*38e8c45fSAndroid Build Coastguard Worker DumpstateLimitedOnly();
3427*38e8c45fSAndroid Build Coastguard Worker } else if (options_->onboarding_only) {
3428*38e8c45fSAndroid Build Coastguard Worker DumpstateOnboardingOnly();
3429*38e8c45fSAndroid Build Coastguard Worker } else {
3430*38e8c45fSAndroid Build Coastguard Worker // Dump state for the default case. This also drops root.
3431*38e8c45fSAndroid Build Coastguard Worker RunStatus s = DumpstateDefaultAfterCritical();
3432*38e8c45fSAndroid Build Coastguard Worker if (s != RunStatus::OK) {
3433*38e8c45fSAndroid Build Coastguard Worker if (s == RunStatus::USER_CONSENT_DENIED) {
3434*38e8c45fSAndroid Build Coastguard Worker HandleUserConsentDenied();
3435*38e8c45fSAndroid Build Coastguard Worker }
3436*38e8c45fSAndroid Build Coastguard Worker return s;
3437*38e8c45fSAndroid Build Coastguard Worker }
3438*38e8c45fSAndroid Build Coastguard Worker }
3439*38e8c45fSAndroid Build Coastguard Worker
3440*38e8c45fSAndroid Build Coastguard Worker /* close output if needed */
3441*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(dup2(dup_stdout_fd, fileno(stdout)));
3442*38e8c45fSAndroid Build Coastguard Worker
3443*38e8c45fSAndroid Build Coastguard Worker // Zip the (now complete) .tmp file within the internal directory.
3444*38e8c45fSAndroid Build Coastguard Worker ATRACE_BEGIN("FinalizeFile");
3445*38e8c45fSAndroid Build Coastguard Worker FinalizeFile();
3446*38e8c45fSAndroid Build Coastguard Worker ATRACE_END();
3447*38e8c45fSAndroid Build Coastguard Worker
3448*38e8c45fSAndroid Build Coastguard Worker // Share the final file with the caller if the user has consented or Shell is the caller.
3449*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = Dumpstate::RunStatus::OK;
3450*38e8c45fSAndroid Build Coastguard Worker if (CalledByApi() && !options_->is_consent_deferred) {
3451*38e8c45fSAndroid Build Coastguard Worker status = CopyBugreportIfUserConsented(calling_uid);
3452*38e8c45fSAndroid Build Coastguard Worker if (status != Dumpstate::RunStatus::OK &&
3453*38e8c45fSAndroid Build Coastguard Worker status != Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT) {
3454*38e8c45fSAndroid Build Coastguard Worker // Do an early return if there were errors. We make an exception for consent
3455*38e8c45fSAndroid Build Coastguard Worker // timing out because it's possible the user got distracted. In this case the
3456*38e8c45fSAndroid Build Coastguard Worker // bugreport is not shared but made available for manual retrieval.
3457*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Bug report generation failed, this could have been due to"
3458*38e8c45fSAndroid Build Coastguard Worker " several reasons such as BR copy failed, user consent was"
3459*38e8c45fSAndroid Build Coastguard Worker " not grated etc. Returning\n");
3460*38e8c45fSAndroid Build Coastguard Worker return status;
3461*38e8c45fSAndroid Build Coastguard Worker }
3462*38e8c45fSAndroid Build Coastguard Worker if (status == Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT) {
3463*38e8c45fSAndroid Build Coastguard Worker MYLOGI(
3464*38e8c45fSAndroid Build Coastguard Worker "Did not receive user consent yet."
3465*38e8c45fSAndroid Build Coastguard Worker " Will not copy the bugreport artifacts to caller.\n");
3466*38e8c45fSAndroid Build Coastguard Worker const String16 incidentcompanion("incidentcompanion");
3467*38e8c45fSAndroid Build Coastguard Worker sp<android::IBinder> ics(defaultServiceManager()->getService(incidentcompanion));
3468*38e8c45fSAndroid Build Coastguard Worker if (ics != nullptr) {
3469*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Canceling user consent request via incidentcompanion service\n");
3470*38e8c45fSAndroid Build Coastguard Worker android::interface_cast<android::os::IIncidentCompanion>(ics)->cancelAuthorization(
3471*38e8c45fSAndroid Build Coastguard Worker consent_callback_.get());
3472*38e8c45fSAndroid Build Coastguard Worker } else {
3473*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Unable to cancel user consent; incidentcompanion service unavailable\n");
3474*38e8c45fSAndroid Build Coastguard Worker }
3475*38e8c45fSAndroid Build Coastguard Worker }
3476*38e8c45fSAndroid Build Coastguard Worker }
3477*38e8c45fSAndroid Build Coastguard Worker
3478*38e8c45fSAndroid Build Coastguard Worker /* vibrate a few but shortly times to let user know it's finished */
3479*38e8c45fSAndroid Build Coastguard Worker if (options_->do_vibrate) {
3480*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
3481*38e8c45fSAndroid Build Coastguard Worker Vibrate(75);
3482*38e8c45fSAndroid Build Coastguard Worker usleep((75 + 50) * 1000);
3483*38e8c45fSAndroid Build Coastguard Worker }
3484*38e8c45fSAndroid Build Coastguard Worker }
3485*38e8c45fSAndroid Build Coastguard Worker
3486*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Final progress: %d/%d (estimated %d)\n", progress_->Get(), progress_->GetMax(),
3487*38e8c45fSAndroid Build Coastguard Worker progress_->GetInitialMax());
3488*38e8c45fSAndroid Build Coastguard Worker progress_->Save();
3489*38e8c45fSAndroid Build Coastguard Worker MYLOGI("done (id %d)\n", id_);
3490*38e8c45fSAndroid Build Coastguard Worker
3491*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(dup2(dup_stderr_fd, fileno(stderr)));
3492*38e8c45fSAndroid Build Coastguard Worker
3493*38e8c45fSAndroid Build Coastguard Worker if (control_socket_fd_ != -1) {
3494*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Closing control socket\n");
3495*38e8c45fSAndroid Build Coastguard Worker close(control_socket_fd_);
3496*38e8c45fSAndroid Build Coastguard Worker }
3497*38e8c45fSAndroid Build Coastguard Worker
3498*38e8c45fSAndroid Build Coastguard Worker tombstone_data_.clear();
3499*38e8c45fSAndroid Build Coastguard Worker anr_data_.clear();
3500*38e8c45fSAndroid Build Coastguard Worker anr_trace_data_.clear();
3501*38e8c45fSAndroid Build Coastguard Worker shutdown_checkpoints_.clear();
3502*38e8c45fSAndroid Build Coastguard Worker
3503*38e8c45fSAndroid Build Coastguard Worker return (consent_callback_ != nullptr &&
3504*38e8c45fSAndroid Build Coastguard Worker consent_callback_->getResult() == UserConsentResult::UNAVAILABLE)
3505*38e8c45fSAndroid Build Coastguard Worker ? USER_CONSENT_TIMED_OUT
3506*38e8c45fSAndroid Build Coastguard Worker : RunStatus::OK;
3507*38e8c45fSAndroid Build Coastguard Worker }
3508*38e8c45fSAndroid Build Coastguard Worker
MaybeTakeEarlyScreenshot()3509*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::MaybeTakeEarlyScreenshot() {
3510*38e8c45fSAndroid Build Coastguard Worker if (!options_->do_screenshot || !do_early_screenshot_) {
3511*38e8c45fSAndroid Build Coastguard Worker return;
3512*38e8c45fSAndroid Build Coastguard Worker }
3513*38e8c45fSAndroid Build Coastguard Worker
3514*38e8c45fSAndroid Build Coastguard Worker TakeScreenshot();
3515*38e8c45fSAndroid Build Coastguard Worker }
3516*38e8c45fSAndroid Build Coastguard Worker
MaybeSnapshotSystemTraceAsync()3517*38e8c45fSAndroid Build Coastguard Worker std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() {
3518*38e8c45fSAndroid Build Coastguard Worker // When capturing traces via bugreport handler (BH), this function will be invoked twice:
3519*38e8c45fSAndroid Build Coastguard Worker // 1) When BH invokes IDumpstate::PreDumpUiData()
3520*38e8c45fSAndroid Build Coastguard Worker // 2) When BH invokes IDumpstate::startBugreport(flags = BUGREPORT_USE_PREDUMPED_UI_DATA)
3521*38e8c45fSAndroid Build Coastguard Worker // In this case we don't want to re-invoke perfetto in step 2.
3522*38e8c45fSAndroid Build Coastguard Worker // In all other standard invocation states, this function is invoked once
3523*38e8c45fSAndroid Build Coastguard Worker // without the flag BUGREPORT_USE_PREDUMPED_UI_DATA.
3524*38e8c45fSAndroid Build Coastguard Worker // This function must run asynchronously to avoid delaying MaybeTakeEarlyScreenshot() in the
3525*38e8c45fSAndroid Build Coastguard Worker // standard invocation states (b/316110955).
3526*38e8c45fSAndroid Build Coastguard Worker if (options_->use_predumped_ui_data) {
3527*38e8c45fSAndroid Build Coastguard Worker return {};
3528*38e8c45fSAndroid Build Coastguard Worker }
3529*38e8c45fSAndroid Build Coastguard Worker
3530*38e8c45fSAndroid Build Coastguard Worker // Create temporary file for the command's output
3531*38e8c45fSAndroid Build Coastguard Worker std::string outPath = ds.bugreport_internal_dir_ + "/tmp_serialize_perfetto_trace";
3532*38e8c45fSAndroid Build Coastguard Worker auto outFd = android::base::unique_fd(TEMP_FAILURE_RETRY(
3533*38e8c45fSAndroid Build Coastguard Worker open(outPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
3534*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
3535*38e8c45fSAndroid Build Coastguard Worker if (outFd < 0) {
3536*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not open %s to serialize perfetto trace.\n", outPath.c_str());
3537*38e8c45fSAndroid Build Coastguard Worker return {};
3538*38e8c45fSAndroid Build Coastguard Worker }
3539*38e8c45fSAndroid Build Coastguard Worker
3540*38e8c45fSAndroid Build Coastguard Worker // If a stale file exists already, remove it.
3541*38e8c45fSAndroid Build Coastguard Worker unlink(SYSTEM_TRACE_SNAPSHOT);
3542*38e8c45fSAndroid Build Coastguard Worker
3543*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Launching async '%s'", SERIALIZE_PERFETTO_TRACE_TASK.c_str())
3544*38e8c45fSAndroid Build Coastguard Worker return std::async(
3545*38e8c45fSAndroid Build Coastguard Worker std::launch::async, [this, outPath = std::move(outPath), outFd = std::move(outFd)] {
3546*38e8c45fSAndroid Build Coastguard Worker // If a background system trace is happening and is marked as "suitable for
3547*38e8c45fSAndroid Build Coastguard Worker // bugreport" (i.e. bugreport_score > 0 in the trace config), this command
3548*38e8c45fSAndroid Build Coastguard Worker // will stop it and serialize into SYSTEM_TRACE_SNAPSHOT. In the (likely)
3549*38e8c45fSAndroid Build Coastguard Worker // case that no trace is ongoing, this command is a no-op.
3550*38e8c45fSAndroid Build Coastguard Worker // Note: this should not be enqueued as we need to freeze the trace before
3551*38e8c45fSAndroid Build Coastguard Worker // dumpstate starts. Otherwise the trace ring buffers will contain mostly
3552*38e8c45fSAndroid Build Coastguard Worker // the dumpstate's own activity which is irrelevant.
3553*38e8c45fSAndroid Build Coastguard Worker RunCommand(
3554*38e8c45fSAndroid Build Coastguard Worker SERIALIZE_PERFETTO_TRACE_TASK, {"perfetto", "--save-for-bugreport"},
3555*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(30).DropRoot().CloseAllFileDescriptorsOnExec().Build(),
3556*38e8c45fSAndroid Build Coastguard Worker false, outFd);
3557*38e8c45fSAndroid Build Coastguard Worker // MaybeAddSystemTraceToZip() will take care of copying the trace in the zip
3558*38e8c45fSAndroid Build Coastguard Worker // file in the later stages.
3559*38e8c45fSAndroid Build Coastguard Worker
3560*38e8c45fSAndroid Build Coastguard Worker return outPath;
3561*38e8c45fSAndroid Build Coastguard Worker });
3562*38e8c45fSAndroid Build Coastguard Worker }
3563*38e8c45fSAndroid Build Coastguard Worker
MaybeWaitForSnapshotSystemTrace(std::future<std::string> task)3564*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::MaybeWaitForSnapshotSystemTrace(std::future<std::string> task) {
3565*38e8c45fSAndroid Build Coastguard Worker if (!task.valid()) {
3566*38e8c45fSAndroid Build Coastguard Worker return;
3567*38e8c45fSAndroid Build Coastguard Worker }
3568*38e8c45fSAndroid Build Coastguard Worker
3569*38e8c45fSAndroid Build Coastguard Worker WaitForTask(std::move(task), SERIALIZE_PERFETTO_TRACE_TASK, STDOUT_FILENO);
3570*38e8c45fSAndroid Build Coastguard Worker }
3571*38e8c45fSAndroid Build Coastguard Worker
MaybeSnapshotUiTraces()3572*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::MaybeSnapshotUiTraces() {
3573*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsUserBuild() || options_->use_predumped_ui_data) {
3574*38e8c45fSAndroid Build Coastguard Worker return;
3575*38e8c45fSAndroid Build Coastguard Worker }
3576*38e8c45fSAndroid Build Coastguard Worker
3577*38e8c45fSAndroid Build Coastguard Worker std::vector<std::vector<std::string>> dumpTracesForBugReportCommands = {
3578*38e8c45fSAndroid Build Coastguard Worker {"cmd", "input_method", "tracing", "save-for-bugreport"},
3579*38e8c45fSAndroid Build Coastguard Worker {"cmd", "window", "tracing", "save-for-bugreport"},
3580*38e8c45fSAndroid Build Coastguard Worker {"cmd", "window", "shell", "tracing", "save-for-bugreport"},
3581*38e8c45fSAndroid Build Coastguard Worker };
3582*38e8c45fSAndroid Build Coastguard Worker
3583*38e8c45fSAndroid Build Coastguard Worker if (!android_tracing_perfetto_transition_tracing()) {
3584*38e8c45fSAndroid Build Coastguard Worker dumpTracesForBugReportCommands.push_back({"dumpsys", "activity", "service",
3585*38e8c45fSAndroid Build Coastguard Worker "SystemUIService", "WMShell", "transitions",
3586*38e8c45fSAndroid Build Coastguard Worker "tracing", "save-for-bugreport"});
3587*38e8c45fSAndroid Build Coastguard Worker }
3588*38e8c45fSAndroid Build Coastguard Worker
3589*38e8c45fSAndroid Build Coastguard Worker if (!android_tracing_perfetto_protolog_tracing()) {
3590*38e8c45fSAndroid Build Coastguard Worker dumpTracesForBugReportCommands.push_back({"dumpsys", "activity", "service",
3591*38e8c45fSAndroid Build Coastguard Worker "SystemUIService", "WMShell", "protolog",
3592*38e8c45fSAndroid Build Coastguard Worker "save-for-bugreport"});
3593*38e8c45fSAndroid Build Coastguard Worker }
3594*38e8c45fSAndroid Build Coastguard Worker
3595*38e8c45fSAndroid Build Coastguard Worker for (const auto& command : dumpTracesForBugReportCommands) {
3596*38e8c45fSAndroid Build Coastguard Worker RunCommand(
3597*38e8c45fSAndroid Build Coastguard Worker // Empty name because it's not intended to be classified as a bugreport section.
3598*38e8c45fSAndroid Build Coastguard Worker // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport.
3599*38e8c45fSAndroid Build Coastguard Worker "", command,
3600*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());
3601*38e8c45fSAndroid Build Coastguard Worker }
3602*38e8c45fSAndroid Build Coastguard Worker }
3603*38e8c45fSAndroid Build Coastguard Worker
MaybeAddUiTracesToZip()3604*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::MaybeAddUiTracesToZip() {
3605*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsUserBuild()) {
3606*38e8c45fSAndroid Build Coastguard Worker return;
3607*38e8c45fSAndroid Build Coastguard Worker }
3608*38e8c45fSAndroid Build Coastguard Worker
3609*38e8c45fSAndroid Build Coastguard Worker ds.AddDir(WMTRACE_DATA_DIR, false);
3610*38e8c45fSAndroid Build Coastguard Worker }
3611*38e8c45fSAndroid Build Coastguard Worker
onUiIntensiveBugreportDumpsFinished(int32_t calling_uid)3612*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid) {
3613*38e8c45fSAndroid Build Coastguard Worker if (multiuser_get_app_id(calling_uid) == AID_SHELL || !CalledByApi()) {
3614*38e8c45fSAndroid Build Coastguard Worker return;
3615*38e8c45fSAndroid Build Coastguard Worker }
3616*38e8c45fSAndroid Build Coastguard Worker if (listener_ != nullptr) {
3617*38e8c45fSAndroid Build Coastguard Worker // Let listener know ui intensive bugreport dumps are finished, then it can do event
3618*38e8c45fSAndroid Build Coastguard Worker // handling if required.
3619*38e8c45fSAndroid Build Coastguard Worker listener_->onUiIntensiveBugreportDumpsFinished();
3620*38e8c45fSAndroid Build Coastguard Worker }
3621*38e8c45fSAndroid Build Coastguard Worker }
3622*38e8c45fSAndroid Build Coastguard Worker
MaybeCheckUserConsent(int32_t calling_uid,const std::string & calling_package)3623*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package) {
3624*38e8c45fSAndroid Build Coastguard Worker if (multiuser_get_app_id(calling_uid) == AID_SHELL ||
3625*38e8c45fSAndroid Build Coastguard Worker !CalledByApi() || options_->is_consent_deferred ||
3626*38e8c45fSAndroid Build Coastguard Worker (android::app::admin::flags::onboarding_consentless_bugreports() &&
3627*38e8c45fSAndroid Build Coastguard Worker options_->skip_user_consent)) {
3628*38e8c45fSAndroid Build Coastguard Worker // No need to get consent for shell triggered dumpstates, or not
3629*38e8c45fSAndroid Build Coastguard Worker // through bugreporting API (i.e. no fd to copy back), or when consent
3630*38e8c45fSAndroid Build Coastguard Worker // is deferred.
3631*38e8c45fSAndroid Build Coastguard Worker return;
3632*38e8c45fSAndroid Build Coastguard Worker }
3633*38e8c45fSAndroid Build Coastguard Worker consent_callback_ = new ConsentCallback();
3634*38e8c45fSAndroid Build Coastguard Worker const String16 incidentcompanion("incidentcompanion");
3635*38e8c45fSAndroid Build Coastguard Worker sp<android::IBinder> ics(defaultServiceManager()->getService(incidentcompanion));
3636*38e8c45fSAndroid Build Coastguard Worker android::String16 package(calling_package.c_str());
3637*38e8c45fSAndroid Build Coastguard Worker if (ics != nullptr) {
3638*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Checking user consent via incidentcompanion service\n");
3639*38e8c45fSAndroid Build Coastguard Worker int flags = 0x1; // IncidentManager.FLAG_CONFIRMATION_DIALOG
3640*38e8c45fSAndroid Build Coastguard Worker if (IsConsentlessBugreportAllowed(*options_)) {
3641*38e8c45fSAndroid Build Coastguard Worker flags |= 0x2; // IncidentManager.FLAG_ALLOW_CONSENTLESS_BUGREPORT
3642*38e8c45fSAndroid Build Coastguard Worker }
3643*38e8c45fSAndroid Build Coastguard Worker android::interface_cast<android::os::IIncidentCompanion>(ics)->authorizeReport(
3644*38e8c45fSAndroid Build Coastguard Worker calling_uid, package, String16(), String16(), flags, consent_callback_.get());
3645*38e8c45fSAndroid Build Coastguard Worker } else {
3646*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Unable to check user consent; incidentcompanion service unavailable\n");
3647*38e8c45fSAndroid Build Coastguard Worker }
3648*38e8c45fSAndroid Build Coastguard Worker }
3649*38e8c45fSAndroid Build Coastguard Worker
IsUserConsentDenied() const3650*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::IsUserConsentDenied() const {
3651*38e8c45fSAndroid Build Coastguard Worker return ds.consent_callback_ != nullptr &&
3652*38e8c45fSAndroid Build Coastguard Worker ds.consent_callback_->getResult() == UserConsentResult::DENIED;
3653*38e8c45fSAndroid Build Coastguard Worker }
3654*38e8c45fSAndroid Build Coastguard Worker
CalledByApi() const3655*38e8c45fSAndroid Build Coastguard Worker bool Dumpstate::CalledByApi() const {
3656*38e8c45fSAndroid Build Coastguard Worker return ds.options_->bugreport_fd.get() != -1 ? true : false;
3657*38e8c45fSAndroid Build Coastguard Worker }
3658*38e8c45fSAndroid Build Coastguard Worker
CleanupTmpFiles()3659*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::CleanupTmpFiles() {
3660*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(tmp_path_);
3661*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(screenshot_path_);
3662*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(path_);
3663*38e8c45fSAndroid Build Coastguard Worker if (dump_traces_path != nullptr) {
3664*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(dump_traces_path);
3665*38e8c45fSAndroid Build Coastguard Worker }
3666*38e8c45fSAndroid Build Coastguard Worker }
3667*38e8c45fSAndroid Build Coastguard Worker
EnableParallelRunIfNeeded()3668*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::EnableParallelRunIfNeeded() {
3669*38e8c45fSAndroid Build Coastguard Worker if (!PropertiesHelper::IsParallelRun()) {
3670*38e8c45fSAndroid Build Coastguard Worker return;
3671*38e8c45fSAndroid Build Coastguard Worker }
3672*38e8c45fSAndroid Build Coastguard Worker dump_pool_ = std::make_unique<DumpPool>(bugreport_internal_dir_);
3673*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_ = std::make_unique<TaskQueue>();
3674*38e8c45fSAndroid Build Coastguard Worker }
3675*38e8c45fSAndroid Build Coastguard Worker
ShutdownDumpPool()3676*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::ShutdownDumpPool() {
3677*38e8c45fSAndroid Build Coastguard Worker if (dump_pool_) {
3678*38e8c45fSAndroid Build Coastguard Worker dump_pool_.reset();
3679*38e8c45fSAndroid Build Coastguard Worker }
3680*38e8c45fSAndroid Build Coastguard Worker if (zip_entry_tasks_) {
3681*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_->run(/* do_cancel = */true);
3682*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_ = nullptr;
3683*38e8c45fSAndroid Build Coastguard Worker }
3684*38e8c45fSAndroid Build Coastguard Worker }
3685*38e8c45fSAndroid Build Coastguard Worker
EnqueueAddZipEntryAndCleanupIfNeeded(const std::string & entry_name,const std::string & entry_path)3686*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::EnqueueAddZipEntryAndCleanupIfNeeded(const std::string& entry_name,
3687*38e8c45fSAndroid Build Coastguard Worker const std::string& entry_path) {
3688*38e8c45fSAndroid Build Coastguard Worker auto func_add_zip_entry_and_cleanup = [=](bool task_cancelled) {
3689*38e8c45fSAndroid Build Coastguard Worker if (!task_cancelled) {
3690*38e8c45fSAndroid Build Coastguard Worker AddZipEntry(entry_name, entry_path);
3691*38e8c45fSAndroid Build Coastguard Worker }
3692*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(entry_path);
3693*38e8c45fSAndroid Build Coastguard Worker };
3694*38e8c45fSAndroid Build Coastguard Worker if (zip_entry_tasks_) {
3695*38e8c45fSAndroid Build Coastguard Worker // Enqueues AddZipEntryAndCleanup function if the parallel run is enabled.
3696*38e8c45fSAndroid Build Coastguard Worker zip_entry_tasks_->add(func_add_zip_entry_and_cleanup, _1);
3697*38e8c45fSAndroid Build Coastguard Worker } else {
3698*38e8c45fSAndroid Build Coastguard Worker // Invokes AddZipEntryAndCleanup immediately
3699*38e8c45fSAndroid Build Coastguard Worker std::invoke(func_add_zip_entry_and_cleanup, /* task_cancelled = */false);
3700*38e8c45fSAndroid Build Coastguard Worker }
3701*38e8c45fSAndroid Build Coastguard Worker }
3702*38e8c45fSAndroid Build Coastguard Worker
HandleUserConsentDenied()3703*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::HandleUserConsentDenied() {
3704*38e8c45fSAndroid Build Coastguard Worker MYLOGD("User denied consent; deleting files and returning\n");
3705*38e8c45fSAndroid Build Coastguard Worker CleanupTmpFiles();
3706*38e8c45fSAndroid Build Coastguard Worker return USER_CONSENT_DENIED;
3707*38e8c45fSAndroid Build Coastguard Worker }
3708*38e8c45fSAndroid Build Coastguard Worker
CopyBugreportIfUserConsented(int32_t calling_uid)3709*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::CopyBugreportIfUserConsented(int32_t calling_uid) {
3710*38e8c45fSAndroid Build Coastguard Worker // If the caller has asked to copy the bugreport over to their directory, we need explicit
3711*38e8c45fSAndroid Build Coastguard Worker // user consent (unless the caller is Shell).
3712*38e8c45fSAndroid Build Coastguard Worker UserConsentResult consent_result;
3713*38e8c45fSAndroid Build Coastguard Worker if (multiuser_get_app_id(calling_uid) == AID_SHELL || (options_->skip_user_consent
3714*38e8c45fSAndroid Build Coastguard Worker && android::app::admin::flags::onboarding_consentless_bugreports())) {
3715*38e8c45fSAndroid Build Coastguard Worker consent_result = UserConsentResult::APPROVED;
3716*38e8c45fSAndroid Build Coastguard Worker } else {
3717*38e8c45fSAndroid Build Coastguard Worker consent_result = consent_callback_->getResult();
3718*38e8c45fSAndroid Build Coastguard Worker }
3719*38e8c45fSAndroid Build Coastguard Worker if (consent_result == UserConsentResult::UNAVAILABLE) {
3720*38e8c45fSAndroid Build Coastguard Worker // User has not responded yet.
3721*38e8c45fSAndroid Build Coastguard Worker uint64_t elapsed_ms = consent_callback_->getElapsedTimeMs();
3722*38e8c45fSAndroid Build Coastguard Worker // Telephony is a fast report type, particularly on user builds where information may be
3723*38e8c45fSAndroid Build Coastguard Worker // more aggressively limited. To give the user time to read the consent dialog, increase the
3724*38e8c45fSAndroid Build Coastguard Worker // timeout.
3725*38e8c45fSAndroid Build Coastguard Worker uint64_t timeout_ms = options_->telephony_only ? TELEPHONY_REPORT_USER_CONSENT_TIMEOUT_MS
3726*38e8c45fSAndroid Build Coastguard Worker : USER_CONSENT_TIMEOUT_MS;
3727*38e8c45fSAndroid Build Coastguard Worker if (elapsed_ms < timeout_ms) {
3728*38e8c45fSAndroid Build Coastguard Worker uint delay_seconds = (timeout_ms - elapsed_ms) / 1000;
3729*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Did not receive user consent yet; going to wait for %d seconds", delay_seconds);
3730*38e8c45fSAndroid Build Coastguard Worker sleep(delay_seconds);
3731*38e8c45fSAndroid Build Coastguard Worker }
3732*38e8c45fSAndroid Build Coastguard Worker consent_result = consent_callback_->getResult();
3733*38e8c45fSAndroid Build Coastguard Worker }
3734*38e8c45fSAndroid Build Coastguard Worker if (consent_result == UserConsentResult::DENIED) {
3735*38e8c45fSAndroid Build Coastguard Worker // User has explicitly denied sharing with the app. To be safe delete the
3736*38e8c45fSAndroid Build Coastguard Worker // internal bugreport & tmp files.
3737*38e8c45fSAndroid Build Coastguard Worker return HandleUserConsentDenied();
3738*38e8c45fSAndroid Build Coastguard Worker }
3739*38e8c45fSAndroid Build Coastguard Worker if (consent_result == UserConsentResult::APPROVED) {
3740*38e8c45fSAndroid Build Coastguard Worker bool copy_succeeded = android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
3741*38e8c45fSAndroid Build Coastguard Worker if (copy_succeeded) {
3742*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(path_);
3743*38e8c45fSAndroid Build Coastguard Worker if (options_->do_screenshot &&
3744*38e8c45fSAndroid Build Coastguard Worker options_->screenshot_fd.get() != -1 &&
3745*38e8c45fSAndroid Build Coastguard Worker !options_->is_screenshot_copied) {
3746*38e8c45fSAndroid Build Coastguard Worker bool is_screenshot_copied = android::os::CopyFileToFd(screenshot_path_,
3747*38e8c45fSAndroid Build Coastguard Worker options_->screenshot_fd.get());
3748*38e8c45fSAndroid Build Coastguard Worker if (is_screenshot_copied) {
3749*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(screenshot_path_);
3750*38e8c45fSAndroid Build Coastguard Worker } else {
3751*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to copy screenshot to a permanent file.\n");
3752*38e8c45fSAndroid Build Coastguard Worker is_screenshot_copied = android::os::CopyFileToFd(DEFAULT_SCREENSHOT_PATH,
3753*38e8c45fSAndroid Build Coastguard Worker options_->screenshot_fd.get());
3754*38e8c45fSAndroid Build Coastguard Worker }
3755*38e8c45fSAndroid Build Coastguard Worker options_->is_screenshot_copied = is_screenshot_copied;
3756*38e8c45fSAndroid Build Coastguard Worker }
3757*38e8c45fSAndroid Build Coastguard Worker }
3758*38e8c45fSAndroid Build Coastguard Worker return copy_succeeded ? Dumpstate::RunStatus::OK : Dumpstate::RunStatus::ERROR;
3759*38e8c45fSAndroid Build Coastguard Worker } else if (consent_result == UserConsentResult::UNAVAILABLE) {
3760*38e8c45fSAndroid Build Coastguard Worker // consent_result is still UNAVAILABLE. The user has likely not responded yet.
3761*38e8c45fSAndroid Build Coastguard Worker // Since we do not have user consent to share the bugreport it does not get
3762*38e8c45fSAndroid Build Coastguard Worker // copied over to the calling app but remains in the internal directory from
3763*38e8c45fSAndroid Build Coastguard Worker // where the user can manually pull it.
3764*38e8c45fSAndroid Build Coastguard Worker std::string final_path = GetPath(".zip");
3765*38e8c45fSAndroid Build Coastguard Worker bool copy_succeeded = android::os::CopyFileToFile(path_, final_path);
3766*38e8c45fSAndroid Build Coastguard Worker if (copy_succeeded) {
3767*38e8c45fSAndroid Build Coastguard Worker android::os::UnlinkAndLogOnError(path_);
3768*38e8c45fSAndroid Build Coastguard Worker }
3769*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT;
3770*38e8c45fSAndroid Build Coastguard Worker }
3771*38e8c45fSAndroid Build Coastguard Worker // Unknown result; must be a programming error.
3772*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unknown user consent result:%d\n", consent_result);
3773*38e8c45fSAndroid Build Coastguard Worker return Dumpstate::RunStatus::ERROR;
3774*38e8c45fSAndroid Build Coastguard Worker }
3775*38e8c45fSAndroid Build Coastguard Worker
ParseCommandlineAndRun(int argc,char * argv[])3776*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus Dumpstate::ParseCommandlineAndRun(int argc, char* argv[]) {
3777*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
3778*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = options->Initialize(argc, argv);
3779*38e8c45fSAndroid Build Coastguard Worker if (status == Dumpstate::RunStatus::OK) {
3780*38e8c45fSAndroid Build Coastguard Worker SetOptions(std::move(options));
3781*38e8c45fSAndroid Build Coastguard Worker // When directly running dumpstate binary, the output is not expected to be written
3782*38e8c45fSAndroid Build Coastguard Worker // to any external file descriptor.
3783*38e8c45fSAndroid Build Coastguard Worker assert(options_->bugreport_fd.get() == -1);
3784*38e8c45fSAndroid Build Coastguard Worker
3785*38e8c45fSAndroid Build Coastguard Worker // calling_uid and calling_package are for user consent to share the bugreport with
3786*38e8c45fSAndroid Build Coastguard Worker // an app; they are irrelevant here because bugreport is triggered via command line.
3787*38e8c45fSAndroid Build Coastguard Worker // Update Last ID before calling Run().
3788*38e8c45fSAndroid Build Coastguard Worker Initialize();
3789*38e8c45fSAndroid Build Coastguard Worker status = Run(0 /* calling_uid */, "" /* calling_package */);
3790*38e8c45fSAndroid Build Coastguard Worker }
3791*38e8c45fSAndroid Build Coastguard Worker return status;
3792*38e8c45fSAndroid Build Coastguard Worker }
3793*38e8c45fSAndroid Build Coastguard Worker
3794*38e8c45fSAndroid Build Coastguard Worker /* Main entry point for dumpstate binary. */
run_main(int argc,char * argv[])3795*38e8c45fSAndroid Build Coastguard Worker int run_main(int argc, char* argv[]) {
3796*38e8c45fSAndroid Build Coastguard Worker Dumpstate::RunStatus status = ds.ParseCommandlineAndRun(argc, argv);
3797*38e8c45fSAndroid Build Coastguard Worker
3798*38e8c45fSAndroid Build Coastguard Worker switch (status) {
3799*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::OK:
3800*38e8c45fSAndroid Build Coastguard Worker exit(0);
3801*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::HELP:
3802*38e8c45fSAndroid Build Coastguard Worker ShowUsage();
3803*38e8c45fSAndroid Build Coastguard Worker exit(0);
3804*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::INVALID_INPUT:
3805*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Invalid combination of args\n");
3806*38e8c45fSAndroid Build Coastguard Worker ShowUsage();
3807*38e8c45fSAndroid Build Coastguard Worker exit(1);
3808*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::ERROR:
3809*38e8c45fSAndroid Build Coastguard Worker FALLTHROUGH_INTENDED;
3810*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::USER_CONSENT_DENIED:
3811*38e8c45fSAndroid Build Coastguard Worker FALLTHROUGH_INTENDED;
3812*38e8c45fSAndroid Build Coastguard Worker case Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT:
3813*38e8c45fSAndroid Build Coastguard Worker exit(2);
3814*38e8c45fSAndroid Build Coastguard Worker }
3815*38e8c45fSAndroid Build Coastguard Worker }
3816*38e8c45fSAndroid Build Coastguard Worker
3817*38e8c45fSAndroid Build Coastguard Worker // TODO(111441001): Default DumpOptions to sensible values.
Dumpstate(const std::string & version)3818*38e8c45fSAndroid Build Coastguard Worker Dumpstate::Dumpstate(const std::string& version)
3819*38e8c45fSAndroid Build Coastguard Worker : pid_(getpid()),
3820*38e8c45fSAndroid Build Coastguard Worker options_(new Dumpstate::DumpOptions()),
3821*38e8c45fSAndroid Build Coastguard Worker last_reported_percent_progress_(0),
3822*38e8c45fSAndroid Build Coastguard Worker version_(version),
3823*38e8c45fSAndroid Build Coastguard Worker now_(time(nullptr)),
3824*38e8c45fSAndroid Build Coastguard Worker open_socket_fn_(open_socket) {
3825*38e8c45fSAndroid Build Coastguard Worker }
3826*38e8c45fSAndroid Build Coastguard Worker
GetInstance()3827*38e8c45fSAndroid Build Coastguard Worker Dumpstate& Dumpstate::GetInstance() {
3828*38e8c45fSAndroid Build Coastguard Worker static Dumpstate singleton_(android::base::GetProperty("dumpstate.version", VERSION_CURRENT));
3829*38e8c45fSAndroid Build Coastguard Worker return singleton_;
3830*38e8c45fSAndroid Build Coastguard Worker }
3831*38e8c45fSAndroid Build Coastguard Worker
DurationReporter(const std::string & title,bool logcat_only,bool verbose,int duration_fd)3832*38e8c45fSAndroid Build Coastguard Worker DurationReporter::DurationReporter(const std::string& title, bool logcat_only, bool verbose,
3833*38e8c45fSAndroid Build Coastguard Worker int duration_fd) : title_(title), logcat_only_(logcat_only), verbose_(verbose),
3834*38e8c45fSAndroid Build Coastguard Worker duration_fd_(duration_fd) {
3835*38e8c45fSAndroid Build Coastguard Worker if (!title_.empty()) {
3836*38e8c45fSAndroid Build Coastguard Worker started_ = Nanotime();
3837*38e8c45fSAndroid Build Coastguard Worker if (title_.find("SHOW MAP") == std::string::npos) {
3838*38e8c45fSAndroid Build Coastguard Worker ATRACE_ASYNC_BEGIN(title_.c_str(), 0);
3839*38e8c45fSAndroid Build Coastguard Worker }
3840*38e8c45fSAndroid Build Coastguard Worker }
3841*38e8c45fSAndroid Build Coastguard Worker }
3842*38e8c45fSAndroid Build Coastguard Worker
~DurationReporter()3843*38e8c45fSAndroid Build Coastguard Worker DurationReporter::~DurationReporter() {
3844*38e8c45fSAndroid Build Coastguard Worker if (!title_.empty()) {
3845*38e8c45fSAndroid Build Coastguard Worker float elapsed = (float)(Nanotime() - started_) / NANOS_PER_SEC;
3846*38e8c45fSAndroid Build Coastguard Worker if (elapsed >= 1.0f || verbose_) {
3847*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Duration of '%s': %.2fs\n", title_.c_str(), elapsed);
3848*38e8c45fSAndroid Build Coastguard Worker }
3849*38e8c45fSAndroid Build Coastguard Worker if (!logcat_only_) {
3850*38e8c45fSAndroid Build Coastguard Worker // Use "Yoda grammar" to make it easier to grep|sort sections.
3851*38e8c45fSAndroid Build Coastguard Worker dprintf(duration_fd_, "------ %.3fs was the duration of '%s' ------\n",
3852*38e8c45fSAndroid Build Coastguard Worker elapsed, title_.c_str());
3853*38e8c45fSAndroid Build Coastguard Worker }
3854*38e8c45fSAndroid Build Coastguard Worker if (title_.find("SHOW MAP") == std::string::npos) {
3855*38e8c45fSAndroid Build Coastguard Worker ATRACE_ASYNC_END(title_.c_str(), 0);
3856*38e8c45fSAndroid Build Coastguard Worker }
3857*38e8c45fSAndroid Build Coastguard Worker }
3858*38e8c45fSAndroid Build Coastguard Worker }
3859*38e8c45fSAndroid Build Coastguard Worker
3860*38e8c45fSAndroid Build Coastguard Worker const int32_t Progress::kDefaultMax = 5000;
3861*38e8c45fSAndroid Build Coastguard Worker
Progress(const std::string & path)3862*38e8c45fSAndroid Build Coastguard Worker Progress::Progress(const std::string& path) : Progress(Progress::kDefaultMax, 1.1, path) {
3863*38e8c45fSAndroid Build Coastguard Worker }
3864*38e8c45fSAndroid Build Coastguard Worker
Progress(int32_t initial_max,int32_t progress,float growth_factor)3865*38e8c45fSAndroid Build Coastguard Worker Progress::Progress(int32_t initial_max, int32_t progress, float growth_factor)
3866*38e8c45fSAndroid Build Coastguard Worker : Progress(initial_max, growth_factor, "") {
3867*38e8c45fSAndroid Build Coastguard Worker progress_ = progress;
3868*38e8c45fSAndroid Build Coastguard Worker }
3869*38e8c45fSAndroid Build Coastguard Worker
Progress(int32_t initial_max,float growth_factor,const std::string & path)3870*38e8c45fSAndroid Build Coastguard Worker Progress::Progress(int32_t initial_max, float growth_factor, const std::string& path)
3871*38e8c45fSAndroid Build Coastguard Worker : initial_max_(initial_max),
3872*38e8c45fSAndroid Build Coastguard Worker progress_(0),
3873*38e8c45fSAndroid Build Coastguard Worker max_(initial_max),
3874*38e8c45fSAndroid Build Coastguard Worker growth_factor_(growth_factor),
3875*38e8c45fSAndroid Build Coastguard Worker n_runs_(0),
3876*38e8c45fSAndroid Build Coastguard Worker average_max_(0),
3877*38e8c45fSAndroid Build Coastguard Worker path_(path) {
3878*38e8c45fSAndroid Build Coastguard Worker if (!path_.empty()) {
3879*38e8c45fSAndroid Build Coastguard Worker Load();
3880*38e8c45fSAndroid Build Coastguard Worker }
3881*38e8c45fSAndroid Build Coastguard Worker }
3882*38e8c45fSAndroid Build Coastguard Worker
Load()3883*38e8c45fSAndroid Build Coastguard Worker void Progress::Load() {
3884*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Loading stats from %s\n", path_.c_str());
3885*38e8c45fSAndroid Build Coastguard Worker std::string content;
3886*38e8c45fSAndroid Build Coastguard Worker if (!android::base::ReadFileToString(path_, &content)) {
3887*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Could not read stats from %s; using max of %d\n", path_.c_str(), max_);
3888*38e8c45fSAndroid Build Coastguard Worker return;
3889*38e8c45fSAndroid Build Coastguard Worker }
3890*38e8c45fSAndroid Build Coastguard Worker if (content.empty()) {
3891*38e8c45fSAndroid Build Coastguard Worker MYLOGE("No stats (empty file) on %s; using max of %d\n", path_.c_str(), max_);
3892*38e8c45fSAndroid Build Coastguard Worker return;
3893*38e8c45fSAndroid Build Coastguard Worker }
3894*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> lines = android::base::Split(content, "\n");
3895*38e8c45fSAndroid Build Coastguard Worker
3896*38e8c45fSAndroid Build Coastguard Worker if (lines.size() < 1) {
3897*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Invalid stats on file %s: not enough lines (%d). Using max of %d\n", path_.c_str(),
3898*38e8c45fSAndroid Build Coastguard Worker (int)lines.size(), max_);
3899*38e8c45fSAndroid Build Coastguard Worker return;
3900*38e8c45fSAndroid Build Coastguard Worker }
3901*38e8c45fSAndroid Build Coastguard Worker char* ptr;
3902*38e8c45fSAndroid Build Coastguard Worker n_runs_ = strtol(lines[0].c_str(), &ptr, 10);
3903*38e8c45fSAndroid Build Coastguard Worker average_max_ = strtol(ptr, nullptr, 10);
3904*38e8c45fSAndroid Build Coastguard Worker if (n_runs_ <= 0 || average_max_ <= 0 || n_runs_ > STATS_MAX_N_RUNS ||
3905*38e8c45fSAndroid Build Coastguard Worker average_max_ > STATS_MAX_AVERAGE) {
3906*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Invalid stats line on file %s: %s\n", path_.c_str(), lines[0].c_str());
3907*38e8c45fSAndroid Build Coastguard Worker initial_max_ = Progress::kDefaultMax;
3908*38e8c45fSAndroid Build Coastguard Worker } else {
3909*38e8c45fSAndroid Build Coastguard Worker initial_max_ = average_max_;
3910*38e8c45fSAndroid Build Coastguard Worker }
3911*38e8c45fSAndroid Build Coastguard Worker max_ = initial_max_;
3912*38e8c45fSAndroid Build Coastguard Worker
3913*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Average max progress: %d in %d runs; estimated max: %d\n", average_max_, n_runs_, max_);
3914*38e8c45fSAndroid Build Coastguard Worker }
3915*38e8c45fSAndroid Build Coastguard Worker
Save()3916*38e8c45fSAndroid Build Coastguard Worker void Progress::Save() {
3917*38e8c45fSAndroid Build Coastguard Worker int32_t total = n_runs_ * average_max_ + progress_;
3918*38e8c45fSAndroid Build Coastguard Worker int32_t runs = n_runs_ + 1;
3919*38e8c45fSAndroid Build Coastguard Worker int32_t average = floor(((float)total) / runs);
3920*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Saving stats (total=%d, runs=%d, average=%d) on %s\n", total, runs, average,
3921*38e8c45fSAndroid Build Coastguard Worker path_.c_str());
3922*38e8c45fSAndroid Build Coastguard Worker if (path_.empty()) {
3923*38e8c45fSAndroid Build Coastguard Worker return;
3924*38e8c45fSAndroid Build Coastguard Worker }
3925*38e8c45fSAndroid Build Coastguard Worker
3926*38e8c45fSAndroid Build Coastguard Worker std::string content = android::base::StringPrintf("%d %d\n", runs, average);
3927*38e8c45fSAndroid Build Coastguard Worker if (!android::base::WriteStringToFile(content, path_)) {
3928*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Could not save stats on %s\n", path_.c_str());
3929*38e8c45fSAndroid Build Coastguard Worker }
3930*38e8c45fSAndroid Build Coastguard Worker }
3931*38e8c45fSAndroid Build Coastguard Worker
Get() const3932*38e8c45fSAndroid Build Coastguard Worker int32_t Progress::Get() const {
3933*38e8c45fSAndroid Build Coastguard Worker return progress_;
3934*38e8c45fSAndroid Build Coastguard Worker }
3935*38e8c45fSAndroid Build Coastguard Worker
Inc(int32_t delta_sec)3936*38e8c45fSAndroid Build Coastguard Worker bool Progress::Inc(int32_t delta_sec) {
3937*38e8c45fSAndroid Build Coastguard Worker bool changed = false;
3938*38e8c45fSAndroid Build Coastguard Worker if (delta_sec >= 0) {
3939*38e8c45fSAndroid Build Coastguard Worker progress_ += delta_sec;
3940*38e8c45fSAndroid Build Coastguard Worker if (progress_ > max_) {
3941*38e8c45fSAndroid Build Coastguard Worker int32_t old_max = max_;
3942*38e8c45fSAndroid Build Coastguard Worker max_ = floor((float)progress_ * growth_factor_);
3943*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Adjusting max progress from %d to %d\n", old_max, max_);
3944*38e8c45fSAndroid Build Coastguard Worker changed = true;
3945*38e8c45fSAndroid Build Coastguard Worker }
3946*38e8c45fSAndroid Build Coastguard Worker }
3947*38e8c45fSAndroid Build Coastguard Worker return changed;
3948*38e8c45fSAndroid Build Coastguard Worker }
3949*38e8c45fSAndroid Build Coastguard Worker
GetMax() const3950*38e8c45fSAndroid Build Coastguard Worker int32_t Progress::GetMax() const {
3951*38e8c45fSAndroid Build Coastguard Worker return max_;
3952*38e8c45fSAndroid Build Coastguard Worker }
3953*38e8c45fSAndroid Build Coastguard Worker
GetInitialMax() const3954*38e8c45fSAndroid Build Coastguard Worker int32_t Progress::GetInitialMax() const {
3955*38e8c45fSAndroid Build Coastguard Worker return initial_max_;
3956*38e8c45fSAndroid Build Coastguard Worker }
3957*38e8c45fSAndroid Build Coastguard Worker
Dump(int fd,const std::string & prefix) const3958*38e8c45fSAndroid Build Coastguard Worker void Progress::Dump(int fd, const std::string& prefix) const {
3959*38e8c45fSAndroid Build Coastguard Worker const char* pr = prefix.c_str();
3960*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%sprogress: %d\n", pr, progress_);
3961*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%smax: %d\n", pr, max_);
3962*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%sinitial_max: %d\n", pr, initial_max_);
3963*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%sgrowth_factor: %0.2f\n", pr, growth_factor_);
3964*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%spath: %s\n", pr, path_.c_str());
3965*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%sn_runs: %d\n", pr, n_runs_);
3966*38e8c45fSAndroid Build Coastguard Worker dprintf(fd, "%saverage_max: %d\n", pr, average_max_);
3967*38e8c45fSAndroid Build Coastguard Worker }
3968*38e8c45fSAndroid Build Coastguard Worker
GetPath(const std::string & suffix) const3969*38e8c45fSAndroid Build Coastguard Worker std::string Dumpstate::GetPath(const std::string& suffix) const {
3970*38e8c45fSAndroid Build Coastguard Worker return GetPath(bugreport_internal_dir_, suffix);
3971*38e8c45fSAndroid Build Coastguard Worker }
3972*38e8c45fSAndroid Build Coastguard Worker
GetPath(const std::string & directory,const std::string & suffix) const3973*38e8c45fSAndroid Build Coastguard Worker std::string Dumpstate::GetPath(const std::string& directory, const std::string& suffix) const {
3974*38e8c45fSAndroid Build Coastguard Worker return android::base::StringPrintf("%s/%s-%s%s", directory.c_str(), base_name_.c_str(),
3975*38e8c45fSAndroid Build Coastguard Worker name_.c_str(), suffix.c_str());
3976*38e8c45fSAndroid Build Coastguard Worker }
3977*38e8c45fSAndroid Build Coastguard Worker
SetProgress(std::unique_ptr<Progress> progress)3978*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::SetProgress(std::unique_ptr<Progress> progress) {
3979*38e8c45fSAndroid Build Coastguard Worker progress_ = std::move(progress);
3980*38e8c45fSAndroid Build Coastguard Worker }
3981*38e8c45fSAndroid Build Coastguard Worker
for_each_userid(void (* func)(int),const char * header)3982*38e8c45fSAndroid Build Coastguard Worker void for_each_userid(void (*func)(int), const char *header) {
3983*38e8c45fSAndroid Build Coastguard Worker std::string title = header == nullptr ? "for_each_userid" : android::base::StringPrintf(
3984*38e8c45fSAndroid Build Coastguard Worker "for_each_userid(%s)", header);
3985*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
3986*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
3987*38e8c45fSAndroid Build Coastguard Worker
3988*38e8c45fSAndroid Build Coastguard Worker DIR *d;
3989*38e8c45fSAndroid Build Coastguard Worker struct dirent *de;
3990*38e8c45fSAndroid Build Coastguard Worker
3991*38e8c45fSAndroid Build Coastguard Worker if (header) printf("\n------ %s ------\n", header);
3992*38e8c45fSAndroid Build Coastguard Worker func(0);
3993*38e8c45fSAndroid Build Coastguard Worker
3994*38e8c45fSAndroid Build Coastguard Worker if (!(d = opendir("/data/system/users"))) {
3995*38e8c45fSAndroid Build Coastguard Worker printf("Failed to open /data/system/users (%s)\n", strerror(errno));
3996*38e8c45fSAndroid Build Coastguard Worker return;
3997*38e8c45fSAndroid Build Coastguard Worker }
3998*38e8c45fSAndroid Build Coastguard Worker
3999*38e8c45fSAndroid Build Coastguard Worker while ((de = readdir(d))) {
4000*38e8c45fSAndroid Build Coastguard Worker int userid;
4001*38e8c45fSAndroid Build Coastguard Worker if (de->d_type != DT_DIR || !(userid = atoi(de->d_name))) {
4002*38e8c45fSAndroid Build Coastguard Worker continue;
4003*38e8c45fSAndroid Build Coastguard Worker }
4004*38e8c45fSAndroid Build Coastguard Worker func(userid);
4005*38e8c45fSAndroid Build Coastguard Worker }
4006*38e8c45fSAndroid Build Coastguard Worker
4007*38e8c45fSAndroid Build Coastguard Worker closedir(d);
4008*38e8c45fSAndroid Build Coastguard Worker }
4009*38e8c45fSAndroid Build Coastguard Worker
__for_each_pid(void (* helper)(int,const char *,void *),const char * header,void * arg)4010*38e8c45fSAndroid Build Coastguard Worker static void __for_each_pid(void (*helper)(int, const char *, void *), const char *header, void *arg) {
4011*38e8c45fSAndroid Build Coastguard Worker DIR *d;
4012*38e8c45fSAndroid Build Coastguard Worker struct dirent *de;
4013*38e8c45fSAndroid Build Coastguard Worker
4014*38e8c45fSAndroid Build Coastguard Worker if (!(d = opendir("/proc"))) {
4015*38e8c45fSAndroid Build Coastguard Worker printf("Failed to open /proc (%s)\n", strerror(errno));
4016*38e8c45fSAndroid Build Coastguard Worker return;
4017*38e8c45fSAndroid Build Coastguard Worker }
4018*38e8c45fSAndroid Build Coastguard Worker
4019*38e8c45fSAndroid Build Coastguard Worker if (header) printf("\n------ %s ------\n", header);
4020*38e8c45fSAndroid Build Coastguard Worker while ((de = readdir(d))) {
4021*38e8c45fSAndroid Build Coastguard Worker if (ds.IsUserConsentDenied()) {
4022*38e8c45fSAndroid Build Coastguard Worker MYLOGE(
4023*38e8c45fSAndroid Build Coastguard Worker "Returning early because user denied consent to share bugreport with calling app.");
4024*38e8c45fSAndroid Build Coastguard Worker closedir(d);
4025*38e8c45fSAndroid Build Coastguard Worker return;
4026*38e8c45fSAndroid Build Coastguard Worker }
4027*38e8c45fSAndroid Build Coastguard Worker int pid;
4028*38e8c45fSAndroid Build Coastguard Worker int fd;
4029*38e8c45fSAndroid Build Coastguard Worker char cmdpath[255];
4030*38e8c45fSAndroid Build Coastguard Worker char cmdline[255];
4031*38e8c45fSAndroid Build Coastguard Worker
4032*38e8c45fSAndroid Build Coastguard Worker if (!(pid = atoi(de->d_name))) {
4033*38e8c45fSAndroid Build Coastguard Worker continue;
4034*38e8c45fSAndroid Build Coastguard Worker }
4035*38e8c45fSAndroid Build Coastguard Worker
4036*38e8c45fSAndroid Build Coastguard Worker memset(cmdline, 0, sizeof(cmdline));
4037*38e8c45fSAndroid Build Coastguard Worker
4038*38e8c45fSAndroid Build Coastguard Worker snprintf(cmdpath, sizeof(cmdpath), "/proc/%d/cmdline", pid);
4039*38e8c45fSAndroid Build Coastguard Worker if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) >= 0) {
4040*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(read(fd, cmdline, sizeof(cmdline) - 2));
4041*38e8c45fSAndroid Build Coastguard Worker close(fd);
4042*38e8c45fSAndroid Build Coastguard Worker if (cmdline[0]) {
4043*38e8c45fSAndroid Build Coastguard Worker helper(pid, cmdline, arg);
4044*38e8c45fSAndroid Build Coastguard Worker continue;
4045*38e8c45fSAndroid Build Coastguard Worker }
4046*38e8c45fSAndroid Build Coastguard Worker }
4047*38e8c45fSAndroid Build Coastguard Worker
4048*38e8c45fSAndroid Build Coastguard Worker // if no cmdline, a kernel thread has comm
4049*38e8c45fSAndroid Build Coastguard Worker snprintf(cmdpath, sizeof(cmdpath), "/proc/%d/comm", pid);
4050*38e8c45fSAndroid Build Coastguard Worker if ((fd = TEMP_FAILURE_RETRY(open(cmdpath, O_RDONLY | O_CLOEXEC))) >= 0) {
4051*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(read(fd, cmdline + 1, sizeof(cmdline) - 4));
4052*38e8c45fSAndroid Build Coastguard Worker close(fd);
4053*38e8c45fSAndroid Build Coastguard Worker if (cmdline[1]) {
4054*38e8c45fSAndroid Build Coastguard Worker cmdline[0] = '[';
4055*38e8c45fSAndroid Build Coastguard Worker size_t len = strcspn(cmdline, "\f\b\r\n");
4056*38e8c45fSAndroid Build Coastguard Worker cmdline[len] = ']';
4057*38e8c45fSAndroid Build Coastguard Worker cmdline[len+1] = '\0';
4058*38e8c45fSAndroid Build Coastguard Worker }
4059*38e8c45fSAndroid Build Coastguard Worker }
4060*38e8c45fSAndroid Build Coastguard Worker if (!cmdline[0]) {
4061*38e8c45fSAndroid Build Coastguard Worker strcpy(cmdline, "N/A");
4062*38e8c45fSAndroid Build Coastguard Worker }
4063*38e8c45fSAndroid Build Coastguard Worker helper(pid, cmdline, arg);
4064*38e8c45fSAndroid Build Coastguard Worker }
4065*38e8c45fSAndroid Build Coastguard Worker
4066*38e8c45fSAndroid Build Coastguard Worker closedir(d);
4067*38e8c45fSAndroid Build Coastguard Worker }
4068*38e8c45fSAndroid Build Coastguard Worker
for_each_pid_helper(int pid,const char * cmdline,void * arg)4069*38e8c45fSAndroid Build Coastguard Worker static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
4070*38e8c45fSAndroid Build Coastguard Worker for_each_pid_func *func = (for_each_pid_func*) arg;
4071*38e8c45fSAndroid Build Coastguard Worker func(pid, cmdline);
4072*38e8c45fSAndroid Build Coastguard Worker }
4073*38e8c45fSAndroid Build Coastguard Worker
for_each_pid(for_each_pid_func func,const char * header)4074*38e8c45fSAndroid Build Coastguard Worker void for_each_pid(for_each_pid_func func, const char *header) {
4075*38e8c45fSAndroid Build Coastguard Worker std::string title = header == nullptr ? "for_each_pid"
4076*38e8c45fSAndroid Build Coastguard Worker : android::base::StringPrintf("for_each_pid(%s)", header);
4077*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
4078*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4079*38e8c45fSAndroid Build Coastguard Worker
4080*38e8c45fSAndroid Build Coastguard Worker __for_each_pid(for_each_pid_helper, header, (void *) func);
4081*38e8c45fSAndroid Build Coastguard Worker }
4082*38e8c45fSAndroid Build Coastguard Worker
for_each_tid_helper(int pid,const char * cmdline,void * arg)4083*38e8c45fSAndroid Build Coastguard Worker static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
4084*38e8c45fSAndroid Build Coastguard Worker DIR *d;
4085*38e8c45fSAndroid Build Coastguard Worker struct dirent *de;
4086*38e8c45fSAndroid Build Coastguard Worker char taskpath[255];
4087*38e8c45fSAndroid Build Coastguard Worker for_each_tid_func *func = (for_each_tid_func *) arg;
4088*38e8c45fSAndroid Build Coastguard Worker
4089*38e8c45fSAndroid Build Coastguard Worker snprintf(taskpath, sizeof(taskpath), "/proc/%d/task", pid);
4090*38e8c45fSAndroid Build Coastguard Worker
4091*38e8c45fSAndroid Build Coastguard Worker if (!(d = opendir(taskpath))) {
4092*38e8c45fSAndroid Build Coastguard Worker printf("Failed to open %s (%s)\n", taskpath, strerror(errno));
4093*38e8c45fSAndroid Build Coastguard Worker return;
4094*38e8c45fSAndroid Build Coastguard Worker }
4095*38e8c45fSAndroid Build Coastguard Worker
4096*38e8c45fSAndroid Build Coastguard Worker func(pid, pid, cmdline);
4097*38e8c45fSAndroid Build Coastguard Worker
4098*38e8c45fSAndroid Build Coastguard Worker while ((de = readdir(d))) {
4099*38e8c45fSAndroid Build Coastguard Worker if (ds.IsUserConsentDenied()) {
4100*38e8c45fSAndroid Build Coastguard Worker MYLOGE(
4101*38e8c45fSAndroid Build Coastguard Worker "Returning early because user denied consent to share bugreport with calling app.");
4102*38e8c45fSAndroid Build Coastguard Worker closedir(d);
4103*38e8c45fSAndroid Build Coastguard Worker return;
4104*38e8c45fSAndroid Build Coastguard Worker }
4105*38e8c45fSAndroid Build Coastguard Worker int tid;
4106*38e8c45fSAndroid Build Coastguard Worker int fd;
4107*38e8c45fSAndroid Build Coastguard Worker char commpath[255];
4108*38e8c45fSAndroid Build Coastguard Worker char comm[255];
4109*38e8c45fSAndroid Build Coastguard Worker
4110*38e8c45fSAndroid Build Coastguard Worker if (!(tid = atoi(de->d_name))) {
4111*38e8c45fSAndroid Build Coastguard Worker continue;
4112*38e8c45fSAndroid Build Coastguard Worker }
4113*38e8c45fSAndroid Build Coastguard Worker
4114*38e8c45fSAndroid Build Coastguard Worker if (tid == pid)
4115*38e8c45fSAndroid Build Coastguard Worker continue;
4116*38e8c45fSAndroid Build Coastguard Worker
4117*38e8c45fSAndroid Build Coastguard Worker snprintf(commpath, sizeof(commpath), "/proc/%d/comm", tid);
4118*38e8c45fSAndroid Build Coastguard Worker memset(comm, 0, sizeof(comm));
4119*38e8c45fSAndroid Build Coastguard Worker if ((fd = TEMP_FAILURE_RETRY(open(commpath, O_RDONLY | O_CLOEXEC))) < 0) {
4120*38e8c45fSAndroid Build Coastguard Worker strcpy(comm, "N/A");
4121*38e8c45fSAndroid Build Coastguard Worker } else {
4122*38e8c45fSAndroid Build Coastguard Worker char *c;
4123*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(read(fd, comm, sizeof(comm) - 2));
4124*38e8c45fSAndroid Build Coastguard Worker close(fd);
4125*38e8c45fSAndroid Build Coastguard Worker
4126*38e8c45fSAndroid Build Coastguard Worker c = strrchr(comm, '\n');
4127*38e8c45fSAndroid Build Coastguard Worker if (c) {
4128*38e8c45fSAndroid Build Coastguard Worker *c = '\0';
4129*38e8c45fSAndroid Build Coastguard Worker }
4130*38e8c45fSAndroid Build Coastguard Worker }
4131*38e8c45fSAndroid Build Coastguard Worker func(pid, tid, comm);
4132*38e8c45fSAndroid Build Coastguard Worker }
4133*38e8c45fSAndroid Build Coastguard Worker
4134*38e8c45fSAndroid Build Coastguard Worker closedir(d);
4135*38e8c45fSAndroid Build Coastguard Worker }
4136*38e8c45fSAndroid Build Coastguard Worker
for_each_tid(for_each_tid_func func,const char * header)4137*38e8c45fSAndroid Build Coastguard Worker void for_each_tid(for_each_tid_func func, const char *header) {
4138*38e8c45fSAndroid Build Coastguard Worker std::string title = header == nullptr ? "for_each_tid"
4139*38e8c45fSAndroid Build Coastguard Worker : android::base::StringPrintf("for_each_tid(%s)", header);
4140*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
4141*38e8c45fSAndroid Build Coastguard Worker
4142*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4143*38e8c45fSAndroid Build Coastguard Worker
4144*38e8c45fSAndroid Build Coastguard Worker __for_each_pid(for_each_tid_helper, header, (void *) func);
4145*38e8c45fSAndroid Build Coastguard Worker }
4146*38e8c45fSAndroid Build Coastguard Worker
show_wchan(int pid,int tid,const char * name)4147*38e8c45fSAndroid Build Coastguard Worker void show_wchan(int pid, int tid, const char *name) {
4148*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4149*38e8c45fSAndroid Build Coastguard Worker
4150*38e8c45fSAndroid Build Coastguard Worker char path[255];
4151*38e8c45fSAndroid Build Coastguard Worker char buffer[255];
4152*38e8c45fSAndroid Build Coastguard Worker int fd, ret, save_errno;
4153*38e8c45fSAndroid Build Coastguard Worker char name_buffer[255];
4154*38e8c45fSAndroid Build Coastguard Worker
4155*38e8c45fSAndroid Build Coastguard Worker memset(buffer, 0, sizeof(buffer));
4156*38e8c45fSAndroid Build Coastguard Worker
4157*38e8c45fSAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/proc/%d/wchan", tid);
4158*38e8c45fSAndroid Build Coastguard Worker if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
4159*38e8c45fSAndroid Build Coastguard Worker printf("Failed to open '%s' (%s)\n", path, strerror(errno));
4160*38e8c45fSAndroid Build Coastguard Worker return;
4161*38e8c45fSAndroid Build Coastguard Worker }
4162*38e8c45fSAndroid Build Coastguard Worker
4163*38e8c45fSAndroid Build Coastguard Worker ret = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
4164*38e8c45fSAndroid Build Coastguard Worker save_errno = errno;
4165*38e8c45fSAndroid Build Coastguard Worker close(fd);
4166*38e8c45fSAndroid Build Coastguard Worker
4167*38e8c45fSAndroid Build Coastguard Worker if (ret < 0) {
4168*38e8c45fSAndroid Build Coastguard Worker printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
4169*38e8c45fSAndroid Build Coastguard Worker return;
4170*38e8c45fSAndroid Build Coastguard Worker }
4171*38e8c45fSAndroid Build Coastguard Worker
4172*38e8c45fSAndroid Build Coastguard Worker snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
4173*38e8c45fSAndroid Build Coastguard Worker pid == tid ? 0 : 3, "", name);
4174*38e8c45fSAndroid Build Coastguard Worker
4175*38e8c45fSAndroid Build Coastguard Worker printf("%-7d %-32s %s\n", tid, name_buffer, buffer);
4176*38e8c45fSAndroid Build Coastguard Worker
4177*38e8c45fSAndroid Build Coastguard Worker return;
4178*38e8c45fSAndroid Build Coastguard Worker }
4179*38e8c45fSAndroid Build Coastguard Worker
4180*38e8c45fSAndroid Build Coastguard Worker // print time in centiseconds
snprcent(char * buffer,size_t len,size_t spc,unsigned long long time)4181*38e8c45fSAndroid Build Coastguard Worker static void snprcent(char *buffer, size_t len, size_t spc,
4182*38e8c45fSAndroid Build Coastguard Worker unsigned long long time) {
4183*38e8c45fSAndroid Build Coastguard Worker static long hz; // cache discovered hz
4184*38e8c45fSAndroid Build Coastguard Worker
4185*38e8c45fSAndroid Build Coastguard Worker if (hz <= 0) {
4186*38e8c45fSAndroid Build Coastguard Worker hz = sysconf(_SC_CLK_TCK);
4187*38e8c45fSAndroid Build Coastguard Worker if (hz <= 0) {
4188*38e8c45fSAndroid Build Coastguard Worker hz = 1000;
4189*38e8c45fSAndroid Build Coastguard Worker }
4190*38e8c45fSAndroid Build Coastguard Worker }
4191*38e8c45fSAndroid Build Coastguard Worker
4192*38e8c45fSAndroid Build Coastguard Worker // convert to centiseconds
4193*38e8c45fSAndroid Build Coastguard Worker time = (time * 100 + (hz / 2)) / hz;
4194*38e8c45fSAndroid Build Coastguard Worker
4195*38e8c45fSAndroid Build Coastguard Worker char str[16];
4196*38e8c45fSAndroid Build Coastguard Worker
4197*38e8c45fSAndroid Build Coastguard Worker snprintf(str, sizeof(str), " %llu.%02u",
4198*38e8c45fSAndroid Build Coastguard Worker time / 100, (unsigned)(time % 100));
4199*38e8c45fSAndroid Build Coastguard Worker size_t offset = strlen(buffer);
4200*38e8c45fSAndroid Build Coastguard Worker snprintf(buffer + offset, (len > offset) ? len - offset : 0,
4201*38e8c45fSAndroid Build Coastguard Worker "%*s", (spc > offset) ? (int)(spc - offset) : 0, str);
4202*38e8c45fSAndroid Build Coastguard Worker }
4203*38e8c45fSAndroid Build Coastguard Worker
4204*38e8c45fSAndroid Build Coastguard Worker // print permille as a percent
snprdec(char * buffer,size_t len,size_t spc,unsigned permille)4205*38e8c45fSAndroid Build Coastguard Worker static void snprdec(char *buffer, size_t len, size_t spc, unsigned permille) {
4206*38e8c45fSAndroid Build Coastguard Worker char str[16];
4207*38e8c45fSAndroid Build Coastguard Worker
4208*38e8c45fSAndroid Build Coastguard Worker snprintf(str, sizeof(str), " %u.%u%%", permille / 10, permille % 10);
4209*38e8c45fSAndroid Build Coastguard Worker size_t offset = strlen(buffer);
4210*38e8c45fSAndroid Build Coastguard Worker snprintf(buffer + offset, (len > offset) ? len - offset : 0,
4211*38e8c45fSAndroid Build Coastguard Worker "%*s", (spc > offset) ? (int)(spc - offset) : 0, str);
4212*38e8c45fSAndroid Build Coastguard Worker }
4213*38e8c45fSAndroid Build Coastguard Worker
show_showtime(int pid,const char * name)4214*38e8c45fSAndroid Build Coastguard Worker void show_showtime(int pid, const char *name) {
4215*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4216*38e8c45fSAndroid Build Coastguard Worker
4217*38e8c45fSAndroid Build Coastguard Worker char path[255];
4218*38e8c45fSAndroid Build Coastguard Worker char buffer[1023];
4219*38e8c45fSAndroid Build Coastguard Worker int fd, ret, save_errno;
4220*38e8c45fSAndroid Build Coastguard Worker
4221*38e8c45fSAndroid Build Coastguard Worker memset(buffer, 0, sizeof(buffer));
4222*38e8c45fSAndroid Build Coastguard Worker
4223*38e8c45fSAndroid Build Coastguard Worker snprintf(path, sizeof(path), "/proc/%d/stat", pid);
4224*38e8c45fSAndroid Build Coastguard Worker if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
4225*38e8c45fSAndroid Build Coastguard Worker printf("Failed to open '%s' (%s)\n", path, strerror(errno));
4226*38e8c45fSAndroid Build Coastguard Worker return;
4227*38e8c45fSAndroid Build Coastguard Worker }
4228*38e8c45fSAndroid Build Coastguard Worker
4229*38e8c45fSAndroid Build Coastguard Worker ret = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
4230*38e8c45fSAndroid Build Coastguard Worker save_errno = errno;
4231*38e8c45fSAndroid Build Coastguard Worker close(fd);
4232*38e8c45fSAndroid Build Coastguard Worker
4233*38e8c45fSAndroid Build Coastguard Worker if (ret < 0) {
4234*38e8c45fSAndroid Build Coastguard Worker printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
4235*38e8c45fSAndroid Build Coastguard Worker return;
4236*38e8c45fSAndroid Build Coastguard Worker }
4237*38e8c45fSAndroid Build Coastguard Worker
4238*38e8c45fSAndroid Build Coastguard Worker // field 14 is utime
4239*38e8c45fSAndroid Build Coastguard Worker // field 15 is stime
4240*38e8c45fSAndroid Build Coastguard Worker // field 42 is iotime
4241*38e8c45fSAndroid Build Coastguard Worker unsigned long long utime = 0, stime = 0, iotime = 0;
4242*38e8c45fSAndroid Build Coastguard Worker if (sscanf(buffer,
4243*38e8c45fSAndroid Build Coastguard Worker "%*u %*s %*s %*d %*d %*d %*d %*d %*d %*d %*d "
4244*38e8c45fSAndroid Build Coastguard Worker "%*d %*d %llu %llu %*d %*d %*d %*d %*d %*d "
4245*38e8c45fSAndroid Build Coastguard Worker "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
4246*38e8c45fSAndroid Build Coastguard Worker "%*d %*d %*d %*d %*d %*d %*d %*d %*d %llu ",
4247*38e8c45fSAndroid Build Coastguard Worker &utime, &stime, &iotime) != 3) {
4248*38e8c45fSAndroid Build Coastguard Worker return;
4249*38e8c45fSAndroid Build Coastguard Worker }
4250*38e8c45fSAndroid Build Coastguard Worker
4251*38e8c45fSAndroid Build Coastguard Worker unsigned long long total = utime + stime;
4252*38e8c45fSAndroid Build Coastguard Worker if (!total) {
4253*38e8c45fSAndroid Build Coastguard Worker return;
4254*38e8c45fSAndroid Build Coastguard Worker }
4255*38e8c45fSAndroid Build Coastguard Worker
4256*38e8c45fSAndroid Build Coastguard Worker unsigned permille = (iotime * 1000 + (total / 2)) / total;
4257*38e8c45fSAndroid Build Coastguard Worker if (permille > 1000) {
4258*38e8c45fSAndroid Build Coastguard Worker permille = 1000;
4259*38e8c45fSAndroid Build Coastguard Worker }
4260*38e8c45fSAndroid Build Coastguard Worker
4261*38e8c45fSAndroid Build Coastguard Worker // try to beautify and stabilize columns at <80 characters
4262*38e8c45fSAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "%-6d%s", pid, name);
4263*38e8c45fSAndroid Build Coastguard Worker if ((name[0] != '[') || utime) {
4264*38e8c45fSAndroid Build Coastguard Worker snprcent(buffer, sizeof(buffer), 57, utime);
4265*38e8c45fSAndroid Build Coastguard Worker }
4266*38e8c45fSAndroid Build Coastguard Worker snprcent(buffer, sizeof(buffer), 65, stime);
4267*38e8c45fSAndroid Build Coastguard Worker if ((name[0] != '[') || iotime) {
4268*38e8c45fSAndroid Build Coastguard Worker snprcent(buffer, sizeof(buffer), 73, iotime);
4269*38e8c45fSAndroid Build Coastguard Worker }
4270*38e8c45fSAndroid Build Coastguard Worker if (iotime) {
4271*38e8c45fSAndroid Build Coastguard Worker snprdec(buffer, sizeof(buffer), 79, permille);
4272*38e8c45fSAndroid Build Coastguard Worker }
4273*38e8c45fSAndroid Build Coastguard Worker puts(buffer); // adds a trailing newline
4274*38e8c45fSAndroid Build Coastguard Worker
4275*38e8c45fSAndroid Build Coastguard Worker return;
4276*38e8c45fSAndroid Build Coastguard Worker }
4277*38e8c45fSAndroid Build Coastguard Worker
do_dmesg()4278*38e8c45fSAndroid Build Coastguard Worker void do_dmesg() {
4279*38e8c45fSAndroid Build Coastguard Worker const char *title = "KERNEL LOG (dmesg)";
4280*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
4281*38e8c45fSAndroid Build Coastguard Worker printf("------ %s ------\n", title);
4282*38e8c45fSAndroid Build Coastguard Worker
4283*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4284*38e8c45fSAndroid Build Coastguard Worker
4285*38e8c45fSAndroid Build Coastguard Worker /* Get size of kernel buffer */
4286*38e8c45fSAndroid Build Coastguard Worker int size = klogctl(KLOG_SIZE_BUFFER, nullptr, 0);
4287*38e8c45fSAndroid Build Coastguard Worker if (size <= 0) {
4288*38e8c45fSAndroid Build Coastguard Worker printf("Unexpected klogctl return value: %d\n\n", size);
4289*38e8c45fSAndroid Build Coastguard Worker return;
4290*38e8c45fSAndroid Build Coastguard Worker }
4291*38e8c45fSAndroid Build Coastguard Worker char *buf = (char *) malloc(size + 1);
4292*38e8c45fSAndroid Build Coastguard Worker if (buf == nullptr) {
4293*38e8c45fSAndroid Build Coastguard Worker printf("memory allocation failed\n\n");
4294*38e8c45fSAndroid Build Coastguard Worker return;
4295*38e8c45fSAndroid Build Coastguard Worker }
4296*38e8c45fSAndroid Build Coastguard Worker int retval = klogctl(KLOG_READ_ALL, buf, size);
4297*38e8c45fSAndroid Build Coastguard Worker if (retval < 0) {
4298*38e8c45fSAndroid Build Coastguard Worker printf("klogctl failure\n\n");
4299*38e8c45fSAndroid Build Coastguard Worker free(buf);
4300*38e8c45fSAndroid Build Coastguard Worker return;
4301*38e8c45fSAndroid Build Coastguard Worker }
4302*38e8c45fSAndroid Build Coastguard Worker buf[retval] = '\0';
4303*38e8c45fSAndroid Build Coastguard Worker printf("%s\n\n", buf);
4304*38e8c45fSAndroid Build Coastguard Worker free(buf);
4305*38e8c45fSAndroid Build Coastguard Worker return;
4306*38e8c45fSAndroid Build Coastguard Worker }
4307*38e8c45fSAndroid Build Coastguard Worker
DumpFile(const std::string & title,const std::string & path)4308*38e8c45fSAndroid Build Coastguard Worker int Dumpstate::DumpFile(const std::string& title, const std::string& path) {
4309*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
4310*38e8c45fSAndroid Build Coastguard Worker
4311*38e8c45fSAndroid Build Coastguard Worker int status = DumpFileToFd(STDOUT_FILENO, title, path);
4312*38e8c45fSAndroid Build Coastguard Worker
4313*38e8c45fSAndroid Build Coastguard Worker UpdateProgress(WEIGHT_FILE);
4314*38e8c45fSAndroid Build Coastguard Worker
4315*38e8c45fSAndroid Build Coastguard Worker return status;
4316*38e8c45fSAndroid Build Coastguard Worker }
4317*38e8c45fSAndroid Build Coastguard Worker
read_file_as_long(const char * path,long int * output)4318*38e8c45fSAndroid Build Coastguard Worker int read_file_as_long(const char *path, long int *output) {
4319*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
4320*38e8c45fSAndroid Build Coastguard Worker if (fd.get() < 0) {
4321*38e8c45fSAndroid Build Coastguard Worker int err = errno;
4322*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Error opening file descriptor for %s: %s\n", path, strerror(err));
4323*38e8c45fSAndroid Build Coastguard Worker return -1;
4324*38e8c45fSAndroid Build Coastguard Worker }
4325*38e8c45fSAndroid Build Coastguard Worker char buffer[50];
4326*38e8c45fSAndroid Build Coastguard Worker ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer, sizeof(buffer)));
4327*38e8c45fSAndroid Build Coastguard Worker if (bytes_read == -1) {
4328*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Error reading file %s: %s\n", path, strerror(errno));
4329*38e8c45fSAndroid Build Coastguard Worker return -2;
4330*38e8c45fSAndroid Build Coastguard Worker }
4331*38e8c45fSAndroid Build Coastguard Worker if (bytes_read == 0) {
4332*38e8c45fSAndroid Build Coastguard Worker MYLOGE("File %s is empty\n", path);
4333*38e8c45fSAndroid Build Coastguard Worker return -3;
4334*38e8c45fSAndroid Build Coastguard Worker }
4335*38e8c45fSAndroid Build Coastguard Worker *output = atoi(buffer);
4336*38e8c45fSAndroid Build Coastguard Worker return 0;
4337*38e8c45fSAndroid Build Coastguard Worker }
4338*38e8c45fSAndroid Build Coastguard Worker
4339*38e8c45fSAndroid Build Coastguard Worker /* calls skip to gate calling dump_from_fd recursively
4340*38e8c45fSAndroid Build Coastguard Worker * in the specified directory. dump_from_fd defaults to
4341*38e8c45fSAndroid Build Coastguard Worker * dump_file_from_fd above when set to NULL. skip defaults
4342*38e8c45fSAndroid Build Coastguard Worker * to false when set to NULL. dump_from_fd will always be
4343*38e8c45fSAndroid Build Coastguard Worker * called with title NULL.
4344*38e8c45fSAndroid Build Coastguard Worker */
dump_files(const std::string & title,const char * dir,bool (* skip)(const char * path),int (* dump_from_fd)(const char * title,const char * path,int fd))4345*38e8c45fSAndroid Build Coastguard Worker int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
4346*38e8c45fSAndroid Build Coastguard Worker int (*dump_from_fd)(const char* title, const char* path, int fd)) {
4347*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title);
4348*38e8c45fSAndroid Build Coastguard Worker DIR *dirp;
4349*38e8c45fSAndroid Build Coastguard Worker struct dirent *d;
4350*38e8c45fSAndroid Build Coastguard Worker char *newpath = nullptr;
4351*38e8c45fSAndroid Build Coastguard Worker const char *slash = "/";
4352*38e8c45fSAndroid Build Coastguard Worker int retval = 0;
4353*38e8c45fSAndroid Build Coastguard Worker
4354*38e8c45fSAndroid Build Coastguard Worker if (!title.empty()) {
4355*38e8c45fSAndroid Build Coastguard Worker printf("------ %s (%s) ------\n", title.c_str(), dir);
4356*38e8c45fSAndroid Build Coastguard Worker }
4357*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return 0;
4358*38e8c45fSAndroid Build Coastguard Worker
4359*38e8c45fSAndroid Build Coastguard Worker if (dir[strlen(dir) - 1] == '/') {
4360*38e8c45fSAndroid Build Coastguard Worker ++slash;
4361*38e8c45fSAndroid Build Coastguard Worker }
4362*38e8c45fSAndroid Build Coastguard Worker dirp = opendir(dir);
4363*38e8c45fSAndroid Build Coastguard Worker if (dirp == nullptr) {
4364*38e8c45fSAndroid Build Coastguard Worker retval = -errno;
4365*38e8c45fSAndroid Build Coastguard Worker MYLOGE("%s: %s\n", dir, strerror(errno));
4366*38e8c45fSAndroid Build Coastguard Worker return retval;
4367*38e8c45fSAndroid Build Coastguard Worker }
4368*38e8c45fSAndroid Build Coastguard Worker
4369*38e8c45fSAndroid Build Coastguard Worker if (!dump_from_fd) {
4370*38e8c45fSAndroid Build Coastguard Worker dump_from_fd = dump_file_from_fd;
4371*38e8c45fSAndroid Build Coastguard Worker }
4372*38e8c45fSAndroid Build Coastguard Worker for (; ((d = readdir(dirp))); free(newpath), newpath = nullptr) {
4373*38e8c45fSAndroid Build Coastguard Worker if ((d->d_name[0] == '.')
4374*38e8c45fSAndroid Build Coastguard Worker && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
4375*38e8c45fSAndroid Build Coastguard Worker || (d->d_name[1] == '\0'))) {
4376*38e8c45fSAndroid Build Coastguard Worker continue;
4377*38e8c45fSAndroid Build Coastguard Worker }
4378*38e8c45fSAndroid Build Coastguard Worker asprintf(&newpath, "%s%s%s%s", dir, slash, d->d_name,
4379*38e8c45fSAndroid Build Coastguard Worker (d->d_type == DT_DIR) ? "/" : "");
4380*38e8c45fSAndroid Build Coastguard Worker if (!newpath) {
4381*38e8c45fSAndroid Build Coastguard Worker retval = -errno;
4382*38e8c45fSAndroid Build Coastguard Worker continue;
4383*38e8c45fSAndroid Build Coastguard Worker }
4384*38e8c45fSAndroid Build Coastguard Worker if (skip && (*skip)(newpath)) {
4385*38e8c45fSAndroid Build Coastguard Worker continue;
4386*38e8c45fSAndroid Build Coastguard Worker }
4387*38e8c45fSAndroid Build Coastguard Worker if (d->d_type == DT_DIR) {
4388*38e8c45fSAndroid Build Coastguard Worker int ret = dump_files("", newpath, skip, dump_from_fd);
4389*38e8c45fSAndroid Build Coastguard Worker if (ret < 0) {
4390*38e8c45fSAndroid Build Coastguard Worker retval = ret;
4391*38e8c45fSAndroid Build Coastguard Worker }
4392*38e8c45fSAndroid Build Coastguard Worker continue;
4393*38e8c45fSAndroid Build Coastguard Worker }
4394*38e8c45fSAndroid Build Coastguard Worker android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC)));
4395*38e8c45fSAndroid Build Coastguard Worker if (fd.get() < 0) {
4396*38e8c45fSAndroid Build Coastguard Worker retval = -1;
4397*38e8c45fSAndroid Build Coastguard Worker printf("*** %s: %s\n", newpath, strerror(errno));
4398*38e8c45fSAndroid Build Coastguard Worker continue;
4399*38e8c45fSAndroid Build Coastguard Worker }
4400*38e8c45fSAndroid Build Coastguard Worker (*dump_from_fd)(nullptr, newpath, fd.get());
4401*38e8c45fSAndroid Build Coastguard Worker }
4402*38e8c45fSAndroid Build Coastguard Worker closedir(dirp);
4403*38e8c45fSAndroid Build Coastguard Worker if (!title.empty()) {
4404*38e8c45fSAndroid Build Coastguard Worker printf("\n");
4405*38e8c45fSAndroid Build Coastguard Worker }
4406*38e8c45fSAndroid Build Coastguard Worker return retval;
4407*38e8c45fSAndroid Build Coastguard Worker }
4408*38e8c45fSAndroid Build Coastguard Worker
4409*38e8c45fSAndroid Build Coastguard Worker /* fd must have been opened with the flag O_NONBLOCK. With this flag set,
4410*38e8c45fSAndroid Build Coastguard Worker * it's possible to avoid issues where opening the file itself can get
4411*38e8c45fSAndroid Build Coastguard Worker * stuck.
4412*38e8c45fSAndroid Build Coastguard Worker */
dump_file_from_fd(const char * title,const char * path,int fd)4413*38e8c45fSAndroid Build Coastguard Worker int dump_file_from_fd(const char *title, const char *path, int fd) {
4414*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return 0;
4415*38e8c45fSAndroid Build Coastguard Worker
4416*38e8c45fSAndroid Build Coastguard Worker int flags = fcntl(fd, F_GETFL);
4417*38e8c45fSAndroid Build Coastguard Worker if (flags == -1) {
4418*38e8c45fSAndroid Build Coastguard Worker printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
4419*38e8c45fSAndroid Build Coastguard Worker return -1;
4420*38e8c45fSAndroid Build Coastguard Worker } else if (!(flags & O_NONBLOCK)) {
4421*38e8c45fSAndroid Build Coastguard Worker printf("*** %s: fd must have O_NONBLOCK set.\n", path);
4422*38e8c45fSAndroid Build Coastguard Worker return -1;
4423*38e8c45fSAndroid Build Coastguard Worker }
4424*38e8c45fSAndroid Build Coastguard Worker return DumpFileFromFdToFd(title, path, fd, STDOUT_FILENO, PropertiesHelper::IsDryRun());
4425*38e8c45fSAndroid Build Coastguard Worker }
4426*38e8c45fSAndroid Build Coastguard Worker
RunCommand(const std::string & title,const std::vector<std::string> & full_command,const CommandOptions & options,bool verbose_duration,int out_fd)4427*38e8c45fSAndroid Build Coastguard Worker int Dumpstate::RunCommand(const std::string& title, const std::vector<std::string>& full_command,
4428*38e8c45fSAndroid Build Coastguard Worker const CommandOptions& options, bool verbose_duration, int out_fd) {
4429*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter(title, false /* logcat_only */,
4430*38e8c45fSAndroid Build Coastguard Worker verbose_duration, out_fd);
4431*38e8c45fSAndroid Build Coastguard Worker
4432*38e8c45fSAndroid Build Coastguard Worker int status = RunCommandToFd(out_fd, title, full_command, options);
4433*38e8c45fSAndroid Build Coastguard Worker
4434*38e8c45fSAndroid Build Coastguard Worker /* TODO: for now we're simplifying the progress calculation by using the
4435*38e8c45fSAndroid Build Coastguard Worker * timeout as the weight. It's a good approximation for most cases, except when calling dumpsys,
4436*38e8c45fSAndroid Build Coastguard Worker * where its weight should be much higher proportionally to its timeout.
4437*38e8c45fSAndroid Build Coastguard Worker * Ideally, it should use a options.EstimatedDuration() instead...*/
4438*38e8c45fSAndroid Build Coastguard Worker UpdateProgress(options.Timeout());
4439*38e8c45fSAndroid Build Coastguard Worker
4440*38e8c45fSAndroid Build Coastguard Worker return status;
4441*38e8c45fSAndroid Build Coastguard Worker }
4442*38e8c45fSAndroid Build Coastguard Worker
RunDumpsys(const std::string & title,const std::vector<std::string> & dumpsys_args,const CommandOptions & options,long dumpsysTimeoutMs,int out_fd)4443*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args,
4444*38e8c45fSAndroid Build Coastguard Worker const CommandOptions& options, long dumpsysTimeoutMs, int out_fd) {
4445*38e8c45fSAndroid Build Coastguard Worker long timeout_ms = dumpsysTimeoutMs > 0 ? dumpsysTimeoutMs : options.TimeoutInMs();
4446*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string> dumpsys = {"/system/bin/dumpsys", "-T", std::to_string(timeout_ms)};
4447*38e8c45fSAndroid Build Coastguard Worker dumpsys.insert(dumpsys.end(), dumpsys_args.begin(), dumpsys_args.end());
4448*38e8c45fSAndroid Build Coastguard Worker RunCommand(title, dumpsys, options, false, out_fd);
4449*38e8c45fSAndroid Build Coastguard Worker }
4450*38e8c45fSAndroid Build Coastguard Worker
open_socket(const char * service)4451*38e8c45fSAndroid Build Coastguard Worker static int open_socket(const char* service) {
4452*38e8c45fSAndroid Build Coastguard Worker int s = android_get_control_socket(service);
4453*38e8c45fSAndroid Build Coastguard Worker if (s < 0) {
4454*38e8c45fSAndroid Build Coastguard Worker MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno));
4455*38e8c45fSAndroid Build Coastguard Worker return -1;
4456*38e8c45fSAndroid Build Coastguard Worker }
4457*38e8c45fSAndroid Build Coastguard Worker fcntl(s, F_SETFD, FD_CLOEXEC);
4458*38e8c45fSAndroid Build Coastguard Worker
4459*38e8c45fSAndroid Build Coastguard Worker // Set backlog to 0 to make sure that queue size will be minimum.
4460*38e8c45fSAndroid Build Coastguard Worker // In Linux, because the minimum queue will be 1, connect() will be blocked
4461*38e8c45fSAndroid Build Coastguard Worker // if the other clients already called connect() and the connection request was not accepted.
4462*38e8c45fSAndroid Build Coastguard Worker if (listen(s, 0) < 0) {
4463*38e8c45fSAndroid Build Coastguard Worker MYLOGE("listen(control socket): %s\n", strerror(errno));
4464*38e8c45fSAndroid Build Coastguard Worker return -1;
4465*38e8c45fSAndroid Build Coastguard Worker }
4466*38e8c45fSAndroid Build Coastguard Worker
4467*38e8c45fSAndroid Build Coastguard Worker struct sockaddr addr;
4468*38e8c45fSAndroid Build Coastguard Worker socklen_t alen = sizeof(addr);
4469*38e8c45fSAndroid Build Coastguard Worker int fd = accept4(s, &addr, &alen, SOCK_CLOEXEC);
4470*38e8c45fSAndroid Build Coastguard Worker
4471*38e8c45fSAndroid Build Coastguard Worker // Close socket just after accept(), to make sure that connect() by client will get error
4472*38e8c45fSAndroid Build Coastguard Worker // when the socket is used by the other services.
4473*38e8c45fSAndroid Build Coastguard Worker // There is still a race condition possibility between accept and close, but there is no way
4474*38e8c45fSAndroid Build Coastguard Worker // to close-on-accept atomically.
4475*38e8c45fSAndroid Build Coastguard Worker // See detail; b/123306389#comment25
4476*38e8c45fSAndroid Build Coastguard Worker close(s);
4477*38e8c45fSAndroid Build Coastguard Worker
4478*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
4479*38e8c45fSAndroid Build Coastguard Worker MYLOGE("accept(control socket): %s\n", strerror(errno));
4480*38e8c45fSAndroid Build Coastguard Worker return -1;
4481*38e8c45fSAndroid Build Coastguard Worker }
4482*38e8c45fSAndroid Build Coastguard Worker
4483*38e8c45fSAndroid Build Coastguard Worker return fd;
4484*38e8c45fSAndroid Build Coastguard Worker }
4485*38e8c45fSAndroid Build Coastguard Worker
4486*38e8c45fSAndroid Build Coastguard Worker // TODO: should call is_valid_output_file and/or be merged into it.
create_parent_dirs(const char * path)4487*38e8c45fSAndroid Build Coastguard Worker void create_parent_dirs(const char *path) {
4488*38e8c45fSAndroid Build Coastguard Worker char *chp = const_cast<char *> (path);
4489*38e8c45fSAndroid Build Coastguard Worker
4490*38e8c45fSAndroid Build Coastguard Worker /* skip initial slash */
4491*38e8c45fSAndroid Build Coastguard Worker if (chp[0] == '/')
4492*38e8c45fSAndroid Build Coastguard Worker chp++;
4493*38e8c45fSAndroid Build Coastguard Worker
4494*38e8c45fSAndroid Build Coastguard Worker /* create leading directories, if necessary */
4495*38e8c45fSAndroid Build Coastguard Worker struct stat dir_stat;
4496*38e8c45fSAndroid Build Coastguard Worker while (chp && chp[0]) {
4497*38e8c45fSAndroid Build Coastguard Worker chp = strchr(chp, '/');
4498*38e8c45fSAndroid Build Coastguard Worker if (chp) {
4499*38e8c45fSAndroid Build Coastguard Worker *chp = 0;
4500*38e8c45fSAndroid Build Coastguard Worker if (stat(path, &dir_stat) == -1 || !S_ISDIR(dir_stat.st_mode)) {
4501*38e8c45fSAndroid Build Coastguard Worker MYLOGI("Creating directory %s\n", path);
4502*38e8c45fSAndroid Build Coastguard Worker if (mkdir(path, 0770)) { /* drwxrwx--- */
4503*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to create directory %s: %s\n", path, strerror(errno));
4504*38e8c45fSAndroid Build Coastguard Worker } else if (chown(path, AID_SHELL, AID_SHELL)) {
4505*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Unable to change ownership of dir %s: %s\n", path, strerror(errno));
4506*38e8c45fSAndroid Build Coastguard Worker }
4507*38e8c45fSAndroid Build Coastguard Worker }
4508*38e8c45fSAndroid Build Coastguard Worker *chp++ = '/';
4509*38e8c45fSAndroid Build Coastguard Worker }
4510*38e8c45fSAndroid Build Coastguard Worker }
4511*38e8c45fSAndroid Build Coastguard Worker }
4512*38e8c45fSAndroid Build Coastguard Worker
_redirect_to_file(FILE * redirect,char * path,int truncate_flag)4513*38e8c45fSAndroid Build Coastguard Worker bool _redirect_to_file(FILE* redirect, char* path, int truncate_flag) {
4514*38e8c45fSAndroid Build Coastguard Worker create_parent_dirs(path);
4515*38e8c45fSAndroid Build Coastguard Worker
4516*38e8c45fSAndroid Build Coastguard Worker int fd = TEMP_FAILURE_RETRY(open(path,
4517*38e8c45fSAndroid Build Coastguard Worker O_WRONLY | O_CREAT | truncate_flag | O_CLOEXEC | O_NOFOLLOW,
4518*38e8c45fSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
4519*38e8c45fSAndroid Build Coastguard Worker if (fd < 0) {
4520*38e8c45fSAndroid Build Coastguard Worker MYLOGE("%s: %s\n", path, strerror(errno));
4521*38e8c45fSAndroid Build Coastguard Worker return false;
4522*38e8c45fSAndroid Build Coastguard Worker }
4523*38e8c45fSAndroid Build Coastguard Worker
4524*38e8c45fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect)));
4525*38e8c45fSAndroid Build Coastguard Worker close(fd);
4526*38e8c45fSAndroid Build Coastguard Worker return true;
4527*38e8c45fSAndroid Build Coastguard Worker }
4528*38e8c45fSAndroid Build Coastguard Worker
redirect_to_file(FILE * redirect,char * path)4529*38e8c45fSAndroid Build Coastguard Worker bool redirect_to_file(FILE* redirect, char* path) {
4530*38e8c45fSAndroid Build Coastguard Worker return _redirect_to_file(redirect, path, O_TRUNC);
4531*38e8c45fSAndroid Build Coastguard Worker }
4532*38e8c45fSAndroid Build Coastguard Worker
redirect_to_existing_file(FILE * redirect,char * path)4533*38e8c45fSAndroid Build Coastguard Worker bool redirect_to_existing_file(FILE* redirect, char* path) {
4534*38e8c45fSAndroid Build Coastguard Worker return _redirect_to_file(redirect, path, O_APPEND);
4535*38e8c45fSAndroid Build Coastguard Worker }
4536*38e8c45fSAndroid Build Coastguard Worker
dump_route_tables()4537*38e8c45fSAndroid Build Coastguard Worker void dump_route_tables() {
4538*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("DUMP ROUTE TABLES");
4539*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4540*38e8c45fSAndroid Build Coastguard Worker const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
4541*38e8c45fSAndroid Build Coastguard Worker ds.DumpFile("RT_TABLES", RT_TABLES_PATH);
4542*38e8c45fSAndroid Build Coastguard Worker FILE* fp = fopen(RT_TABLES_PATH, "re");
4543*38e8c45fSAndroid Build Coastguard Worker if (!fp) {
4544*38e8c45fSAndroid Build Coastguard Worker printf("*** %s: %s\n", RT_TABLES_PATH, strerror(errno));
4545*38e8c45fSAndroid Build Coastguard Worker return;
4546*38e8c45fSAndroid Build Coastguard Worker }
4547*38e8c45fSAndroid Build Coastguard Worker char table[16];
4548*38e8c45fSAndroid Build Coastguard Worker // Each line has an integer (the table number), a space, and a string (the table name). We only
4549*38e8c45fSAndroid Build Coastguard Worker // need the table number. It's a 32-bit unsigned number, so max 10 chars. Skip the table name.
4550*38e8c45fSAndroid Build Coastguard Worker // Add a fixed max limit so this doesn't go awry.
4551*38e8c45fSAndroid Build Coastguard Worker for (int i = 0; i < 64 && fscanf(fp, " %10s %*s", table) == 1; ++i) {
4552*38e8c45fSAndroid Build Coastguard Worker RunCommand("ROUTE TABLE IPv4", {"ip", "-4", "route", "show", "table", table});
4553*38e8c45fSAndroid Build Coastguard Worker RunCommand("ROUTE TABLE IPv6", {"ip", "-6", "route", "show", "table", table});
4554*38e8c45fSAndroid Build Coastguard Worker }
4555*38e8c45fSAndroid Build Coastguard Worker fclose(fp);
4556*38e8c45fSAndroid Build Coastguard Worker }
4557*38e8c45fSAndroid Build Coastguard Worker
dump_frozen_cgroupfs(const char * dir,int level,int (* dump_from_fd)(const char * title,const char * path,int fd))4558*38e8c45fSAndroid Build Coastguard Worker void dump_frozen_cgroupfs(const char *dir, int level,
4559*38e8c45fSAndroid Build Coastguard Worker int (*dump_from_fd)(const char* title, const char* path, int fd)) {
4560*38e8c45fSAndroid Build Coastguard Worker DIR *dirp;
4561*38e8c45fSAndroid Build Coastguard Worker struct dirent *d;
4562*38e8c45fSAndroid Build Coastguard Worker char *newpath = nullptr;
4563*38e8c45fSAndroid Build Coastguard Worker
4564*38e8c45fSAndroid Build Coastguard Worker dirp = opendir(dir);
4565*38e8c45fSAndroid Build Coastguard Worker if (dirp == nullptr) {
4566*38e8c45fSAndroid Build Coastguard Worker MYLOGE("%s: %s\n", dir, strerror(errno));
4567*38e8c45fSAndroid Build Coastguard Worker return;
4568*38e8c45fSAndroid Build Coastguard Worker }
4569*38e8c45fSAndroid Build Coastguard Worker
4570*38e8c45fSAndroid Build Coastguard Worker for (; ((d = readdir(dirp))); free(newpath), newpath = nullptr) {
4571*38e8c45fSAndroid Build Coastguard Worker if ((d->d_name[0] == '.')
4572*38e8c45fSAndroid Build Coastguard Worker && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
4573*38e8c45fSAndroid Build Coastguard Worker || (d->d_name[1] == '\0'))) {
4574*38e8c45fSAndroid Build Coastguard Worker continue;
4575*38e8c45fSAndroid Build Coastguard Worker }
4576*38e8c45fSAndroid Build Coastguard Worker if (d->d_type == DT_DIR) {
4577*38e8c45fSAndroid Build Coastguard Worker asprintf(&newpath, "%s/%s/", dir, d->d_name);
4578*38e8c45fSAndroid Build Coastguard Worker if (!newpath) {
4579*38e8c45fSAndroid Build Coastguard Worker continue;
4580*38e8c45fSAndroid Build Coastguard Worker }
4581*38e8c45fSAndroid Build Coastguard Worker if (level == 0 && !strncmp(d->d_name, "uid_", 4)) {
4582*38e8c45fSAndroid Build Coastguard Worker dump_frozen_cgroupfs(newpath, 1, dump_from_fd);
4583*38e8c45fSAndroid Build Coastguard Worker } else if (level == 1 && !strncmp(d->d_name, "pid_", 4)) {
4584*38e8c45fSAndroid Build Coastguard Worker char *freezer = nullptr;
4585*38e8c45fSAndroid Build Coastguard Worker asprintf(&freezer, "%s/%s", newpath, "cgroup.freeze");
4586*38e8c45fSAndroid Build Coastguard Worker if (freezer) {
4587*38e8c45fSAndroid Build Coastguard Worker FILE* fp = fopen(freezer, "r");
4588*38e8c45fSAndroid Build Coastguard Worker if (fp != NULL) {
4589*38e8c45fSAndroid Build Coastguard Worker int frozen;
4590*38e8c45fSAndroid Build Coastguard Worker fscanf(fp, "%d", &frozen);
4591*38e8c45fSAndroid Build Coastguard Worker if (frozen > 0) {
4592*38e8c45fSAndroid Build Coastguard Worker dump_files("", newpath, skip_none, dump_from_fd);
4593*38e8c45fSAndroid Build Coastguard Worker }
4594*38e8c45fSAndroid Build Coastguard Worker fclose(fp);
4595*38e8c45fSAndroid Build Coastguard Worker }
4596*38e8c45fSAndroid Build Coastguard Worker free(freezer);
4597*38e8c45fSAndroid Build Coastguard Worker }
4598*38e8c45fSAndroid Build Coastguard Worker }
4599*38e8c45fSAndroid Build Coastguard Worker }
4600*38e8c45fSAndroid Build Coastguard Worker }
4601*38e8c45fSAndroid Build Coastguard Worker closedir(dirp);
4602*38e8c45fSAndroid Build Coastguard Worker }
4603*38e8c45fSAndroid Build Coastguard Worker
dump_frozen_cgroupfs()4604*38e8c45fSAndroid Build Coastguard Worker void dump_frozen_cgroupfs() {
4605*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Adding frozen processes from %s\n", CGROUPFS_DIR);
4606*38e8c45fSAndroid Build Coastguard Worker DurationReporter duration_reporter("FROZEN CGROUPFS");
4607*38e8c45fSAndroid Build Coastguard Worker if (PropertiesHelper::IsDryRun()) return;
4608*38e8c45fSAndroid Build Coastguard Worker dump_frozen_cgroupfs(CGROUPFS_DIR, 0, _add_file_from_fd);
4609*38e8c45fSAndroid Build Coastguard Worker }
4610*38e8c45fSAndroid Build Coastguard Worker
UpdateProgress(int32_t delta_sec)4611*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::UpdateProgress(int32_t delta_sec) {
4612*38e8c45fSAndroid Build Coastguard Worker if (progress_ == nullptr) {
4613*38e8c45fSAndroid Build Coastguard Worker MYLOGE("UpdateProgress: progress_ not set\n");
4614*38e8c45fSAndroid Build Coastguard Worker return;
4615*38e8c45fSAndroid Build Coastguard Worker }
4616*38e8c45fSAndroid Build Coastguard Worker // This function updates progress related members of the dumpstate and reports
4617*38e8c45fSAndroid Build Coastguard Worker // progress percentage to the bugreport client. Since it could be called by
4618*38e8c45fSAndroid Build Coastguard Worker // different dump tasks at the same time if the parallel run is enabled, a
4619*38e8c45fSAndroid Build Coastguard Worker // mutex lock is necessary here to synchronize the call.
4620*38e8c45fSAndroid Build Coastguard Worker std::lock_guard<std::recursive_mutex> lock(mutex_);
4621*38e8c45fSAndroid Build Coastguard Worker
4622*38e8c45fSAndroid Build Coastguard Worker // Always update progess so stats can be tuned...
4623*38e8c45fSAndroid Build Coastguard Worker progress_->Inc(delta_sec);
4624*38e8c45fSAndroid Build Coastguard Worker
4625*38e8c45fSAndroid Build Coastguard Worker // ...but only notifiy listeners when necessary.
4626*38e8c45fSAndroid Build Coastguard Worker if (!options_->do_progress_updates) return;
4627*38e8c45fSAndroid Build Coastguard Worker
4628*38e8c45fSAndroid Build Coastguard Worker int progress = progress_->Get();
4629*38e8c45fSAndroid Build Coastguard Worker int max = progress_->GetMax();
4630*38e8c45fSAndroid Build Coastguard Worker int percent = 100 * progress / max;
4631*38e8c45fSAndroid Build Coastguard Worker
4632*38e8c45fSAndroid Build Coastguard Worker if (last_reported_percent_progress_ > 0 && percent <= last_reported_percent_progress_) {
4633*38e8c45fSAndroid Build Coastguard Worker return;
4634*38e8c45fSAndroid Build Coastguard Worker }
4635*38e8c45fSAndroid Build Coastguard Worker last_reported_percent_progress_ = percent;
4636*38e8c45fSAndroid Build Coastguard Worker
4637*38e8c45fSAndroid Build Coastguard Worker if (control_socket_fd_ >= 0) {
4638*38e8c45fSAndroid Build Coastguard Worker dprintf(control_socket_fd_, "PROGRESS:%d/%d\n", progress, max);
4639*38e8c45fSAndroid Build Coastguard Worker fsync(control_socket_fd_);
4640*38e8c45fSAndroid Build Coastguard Worker }
4641*38e8c45fSAndroid Build Coastguard Worker
4642*38e8c45fSAndroid Build Coastguard Worker if (listener_ != nullptr) {
4643*38e8c45fSAndroid Build Coastguard Worker if (percent % 10 == 0) {
4644*38e8c45fSAndroid Build Coastguard Worker // We don't want to spam logcat, so only log multiples of 10.
4645*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Setting progress: %d/%d (%d%%)\n", progress, max, percent);
4646*38e8c45fSAndroid Build Coastguard Worker } else {
4647*38e8c45fSAndroid Build Coastguard Worker // stderr is ignored on normal invocations, but useful when calling
4648*38e8c45fSAndroid Build Coastguard Worker // /system/bin/dumpstate directly for debuggging.
4649*38e8c45fSAndroid Build Coastguard Worker fprintf(stderr, "Setting progress: %d/%d (%d%%)\n", progress, max, percent);
4650*38e8c45fSAndroid Build Coastguard Worker }
4651*38e8c45fSAndroid Build Coastguard Worker
4652*38e8c45fSAndroid Build Coastguard Worker listener_->onProgress(percent);
4653*38e8c45fSAndroid Build Coastguard Worker }
4654*38e8c45fSAndroid Build Coastguard Worker }
4655*38e8c45fSAndroid Build Coastguard Worker
TakeScreenshot(const std::string & path)4656*38e8c45fSAndroid Build Coastguard Worker void Dumpstate::TakeScreenshot(const std::string& path) {
4657*38e8c45fSAndroid Build Coastguard Worker const std::string& real_path = path.empty() ? screenshot_path_ : path;
4658*38e8c45fSAndroid Build Coastguard Worker int status =
4659*38e8c45fSAndroid Build Coastguard Worker RunCommand("", {"screencap", "-p", real_path},
4660*38e8c45fSAndroid Build Coastguard Worker CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());
4661*38e8c45fSAndroid Build Coastguard Worker if (status == 0) {
4662*38e8c45fSAndroid Build Coastguard Worker MYLOGD("Screenshot saved on %s\n", real_path.c_str());
4663*38e8c45fSAndroid Build Coastguard Worker } else {
4664*38e8c45fSAndroid Build Coastguard Worker MYLOGE("Failed to take screenshot on %s\n", real_path.c_str());
4665*38e8c45fSAndroid Build Coastguard Worker }
4666*38e8c45fSAndroid Build Coastguard Worker if (listener_ != nullptr) {
4667*38e8c45fSAndroid Build Coastguard Worker // Show a visual indication to indicate screenshot is taken via
4668*38e8c45fSAndroid Build Coastguard Worker // IDumpstateListener.onScreenshotTaken()
4669*38e8c45fSAndroid Build Coastguard Worker listener_->onScreenshotTaken(status == 0);
4670*38e8c45fSAndroid Build Coastguard Worker }
4671*38e8c45fSAndroid Build Coastguard Worker }
4672*38e8c45fSAndroid Build Coastguard Worker
is_dir(const char * pathname)4673*38e8c45fSAndroid Build Coastguard Worker bool is_dir(const char* pathname) {
4674*38e8c45fSAndroid Build Coastguard Worker struct stat info;
4675*38e8c45fSAndroid Build Coastguard Worker if (stat(pathname, &info) == -1) {
4676*38e8c45fSAndroid Build Coastguard Worker return false;
4677*38e8c45fSAndroid Build Coastguard Worker }
4678*38e8c45fSAndroid Build Coastguard Worker return S_ISDIR(info.st_mode);
4679*38e8c45fSAndroid Build Coastguard Worker }
4680*38e8c45fSAndroid Build Coastguard Worker
get_mtime(int fd,time_t default_mtime)4681*38e8c45fSAndroid Build Coastguard Worker time_t get_mtime(int fd, time_t default_mtime) {
4682*38e8c45fSAndroid Build Coastguard Worker struct stat info;
4683*38e8c45fSAndroid Build Coastguard Worker if (fstat(fd, &info) == -1) {
4684*38e8c45fSAndroid Build Coastguard Worker return default_mtime;
4685*38e8c45fSAndroid Build Coastguard Worker }
4686*38e8c45fSAndroid Build Coastguard Worker return info.st_mtime;
4687*38e8c45fSAndroid Build Coastguard Worker }
4688