Merge "tests: explain how to debug FileCheck failures"
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 93f62cf..6cda463 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -96,6 +96,9 @@
"tests/benchmark_test.cpp",
"tests/interface_test.cpp",
],
- static_libs: ["libBionicBenchmarksUtils"],
+ static_libs: [
+ "libbase",
+ "libBionicBenchmarksUtils",
+ ],
data: ["suites/test_*.xml"],
}
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 3f5e0f1..0e7f668 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -19,9 +19,20 @@
#include <stdio_ext.h>
#include <stdlib.h>
+#include <android-base/test_utils.h>
#include <benchmark/benchmark.h>
#include "util.h"
+static void FillFile(TemporaryFile& tf) {
+ char line[256];
+ memset(line, 'x', sizeof(line));
+ line[sizeof(line) - 1] = '\0';
+
+ FILE* fp = fopen(tf.path, "w");
+ for (size_t i = 0; i < 4096; ++i) fputs(line, fp);
+ fclose(fp);
+}
+
template <typename Fn>
void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) {
size_t chunk_size = state.range(0);
@@ -65,14 +76,39 @@
}
BIONIC_BENCHMARK(BM_stdio_fwrite_unbuffered);
-static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
- size_t nbytes = state.range(0);
- char buf[nbytes];
+#if !defined(__GLIBC__)
+static void FopenFgetlnFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
while (state.KeepRunning()) {
- FILE* fp = fopen("/dev/zero", "re");
+ FILE* fp = fopen(tf.path, "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
- if (fgets(buf, sizeof(buf), fp) == nullptr) {
- errx(1, "ERROR: fgets of %zu bytes failed.", nbytes);
+ size_t length;
+ while (fgetln(fp, &length) != nullptr) {
+ }
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_fgetln_fclose_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_locking);
+
+void BM_stdio_fopen_fgetln_fclose_no_locking(benchmark::State& state) {
+ FopenFgetlnFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetln_fclose_no_locking);
+#endif
+
+static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ char buf[BUFSIZ];
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ while (fgets(buf, sizeof(buf), fp) != nullptr) {
}
fclose(fp);
}
@@ -88,6 +124,31 @@
}
BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
+static void FopenGetlineFclose(benchmark::State& state, bool no_locking) {
+ TemporaryFile tf;
+ FillFile(tf);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen(tf.path, "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ char* line = nullptr;
+ size_t n = 0;
+ while (getline(&line, &n, fp) != -1) {
+ }
+ free(line);
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_getline_fclose_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_locking);
+
+void BM_stdio_fopen_getline_fclose_no_locking(benchmark::State& state) {
+ FopenGetlineFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_getline_fclose_no_locking);
+
static void FopenFgetcFclose(benchmark::State& state, bool no_locking) {
size_t nbytes = state.range(0);
while (state.KeepRunning()) {
diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml
index 8c9aef6..fc58914 100644
--- a/benchmarks/suites/full.xml
+++ b/benchmarks/suites/full.xml
@@ -179,12 +179,16 @@
<args>AT_COMMON_SIZES</args>
</fn>
<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetln_fclose_no_locking</name>
+</fn>
+<fn>
<name>BM_stdio_fopen_fgets_fclose_locking</name>
- <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_no_locking</name>
- <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgetc_fclose_locking</name>
@@ -195,6 +199,12 @@
<args>1024</args>
</fn>
<fn>
+ <name>BM_stdio_fopen_getline_fclose_locking</name>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_getline_fclose_no_locking</name>
+</fn>
+<fn>
<name>BM_string_memcmp</name>
<args>AT_ALIGNED_TWOBUF</args>
</fn>
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index 9283e6b..601dcc5 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include <android-base/file.h>
#include <gtest/gtest.h>
class SystemTests : public ::testing::Test {
@@ -49,6 +50,10 @@
int fd_;
};
+static std::string GetBionicXmlArg(const char* xml_file) {
+ return "--bionic_xml=" + android::base::GetExecutableDirectory() + "/suites/" + xml_file;
+}
+
void SystemTests::SanitizeOutput() {
// Cut off anything after the arguments, since that varies with time.
sanitized_output_ = std::regex_replace(raw_output_, std::regex(".+(BM_\\S+) +.+"), "$1");
@@ -377,16 +382,17 @@
"BM_stdlib_malloc_free/65536/0/iterations:1\n"
"BM_stdlib_mbstowcs/0/0/iterations:1\n"
"BM_stdlib_mbrtowc/0/iterations:1\n";
- Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_full.xml",
+ Verify(expected, 0, std::vector<const char *>{GetBionicXmlArg("test_full.xml").c_str(),
"--bionic_iterations=1"});
}
TEST_F(SystemTests, small) {
std::string expected =
- "BM_string_memcmp/8/8/8\n"
- "BM_math_sqrt\n"
- "BM_property_get/1\n";
- Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_small.xml"});
+ "BM_string_memcmp/8/8/8/iterations:1\n"
+ "BM_math_sqrt/iterations:1\n"
+ "BM_property_get/1/iterations:1\n";
+ Verify(expected, 0, std::vector<const char *>{GetBionicXmlArg("test_small.xml").c_str(),
+ "--bionic_iterations=1"});
}
TEST_F(SystemTests, medium) {
@@ -402,7 +408,7 @@
"BM_math_sqrt/iterations:1\n"
"BM_string_memcpy/512/4/4/iterations:25\n"
"BM_property_get/1/iterations:1\n";
- Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_medium.xml",
+ Verify(expected, 0, std::vector<const char *>{GetBionicXmlArg("test_medium.xml").c_str(),
"--bionic_iterations=1"});
}
@@ -417,7 +423,7 @@
"BM_string_memcpy/512/4/4/iterations:1\n"
"BM_time_clock_gettime/iterations:1\n"
"BM_unistd_getpid/iterations:1\n";
- Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_from_each.xml",
+ Verify(expected, 0, std::vector<const char *>{GetBionicXmlArg("test_from_each.xml").c_str(),
"--bionic_iterations=1"});
}
@@ -462,8 +468,8 @@
"BM_math_log10/iterations:1\n";
Verify(expected, 0, std::vector<const char *>{"--bionic_extra=BM_string_memcpy AT_ALIGNED_TWOBUF",
"--bionic_extra=BM_math_log10",
- "--bionic_cpu -1",
- "--bionic_xml=suites/test_medium.xml",
+ "--bionic_cpu=0",
+ GetBionicXmlArg("test_medium.xml").c_str(),
"--bionic_iterations=1"});
}
@@ -549,6 +555,6 @@
"BM_string_strlen/16384/2048/iterations:1\n"
"BM_string_strlen/32768/2048/iterations:1\n"
"BM_string_strlen/65536/2048/iterations:1\n";
- Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_alignment.xml",
- "--bionic_iterations=100"});
+ Verify(expected, 0, std::vector<const char *>{GetBionicXmlArg("test_alignment.xml").c_str(),
+ "--bionic_iterations=1"});
}
diff --git a/libc/bionic/assert.cpp b/libc/bionic/assert.cpp
index 41831cb..0f4ee97 100644
--- a/libc/bionic/assert.cpp
+++ b/libc/bionic/assert.cpp
@@ -39,7 +39,3 @@
void __assert2(const char* file, int line, const char* function, const char* failed_expression) {
async_safe_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression);
}
-
-extern "C" __LIBC_HIDDEN__ void longjmperror() {
- async_safe_fatal("longjmp botch");
-}
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index cbcc976..4b7b776 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -147,7 +147,7 @@
void* __memrchr_chk(const void* s, int c, size_t n, size_t actual_size) {
__check_buffer_access("memrchr", "read from", n, actual_size);
- return memrchr(s, c, n);
+ return memrchr(const_cast<void *>(s), c, n);
}
// memset is performance-critical enough that we have assembler __memset_chk implementations.
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 667e21d..f994e3e 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -38,6 +38,8 @@
size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
#if defined(__BIONIC_FORTIFY)
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+
// These can share their implementation between gcc and clang with minimal
// trickery...
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
@@ -116,11 +118,11 @@
}
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
size_t bos = __bos(s);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(memrchr)(s, c, n);
+ return __memrchr_real(s, c, n);
}
return __memrchr_chk(s, c, n, bos);
@@ -231,7 +233,6 @@
#else // defined(__clang__)
extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
extern size_t __strlcpy_real(char*, const char*, size_t)
__RENAME(strlcpy);
extern size_t __strlcat_real(char*, const char*, size_t)
@@ -261,7 +262,7 @@
}
__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* s, int c, size_t n) {
+void* __memrchr_fortify(const void* s, int c, size_t n) {
size_t bos = __bos(s);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -415,4 +416,26 @@
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
#endif /* defined(__clang__) */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__cplusplus)
+extern "C++" {
+__BIONIC_FORTIFY_INLINE
+void* memrchr(void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+
+__BIONIC_FORTIFY_INLINE
+const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
+ return __memrchr_fortify(s, c, n);
+}
+}
+#else
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
+ return __memrchr_fortify(s, c, n);
+}
+#endif
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/string.h b/libc/include/string.h
index 33ef468..d409ba8 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -43,7 +43,12 @@
void* memccpy(void* __dst, const void* __src, int __stop_char, size_t __n);
void* memchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memchr);
+#if defined(__cplusplus)
+extern "C++" void* memrchr(void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+extern "C++" const void* memrchr(const void* __s, int __ch, size_t __n) __RENAME(memrchr) __attribute_pure__;
+#else
void* memrchr(const void* __s, int __ch, size_t __n) __attribute_pure__ __overloadable __RENAME_CLANG(memrchr);
+#endif
int memcmp(const void* __lhs, const void* __rhs, size_t __n) __attribute_pure__;
void* memcpy(void*, const void*, size_t)
__overloadable __RENAME_CLANG(memcpy);
@@ -81,7 +86,12 @@
char* strdup(const char* __s);
char* strstr(const char* __haystack, const char* __needle) __attribute_pure__;
+#if defined(__cplusplus)
+extern "C++" char* strcasestr(char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+extern "C++" const char* strcasestr(const char*, const char*) __RENAME(strcasestr) __attribute_pure__;
+#else
char* strcasestr(const char* __haystack, const char* __needle) __attribute_pure__;
+#endif
char* strtok(char* __s, const char* __delimiter);
char* strtok_r(char* __s, const char* __delimiter, char** __pos_ptr);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8aadd14..59e4bac 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -66,6 +66,7 @@
#include "linker_reloc_iterators.h"
#include "linker_utils.h"
+#include "android-base/macros.h"
#include "android-base/strings.h"
#include "android-base/stringprintf.h"
#include "ziparchive/zip_archive.h"
@@ -83,6 +84,8 @@
static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
+static const char* const kLdConfigArchFilePath = "/system/etc/ld.config." ABI_STRING ".txt";
+
static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
#if defined(__LP64__)
@@ -3467,7 +3470,7 @@
std::string error_msg;
- const char* config_file = kLdConfigFilePath;
+ const char* config_file = file_exists(kLdConfigArchFilePath) ? kLdConfigArchFilePath : kLdConfigFilePath;
#ifdef USE_LD_CONFIG_FILE
// This is a debugging/testing only feature. Must not be available on
// production builds.