diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Android.mk | 8 | ||||
-rw-r--r-- | tests/dlext_test.cpp | 4 | ||||
-rw-r--r-- | tests/dlfcn_test.cpp | 93 | ||||
-rw-r--r-- | tests/libdl_test.cpp | 34 | ||||
-rw-r--r-- | tests/libs/Android.mk | 32 | ||||
-rw-r--r-- | tests/libs/dlsym_from_this_functions.cpp | 52 | ||||
-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.cpp | 18 | ||||
-rw-r--r-- | tests/pthread_dlfcn_test.cpp | 83 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 127 | ||||
-rw-r--r-- | tests/sys_personality_test.cpp | 2 | ||||
-rw-r--r-- | tests/sys_procfs_test.cpp | 39 | ||||
-rw-r--r-- | tests/sys_uio_test.cpp | 27 | ||||
-rw-r--r-- | tests/sys_xattr_test.cpp | 100 | ||||
-rw-r--r-- | tests/unistd_test.cpp | 7 |
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(®, 0, sizeof(reg)); + + elf_gregset_t regs; + memset(®s, 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; |