Merge "base: extract {ASSERT,EXPECT}_MATCH helpers from debuggerd_test."
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index c473e33..7fec47d 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -218,6 +218,16 @@
},
}
+cc_benchmark {
+ name: "debuggerd_benchmark",
+ defaults: ["debuggerd_defaults"],
+ srcs: ["debuggerd_benchmark.cpp"],
+ shared_libs: [
+ "libbase",
+ "libdebuggerd_client",
+ ],
+}
+
cc_binary {
name: "crash_dump",
srcs: [
diff --git a/debuggerd/debuggerd_benchmark.cpp b/debuggerd/debuggerd_benchmark.cpp
new file mode 100644
index 0000000..37ee214
--- /dev/null
+++ b/debuggerd/debuggerd_benchmark.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 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 <err.h>
+#include <errno.h>
+#include <sched.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <chrono>
+#include <thread>
+
+#include <benchmark/benchmark.h>
+#include <debuggerd/client.h>
+
+using namespace std::chrono_literals;
+
+static_assert(std::chrono::high_resolution_clock::is_steady);
+
+enum class ThreadState { Starting, Started, Stopping };
+
+static void SetScheduler() {
+ struct sched_param param {
+ .sched_priority = 1,
+ };
+
+ if (sched_setscheduler(getpid(), SCHED_FIFO, ¶m) != 0) {
+ fprintf(stderr, "failed to set scheduler to SCHED_FIFO: %s", strerror(errno));
+ }
+}
+
+static std::chrono::duration<double> GetMaximumPause(std::atomic<ThreadState>& state) {
+ std::chrono::duration<double> max_diff(0);
+
+ const auto begin = std::chrono::high_resolution_clock::now();
+ auto last = begin;
+ state.store(ThreadState::Started);
+ while (state.load() != ThreadState::Stopping) {
+ auto now = std::chrono::high_resolution_clock::now();
+
+ auto diff = now - last;
+ if (diff > max_diff) {
+ max_diff = diff;
+ }
+
+ last = now;
+ }
+
+ return max_diff;
+}
+
+static void PerformDump() {
+ pid_t target = getpid();
+ pid_t forkpid = fork();
+ if (forkpid == -1) {
+ err(1, "fork failed");
+ } else if (forkpid != 0) {
+ int status;
+ pid_t pid = waitpid(forkpid, &status, 0);
+ if (pid == -1) {
+ err(1, "waitpid failed");
+ } else if (!WIFEXITED(status)) {
+ err(1, "child didn't exit");
+ } else if (WEXITSTATUS(status) != 0) {
+ errx(1, "child exited with non-zero status %d", WEXITSTATUS(status));
+ }
+ } else {
+ android::base::unique_fd output_fd(open("/dev/null", O_WRONLY | O_CLOEXEC));
+ if (output_fd == -1) {
+ err(1, "failed to open /dev/null");
+ }
+
+ if (!debuggerd_trigger_dump(target, kDebuggerdNativeBacktrace, 1000, std::move(output_fd))) {
+ errx(1, "failed to trigger dump");
+ }
+
+ _exit(0);
+ }
+}
+
+template <typename Fn>
+static void BM_maximum_pause_impl(benchmark::State& state, const Fn& function) {
+ SetScheduler();
+
+ for (auto _ : state) {
+ std::chrono::duration<double> max_pause;
+ std::atomic<ThreadState> thread_state(ThreadState::Starting);
+ auto thread = std::thread([&]() { max_pause = GetMaximumPause(thread_state); });
+
+ while (thread_state != ThreadState::Started) {
+ std::this_thread::sleep_for(1ms);
+ }
+
+ function();
+
+ thread_state = ThreadState::Stopping;
+ thread.join();
+
+ state.SetIterationTime(max_pause.count());
+ }
+}
+
+static void BM_maximum_pause_noop(benchmark::State& state) {
+ BM_maximum_pause_impl(state, []() {});
+}
+
+static void BM_maximum_pause_debuggerd(benchmark::State& state) {
+ BM_maximum_pause_impl(state, []() { PerformDump(); });
+}
+
+BENCHMARK(BM_maximum_pause_noop)->Iterations(128)->UseManualTime();
+BENCHMARK(BM_maximum_pause_debuggerd)->Iterations(128)->UseManualTime();
+
+BENCHMARK_MAIN();
diff --git a/property_service/libpropertyinfoparser/property_info_parser.cpp b/property_service/libpropertyinfoparser/property_info_parser.cpp
index e53c625..a8f6636 100644
--- a/property_service/libpropertyinfoparser/property_info_parser.cpp
+++ b/property_service/libpropertyinfoparser/property_info_parser.cpp
@@ -96,8 +96,12 @@
if (prefix_len > remaining_name_size) continue;
if (!strncmp(c_string(trie_node.prefix(i)->name_offset), remaining_name, prefix_len)) {
- *context_index = trie_node.prefix(i)->context_index;
- *schema_index = trie_node.prefix(i)->schema_index;
+ if (trie_node.prefix(i)->context_index != ~0u) {
+ *context_index = trie_node.prefix(i)->context_index;
+ }
+ if (trie_node.prefix(i)->schema_index != ~0u) {
+ *schema_index = trie_node.prefix(i)->schema_index;
+ }
return;
}
}
@@ -142,8 +146,20 @@
// Check exact matches
for (uint32_t i = 0; i < trie_node.num_exact_matches(); ++i) {
if (!strcmp(c_string(trie_node.exact_match(i)->name_offset), remaining_name)) {
- if (context_index != nullptr) *context_index = trie_node.exact_match(i)->context_index;
- if (schema_index != nullptr) *schema_index = trie_node.exact_match(i)->schema_index;
+ if (context_index != nullptr) {
+ if (trie_node.exact_match(i)->context_index != ~0u) {
+ *context_index = trie_node.exact_match(i)->context_index;
+ } else {
+ *context_index = return_context_index;
+ }
+ }
+ if (schema_index != nullptr) {
+ if (trie_node.exact_match(i)->schema_index != ~0u) {
+ *schema_index = trie_node.exact_match(i)->schema_index;
+ } else {
+ *schema_index = return_schema_index;
+ }
+ }
return;
}
}
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index b3fae26..46c2d06 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -844,5 +844,47 @@
EXPECT_STREQ("3rd", schema);
}
+TEST(propertyinfoserializer, GetPropertyInfo_empty_context_and_schema) {
+ auto property_info = std::vector<PropertyInfoEntry>{
+ {"persist.", "1st", "", false},
+ {"persist.dot_prefix.", "2nd", "", false},
+ {"persist.non_dot_prefix", "3rd", "", false},
+ {"persist.exact_match", "", "", true},
+ {"persist.dot_prefix2.", "", "4th", false},
+ {"persist.non_dot_prefix2", "", "5th", false},
+ };
+
+ auto serialized_trie = std::string();
+ auto build_trie_error = std::string();
+ ASSERT_TRUE(BuildTrie(property_info, "default", "default", &serialized_trie, &build_trie_error))
+ << build_trie_error;
+
+ auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data());
+
+ const char* context;
+ const char* schema;
+ property_info_area->GetPropertyInfo("notpersist.radio.something", &context, &schema);
+ EXPECT_STREQ("default", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.nomatch", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.dot_prefix.something", &context, &schema);
+ EXPECT_STREQ("2nd", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.non_dot_prefix.something", &context, &schema);
+ EXPECT_STREQ("3rd", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.exact_match", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.dot_prefix2.something", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("4th", schema);
+ property_info_area->GetPropertyInfo("persist.non_dot_prefix2.something", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("5th", schema);
+}
+
} // namespace properties
} // namespace android
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 1da93af..b86104d 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -258,12 +258,7 @@
namespace.default.search.paths += /system/${LIB}/vndk-sp${VNDK_VER}
namespace.default.search.paths += /system/${LIB}
-# TODO(b/70551668) Remove /vendor/${LIB}/hw from search paths.
-# Shared libraries in the directory should be dlopened with full file paths.
-# This is a workaround for some legacy prebuilt binaries.
-namespace.default.search.paths += /vendor/${LIB}/hw
-
-namespace.default.asan.search.paths += /data/asan/odm/${LIB}
+namespace.default.asan.search.paths = /data/asan/odm/${LIB}
namespace.default.asan.search.paths += /odm/${LIB}
namespace.default.asan.search.paths += /data/asan/odm/${LIB}/vndk
namespace.default.asan.search.paths += /odm/${LIB}/vndk
@@ -281,9 +276,3 @@
namespace.default.asan.search.paths += /system/${LIB}/vndk-sp${VNDK_VER}
namespace.default.asan.search.paths += /data/asan/system/${LIB}
namespace.default.asan.search.paths += /system/${LIB}
-
-# TODO(b/70551668) Remove /vendor/${LIB}/hw from search paths.
-# Shared libraries in the directory should be dlopened with full file paths.
-# This is a workaround for some legacy prebuilt binaries.
-namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/hw
-namespace.default.asan.search.paths += /vendor/${LIB}/hw
diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in
index 77c2062..df26f90 100644
--- a/rootdir/etc/ld.config.txt.in
+++ b/rootdir/etc/ld.config.txt.in
@@ -240,9 +240,6 @@
namespace.default.search.paths += /vendor/${LIB}/vndk
namespace.default.search.paths += /vendor/${LIB}/vndk-sp
-# TODO(b/70551668) remove this
-namespace.default.search.paths += /vendor/${LIB}/hw
-
namespace.default.permitted.paths = /odm
namespace.default.permitted.paths += /vendor
@@ -259,10 +256,6 @@
namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/vndk-sp
namespace.default.asan.search.paths += /vendor/${LIB}/vndk-sp
-# TODO(b/70551668) remove this
-namespace.default.asan.search.paths += /data/asan/vendor/${LIB}/hw
-namespace.default.asan.search.paths += /vendor/${LIB}/hw
-
namespace.default.asan.permitted.paths = /data/asan/odm
namespace.default.asan.permitted.paths += /odm
namespace.default.asan.permitted.paths += /data/asan/vendor