Improved how the Shell directories are created.
When dumpstate is run for the first time, the
/data/data/com.android.shell/files/bugreports does not exist, which was
crashing dumpstate because the code that added the version.txt entry was
not checking if the zip_writer was NULL.
The crash itself was fixed by adding a sanity check in the functions
that add entries to the zip file, but that only hid the real problem:
it is necessary to create the parent directories before creating the zip
file, otherwise the first run will always generate a .txt file (since
dumpstate falls back to .txt when it cannot create the .zip).
This change also improves how the parent directories are created by
checking if they exist first, rather than always calling mkdir().
BUG: 26949960
Change-Id: I1434be5c36a3fad0b3a2a26c7eaaab03a1228c30
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 054db74..22fd2c3 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -368,6 +368,10 @@
/* adds a new entry to the existing zip file. */
static bool add_zip_entry_from_fd(const std::string& entry_name, int fd) {
+ if (!zip_writer) {
+ ALOGD("Not adding zip entry %s from fd because zip_writer is not set", entry_name.c_str());
+ return false;
+ }
ALOGD("Adding zip entry %s", entry_name.c_str());
int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(),
ZipWriter::kCompress, get_mtime(fd, now));
@@ -420,14 +424,21 @@
/* adds all files from a directory to the zipped bugreport file */
void add_dir(const char *dir, bool recursive) {
- if (!zip_writer) return;
+ if (!zip_writer) {
+ ALOGD("Not adding dir %s because zip_writer is not set", dir);
+ return;
+ }
DurationReporter duration_reporter(dir, NULL);
dump_files(NULL, dir, recursive ? skip_none : is_dir, _add_file_from_fd);
}
/* adds a text entry entry to the existing zip file. */
static bool add_text_zip_entry(const std::string& entry_name, const std::string& content) {
- ALOGD("Adding zip text entry %s (%s)", entry_name.c_str(), content.c_str());
+ if (!zip_writer) {
+ ALOGD("Not adding text zip entry %s because zip_writer is not set", entry_name.c_str());
+ return false;
+ }
+ ALOGD("Adding zip text entry %s", entry_name.c_str());
int32_t err = zip_writer->StartEntryWithTime(entry_name.c_str(), ZipWriter::kCompress, now);
if (err) {
ALOGE("zip_writer->StartEntryWithTime(%s): %s\n", entry_name.c_str(),
@@ -772,7 +783,7 @@
" -s: write output to control socket (for init)\n"
" -q: disable vibrate\n"
" -B: send broadcast when finished (requires -o)\n"
- " -P: send broadacast when started and update system properties on progress (requires -o and -B)\n"
+ " -P: send broadcast when started and update system properties on progress (requires -o and -B)\n"
" -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n"
" -V: sets the bugreport format version (%s or %s)\n",
VERSION_DEFAULT.c_str(), VERSION_DUMPSYS_SPLIT.c_str());
@@ -794,6 +805,7 @@
}
if (!add_text_zip_entry("main_entry.txt", bugreport_name)) {
ALOGE("Failed to add main_entry.txt to .zip file\n");
+ return false;
}
int32_t err = zip_writer->Finish();
@@ -1027,6 +1039,7 @@
if (do_zip_file) {
ALOGD("Creating initial .zip file");
path = bugreport_dir + "/" + base_name + "-" + suffix + ".zip";
+ create_parent_dirs(path.c_str());
zip_file.reset(fopen(path.c_str(), "wb"));
if (!zip_file) {
ALOGE("fopen(%s, 'wb'): %s\n", path.c_str(), strerror(errno));