summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk8
-rw-r--r--tests/dlext_test.cpp4
-rw-r--r--tests/dlfcn_test.cpp93
-rw-r--r--tests/libdl_test.cpp34
-rw-r--r--tests/libs/Android.mk32
-rw-r--r--tests/libs/dlsym_from_this_functions.cpp52
-rw-r--r--tests/libs/dlsym_from_this_symbol.cpp (renamed from tests/libs/dlsym_from_this.cpp)15
-rw-r--r--tests/libs/dlsym_from_this_symbol2.cpp18
-rw-r--r--tests/pthread_dlfcn_test.cpp83
-rw-r--r--tests/pthread_test.cpp127
-rw-r--r--tests/sys_personality_test.cpp2
-rw-r--r--tests/sys_procfs_test.cpp39
-rw-r--r--tests/sys_uio_test.cpp27
-rw-r--r--tests/sys_xattr_test.cpp100
-rw-r--r--tests/unistd_test.cpp7
15 files changed, 518 insertions, 123 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index cd65c10..cd60668 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -93,6 +93,7 @@ libBionicStandardTests_src_files := \
sys_epoll_test.cpp \
sys_mman_test.cpp \
sys_personality_test.cpp \
+ sys_procfs_test.cpp \
sys_resource_test.cpp \
sys_select_test.cpp \
sys_sendfile_test.cpp \
@@ -103,7 +104,9 @@ libBionicStandardTests_src_files := \
sys_sysinfo_test.cpp \
sys_time_test.cpp \
sys_types_test.cpp \
+ sys_uio_test.cpp \
sys_vfs_test.cpp \
+ sys_xattr_test.cpp \
system_properties_test.cpp \
time_test.cpp \
uchar_test.cpp \
@@ -269,6 +272,8 @@ bionic-unit-tests_src_files := \
dlext_test.cpp \
__cxa_thread_atexit_test.cpp \
dlfcn_test.cpp \
+ libdl_test.cpp \
+ pthread_dlfcn_test.cpp \
bionic-unit-tests_cflags := $(test_cflags)
@@ -346,6 +351,7 @@ bionic-unit-tests-glibc_src_files := \
atexit_test.cpp \
dlfcn_test.cpp \
dl_test.cpp \
+ pthread_dlfcn_test.cpp \
bionic-unit-tests-glibc_shared_libraries := \
libdl_preempt_test_1 \
@@ -396,7 +402,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \
LOCAL_CXX = $(LOCAL_PATH)/file-check-cxx \
$(HOST_OUT_EXECUTABLES)/FileCheck \
- $($(LOCAL_2ND_ARCH_VAR_PREFIX)CXX_BARE) \
+ $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CXX) \
GCC \
LOCAL_CLANG := false
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 56a8f6f..f901708 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -214,7 +214,7 @@ TEST(dlext, android_dlopen_ext_force_load_soname_exception) {
TEST(dlfcn, dlopen_from_zip_absolute_path) {
const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH;
- void* handle = dlopen((lib_path + "!libdir/libdlext_test_fd.so").c_str(), RTLD_NOW);
+ void* handle = dlopen((lib_path + "!/libdir/libdlext_test_fd.so").c_str(), RTLD_NOW);
ASSERT_TRUE(handle != nullptr) << dlerror();
int (*fn)(void);
@@ -226,7 +226,7 @@ TEST(dlfcn, dlopen_from_zip_absolute_path) {
}
TEST(dlfcn, dlopen_from_zip_ld_library_path) {
- const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH + "!libdir";
+ const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH + "!/libdir";
typedef void (*fn_t)(const char*);
fn_t android_update_LD_LIBRARY_PATH =
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 6b1f109..3c9b8e3 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -71,30 +71,102 @@ TEST(dlfcn, dlsym_from_sofile) {
void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_LAZY | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
- // check that we cant find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
+ // check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
ASSERT_TRUE(symbol == nullptr);
ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
typedef int* (*fn_t)();
- fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
+ fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
+ ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
- ASSERT_TRUE(fn != nullptr) << dlerror();
+ int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
+ ASSERT_TRUE(ptr != nullptr) << dlerror();
+ ASSERT_EQ(42, *ptr);
+
+ fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
+ ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
+
+ ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
+ ASSERT_TRUE(ptr != nullptr) << dlerror();
+ ASSERT_EQ(44, *ptr);
+
+ fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
+ ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
+
+ ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
+ ASSERT_TRUE(ptr != nullptr) << dlerror();
+ ASSERT_EQ(43, *ptr);
+
+ dlclose(handle);
+}
+
+TEST(dlfcn, dlsym_from_sofile_with_preload) {
+ void* preload = dlopen("libtest_dlsym_from_this_grandchild.so", RTLD_NOW | RTLD_LOCAL);
+ ASSERT_TRUE(preload != nullptr) << dlerror();
+
+ void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+
+ // check that we can't find '_test_dlsym_symbol' via dlsym(RTLD_DEFAULT)
+ void* symbol = dlsym(RTLD_DEFAULT, "test_dlsym_symbol");
+ ASSERT_TRUE(symbol == nullptr);
+ ASSERT_SUBSTR("undefined symbol: test_dlsym_symbol", dlerror());
+
+ typedef int* (*fn_t)();
+ fn_t lookup_dlsym_symbol_using_RTLD_DEFAULT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_DEFAULT"));
+ ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_DEFAULT != nullptr) << dlerror();
- int* ptr = fn();
+ int* ptr = lookup_dlsym_symbol_using_RTLD_DEFAULT();
ASSERT_TRUE(ptr != nullptr) << dlerror();
ASSERT_EQ(42, *ptr);
+ fn_t lookup_dlsym_symbol2_using_RTLD_DEFAULT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol2_using_RTLD_DEFAULT"));
+ ASSERT_TRUE(lookup_dlsym_symbol2_using_RTLD_DEFAULT != nullptr) << dlerror();
+
+ ptr = lookup_dlsym_symbol2_using_RTLD_DEFAULT();
+ ASSERT_TRUE(ptr != nullptr) << dlerror();
+ ASSERT_EQ(44, *ptr);
+
+ fn_t lookup_dlsym_symbol_using_RTLD_NEXT =
+ reinterpret_cast<fn_t>(dlsym(handle, "lookup_dlsym_symbol_using_RTLD_NEXT"));
+ ASSERT_TRUE(lookup_dlsym_symbol_using_RTLD_NEXT != nullptr) << dlerror();
+
+ ptr = lookup_dlsym_symbol_using_RTLD_NEXT();
+ ASSERT_TRUE(ptr != nullptr) << dlerror();
+ ASSERT_EQ(43, *ptr);
+
+ dlclose(handle);
+ dlclose(preload);
+}
+
+TEST(dlfcn, dlsym_handle_global_sym) {
+ // check that we do not look into global group
+ // when looking up symbol by handle
+ void* handle = dlopen("libtest_empty.so", RTLD_NOW);
+ dlopen("libtest_with_dependency.so", RTLD_NOW | RTLD_GLOBAL);
+ void* sym = dlsym(handle, "getRandomNumber");
+ ASSERT_TRUE(sym == nullptr);
+ ASSERT_SUBSTR("undefined symbol: getRandomNumber", dlerror());
+
+ sym = dlsym(handle, "DlSymTestFunction");
+ ASSERT_TRUE(sym == nullptr);
+ ASSERT_SUBSTR("undefined symbol: DlSymTestFunction", dlerror());
dlclose(handle);
}
TEST(dlfcn, dlsym_with_dependencies) {
void* handle = dlopen("libtest_with_dependency.so", RTLD_NOW);
- ASSERT_TRUE(handle != NULL);
+ ASSERT_TRUE(handle != nullptr);
dlerror();
// This symbol is in DT_NEEDED library.
void* sym = dlsym(handle, "getRandomNumber");
- ASSERT_TRUE(sym != NULL);
+ ASSERT_TRUE(sym != nullptr) << dlerror();
int (*fn)(void);
fn = reinterpret_cast<int (*)(void)>(sym);
EXPECT_EQ(4, fn());
@@ -526,6 +598,15 @@ TEST(dlfcn, dlopen_check_rtld_global) {
// RTLD_GLOBAL implies RTLD_NODELETE, let's check that
void* sym_after_dlclose = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
ASSERT_EQ(sym, sym_after_dlclose);
+
+ // Check if dlsym() for main program's handle searches RTLD_GLOBAL
+ // shared libraries after symbol was not found in the main executable
+ // and dependent libraries.
+ void* handle_for_main_executable = dlopen(nullptr, RTLD_NOW);
+ sym = dlsym(handle_for_main_executable, "dlopen_testlib_simple_func");
+ ASSERT_TRUE(sym != nullptr) << dlerror();
+
+ dlclose(handle_for_main_executable);
}
// libtest_with_dependency_loop.so -> libtest_with_dependency_loop_a.so ->
diff --git a/tests/libdl_test.cpp b/tests/libdl_test.cpp
new file mode 100644
index 0000000..b162edc
--- /dev/null
+++ b/tests/libdl_test.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <android/api-level.h>
+
+extern "C" uint32_t android_get_application_target_sdk_version();
+extern "C" void android_set_application_target_sdk_version(uint32_t target);
+
+TEST(libdl, application_sdk_versions_smoke) {
+ // Check initial values
+ ASSERT_EQ(static_cast<uint32_t>(__ANDROID_API__), android_get_application_target_sdk_version());
+
+ android_set_application_target_sdk_version(20U);
+ ASSERT_EQ(20U, android_get_application_target_sdk_version());
+
+ android_set_application_target_sdk_version(22U);
+ ASSERT_EQ(22U, android_get_application_target_sdk_version());
+}
+
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index c432c2e..a5ef622 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -355,10 +355,7 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
libdl_test_df_1_global_src_files := dl_df_1_global.cpp
libdl_test_df_1_global_ldflags := -Wl,-z,global
-# TODO (dimitry): x86* toolchain does not support -z global - switch to bfd
-ifeq ($(filter $(TARGET_ARCH),x86 x86_64),$(TARGET_ARCH))
-libdl_test_df_1_global_ldflags_target := -fuse-ld=bfd
-endif
+
# TODO (dimitry): host ld.gold does not yet support -z global
# remove this line once it is updated.
libdl_test_df_1_global_ldflags_host := -fuse-ld=bfd
@@ -385,11 +382,34 @@ include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
# Library to check RTLD_LOCAL with dlsym in 'this'
# -----------------------------------------------------------------------------
-libtest_dlsym_from_this_src_files := dlsym_from_this.cpp
+libtest_dlsym_from_this_src_files := dlsym_from_this_symbol.cpp
-module := libtest_dlsym_from_this
libtest_dlsym_from_this_shared_libraries_target := libdl
+libtest_dlsym_from_this_shared_libraries := libtest_dlsym_from_this_child
+
+module := libtest_dlsym_from_this
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+libtest_dlsym_from_this_child_src_files := dlsym_from_this_functions.cpp
+
+libtest_dlsym_from_this_child_shared_libraries := libtest_dlsym_from_this_grandchild
+
+module := libtest_dlsym_from_this_child
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+libtest_dlsym_from_this_grandchild_src_files := dlsym_from_this_symbol2.cpp
+
+module := libtest_dlsym_from_this_grandchild
+include $(LOCAL_PATH)/Android.build.testlib.mk
+
+# -----------------------------------------------------------------------------
+# Empty library
+# -----------------------------------------------------------------------------
+libtest_empty_src_files := empty.cpp
+module := libtest_empty
include $(LOCAL_PATH)/Android.build.testlib.mk
# -----------------------------------------------------------------------------
diff --git a/tests/libs/dlsym_from_this_functions.cpp b/tests/libs/dlsym_from_this_functions.cpp
new file mode 100644
index 0000000..1f357e0
--- /dev/null
+++ b/tests/libs/dlsym_from_this_functions.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 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 <dlfcn.h>
+#include <stdio.h>
+
+extern int test_dlsym_symbol;
+
+int test_dlsym_symbol = -1;
+
+extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
+ dlerror();
+ int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
+ // TODO: remove this once b/20049306 is fixed
+ if (result == nullptr) {
+ printf("Cannot find the answer\n");
+ }
+ return result;
+}
+
+extern "C" int* lookup_dlsym_symbol2_using_RTLD_DEFAULT() {
+ dlerror();
+ int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol2"));
+ // TODO: remove this once b/20049306 is fixed
+ if (result == nullptr) {
+ printf("Cannot find the answer\n");
+ }
+ return result;
+}
+
+extern "C" int* lookup_dlsym_symbol_using_RTLD_NEXT() {
+ dlerror();
+ int* result = static_cast<int*>(dlsym(RTLD_NEXT, "test_dlsym_symbol"));
+ // TODO: remove this once b/20049306 is fixed
+ if (result == nullptr) {
+ printf("Cannot find the answer\n");
+ }
+ return result;
+}
+
diff --git a/tests/libs/dlsym_from_this.cpp b/tests/libs/dlsym_from_this_symbol.cpp
index b5215c9..c3ec255 100644
--- a/tests/libs/dlsym_from_this.cpp
+++ b/tests/libs/dlsym_from_this_symbol.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 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.
@@ -13,18 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <dlfcn.h>
-#include <stdio.h>
int test_dlsym_symbol = 42;
-
-extern "C" int* lookup_dlsym_symbol_using_RTLD_DEFAULT() {
- dlerror();
- int* result = static_cast<int*>(dlsym(RTLD_DEFAULT, "test_dlsym_symbol"));
- // TODO: remove this once b/20049306 is fixed
- if (result == nullptr) {
- printf("Cannot find the answer\n");
- }
- return result;
-}
-
diff --git a/tests/libs/dlsym_from_this_symbol2.cpp b/tests/libs/dlsym_from_this_symbol2.cpp
new file mode 100644
index 0000000..20da1d5
--- /dev/null
+++ b/tests/libs/dlsym_from_this_symbol2.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+int test_dlsym_symbol = 43;
+int test_dlsym_symbol2 = 44;
diff --git a/tests/pthread_dlfcn_test.cpp b/tests/pthread_dlfcn_test.cpp
new file mode 100644
index 0000000..5e8b206
--- /dev/null
+++ b/tests/pthread_dlfcn_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <dlfcn.h>
+
+static int g_atfork_prepare_calls = 0;
+static void AtForkPrepare1() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 1; }
+static void AtForkPrepare2() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 2; }
+static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
+static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
+
+static int g_atfork_parent_calls = 0;
+static void AtForkParent1() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 1; }
+static void AtForkParent2() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 2; }
+static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
+static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
+
+static int g_atfork_child_calls = 0;
+static void AtForkChild1() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 1; }
+static void AtForkChild2() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 2; }
+static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
+static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
+
+TEST(pthread, pthread_atfork_with_dlclose) {
+ ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
+
+ void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+ typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
+ fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
+ ASSERT_TRUE(fn != nullptr) << dlerror();
+ // the library registers 2 additional atfork handlers in a constructor
+ ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
+ ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
+
+ ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
+
+ int pid = fork();
+
+ ASSERT_NE(-1, pid) << strerror(errno);
+
+ if (pid == 0) {
+ ASSERT_EQ(1234, g_atfork_child_calls);
+ _exit(0);
+ }
+
+ ASSERT_EQ(1234, g_atfork_parent_calls);
+ ASSERT_EQ(4321, g_atfork_prepare_calls);
+
+ EXPECT_EQ(0, dlclose(handle));
+ g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
+
+ int status;
+ ASSERT_EQ(pid, waitpid(pid, &status, 0));
+
+ pid = fork();
+
+ ASSERT_NE(-1, pid) << strerror(errno);
+
+ if (pid == 0) {
+ ASSERT_EQ(14, g_atfork_child_calls);
+ _exit(0);
+ }
+
+ ASSERT_EQ(14, g_atfork_parent_calls);
+ ASSERT_EQ(41, g_atfork_prepare_calls);
+
+ ASSERT_EQ(pid, waitpid(pid, &status, 0));
+}
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index cb5e818..8ae28d8 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -16,7 +16,6 @@
#include <gtest/gtest.h>
-#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -459,42 +458,6 @@ TEST(pthread, pthread_detach__no_such_thread) {
ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
}
-TEST(pthread, pthread_detach_no_leak) {
- size_t initial_bytes = 0;
- // Run this loop more than once since the first loop causes some memory
- // to be allocated permenantly. Run an extra loop to help catch any subtle
- // memory leaks.
- for (size_t loop = 0; loop < 3; loop++) {
- // Set the initial bytes on the second loop since the memory in use
- // should have stabilized.
- if (loop == 1) {
- initial_bytes = mallinfo().uordblks;
- }
-
- pthread_attr_t attr;
- ASSERT_EQ(0, pthread_attr_init(&attr));
- ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
-
- std::vector<pthread_t> threads;
- for (size_t i = 0; i < 32; ++i) {
- pthread_t t;
- ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
- threads.push_back(t);
- }
-
- sleep(1);
-
- for (size_t i = 0; i < 32; ++i) {
- ASSERT_EQ(0, pthread_detach(threads[i])) << i;
- }
- }
-
- size_t final_bytes = mallinfo().uordblks;
- int leaked_bytes = (final_bytes - initial_bytes);
-
- ASSERT_EQ(0, leaked_bytes);
-}
-
TEST(pthread, pthread_getcpuclockid__clock_gettime) {
SpinFunctionHelper spinhelper;
@@ -1019,62 +982,6 @@ TEST(pthread, pthread_atfork_smoke) {
ASSERT_EQ(pid, waitpid(pid, &status, 0));
}
-static void AtForkPrepare3() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 3; }
-static void AtForkPrepare4() { g_atfork_prepare_calls = (g_atfork_prepare_calls * 10) + 4; }
-
-static void AtForkParent3() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 3; }
-static void AtForkParent4() { g_atfork_parent_calls = (g_atfork_parent_calls * 10) + 4; }
-
-static void AtForkChild3() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 3; }
-static void AtForkChild4() { g_atfork_child_calls = (g_atfork_child_calls * 10) + 4; }
-
-TEST(pthread, pthread_atfork_with_dlclose) {
- ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1));
-
- void* handle = dlopen("libtest_pthread_atfork.so", RTLD_NOW | RTLD_LOCAL);
- ASSERT_TRUE(handle != nullptr) << dlerror();
- typedef int (*fn_t)(void (*)(void), void (*)(void), void (*)(void));
- fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "proxy_pthread_atfork"));
- ASSERT_TRUE(fn != nullptr) << dlerror();
- // the library registers 2 additional atfork handlers in a constructor
- ASSERT_EQ(0, fn(AtForkPrepare2, AtForkParent2, AtForkChild2));
- ASSERT_EQ(0, fn(AtForkPrepare3, AtForkParent3, AtForkChild3));
-
- ASSERT_EQ(0, pthread_atfork(AtForkPrepare4, AtForkParent4, AtForkChild4));
-
- int pid = fork();
-
- ASSERT_NE(-1, pid) << strerror(errno);
-
- if (pid == 0) {
- ASSERT_EQ(1234, g_atfork_child_calls);
- _exit(0);
- }
-
- ASSERT_EQ(1234, g_atfork_parent_calls);
- ASSERT_EQ(4321, g_atfork_prepare_calls);
-
- EXPECT_EQ(0, dlclose(handle));
- g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0;
-
- int status;
- ASSERT_EQ(pid, waitpid(pid, &status, 0));
-
- pid = fork();
-
- ASSERT_NE(-1, pid) << strerror(errno);
-
- if (pid == 0) {
- ASSERT_EQ(14, g_atfork_child_calls);
- _exit(0);
- }
-
- ASSERT_EQ(14, g_atfork_parent_calls);
- ASSERT_EQ(41, g_atfork_prepare_calls);
-
- ASSERT_EQ(pid, waitpid(pid, &status, 0));
-}
-
TEST(pthread, pthread_attr_getscope) {
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
@@ -1630,3 +1537,37 @@ TEST(pthread, pthread_types_allow_four_bytes_alignment) {
GTEST_LOG_(INFO) << "This test tests bionic implementation details.";
#endif
}
+
+TEST(pthread, pthread_mutex_lock_null_32) {
+#if defined(__BIONIC__) && !defined(__LP64__)
+ ASSERT_EQ(EINVAL, pthread_mutex_lock(NULL));
+#else
+ GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+#endif
+}
+
+TEST(pthread, pthread_mutex_unlock_null_32) {
+#if defined(__BIONIC__) && !defined(__LP64__)
+ ASSERT_EQ(EINVAL, pthread_mutex_unlock(NULL));
+#else
+ GTEST_LOG_(INFO) << "This test tests bionic implementation details on 32 bit devices.";
+#endif
+}
+
+TEST_F(pthread_DeathTest, pthread_mutex_lock_null_64) {
+#if defined(__BIONIC__) && defined(__LP64__)
+ pthread_mutex_t* null_value = nullptr;
+ ASSERT_EXIT(pthread_mutex_lock(null_value), testing::KilledBySignal(SIGSEGV), "");
+#else
+ GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+#endif
+}
+
+TEST_F(pthread_DeathTest, pthread_mutex_unlock_null_64) {
+#if defined(__BIONIC__) && defined(__LP64__)
+ pthread_mutex_t* null_value = nullptr;
+ ASSERT_EXIT(pthread_mutex_unlock(null_value), testing::KilledBySignal(SIGSEGV), "");
+#else
+ GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices.";
+#endif
+}
diff --git a/tests/sys_personality_test.cpp b/tests/sys_personality_test.cpp
index 55a023d..2dfaa65 100644
--- a/tests/sys_personality_test.cpp
+++ b/tests/sys_personality_test.cpp
@@ -19,7 +19,7 @@
#include <sys/personality.h>
TEST(sys_personality, current_persona) {
- int persona = personality(0xffffffff);
+ int persona = personality(0xffffffff) & PER_MASK;
#if defined(__BIONIC__)
#if defined(__LP64__)
ASSERT_EQ(PER_LINUX, persona);
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
new file mode 100644
index 0000000..8054869
--- /dev/null
+++ b/tests/sys_procfs_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <sys/procfs.h>
+
+TEST(sys_procfs, smoke) {
+ elf_greg_t reg;
+ memset(&reg, 0, sizeof(reg));
+
+ elf_gregset_t regs;
+ memset(&regs, 0, sizeof(regs));
+
+ elf_fpregset_t fp_regs;
+ memset(&fp_regs, 0, sizeof(fp_regs));
+
+ prgregset_t pr_g_regs;
+ memset(&pr_g_regs, 0, sizeof(pr_g_regs));
+
+ prfpregset_t pr_fp_regs;
+ memset(&pr_fp_regs, 0, sizeof(pr_fp_regs));
+
+ static_assert(sizeof(prgregset_t) == sizeof(elf_gregset_t), "");
+ static_assert(sizeof(prfpregset_t) == sizeof(elf_fpregset_t), "");
+}
diff --git a/tests/sys_uio_test.cpp b/tests/sys_uio_test.cpp
new file mode 100644
index 0000000..c7af8a7
--- /dev/null
+++ b/tests/sys_uio_test.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <sys/uio.h>
+
+TEST(sys_uio, process_vm_readv_ESRCH) {
+ ASSERT_EQ(0, process_vm_readv(0, nullptr, 0, nullptr, 0, 0));
+}
+
+TEST(sys_uio, process_vm_writev_ESRCH) {
+ ASSERT_EQ(0, process_vm_writev(0, nullptr, 0, nullptr, 0, 0));
+}
diff --git a/tests/sys_xattr_test.cpp b/tests/sys_xattr_test.cpp
new file mode 100644
index 0000000..1842682
--- /dev/null
+++ b/tests/sys_xattr_test.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/xattr.h>
+
+#include "TemporaryFile.h"
+
+TEST(sys_xattr, setxattr) {
+ TemporaryFile tf;
+ char buf[10];
+ ASSERT_EQ(0, setxattr(tf.filename, "user.foo", "bar", 4, 0));
+ ASSERT_EQ(4, getxattr(tf.filename, "user.foo", buf, sizeof(buf)));
+ ASSERT_STREQ("bar", buf);
+ buf[0] = '\0';
+ ASSERT_EQ(4, lgetxattr(tf.filename, "user.foo", buf, sizeof(buf)));
+ ASSERT_STREQ("bar", buf);
+}
+
+TEST(sys_xattr, fsetxattr) {
+ TemporaryFile tf;
+ char buf[10];
+ ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "bar", 4, 0));
+ ASSERT_EQ(4, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
+ ASSERT_STREQ("bar", buf);
+}
+
+TEST(sys_xattr, fsetxattr_zerobuf) {
+ TemporaryFile tf;
+ char buf[10];
+ ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "", 0, 0));
+ ASSERT_EQ(0, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
+}
+
+TEST(sys_xattr, fsetxattr_toosmallbuf) {
+ TemporaryFile tf;
+ char buf[10];
+ ASSERT_EQ(0, fsetxattr(tf.fd, "user.foo", "01234567890123456789", 21, 0));
+ ASSERT_EQ(-1, fgetxattr(tf.fd, "user.foo", buf, sizeof(buf)));
+ ASSERT_EQ(ERANGE, errno);
+}
+
+TEST(sys_xattr, fsetxattr_invalidfd) {
+ char buf[10];
+ errno = 0;
+ ASSERT_EQ(-1, fsetxattr(65535, "user.foo", "0123", 5, 0));
+ ASSERT_EQ(EBADF, errno);
+ errno = 0;
+ ASSERT_EQ(-1, fgetxattr(65535, "user.foo", buf, sizeof(buf)));
+ ASSERT_EQ(EBADF, errno);
+}
+
+TEST(sys_xattr, fsetxattr_with_opath) {
+ TemporaryFile tf;
+ int fd = open(tf.filename, O_PATH);
+ ASSERT_NE(-1, fd);
+
+ int res = fsetxattr(fd, "user.foo", "bar", 4, 0);
+#if defined(__BIONIC__)
+ char buf[10];
+ ASSERT_EQ(0, res);
+ ASSERT_EQ(4, fgetxattr(fd, "user.foo", buf, sizeof(buf)));
+ ASSERT_STREQ("bar", buf);
+#else
+ ASSERT_EQ(-1, res);
+ ASSERT_EQ(EBADF, errno);
+#endif
+}
+
+TEST(sys_xattr, fsetxattr_with_opath_toosmall) {
+ TemporaryFile tf;
+ int fd = open(tf.filename, O_PATH);
+ ASSERT_NE(-1, fd);
+
+ int res = fsetxattr(fd, "user.foo", "01234567890123456789", 21, 0);
+#if defined(__BIONIC__)
+ char buf[10];
+ ASSERT_EQ(0, res);
+ ASSERT_EQ(-1, fgetxattr(fd, "user.foo", buf, sizeof(buf)));
+ ASSERT_EQ(ERANGE, errno);
+#else
+ ASSERT_EQ(-1, res);
+ ASSERT_EQ(EBADF, errno);
+#endif
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index f54a461..79c16d7 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -176,6 +176,13 @@ TEST(unistd, ftruncate64) {
ASSERT_EQ(123, sb.st_size);
}
+TEST(unistd, ftruncate_negative) {
+ TemporaryFile tf;
+ errno = 0;
+ ASSERT_EQ(-1, ftruncate(tf.fd, -123));
+ ASSERT_EQ(EINVAL, errno);
+}
+
static bool g_pause_test_flag = false;
static void PauseTestSignalHandler(int) {
g_pause_test_flag = true;