Fix getpid caching across a clone.
If you make clone, fork, or vfork system calls directly, you're still
on your own, but we now do the right thing for the clone wrapper.
With this implementation, children lose the getpid caching, but we've
no reason to think that that covers any significant use cases.
Bug: 15387103
Change-Id: Icfab6b63c708fea830960742ec92aeba8ce7680d
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 95e63b3..58c9ad9 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -381,6 +381,14 @@
TestFsyncFunction(fsync);
}
+static void AssertGetPidCorrect() {
+ // The loop is just to make manual testing/debugging with strace easier.
+ pid_t getpid_syscall_result = syscall(__NR_getpid);
+ for (size_t i = 0; i < 128; ++i) {
+ ASSERT_EQ(getpid_syscall_result, getpid());
+ }
+}
+
TEST(unistd, getpid_caching_and_fork) {
pid_t parent_pid = getpid();
ASSERT_EQ(syscall(__NR_getpid), parent_pid);
@@ -389,7 +397,7 @@
ASSERT_NE(fork_result, -1);
if (fork_result == 0) {
// We're the child.
- ASSERT_EQ(syscall(__NR_getpid), getpid());
+ AssertGetPidCorrect();
ASSERT_EQ(parent_pid, getppid());
_exit(123);
} else {
@@ -403,12 +411,29 @@
}
}
-static void GetPidCachingHelperHelper() {
- ASSERT_EQ(syscall(__NR_getpid), getpid());
+static int GetPidCachingCloneStartRoutine(void*) {
+ AssertGetPidCorrect();
+ return 123;
}
-static void* GetPidCachingHelper(void*) {
- GetPidCachingHelperHelper(); // Can't assert in a non-void function.
+TEST(unistd, getpid_caching_and_clone) {
+ pid_t parent_pid = getpid();
+ ASSERT_EQ(syscall(__NR_getpid), parent_pid);
+
+ void* child_stack[1024];
+ int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL);
+ ASSERT_NE(clone_result, -1);
+
+ ASSERT_EQ(parent_pid, getpid());
+
+ int status;
+ ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0));
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(123, WEXITSTATUS(status));
+}
+
+static void* GetPidCachingPthreadStartRoutine(void*) {
+ AssertGetPidCorrect();
return NULL;
}
@@ -416,7 +441,7 @@
pid_t parent_pid = getpid();
pthread_t t;
- ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingHelper, NULL));
+ ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL));
ASSERT_EQ(parent_pid, getpid());