Merge "crash_reporter: Add unit tests to debug builds"
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index 25e8376..386f221 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -306,12 +306,14 @@
auto it = g_poll_node_map.find(subproc_fd);
if (it == g_poll_node_map.end()) {
D("subproc_fd %d cleared from fd_table", subproc_fd);
+ adb_close(subproc_fd);
return;
}
fdevent* subproc_fde = it->second.fde;
if(subproc_fde->fd != subproc_fd) {
// Already reallocated?
- D("subproc_fd(%d) != subproc_fde->fd(%d)", subproc_fd, subproc_fde->fd);
+ LOG(FATAL) << "subproc_fd(" << subproc_fd << ") != subproc_fde->fd(" << subproc_fde->fd
+ << ")";
return;
}
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index 366ed07..e092dc4 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -183,7 +183,6 @@
~Subprocess();
const std::string& command() const { return command_; }
- bool is_interactive() const { return command_.empty(); }
int local_socket_fd() const { return local_socket_sfd_.fd(); }
@@ -233,6 +232,7 @@
}
Subprocess::~Subprocess() {
+ WaitForExit();
}
bool Subprocess::ForkAndExec() {
@@ -331,7 +331,7 @@
parent_error_sfd.Reset();
close_on_exec(child_error_sfd.fd());
- if (is_interactive()) {
+ if (command_.empty()) {
execle(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr, cenv.data());
} else {
execle(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr, cenv.data());
@@ -408,20 +408,6 @@
exit(-1);
}
- if (!is_interactive()) {
- termios tattr;
- if (tcgetattr(child_fd, &tattr) == -1) {
- WriteFdExactly(error_sfd->fd(), "tcgetattr failed");
- exit(-1);
- }
-
- cfmakeraw(&tattr);
- if (tcsetattr(child_fd, TCSADRAIN, &tattr) == -1) {
- WriteFdExactly(error_sfd->fd(), "tcsetattr failed");
- exit(-1);
- }
- }
-
return child_fd;
}
@@ -432,7 +418,6 @@
"shell srvc %d", subprocess->local_socket_fd()));
subprocess->PassDataStreams();
- subprocess->WaitForExit();
D("deleting Subprocess for PID %d", subprocess->pid());
delete subprocess;
diff --git a/bootstat/README.md b/bootstat/README.md
index b494951..1b4bf7f 100644
--- a/bootstat/README.md
+++ b/bootstat/README.md
@@ -34,8 +34,9 @@
$ bootstat -l
bootstat logs all boot events recorded using the `-r` option to the EventLog
-using the Tron histogram. On GMS devices these logs are uploaded via Clearcut
-for aggregation and analysis.
+using the Tron histogram. These logs may be uploaded by interested parties
+for aggregation and analysis of boot time across different devices and
+versions.
## Printing boot events ##
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 90874f5..384f84d 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -65,7 +65,7 @@
const std::string entry_path = path + "/" + entry_name;
if (entry->d_type == DT_DIR) {
DeleteDirectory(entry_path);
- } else {
+ } else {
unlink(entry_path.c_str());
}
}
diff --git a/crash_reporter/crash_collector_test.cc b/crash_reporter/crash_collector_test.cc
index b55c324..11c8c0d 100644
--- a/crash_reporter/crash_collector_test.cc
+++ b/crash_reporter/crash_collector_test.cc
@@ -20,6 +20,7 @@
#include <utility>
#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/syslog_logging.h>
@@ -52,20 +53,17 @@
EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(Return());
collector_.Initialize(CountCrash, IsMetrics);
- test_dir_ = FilePath("test");
- base::CreateDirectory(test_dir_);
+ EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
brillo::ClearLog();
}
- void TearDown() {
- base::DeleteFile(test_dir_, true);
- }
-
bool CheckHasCapacity();
protected:
CrashCollectorMock collector_;
- FilePath test_dir_;
+
+ // Temporary directory used for tests.
+ base::ScopedTempDir test_dir_;
};
TEST_F(CrashCollectorTest, Initialize) {
@@ -74,7 +72,7 @@
}
TEST_F(CrashCollectorTest, WriteNewFile) {
- FilePath test_file = test_dir_.Append("test_new");
+ FilePath test_file = test_dir_.path().Append("test_new");
const char kBuffer[] = "buffer";
EXPECT_EQ(strlen(kBuffer),
collector_.WriteNewFile(test_file,
@@ -122,8 +120,10 @@
bool CrashCollectorTest::CheckHasCapacity() {
- static const char kFullMessage[] = "Crash directory test already full";
- bool has_capacity = collector_.CheckHasCapacity(test_dir_);
+ const char* kFullMessage =
+ StringPrintf("Crash directory %s already full",
+ test_dir_.path().value().c_str()).c_str();
+ bool has_capacity = collector_.CheckHasCapacity(test_dir_.path());
bool has_message = FindLog(kFullMessage);
EXPECT_EQ(has_message, !has_capacity);
return has_capacity;
@@ -132,19 +132,22 @@
TEST_F(CrashCollectorTest, CheckHasCapacityUsual) {
// Test kMaxCrashDirectorySize - 1 non-meta files can be added.
for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf("file%d.core", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.core", i)),
+ "", 0);
EXPECT_TRUE(CheckHasCapacity());
}
// Test an additional kMaxCrashDirectorySize - 1 meta files fit.
for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf("file%d.meta", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.meta", i)),
+ "", 0);
EXPECT_TRUE(CheckHasCapacity());
}
// Test an additional kMaxCrashDirectorySize meta files don't fit.
for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf("overage%d.meta", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf("overage%d.meta", i)),
+ "", 0);
EXPECT_FALSE(CheckHasCapacity());
}
}
@@ -152,50 +155,52 @@
TEST_F(CrashCollectorTest, CheckHasCapacityCorrectBasename) {
// Test kMaxCrashDirectorySize - 1 files can be added.
for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf("file.%d.core", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf("file.%d.core", i)),
+ "", 0);
EXPECT_TRUE(CheckHasCapacity());
}
- base::WriteFile(test_dir_.Append("file.last.core"), "", 0);
+ base::WriteFile(test_dir_.path().Append("file.last.core"), "", 0);
EXPECT_FALSE(CheckHasCapacity());
}
TEST_F(CrashCollectorTest, CheckHasCapacityStrangeNames) {
// Test many files with different extensions and same base fit.
for (int i = 0; i < 5 * CrashCollector::kMaxCrashDirectorySize; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf("a.%d", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf("a.%d", i)), "", 0);
EXPECT_TRUE(CheckHasCapacity());
}
// Test dot files are treated as individual files.
for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 2; ++i) {
- base::WriteFile(test_dir_.Append(StringPrintf(".file%d", i)), "", 0);
+ base::WriteFile(test_dir_.path().Append(StringPrintf(".file%d", i)), "", 0);
EXPECT_TRUE(CheckHasCapacity());
}
- base::WriteFile(test_dir_.Append("normal.meta"), "", 0);
+ base::WriteFile(test_dir_.path().Append("normal.meta"), "", 0);
EXPECT_FALSE(CheckHasCapacity());
}
TEST_F(CrashCollectorTest, MetaData) {
const char kMetaFileBasename[] = "generated.meta";
- FilePath meta_file = test_dir_.Append(kMetaFileBasename);
- FilePath payload_file = test_dir_.Append("payload-file");
+ FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
+ FilePath payload_file = test_dir_.path().Append("payload-file");
std::string contents;
const char kPayload[] = "foo";
ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
collector_.AddCrashMetaData("foo", "bar");
collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
- const char kExpectedMeta[] =
- "foo=bar\n"
- "exec_name=kernel\n"
- "payload=test/payload-file\n"
- "payload_size=3\n"
- "done=1\n";
+ const std::string kExpectedMeta =
+ StringPrintf("foo=bar\n"
+ "exec_name=kernel\n"
+ "payload=%s\n"
+ "payload_size=3\n"
+ "done=1\n",
+ test_dir_.path().Append("payload-file").value().c_str());
EXPECT_EQ(kExpectedMeta, contents);
// Test target of symlink is not overwritten.
- payload_file = test_dir_.Append("payload2-file");
+ payload_file = test_dir_.path().Append("payload2-file");
ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
- FilePath meta_symlink_path = test_dir_.Append("symlink.meta");
+ FilePath meta_symlink_path = test_dir_.path().Append("symlink.meta");
ASSERT_EQ(0,
symlink(kMetaFileBasename,
meta_symlink_path.value().c_str()));
@@ -221,8 +226,8 @@
}
TEST_F(CrashCollectorTest, GetLogContents) {
- FilePath config_file = test_dir_.Append("crash_config");
- FilePath output_file = test_dir_.Append("crash_log");
+ FilePath config_file = test_dir_.path().Append("crash_config");
+ FilePath output_file = test_dir_.path().Append("crash_log");
const char kConfigContents[] =
"foobar=echo hello there | \\\n sed -e \"s/there/world/\"";
ASSERT_TRUE(
diff --git a/crash_reporter/kernel_collector.cc b/crash_reporter/kernel_collector.cc
index 12b00b9..cb3a315 100644
--- a/crash_reporter/kernel_collector.cc
+++ b/crash_reporter/kernel_collector.cc
@@ -68,8 +68,8 @@
" RIP \\[<.*>\\] ([^\\+ ]+).*", // X86_64 uses RIP for the program counter
};
-COMPILE_ASSERT(arraysize(kPCRegex) == KernelCollector::kArchCount,
- missing_arch_pc_regexp);
+static_assert(arraysize(kPCRegex) == KernelCollector::kArchCount,
+ "Missing Arch PC regexp");
} // namespace
diff --git a/crash_reporter/list_proxies.cc b/crash_reporter/list_proxies.cc
index d445557..3374b5f 100644
--- a/crash_reporter/list_proxies.cc
+++ b/crash_reporter/list_proxies.cc
@@ -75,13 +75,12 @@
// Start by finding the first space (if any).
std::string::iterator space;
for (space = token.begin(); space != token.end(); ++space) {
- if (IsAsciiWhitespace(*space)) {
+ if (base::IsAsciiWhitespace(*space)) {
break;
}
}
- std::string scheme = std::string(token.begin(), space);
- base::StringToLowerASCII(&scheme);
+ std::string scheme = base::ToLowerASCII(std::string(token.begin(), space));
// Chrome uses "socks" to mean socks4 and "proxy" to mean http.
if (scheme == "socks")
scheme += "4";
@@ -183,7 +182,7 @@
timeout_callback_.Cancel();
proxies_ = ParseProxyString(proxy_info);
LOG(INFO) << "Found proxies via browser signal: "
- << JoinString(proxies_, 'x');
+ << base::JoinString(proxies_, "x");
Quit();
}
diff --git a/crash_reporter/unclean_shutdown_collector_test.cc b/crash_reporter/unclean_shutdown_collector_test.cc
index 3bdeca1..56d2704 100644
--- a/crash_reporter/unclean_shutdown_collector_test.cc
+++ b/crash_reporter/unclean_shutdown_collector_test.cc
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_util.h>
#include <brillo/syslog_logging.h>
#include <gmock/gmock.h>
@@ -32,10 +33,6 @@
int s_crashes = 0;
bool s_metrics = true;
-const char kTestDirectory[] = "test";
-const char kTestSuspended[] = "test/suspended";
-const char kTestUnclean[] = "test/unclean";
-
void CountCrash() {
++s_crashes;
}
@@ -59,12 +56,17 @@
collector_.Initialize(CountCrash,
IsMetrics);
- rmdir(kTestDirectory);
- test_unclean_ = FilePath(kTestUnclean);
- collector_.unclean_shutdown_file_ = kTestUnclean;
+
+ EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
+
+ test_directory_ = test_dir_.path().Append("test");
+ test_unclean_ = test_dir_.path().Append("test/unclean");
+
+ collector_.unclean_shutdown_file_ = test_unclean_.value().c_str();
base::DeleteFile(test_unclean_, true);
// Set up an alternate power manager state file as well
- collector_.powerd_suspended_file_ = FilePath(kTestSuspended);
+ collector_.powerd_suspended_file_ =
+ test_dir_.path().Append("test/suspended");
brillo::ClearLog();
}
@@ -75,6 +77,10 @@
}
UncleanShutdownCollectorMock collector_;
+
+ // Temporary directory used for tests.
+ base::ScopedTempDir test_dir_;
+ FilePath test_directory_;
FilePath test_unclean_;
};
@@ -84,7 +90,7 @@
}
TEST_F(UncleanShutdownCollectorTest, EnableWithParent) {
- mkdir(kTestDirectory, 0777);
+ mkdir(test_directory_.value().c_str(), 0777);
ASSERT_TRUE(collector_.Enable());
ASSERT_TRUE(base::PathExists(test_unclean_));
}
@@ -133,15 +139,15 @@
}
TEST_F(UncleanShutdownCollectorTest, CantDisable) {
- mkdir(kTestDirectory, 0700);
- if (mkdir(kTestUnclean, 0700)) {
+ mkdir(test_directory_.value().c_str(), 0700);
+ if (mkdir(test_unclean_.value().c_str(), 0700)) {
ASSERT_EQ(EEXIST, errno)
- << "Error while creating directory '" << kTestUnclean
+ << "Error while creating directory '" << test_unclean_.value()
<< "': " << strerror(errno);
}
ASSERT_EQ(0, base::WriteFile(test_unclean_.Append("foo"), "", 0))
<< "Error while creating empty file '"
<< test_unclean_.Append("foo").value() << "': " << strerror(errno);
ASSERT_FALSE(collector_.Disable());
- rmdir(kTestUnclean);
+ rmdir(test_unclean_.value().c_str());
}
diff --git a/crash_reporter/user_collector.cc b/crash_reporter/user_collector.cc
index 6714f52..98d7448 100644
--- a/crash_reporter/user_collector.cc
+++ b/crash_reporter/user_collector.cc
@@ -151,8 +151,8 @@
return false;
}
std::string id_substring = id_line.substr(strlen(prefix), std::string::npos);
- std::vector<std::string> ids;
- base::SplitString(id_substring, '\t', &ids);
+ std::vector<std::string> ids = base::SplitString(
+ id_substring, "\t", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (ids.size() != kIdMax || kind < 0 || kind >= kIdMax) {
return false;
}
@@ -313,8 +313,8 @@
uid_t uid;
if (base::ReadFileToString(process_path.Append("status"), &status)) {
- std::vector<std::string> status_lines;
- base::SplitString(status, '\n', &status_lines);
+ std::vector<std::string> status_lines = base::SplitString(
+ status, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
std::string process_state;
if (!GetStateFromStatus(status_lines, &process_state)) {
diff --git a/crash_reporter/user_collector_test.cc b/crash_reporter/user_collector_test.cc
index 638ea34..d9c9a5b 100644
--- a/crash_reporter/user_collector_test.cc
+++ b/crash_reporter/user_collector_test.cc
@@ -65,8 +65,10 @@
false,
false,
"");
- base::DeleteFile(FilePath("test"), true);
- mkdir("test", 0777);
+
+ EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
+
+ mkdir(test_dir_.path().Append("test").value().c_str(), 0777);
pid_ = getpid();
brillo::ClearLog();
}
@@ -80,13 +82,13 @@
}
std::vector<std::string> SplitLines(const std::string &lines) const {
- std::vector<std::string> result;
- base::SplitString(lines, '\n', &result);
- return result;
+ return base::SplitString(lines, "\n", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_ALL);
}
UserCollectorMock collector_;
pid_t pid_;
+ base::ScopedTempDir test_dir_;
};
TEST_F(UserCollectorTest, ParseCrashAttributes) {
@@ -173,14 +175,15 @@
&result));
ASSERT_TRUE(FindLog(
"Readlink failed on /does_not_exist with 2"));
- std::string long_link;
+ std::string long_link = test_dir_.path().value();
for (int i = 0; i < 50; ++i)
long_link += "0123456789";
long_link += "/gold";
for (size_t len = 1; len <= long_link.size(); ++len) {
std::string this_link;
- static const char kLink[] = "test/this_link";
+ static const char* kLink =
+ test_dir_.path().Append("test/this_link").value().c_str();
this_link.assign(long_link.c_str(), len);
ASSERT_EQ(len, this_link.size());
unlink(kLink);
@@ -341,13 +344,13 @@
}
TEST_F(UserCollectorTest, CopyOffProcFilesBadPid) {
- FilePath container_path("test/container");
+ FilePath container_path(test_dir_.path().Append("test/container"));
ASSERT_FALSE(collector_.CopyOffProcFiles(0, container_path));
EXPECT_TRUE(FindLog("Path /proc/0 does not exist"));
}
TEST_F(UserCollectorTest, CopyOffProcFilesOK) {
- FilePath container_path("test/container");
+ FilePath container_path(test_dir_.path().Append("test/container"));
ASSERT_TRUE(collector_.CopyOffProcFiles(pid_, container_path));
EXPECT_FALSE(FindLog("Could not copy"));
static struct {
@@ -371,9 +374,7 @@
}
TEST_F(UserCollectorTest, ValidateProcFiles) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- FilePath container_dir = temp_dir.path();
+ FilePath container_dir = test_dir_.path();
// maps file not exists (i.e. GetFileSize fails)
EXPECT_FALSE(collector_.ValidateProcFiles(container_dir));
@@ -392,9 +393,7 @@
}
TEST_F(UserCollectorTest, ValidateCoreFile) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- FilePath container_dir = temp_dir.path();
+ FilePath container_dir = test_dir_.path();
FilePath core_file = container_dir.Append("core");
// Core file does not exist
diff --git a/init/builtins.cpp b/init/builtins.cpp
index d2291bb..35f1a9e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -418,20 +418,32 @@
while (1) { pause(); } // never reached
}
-static void import_late() {
- static const std::vector<std::string> init_directories = {
- "/system/etc/init",
- "/vendor/etc/init",
- "/odm/etc/init"
- };
-
+/* Imports .rc files from the specified paths. Default ones are applied if none is given.
+ *
+ * start_index: index of the first path in the args list
+ */
+static void import_late(const std::vector<std::string>& args, size_t start_index) {
Parser& parser = Parser::GetInstance();
- for (const auto& dir : init_directories) {
- parser.ParseConfig(dir.c_str());
+ if (args.size() <= start_index) {
+ // Use the default set if no path is given
+ static const std::vector<std::string> init_directories = {
+ "/system/etc/init",
+ "/vendor/etc/init",
+ "/odm/etc/init"
+ };
+
+ for (const auto& dir : init_directories) {
+ parser.ParseConfig(dir);
+ }
+ } else {
+ for (size_t i = start_index; i < args.size(); ++i) {
+ parser.ParseConfig(args[i]);
+ }
}
}
-/*
+/* mount_all <fstab> [ <path> ]*
+ *
* This function might request a reboot, in which case it will
* not return.
*/
@@ -478,7 +490,8 @@
return -1;
}
- import_late();
+ /* Paths of .rc files are specified at the 2nd argument and beyond */
+ import_late(args, 2);
if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
property_set("vold.decrypt", "trigger_encryption");
@@ -900,7 +913,7 @@
{"load_system_props", {0, 0, do_load_system_props}},
{"loglevel", {1, 1, do_loglevel}},
{"mkdir", {1, 4, do_mkdir}},
- {"mount_all", {1, 1, do_mount_all}},
+ {"mount_all", {1, kMax, do_mount_all}},
{"mount", {3, kMax, do_mount}},
{"powerctl", {1, 1, do_powerctl}},
{"restart", {1, 1, do_restart}},
diff --git a/init/readme.txt b/init/readme.txt
index bacd6bd..5a1cf44 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -49,6 +49,8 @@
actions or daemons needed for motion sensor or other peripheral
functionality.
+One may specify paths in the mount_all command line to have it import
+.rc files at the specified paths instead of the default ones described above.
Actions
-------
@@ -263,8 +265,10 @@
owned by the root user and root group. If provided, the mode, owner and group
will be updated if the directory exists already.
-mount_all <fstab>
- Calls fs_mgr_mount_all on the given fs_mgr-format fstab.
+mount_all <fstab> [ <path> ]*
+ Calls fs_mgr_mount_all on the given fs_mgr-format fstab and imports .rc files
+ at the specified paths (e.g., on the partitions just mounted). Refer to the
+ section of "Init .rc Files" for detail.
mount <type> <device> <dir> [ <flag> ]* [<options>]
Attempt to mount the named device at the directory <dir>
@@ -358,7 +362,8 @@
There are only two times where the init executable imports .rc files,
1) When it imports /init.rc during initial boot
- 2) When it imports /{system,vendor,odm}/etc/init/ during mount_all
+ 2) When it imports /{system,vendor,odm}/etc/init/ or .rc files at specified
+ paths during mount_all
Properties
diff --git a/liblog/logprint.c b/liblog/logprint.c
index bd36cdd..4ef62a1 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -1488,7 +1488,7 @@
strcat(p, suffixBuf);
p += suffixLen;
} else {
- while(pm < (entry->message + entry->messageLen)) {
+ do {
const char *lineStart;
size_t lineLen;
lineStart = pm;
@@ -1510,7 +1510,7 @@
p += suffixLen;
if (*pm == '\n') pm++;
- }
+ } while (pm < (entry->message + entry->messageLen));
}
if (p_outLength != NULL) {
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 50afc5f..a936455 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -165,6 +165,133 @@
android_logger_list_close(logger_list);
}
+static inline int32_t get4LE(const char* src)
+{
+ return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+}
+
+TEST(liblog, __android_log_bswrite) {
+ struct logger_list *logger_list;
+
+ pid_t pid = getpid();
+
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+ static const char buffer[] = "Hello World";
+ log_time ts(android_log_clockid());
+
+ ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ usleep(1000000);
+
+ int count = 0;
+
+ for (;;) {
+ log_msg log_msg;
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+ break;
+ }
+
+ ASSERT_EQ(log_msg.entry.pid, pid);
+
+ if ((log_msg.entry.sec < (ts.tv_sec - 1))
+ || ((ts.tv_sec + 1) < log_msg.entry.sec)
+ || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
+ || (log_msg.id() != LOG_ID_EVENTS)) {
+ continue;
+ }
+
+ char *eventData = log_msg.msg();
+
+ if (eventData[4] != EVENT_TYPE_STRING) {
+ continue;
+ }
+
+ int len = get4LE(eventData + 4 + 1);
+ if (len == (sizeof(buffer) - 1)) {
+ ++count;
+
+ AndroidLogFormat *logformat = android_log_format_new();
+ EXPECT_TRUE(NULL != logformat);
+ AndroidLogEntry entry;
+ char msgBuf[1024];
+ EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
+ &entry,
+ NULL,
+ msgBuf,
+ sizeof(msgBuf)));
+ fflush(stderr);
+ EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
+ android_log_format_free(logformat);
+ }
+ }
+
+ EXPECT_EQ(1, count);
+
+ android_logger_list_close(logger_list);
+}
+
+TEST(liblog, __android_log_bswrite__empty_string) {
+ struct logger_list *logger_list;
+
+ pid_t pid = getpid();
+
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+ static const char buffer[] = "";
+ log_time ts(android_log_clockid());
+
+ ASSERT_LT(0, __android_log_bswrite(0, buffer));
+ usleep(1000000);
+
+ int count = 0;
+
+ for (;;) {
+ log_msg log_msg;
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+ break;
+ }
+
+ ASSERT_EQ(log_msg.entry.pid, pid);
+
+ if ((log_msg.entry.sec < (ts.tv_sec - 1))
+ || ((ts.tv_sec + 1) < log_msg.entry.sec)
+ || (log_msg.entry.len != (4 + 1 + 4))
+ || (log_msg.id() != LOG_ID_EVENTS)) {
+ continue;
+ }
+
+ char *eventData = log_msg.msg();
+
+ if (eventData[4] != EVENT_TYPE_STRING) {
+ continue;
+ }
+
+ int len = get4LE(eventData + 4 + 1);
+ if (len == 0) {
+ ++count;
+
+ AndroidLogFormat *logformat = android_log_format_new();
+ EXPECT_TRUE(NULL != logformat);
+ AndroidLogEntry entry;
+ char msgBuf[1024];
+ EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
+ &entry,
+ NULL,
+ msgBuf,
+ sizeof(msgBuf)));
+ fflush(stderr);
+ EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
+ android_log_format_free(logformat);
+ }
+ }
+
+ EXPECT_EQ(1, count);
+
+ android_logger_list_close(logger_list);
+}
+
TEST(liblog, __security) {
static const char persist_key[] = "persist.logd.security";
static const char readonly_key[] = "ro.device_owner";
@@ -1106,11 +1233,6 @@
property_set(key + base_offset, hold[3]);
}
-static inline int32_t get4LE(const char* src)
-{
- return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
-}
-
TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
const int TAG = 123456781;
const char SUBTAG[] = "test-subtag";
diff --git a/metricsd/collectors/cpu_usage_collector.cc b/metricsd/collectors/cpu_usage_collector.cc
index 05934b4..9b0bb34 100644
--- a/metricsd/collectors/cpu_usage_collector.cc
+++ b/metricsd/collectors/cpu_usage_collector.cc
@@ -104,14 +104,15 @@
uint64_t *user_ticks,
uint64_t *user_nice_ticks,
uint64_t *system_ticks) {
- std::vector<std::string> proc_stat_lines;
- base::SplitString(stat_content, '\n', &proc_stat_lines);
+ std::vector<std::string> proc_stat_lines = base::SplitString(
+ stat_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (proc_stat_lines.empty()) {
LOG(WARNING) << "No lines found in " << kMetricsProcStatFileName;
return false;
}
- std::vector<std::string> proc_stat_totals;
- base::SplitStringAlongWhitespace(proc_stat_lines[0], &proc_stat_totals);
+ std::vector<std::string> proc_stat_totals =
+ base::SplitString(proc_stat_lines[0], base::kWhitespaceASCII,
+ base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount ||
proc_stat_totals[0] != "cpu" ||
diff --git a/metricsd/libmetrics-334380.gyp b/metricsd/libmetrics-369476.gyp
similarity index 72%
rename from metricsd/libmetrics-334380.gyp
rename to metricsd/libmetrics-369476.gyp
index 9771821..b545d35 100644
--- a/metricsd/libmetrics-334380.gyp
+++ b/metricsd/libmetrics-369476.gyp
@@ -1,6 +1,6 @@
{
'variables': {
- 'libbase_ver': 334380,
+ 'libbase_ver': 369476,
},
'includes': [
'libmetrics.gypi',
diff --git a/metricsd/metrics_collector.cc b/metricsd/metrics_collector.cc
index 2cf2338..ec7e040 100644
--- a/metricsd/metrics_collector.cc
+++ b/metricsd/metrics_collector.cc
@@ -534,18 +534,20 @@
bool MetricsCollector::FillMeminfo(const string& meminfo_raw,
vector<MeminfoRecord>* fields) {
- vector<string> lines;
- unsigned int nlines = Tokenize(meminfo_raw, "\n", &lines);
+ vector<std::string> lines =
+ base::SplitString(meminfo_raw, "\n", base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
// Scan meminfo output and collect field values. Each field name has to
// match a meminfo entry (case insensitive) after removing non-alpha
// characters from the entry.
- unsigned int ifield = 0;
- for (unsigned int iline = 0;
- iline < nlines && ifield < fields->size();
+ size_t ifield = 0;
+ for (size_t iline = 0;
+ iline < lines.size() && ifield < fields->size();
iline++) {
- vector<string> tokens;
- Tokenize(lines[iline], ": ", &tokens);
+ vector<string> tokens =
+ base::SplitString(lines[iline], ": ", base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
if (strcmp((*fields)[ifield].match, tokens[0].c_str()) == 0) {
// Name matches. Parse value and save.
if (!base::StringToInt(tokens[1], &(*fields)[ifield].value)) {
diff --git a/metricsd/metrics_collector_main.cc b/metricsd/metrics_collector_main.cc
index d7aaaf5..14bb935 100644
--- a/metricsd/metrics_collector_main.cc
+++ b/metricsd/metrics_collector_main.cc
@@ -41,7 +41,8 @@
}
dev_path = dev_path_cstr;
// Check that rootdev begins with "/dev/block/".
- if (!base::StartsWithASCII(dev_path, dev_prefix, false)) {
+ if (!base::StartsWith(dev_path, dev_prefix,
+ base::CompareCase::INSENSITIVE_ASCII)) {
LOG(WARNING) << "unexpected root device " << dev_path;
return "";
}
diff --git a/metricsd/uploader/metricsd_service_runner.cc b/metricsd/uploader/metricsd_service_runner.cc
index 2834977..5a759d3 100644
--- a/metricsd/uploader/metricsd_service_runner.cc
+++ b/metricsd/uploader/metricsd_service_runner.cc
@@ -54,7 +54,7 @@
void MetricsdServiceRunner::Stop() {
message_loop_for_io_->PostTask(FROM_HERE,
- message_loop_for_io_->QuitClosure());
+ message_loop_for_io_->QuitWhenIdleClosure());
thread_->join();
}