summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Abhijeet Kaur <abkaur@google.com> 2020-03-27 12:51:12 +0000
committer Abhijeet Kaur <abkaur@google.com> 2020-04-02 12:56:30 +0100
commita407fb81372c6571c28d603504b23ece2d6bc79e (patch)
tree17d7587ab566c26277e9bd7c14ee3b5d3dd8e2c4
parenta02bd1948597a829b4c72a1179a0897aa0c633e5 (diff)
Update Last ID early in the bugreport generation
The lifecycle of a bugreport triggered by Shell: 1. Triggers a bugreport using bugreport API. At this point shell does not have any state of the bugreport. mBugreportInfos is the sparse array in Shell that tracks bugreportInfos keyed with the ID. The ID of the bugreport is currently incremented in RunInternal() which is called in a different thread triggered by the DumpstateService (for an API call) 2. dumpstate calls one of the callbacks #onProgress, #onError and #onFinished(), it is then that the corresponding bugreportinfo is tracked in mBugreportInfos keyed with the ID. Problem: Consider a case when 2 bugreports are triggered such that Shell has not received #onProgress for the first one, and received #onError for the second one. This results in a race condition as Shell assumes that the first bugreport has called onError. This race condition occurs due to the fact that Shell depends on the callback to track the bugreports. Solution: Update Id at a definite time (not in some other thread) in Initialize so that the service calling the API can track it right away. Bug: 152292912 Test: Tigger consecutive calls to bugreport from ActivityManager is WAI Test: adb bugreport (open the finished bugreport and check that the correct ID is shown) Test: atest dumpstate_test Change-Id: I63966800725d2aaa1d1d9d6eb997b86d564acf44
-rw-r--r--cmds/dumpstate/DumpstateService.cpp2
-rw-r--r--cmds/dumpstate/dumpstate.cpp17
-rw-r--r--cmds/dumpstate/dumpstate.h10
3 files changed, 21 insertions, 8 deletions
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 1824943eb2..bfcc058c1b 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -137,6 +137,8 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid,
ds_info->calling_package = calling_package;
pthread_t thread;
+ // Initialize dumpstate
+ ds_->Initialize();
status_t err = pthread_create(&thread, nullptr, dumpstate_thread_main, ds_info);
if (err != 0) {
delete ds_info;
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 772b9fe069..b475c90c04 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2395,6 +2395,13 @@ void Dumpstate::SetOptions(std::unique_ptr<DumpOptions> options) {
options_ = std::move(options);
}
+void Dumpstate::Initialize() {
+ /* gets the sequential id */
+ uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
+ id_ = ++last_id;
+ android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
+}
+
Dumpstate::RunStatus Dumpstate::Run(int32_t calling_uid, const std::string& calling_package) {
Dumpstate::RunStatus status = RunInternal(calling_uid, calling_package);
if (listener_ != nullptr) {
@@ -2505,11 +2512,6 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid,
: "";
progress_.reset(new Progress(stats_path));
- /* gets the sequential id */
- uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
- id_ = ++last_id;
- android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
-
if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
MYLOGE("Failed to acquire wake lock: %s\n", strerror(errno));
} else {
@@ -2837,8 +2839,9 @@ Dumpstate::RunStatus Dumpstate::ParseCommandlineAndRun(int argc, char* argv[]) {
assert(options_->bugreport_fd.get() == -1);
// calling_uid and calling_package are for user consent to share the bugreport with
- // an app; they are irrelvant here because bugreport is only written to a local
- // directory, and not shared.
+ // an app; they are irrelevant here because bugreport is triggered via command line.
+ // Update Last ID before calling Run().
+ Initialize();
status = Run(-1 /* calling_uid */, "" /* calling_package */);
}
return status;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 9ce662b255..498f338227 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -216,6 +216,9 @@ class Dumpstate {
/* Checkes whether dumpstate is generating a zipped bugreport. */
bool IsZipping() const;
+ /* Initialize dumpstate fields before starting bugreport generation */
+ void Initialize();
+
/*
* Forks a command, waits for it to finish, and returns its status.
*
@@ -329,7 +332,12 @@ class Dumpstate {
struct DumpOptions;
- /* Main entry point for running a complete bugreport. */
+ /*
+ * Main entry point for running a complete bugreport.
+ *
+ * Initialize() dumpstate before calling this method.
+ *
+ */
RunStatus Run(int32_t calling_uid, const std::string& calling_package);
RunStatus ParseCommandlineAndRun(int argc, char* argv[]);