diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-04 22:17:58 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-03-04 22:17:58 +0000 |
commit | b2c917476d2d2cc6ad2dd1ae3150b6a8dfca1ebe (patch) | |
tree | f482f40a2adaf0e034b3f295162434241a462be9 | |
parent | db3f2240845fa9144cea4d14c8eba35c7bcc4d51 (diff) | |
parent | 6b384dece63de256f69de4b64fa12d77fcf386c8 (diff) | |
download | bionic-simpleperf-release.tar.gz |
Merge "Snap for 11526323 from 2c0e9a58ead53aff66f0978c51142d8331ffffb0 to simpleperf-release" into simpleperf-releasesimpleperf-release
-rw-r--r-- | libc/bionic/fork.cpp | 8 | ||||
-rw-r--r-- | libc/include/android/crash_detail.h | 2 | ||||
-rw-r--r-- | libc/include/bits/page_size.h | 2 | ||||
-rw-r--r-- | libc/include/spawn.h | 2 | ||||
-rw-r--r-- | libc/include/unistd.h | 33 | ||||
-rw-r--r-- | libc/libc.map.txt | 1 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 41 | ||||
-rw-r--r-- | tests/unistd_test.cpp | 16 |
8 files changed, 95 insertions, 10 deletions
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp index d432c6db7..615e81f9f 100644 --- a/libc/bionic/fork.cpp +++ b/libc/bionic/fork.cpp @@ -50,11 +50,13 @@ int __clone_for_fork() { return result; } +int _Fork() { + return __clone_for_fork(); +} + int fork() { __bionic_atfork_run_prepare(); - - int result = __clone_for_fork(); - + int result = _Fork(); if (result == 0) { // Disable fdsan and fdtrack post-fork, so we don't falsely trigger on processes that // fork, close all of their fds, and then exec. diff --git a/libc/include/android/crash_detail.h b/libc/include/android/crash_detail.h index 6744385ba..1889f9f41 100644 --- a/libc/include/android/crash_detail.h +++ b/libc/include/android/crash_detail.h @@ -34,8 +34,6 @@ */ #include <stddef.h> -#include <stdint.h> -#include <string.h> #include <sys/cdefs.h> __BEGIN_DECLS diff --git a/libc/include/bits/page_size.h b/libc/include/bits/page_size.h index ca434e568..df0cb7fcc 100644 --- a/libc/include/bits/page_size.h +++ b/libc/include/bits/page_size.h @@ -32,7 +32,7 @@ __BEGIN_DECLS -#if !defined(__BIONIC_NO_PAGE_SIZE_MACRO) +#if !defined(__BIONIC_NO_PAGE_SIZE_MACRO) || defined(__BIONIC_DEPRECATED_PAGE_SIZE_MACRO) #define PAGE_SIZE 4096 #define PAGE_MASK (~(PAGE_SIZE - 1)) #endif diff --git a/libc/include/spawn.h b/libc/include/spawn.h index 6c34b98bc..3ce402fef 100644 --- a/libc/include/spawn.h +++ b/libc/include/spawn.h @@ -55,7 +55,7 @@ typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t; int posix_spawn(pid_t* _Nullable __pid, const char* _Nonnull __path, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28); int posix_spawnp(pid_t* _Nullable __pid, const char* _Nonnull __file, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28); -int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28); +int posix_spawnattr_init(posix_spawnattr_t _Nullable * _Nonnull __attr) __INTRODUCED_IN(28); int posix_spawnattr_destroy(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28); int posix_spawnattr_setflags(posix_spawnattr_t _Nonnull * _Nonnull __attr, short __flags) __INTRODUCED_IN(28); diff --git a/libc/include/unistd.h b/libc/include/unistd.h index c8cceb21e..b94197eb0 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -78,8 +78,37 @@ extern char* _Nullable * _Nullable environ; __noreturn void _exit(int __status); -pid_t fork(void); -pid_t vfork(void) __returns_twice; +/** + * [fork(2)](http://man7.org/linux/man-pages/man2/fork.2.html) creates a new + * process. fork() runs any handlers set by pthread_atfork(). + * + * Returns 0 in the child, the pid of the child in the parent, + * and returns -1 and sets `errno` on failure. + */ +pid_t fork(void); + +/** + * _Fork() creates a new process. _Fork() differs from fork() in that it does + * not run any handlers set by pthread_atfork(). + * + * Returns 0 in the child, the pid of the child in the parent, + * and returns -1 and sets `errno` on failure. + * + * Available since API level 35. + */ +pid_t _Fork(void) __INTRODUCED_IN(35); + +/** + * [vfork(2)](http://man7.org/linux/man-pages/man2/vfork.2.html) creates a new + * process. vfork() differs from fork() in that it does not run any handlers + * set by pthread_atfork(), and the parent is suspended until the child calls + * exec() or exits. + * + * Returns 0 in the child, the pid of the child in the parent, + * and returns -1 and sets `errno` on failure. + */ +pid_t vfork(void) __returns_twice; + pid_t getpid(void); pid_t gettid(void) __attribute_const__; pid_t getpgid(pid_t __pid); diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 5e9763bef..2c8ec0796 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1592,6 +1592,7 @@ LIBC_V { # introduced=VanillaIceCream android_crash_detail_replace_data; epoll_pwait2; epoll_pwait2_64; + _Fork; localtime_rz; mbsrtowcs_l; mktime_z; diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 1a882beb5..2bf755b44 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -1423,10 +1423,11 @@ 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; } -TEST(pthread, pthread_atfork_smoke) { +TEST(pthread, pthread_atfork_smoke_fork) { ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); + g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0; pid_t pid = fork(); ASSERT_NE(-1, pid) << strerror(errno); @@ -1442,6 +1443,44 @@ TEST(pthread, pthread_atfork_smoke) { AssertChildExited(pid, 0); } +TEST(pthread, pthread_atfork_smoke_vfork) { + ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); + ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); + + g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0; + pid_t pid = vfork(); + ASSERT_NE(-1, pid) << strerror(errno); + + // atfork handlers are not called. + if (pid == 0) { + ASSERT_EQ(0, g_atfork_child_calls); + _exit(0); + } + ASSERT_EQ(0, g_atfork_parent_calls); + ASSERT_EQ(0, g_atfork_prepare_calls); + AssertChildExited(pid, 0); +} + +TEST(pthread, pthread_atfork_smoke__Fork) { +#if defined(__BIONIC__) + ASSERT_EQ(0, pthread_atfork(AtForkPrepare1, AtForkParent1, AtForkChild1)); + ASSERT_EQ(0, pthread_atfork(AtForkPrepare2, AtForkParent2, AtForkChild2)); + + g_atfork_prepare_calls = g_atfork_parent_calls = g_atfork_child_calls = 0; + pid_t pid = _Fork(); + ASSERT_NE(-1, pid) << strerror(errno); + + // atfork handlers are not called. + if (pid == 0) { + ASSERT_EQ(0, g_atfork_child_calls); + _exit(0); + } + ASSERT_EQ(0, g_atfork_parent_calls); + ASSERT_EQ(0, g_atfork_prepare_calls); + AssertChildExited(pid, 0); +#endif +} + TEST(pthread, pthread_attr_getscope) { pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp index 6c08972e6..78b55c18b 100644 --- a/tests/unistd_test.cpp +++ b/tests/unistd_test.cpp @@ -440,6 +440,22 @@ TEST(UNISTD_TEST, syncfs) { TestSyncFunction(syncfs); } +TEST(UNISTD_TEST, _Fork) { +#if defined(__BIONIC__) + pid_t rc = _Fork(); + ASSERT_NE(-1, rc); + if (rc == 0) { + _exit(66); + } + + int status; + pid_t wait_result = waitpid(rc, &status, 0); + ASSERT_EQ(wait_result, rc); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(66, WEXITSTATUS(status)); +#endif +} + TEST(UNISTD_TEST, vfork) { #if defined(__BIONIC__) pthread_internal_t* self = __get_thread(); |