Set __get_thread()->tid as part of clone().
This was previously done only in fork() and pthread_create(), but this left raw
clone() with an invalid cached tid. Since the tid is used for pthread routines,
this led to unstable behavior after clone().
Test: ltp clone01 (see bug for more)
Test: mmma bionic/tests
Test: bionic-unit-tests-static --gtest_filter=*fork*:*clone*
Bug: 32612735
Bug: 32305649
Change-Id: I30eae5a8024b4c5da65476fcadfe14c6db35bb79
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 660679f..b488e82 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -426,7 +426,7 @@
}
}
-static void TestGetPidCachingWithFork(int (*fork_fn)()) {
+static void TestGetPidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
pid_t parent_pid = getpid();
ASSERT_EQ(syscall(__NR_getpid), parent_pid);
@@ -436,7 +436,7 @@
// We're the child.
ASSERT_NO_FATAL_FAILURE(AssertGetPidCorrect());
ASSERT_EQ(parent_pid, getppid());
- _exit(123);
+ exit_fn(123);
} else {
// We're the parent.
ASSERT_EQ(parent_pid, getpid());
@@ -460,7 +460,7 @@
}
}
-static void TestGetTidCachingWithFork(int (*fork_fn)()) {
+static void TestGetTidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
pid_t parent_tid = GetTidForTest();
ASSERT_EQ(syscall(__NR_gettid), parent_tid);
@@ -472,7 +472,7 @@
EXPECT_EQ(getpid(), GetTidForTest()) << "real tid is " << syscall(__NR_gettid)
<< ", pid is " << syscall(__NR_getpid);
ASSERT_NO_FATAL_FAILURE(AssertGetTidCorrect());
- _exit(123);
+ exit_fn(123);
} else {
// We're the parent.
ASSERT_EQ(parent_tid, GetTidForTest());
@@ -481,15 +481,15 @@
}
TEST(UNISTD_TEST, getpid_caching_and_fork) {
- TestGetPidCachingWithFork(fork);
+ TestGetPidCachingWithFork(fork, exit);
}
TEST(UNISTD_TEST, gettid_caching_and_fork) {
- TestGetTidCachingWithFork(fork);
+ TestGetTidCachingWithFork(fork, exit);
}
TEST(UNISTD_TEST, getpid_caching_and_vfork) {
- TestGetPidCachingWithFork(vfork);
+ TestGetPidCachingWithFork(vfork, _exit);
}
static int CloneLikeFork() {
@@ -497,11 +497,11 @@
}
TEST(UNISTD_TEST, getpid_caching_and_clone_process) {
- TestGetPidCachingWithFork(CloneLikeFork);
+ TestGetPidCachingWithFork(CloneLikeFork, exit);
}
TEST(UNISTD_TEST, gettid_caching_and_clone_process) {
- TestGetTidCachingWithFork(CloneLikeFork);
+ TestGetTidCachingWithFork(CloneLikeFork, exit);
}
static int CloneAndSetTid() {
@@ -525,7 +525,7 @@
}
TEST(UNISTD_TEST, gettid_caching_and_clone_process_settid) {
- TestGetTidCachingWithFork(CloneAndSetTid);
+ TestGetTidCachingWithFork(CloneAndSetTid, exit);
}
static int CloneStartRoutine(int (*start_routine)(void*)) {
@@ -572,6 +572,22 @@
AssertChildExited(clone_result, 123);
}
+static int CloneChildExit(void*) {
+ AssertGetPidCorrect();
+ AssertGetTidCorrect();
+ exit(33);
+}
+
+TEST(UNISTD_TEST, clone_fn_and_exit) {
+ int clone_result = CloneStartRoutine(CloneChildExit);
+ ASSERT_NE(-1, clone_result);
+
+ AssertGetPidCorrect();
+ AssertGetTidCorrect();
+
+ AssertChildExited(clone_result, 33);
+}
+
static void* GetPidCachingPthreadStartRoutine(void*) {
AssertGetPidCorrect();
return NULL;