diff options
| author | 2018-03-14 15:12:46 -0700 | |
|---|---|---|
| committer | 2018-03-16 12:53:48 -0700 | |
| commit | 5f6ee4a11de1de262cea6465c2f991834b2e4792 (patch) | |
| tree | 3bd092f0a2157341cacdc368ab8cbf37877bac04 | |
| parent | 5f643f8f4f9ca0f93b5b6ab9b9130b753c425cca (diff) | |
Clean up DumpData-related functions
This change cleans a few DumpData-related functions:
* Makes GetDumpFds return the std::vector<DumpData> by value instead of
by pointer.
* Makes Dumpstate own the list of open tombstone and ANR files.
* Removes two more globals.
* Prevents a potential FD leak.
Bug: http://b/73140330
Test: `adb bugreport` succeeded
(cherry picked from commit 91c2ae50d57149366d5ab8ee9c763b4c4c6c9e0b)
Change-Id: I5ceb9e4fc1e123dfd6823a7626492ce0b63cf822
| -rw-r--r-- | cmds/dumpstate/dumpstate.cpp | 62 | ||||
| -rw-r--r-- | cmds/dumpstate/dumpstate.h | 21 |
2 files changed, 43 insertions, 40 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 10f252fb7e..fd2fccba4e 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -112,19 +112,6 @@ static const std::string TOMBSTONE_FILE_PREFIX = "tombstone_"; static const std::string ANR_DIR = "/data/anr/"; static const std::string ANR_FILE_PREFIX = "anr_"; -struct DumpData { - std::string name; - int fd; - time_t mtime; -}; - -static bool operator<(const DumpData& d1, const DumpData& d2) { - return d1.mtime > d2.mtime; -} - -static std::unique_ptr<std::vector<DumpData>> tombstone_data; -static std::unique_ptr<std::vector<DumpData>> anr_data; - // TODO: temporary variables and functions used during C++ refactoring static Dumpstate& ds = Dumpstate::GetInstance(); static int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand, @@ -167,20 +154,20 @@ static const CommandOptions AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot( * is set, the vector only contains files that were written in the last 30 minutes. * If |limit_by_count| is set, the vector only contains the ten latest files. */ -static std::vector<DumpData>* GetDumpFds(const std::string& dir_path, - const std::string& file_prefix, - bool limit_by_mtime, - bool limit_by_count = true) { +static std::vector<DumpData> GetDumpFds(const std::string& dir_path, + const std::string& file_prefix, + bool limit_by_mtime, + bool limit_by_count = true) { const time_t thirty_minutes_ago = ds.now_ - 60 * 30; - std::unique_ptr<std::vector<DumpData>> dump_data(new std::vector<DumpData>()); std::unique_ptr<DIR, decltype(&closedir)> dump_dir(opendir(dir_path.c_str()), closedir); if (dump_dir == nullptr) { MYLOGW("Unable to open directory %s: %s\n", dir_path.c_str(), strerror(errno)); - return dump_data.release(); + return std::vector<DumpData>(); } + std::vector<DumpData> dump_data; struct dirent* entry = nullptr; while ((entry = readdir(dump_dir.get()))) { if (entry->d_type != DT_REG) { @@ -211,18 +198,19 @@ static std::vector<DumpData>* GetDumpFds(const std::string& dir_path, continue; } - DumpData data = {.name = abs_path, .fd = fd.release(), .mtime = st.st_mtime}; - - dump_data->push_back(data); + dump_data.emplace_back(DumpData{abs_path, std::move(fd), st.st_mtime}); } - std::sort(dump_data->begin(), dump_data->end()); + // Sort in descending modification time so that we only keep the newest + // reports if |limit_by_count| is true. + std::sort(dump_data.begin(), dump_data.end(), + [](const DumpData& d1, const DumpData& d2) { return d1.mtime > d2.mtime; }); - if (limit_by_count && dump_data->size() > 10) { - dump_data->erase(dump_data->begin() + 10, dump_data->end()); + if (limit_by_count && dump_data.size() > 10) { + dump_data.erase(dump_data.begin() + 10, dump_data.end()); } - return dump_data.release(); + return dump_data; } static bool AddDumps(const std::vector<DumpData>::const_iterator start, @@ -257,12 +245,6 @@ static bool AddDumps(const std::vector<DumpData>::const_iterator start, return dumped; } -static void CloseDumpFds(const std::vector<DumpData>* dumps) { - for (auto it = dumps->begin(); it != dumps->end(); ++it) { - close(it->fd); - } -} - // for_each_pid() callback to get mount info about a process. void do_mountinfo(int pid, const char* name __attribute__((unused))) { char path[PATH_MAX]; @@ -1007,15 +989,15 @@ static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_ } // Add a specific message for the first ANR Dump. - if (anr_data->size() > 0) { - AddDumps(anr_data->begin(), anr_data->begin() + 1, + if (ds.anr_data_.size() > 0) { + AddDumps(ds.anr_data_.begin(), ds.anr_data_.begin() + 1, "VM TRACES AT LAST ANR", add_to_zip); // The "last" ANR will always be included as separate entry in the zip file. In addition, // it will be present in the body of the main entry if |add_to_zip| == false. // // Historical ANRs are always included as separate entries in the bugreport zip file. - AddDumps(anr_data->begin() + ((add_to_zip) ? 1 : 0), anr_data->end(), + AddDumps(ds.anr_data_.begin() + ((add_to_zip) ? 1 : 0), ds.anr_data_.end(), "HISTORICAL ANR", true /* add_to_zip */); } else { printf("*** NO ANRs to dump in %s\n\n", ANR_DIR.c_str()); @@ -1362,7 +1344,7 @@ static void dumpstate() { // NOTE: tombstones are always added as separate entries in the zip archive // and are not interspersed with the main report. - const bool tombstones_dumped = AddDumps(tombstone_data->begin(), tombstone_data->end(), + const bool tombstones_dumped = AddDumps(ds.tombstone_data_.begin(), ds.tombstone_data_.end(), "TOMBSTONE", true /* add_to_zip */); if (!tombstones_dumped) { printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR.c_str()); @@ -2114,8 +2096,8 @@ int run_main(int argc, char* argv[]) { dump_traces_path = dump_traces(); /* Run some operations that require root. */ - tombstone_data.reset(GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping())); - anr_data.reset(GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping())); + ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping()); + ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping()); ds.AddDir(RECOVERY_DIR, true); ds.AddDir(RECOVERY_DATA_DIR, true); @@ -2288,8 +2270,8 @@ int run_main(int argc, char* argv[]) { close(ds.control_socket_fd_); } - CloseDumpFds(tombstone_data.get()); - CloseDumpFds(anr_data.get()); + ds.tombstone_data_.clear(); + ds.anr_data_.clear(); return 0; } diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h index ea4fccd815..b220013f17 100644 --- a/cmds/dumpstate/dumpstate.h +++ b/cmds/dumpstate/dumpstate.h @@ -26,6 +26,7 @@ #include <vector> #include <android-base/macros.h> +#include <android-base/unique_fd.h> #include <android/os/IDumpstateListener.h> #include <utils/StrongPointer.h> #include <ziparchive/zip_writer.h> @@ -159,6 +160,20 @@ static std::string VERSION_SPLIT_ANR = "3.0-dev-split-anr"; static std::string VERSION_DEFAULT = "default"; /* + * Structure that contains the information of an open dump file. + */ +struct DumpData { + // Path of the file. + std::string name; + + // Open file descriptor for the file. + android::base::unique_fd fd; + + // Modification time of the file. + time_t mtime; +}; + +/* * Main class driving a bugreport generation. * * Currently, it only contains variables that are accessed externally, but gradually the functions @@ -350,6 +365,12 @@ class Dumpstate { std::string notification_title; std::string notification_description; + // List of open tombstone dump files. + std::vector<DumpData> tombstone_data_; + + // List of open ANR dump files. + std::vector<DumpData> anr_data_; + private: // Used by GetInstance() only. Dumpstate(const std::string& version = VERSION_CURRENT); |