arc: Implement smaller dumpstate output
Adds a -L commandline option to indicate a much smaller set of
dumpstate output safe for feedback reports.
Implements output of system logcat, event logs, networking, and dropbox
system server crash/system app crashes only.
Bug: 142684959
Bug: 136273873
Test: atest dumpstate_test
Change-Id: I1d564b949d0a44ff9cc014302d79703294a13d78
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 5359619..942c16c 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1367,6 +1367,46 @@
printf("\n");
}
+static void DumpstateLimitedOnly() {
+ // Trimmed-down version of dumpstate to only include a whitelisted
+ // set of logs (system log, event log, and system server / system app
+ // crashes, and networking logs). See b/136273873 and b/138459828
+ // for context.
+ DurationReporter duration_reporter("DUMPSTATE");
+ unsigned long timeout_ms;
+ // calculate timeout
+ timeout_ms = logcat_timeout({"main", "system", "crash"});
+ RunCommand("SYSTEM LOG",
+ {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
+ CommandOptions::WithTimeoutInMs(timeout_ms).Build());
+ timeout_ms = logcat_timeout({"events"});
+ RunCommand(
+ "EVENT LOG",
+ {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
+ CommandOptions::WithTimeoutInMs(timeout_ms).Build());
+
+ printf("========================================================\n");
+ printf("== Networking Service\n");
+ printf("========================================================\n");
+
+ RunDumpsys("DUMPSYS NETWORK_SERVICE_LIMITED", {"wifi", "-a"},
+ CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
+
+ printf("========================================================\n");
+ printf("== Dropbox crashes\n");
+ printf("========================================================\n");
+
+ RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {"dropbox", "-p", "system_server_crash"});
+ RunDumpsys("DROPBOX SYSTEM APP CRASHES", {"dropbox", "-p", "system_app_crash"});
+
+ printf("========================================================\n");
+ printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
+ ds.progress_->GetMax(), ds.progress_->GetInitialMax());
+ printf("========================================================\n");
+ printf("== dumpstate: done (id %d)\n", ds.id_);
+ printf("========================================================\n");
+}
+
// Dumps various things. Returns early with status USER_CONSENT_DENIED if user denies consent
// via the consent they are shown. Ignores other errors that occur while running various
// commands. The consent checking is currently done around long running tasks, which happen to
@@ -2053,7 +2093,7 @@
static void ShowUsage() {
fprintf(stderr,
"usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-d] [-p] "
- "[-z] [-s] [-S] [-q] [-P] [-R] [-V version]\n"
+ "[-z] [-s] [-S] [-q] [-P] [-R] [-L] [-V version]\n"
" -h: display this help message\n"
" -b: play sound file instead of vibrate, at beginning of job\n"
" -e: play sound file instead of vibrate, at end of job\n"
@@ -2066,6 +2106,7 @@
" -P: send broadcast when started and do progress updates\n"
" -R: take bugreport in remote mode (requires -z and -d, shouldn't be used with -P)\n"
" -w: start binder service and make it wait for a call to startBugreport\n"
+ " -L: output limited information that is safe for submission in feedback reports\n"
" -v: prints the dumpstate header and exit\n");
}
@@ -2311,13 +2352,12 @@
"do_zip_file: %d do_vibrate: %d use_socket: %d use_control_socket: %d do_screenshot: %d "
"is_remote_mode: %d show_header_only: %d do_start_service: %d telephony_only: %d "
"wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s dumpstate_hal_mode: %s "
- "args: %s\n",
+ "limited_only: %d args: %s\n",
options.do_zip_file, options.do_vibrate, options.use_socket, options.use_control_socket,
options.do_screenshot, options.is_remote_mode, options.show_header_only,
- options.do_start_service,
- options.telephony_only, options.wifi_only, options.do_progress_updates,
- options.bugreport_fd.get(), options.bugreport_mode.c_str(),
- toString(options.dumpstate_hal_mode).c_str(), options.args.c_str());
+ options.do_start_service, options.telephony_only, options.wifi_only,
+ options.do_progress_updates, options.bugreport_fd.get(), options.bugreport_mode.c_str(),
+ toString(options.dumpstate_hal_mode).c_str(), options.limited_only, options.args.c_str());
}
void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
@@ -2339,7 +2379,7 @@
Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) {
RunStatus status = RunStatus::OK;
int c;
- while ((c = getopt(argc, argv, "dho:svqzpPBRSV:w")) != -1) {
+ while ((c = getopt(argc, argv, "dho:svqzpLPBRSV:w")) != -1) {
switch (c) {
// clang-format off
case 'd': do_add_date = true; break;
@@ -2351,6 +2391,7 @@
case 'p': do_screenshot = true; break;
case 'P': do_progress_updates = true; break;
case 'R': is_remote_mode = true; break;
+ case 'L': limited_only = true; break;
case 'V': break; // compatibility no-op
case 'w':
// This was already processed
@@ -2635,6 +2676,7 @@
// duration is logged into MYLOG instead.
PrintHeader();
+ // TODO(b/158737089) reduce code repetition in if branches
if (options_->telephony_only) {
MaybeTakeEarlyScreenshot();
onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
@@ -2646,6 +2688,11 @@
onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
MaybeCheckUserConsent(calling_uid, calling_package);
DumpstateWifiOnly();
+ } else if (options_->limited_only) {
+ MaybeTakeEarlyScreenshot();
+ onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
+ MaybeCheckUserConsent(calling_uid, calling_package);
+ DumpstateLimitedOnly();
} else {
// Invoke critical dumpsys first to preserve system state, before doing anything else.
RunDumpsysCritical();
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 28d8936..dc0848a 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -377,6 +377,8 @@
bool do_start_service = false;
bool telephony_only = false;
bool wifi_only = false;
+ // Trimmed-down version of dumpstate to only include whitelisted logs.
+ bool limited_only = false;
// Whether progress updates should be published.
bool do_progress_updates = false;
// The mode we'll use when calling IDumpstateDevice::dumpstateBoard.
diff --git a/cmds/dumpstate/main.cpp b/cmds/dumpstate/main.cpp
index 68d3733..ec89c0d 100644
--- a/cmds/dumpstate/main.cpp
+++ b/cmds/dumpstate/main.cpp
@@ -30,7 +30,7 @@
bool do_wait = false;
int c;
// Keep flags in sync with Dumpstate::DumpOptions::Initialize.
- while ((c = getopt(argc, argv, "wdho:svqzpPBRSV:")) != -1 && !do_wait) {
+ while ((c = getopt(argc, argv, "dho:svqzpLPBRSV:w")) != -1 && !do_wait) {
switch (c) {
case 'w':
do_wait = true;
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 9871a3b..e94e51c 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -179,6 +179,7 @@
EXPECT_FALSE(options_.do_screenshot);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.limited_only);
EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
@@ -206,6 +207,7 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
@@ -231,6 +233,7 @@
EXPECT_FALSE(options_.do_screenshot);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.limited_only);
EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
@@ -249,6 +252,7 @@
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
EXPECT_FALSE(options_.do_start_service);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
@@ -266,6 +270,7 @@
EXPECT_FALSE(options_.show_header_only);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
@@ -282,6 +287,7 @@
EXPECT_FALSE(options_.show_header_only);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializeWearBugReport) {
@@ -299,6 +305,7 @@
EXPECT_FALSE(options_.show_header_only);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
@@ -316,6 +323,7 @@
EXPECT_FALSE(options_.show_header_only);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
@@ -333,6 +341,37 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
+ EXPECT_FALSE(options_.limited_only);
+}
+
+TEST_F(DumpOptionsTest, InitializeLimitedOnlyBugreport) {
+ // clang-format off
+ char* argv[] = {
+ const_cast<char*>("dumpstatez"),
+ const_cast<char*>("-S"),
+ const_cast<char*>("-d"),
+ const_cast<char*>("-z"),
+ const_cast<char*>("-q"),
+ const_cast<char*>("-L")
+ };
+ // clang-format on
+
+ Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+ EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+ EXPECT_TRUE(options_.do_add_date);
+ EXPECT_TRUE(options_.do_zip_file);
+ EXPECT_TRUE(options_.use_control_socket);
+ EXPECT_FALSE(options_.do_vibrate);
+ EXPECT_TRUE(options_.limited_only);
+
+ // Other options retain default values
+ EXPECT_FALSE(options_.show_header_only);
+ EXPECT_FALSE(options_.do_screenshot);
+ EXPECT_FALSE(options_.do_progress_updates);
+ EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.use_socket);
+ EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
@@ -361,6 +400,7 @@
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.use_socket);
EXPECT_FALSE(options_.wifi_only);
+ EXPECT_FALSE(options_.limited_only);
}
TEST_F(DumpOptionsTest, InitializePartial1) {
@@ -390,6 +430,7 @@
EXPECT_FALSE(options_.do_screenshot);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
+ EXPECT_FALSE(options_.limited_only);
EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
@@ -419,6 +460,7 @@
EXPECT_FALSE(options_.do_zip_file);
EXPECT_FALSE(options_.use_socket);
EXPECT_FALSE(options_.use_control_socket);
+ EXPECT_FALSE(options_.limited_only);
EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}