Merge "Implement android::base::WaitForProperty."
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/libbacktrace/BacktraceOffline.cpp b/libbacktrace/BacktraceOffline.cpp
index 53ea796..0a2f5a3 100644
--- a/libbacktrace/BacktraceOffline.cpp
+++ b/libbacktrace/BacktraceOffline.cpp
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -91,9 +92,6 @@
has_debug_frame(false), has_gnu_debugdata(false) { }
};
-static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>& g_debug_frames =
- *new std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>;
-
void Space::Clear() {
start = 0;
end = 0;
@@ -557,18 +555,31 @@
return "";
}
+static std::mutex g_lock;
+static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>* g_debug_frames = nullptr;
+
static DebugFrameInfo* ReadDebugFrameFromFile(const std::string& filename);
DebugFrameInfo* BacktraceOffline::GetDebugFrameInFile(const std::string& filename) {
if (cache_file_) {
- auto it = g_debug_frames.find(filename);
- if (it != g_debug_frames.end()) {
- return it->second.get();
+ std::lock_guard<std::mutex> lock(g_lock);
+ if (g_debug_frames != nullptr) {
+ auto it = g_debug_frames->find(filename);
+ if (it != g_debug_frames->end()) {
+ return it->second.get();
+ }
}
}
DebugFrameInfo* debug_frame = ReadDebugFrameFromFile(filename);
if (cache_file_) {
- g_debug_frames.emplace(filename, std::unique_ptr<DebugFrameInfo>(debug_frame));
+ std::lock_guard<std::mutex> lock(g_lock);
+ if (g_debug_frames == nullptr) {
+ g_debug_frames = new std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>;
+ }
+ auto pair = g_debug_frames->emplace(filename, std::unique_ptr<DebugFrameInfo>(debug_frame));
+ if (!pair.second) {
+ debug_frame = pair.first->second.get();
+ }
}
return debug_frame;
}
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/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();
-}