Merge "Revert "bootstat: Refactor init/utils/boot_clock into base/chrono_utils.""
diff --git a/base/Android.bp b/base/Android.bp
index b9a6e0b..a7600f3 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -37,6 +37,9 @@
cppflags: libbase_cppflags,
export_include_dirs: ["include"],
shared_libs: ["liblog"],
+ sanitize: {
+ misc_undefined: ["integer"],
+ },
target: {
android: {
srcs: [
@@ -86,6 +89,9 @@
"strings_test.cpp",
"test_main.cpp",
],
+ sanitize: {
+ misc_undefined: ["integer"],
+ },
target: {
android: {
srcs: ["properties_test.cpp"],
diff --git a/base/include/android-base/properties.h b/base/include/android-base/properties.h
index 4d7082a..e275fa2 100644
--- a/base/include/android-base/properties.h
+++ b/base/include/android-base/properties.h
@@ -58,6 +58,9 @@
// tell you whether or not your call succeeded. A `false` return value definitely means failure.
bool SetProperty(const std::string& key, const std::string& value);
+// Waits for the system property `key` to have the value `expected_value`, .
+void WaitForProperty(const std::string& key, const std::string& expected_value);
+
} // namespace base
} // namespace android
diff --git a/base/properties.cpp b/base/properties.cpp
index 37daf9a..0f0f638 100644
--- a/base/properties.cpp
+++ b/base/properties.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+
#include "android-base/properties.h"
#include <sys/system_properties.h>
+#include <sys/_system_properties.h>
#include <string>
@@ -78,5 +81,43 @@
return (__system_property_set(key.c_str(), value.c_str()) == 0);
}
+struct WaitForPropertyData {
+ bool done;
+ const std::string* expected_value;
+ unsigned last_read_serial;
+};
+
+static void WaitForPropertyCallback(void* data_ptr, const char*, const char* value, unsigned serial) {
+ WaitForPropertyData* data = reinterpret_cast<WaitForPropertyData*>(data_ptr);
+ if (*data->expected_value == value) {
+ data->done = true;
+ } else {
+ data->last_read_serial = serial;
+ }
+}
+
+void WaitForProperty(const std::string& key, const std::string& expected_value) {
+ // Find the property's prop_info*.
+ const prop_info* pi;
+ unsigned global_serial = 0;
+ while ((pi = __system_property_find(key.c_str())) == nullptr) {
+ // The property doesn't even exist yet.
+ // Wait for a global change and then look again.
+ global_serial = __system_property_wait_any(global_serial);
+ }
+
+ WaitForPropertyData data;
+ data.expected_value = &expected_value;
+ data.done = false;
+ while (true) {
+ // Check whether the property has the value we're looking for?
+ __system_property_read_callback(pi, WaitForPropertyCallback, &data);
+ if (data.done) return;
+
+ // It didn't so wait for it to change before checking again.
+ __system_property_wait(pi, data.last_read_serial);
+ }
+}
+
} // namespace base
} // namespace android
diff --git a/base/properties_test.cpp b/base/properties_test.cpp
index da89ec5..d8186be 100644
--- a/base/properties_test.cpp
+++ b/base/properties_test.cpp
@@ -18,7 +18,12 @@
#include <gtest/gtest.h>
+#include <atomic>
+#include <chrono>
#include <string>
+#include <thread>
+
+using namespace std::chrono_literals;
TEST(properties, smoke) {
android::base::SetProperty("debug.libbase.property_test", "hello");
@@ -119,3 +124,18 @@
TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
+
+TEST(properties, WaitForProperty) {
+ std::atomic<bool> flag{false};
+ std::thread thread([&]() {
+ std::this_thread::sleep_for(100ms);
+ android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
+ while (!flag) std::this_thread::yield();
+ android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
+ });
+
+ android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a");
+ flag = true;
+ android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b");
+ thread.join();
+}
diff --git a/base/strings.cpp b/base/strings.cpp
index 46fe939..bfdaf12 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -36,11 +36,12 @@
size_t base = 0;
size_t found;
- do {
+ while (true) {
found = s.find_first_of(delimiters, base);
result.push_back(s.substr(base, found - base));
+ if (found == s.npos) break;
base = found + 1;
- } while (found != s.npos);
+ }
return result;
}
diff --git a/base/strings_test.cpp b/base/strings_test.cpp
index 7a65a00..7ed5b2b 100644
--- a/base/strings_test.cpp
+++ b/base/strings_test.cpp
@@ -251,3 +251,7 @@
ASSERT_FALSE(android::base::EqualsIgnoreCase("foo", "bar"));
ASSERT_FALSE(android::base::EqualsIgnoreCase("foo", "fool"));
}
+
+TEST(strings, ubsan_28729303) {
+ android::base::Split("/dev/null", ":");
+}
diff --git a/base/test_utils.cpp b/base/test_utils.cpp
index 3b3d698..636477d 100644
--- a/base/test_utils.cpp
+++ b/base/test_utils.cpp
@@ -57,7 +57,13 @@
static std::string GetSystemTempDir() {
#if defined(__ANDROID__)
- return "/data/local/tmp";
+ const char* tmpdir = "/data/local/tmp";
+ if (access(tmpdir, R_OK | W_OK | X_OK) == 0) {
+ return tmpdir;
+ }
+ // Tests running in app context can't access /data/local/tmp,
+ // so try current directory if /data/local/tmp is not accessible.
+ return ".";
#elif defined(_WIN32)
char tmp_dir[MAX_PATH];
DWORD result = GetTempPathA(sizeof(tmp_dir), tmp_dir);
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 002e940..e22d6a9 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -407,3 +407,35 @@
});
AssertDeath(SIGUSR1);
}
+
+TEST(crash_dump, zombie) {
+ pid_t forkpid = fork();
+
+ int pipefd[2];
+ ASSERT_EQ(0, pipe2(pipefd, O_CLOEXEC));
+
+ pid_t rc;
+ int status;
+
+ if (forkpid == 0) {
+ errno = 0;
+ rc = waitpid(-1, &status, WNOHANG | __WALL | __WNOTHREAD);
+ if (rc != -1 || errno != ECHILD) {
+ errx(2, "first waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
+ }
+
+ raise(DEBUGGER_SIGNAL);
+
+ errno = 0;
+ rc = waitpid(-1, &status, __WALL | __WNOTHREAD);
+ if (rc != -1 || errno != ECHILD) {
+ errx(2, "second waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
+ }
+ _exit(0);
+ } else {
+ rc = waitpid(forkpid, &status, 0);
+ ASSERT_EQ(forkpid, rc);
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(0, WEXITSTATUS(status));
+ }
+}
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 38a7be3..353f642 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -249,7 +249,7 @@
// Don't leave a zombie child.
int status;
- if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, __WCLONE)) == -1 && errno != ECHILD) {
+ if (TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0)) == -1) {
__libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to wait for crash_dump helper: %s",
strerror(errno));
} else if (WIFSTOPPED(status) || WIFSIGNALED(status)) {
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index b701bba..7e27c3e 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -161,7 +161,7 @@
/* Support wifi_hal_legacy administering a network interface. */
{ 00755, AID_WIFI, AID_WIFI, CAP_MASK_LONG(CAP_NET_ADMIN) |
CAP_MASK_LONG(CAP_NET_RAW),
- "system/bin/hw/android.hardware.wifi@1.0-service" },
+ "vendor/bin/hw/android.hardware.wifi@1.0-service" },
/* Support Bluetooth legacy hal accessing /sys/class/rfkill */
{ 00700, AID_BLUETOOTH, AID_BLUETOOTH, CAP_MASK_LONG(CAP_NET_ADMIN),
diff --git a/libcutils/properties.cpp b/libcutils/properties.cpp
index 43ad574..d2645e6 100644
--- a/libcutils/properties.cpp
+++ b/libcutils/properties.cpp
@@ -129,7 +129,7 @@
void* cookie;
};
-static void trampoline(void* raw_data, const char* name, const char* value) {
+static void trampoline(void* raw_data, const char* name, const char* value, unsigned /*serial*/) {
callback_data* data = reinterpret_cast<callback_data*>(raw_data);
data->callback(name, value, data->cookie);
}
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp
index ca8af57..75eab66 100644
--- a/libmetricslogger/Android.bp
+++ b/libmetricslogger/Android.bp
@@ -57,8 +57,8 @@
"libbase",
"libmetricslogger_debug",
],
+ static_libs: ["libBionicGtestMain"],
srcs: [
"metrics_logger_test.cpp",
- "testrunner.cpp",
],
}
diff --git a/libmetricslogger/metrics_logger_test.cpp b/libmetricslogger/metrics_logger_test.cpp
index d77199c..5a30ad7 100644
--- a/libmetricslogger/metrics_logger_test.cpp
+++ b/libmetricslogger/metrics_logger_test.cpp
@@ -20,12 +20,5 @@
TEST(MetricsLoggerTest, AddSingleBootEvent) {
android::metricslogger::LogHistogram("test_event", 42);
- /*pid_t pid = getpid();
- struct logger_list *logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, pid);
-
- logger_list = NULL;
- log_msg log_msg;
- android_logger_list_read(logger_list, &log_msg);
- std::cout << log_msg.len() << std::endl;*/
+ // TODO(jhawkins): Verify the EventLog is updated.
}
diff --git a/libmetricslogger/testrunner.cpp b/libmetricslogger/testrunner.cpp
deleted file mode 100644
index edbf4d5..0000000
--- a/libmetricslogger/testrunner.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <gtest/gtest.h>
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- android::base::InitLogging(argv, android::base::StderrLogger);
- return RUN_ALL_TESTS();
-}
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index ed11164..80bb673 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -11,7 +11,7 @@
onrestart restart media
onrestart restart netd
onrestart restart wificond
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index 66e7750..36bb443 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -11,7 +11,7 @@
onrestart restart media
onrestart restart netd
onrestart restart wificond
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
+ writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main