diff options
author | Josh Gao <jmgao@google.com> | 2018-10-18 17:47:17 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-10-18 17:47:17 +0000 |
commit | 7ff7d03286dcf8abc6b4bd0455c428256493c96d (patch) | |
tree | 54e9ee60ee1a9268eb490ae69eeb5c5467324556 | |
parent | 89376008975d88e771c048db57ac749d9d4ace55 (diff) | |
parent | ddf757e35eb36d684b16273f0ddfe2d387983e8e (diff) | |
download | bionic-ndk-release-r19.tar.gz |
Merge "Properly fail with ESRCH when pthread_killing an exited thread."ndk-r19cndk-r19bndk-r19-beta2ndk-r19-beta1ndk-r19ndk-release-r19
-rw-r--r-- | libc/bionic/pthread_kill.cpp | 4 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 20 |
2 files changed, 23 insertions, 1 deletions
diff --git a/libc/bionic/pthread_kill.cpp b/libc/bionic/pthread_kill.cpp index 3761a7589..153157496 100644 --- a/libc/bionic/pthread_kill.cpp +++ b/libc/bionic/pthread_kill.cpp @@ -36,7 +36,9 @@ int pthread_kill(pthread_t t, int sig) { ErrnoRestorer errno_restorer; pid_t tid = pthread_gettid_np(t); - if (tid == -1) return ESRCH; + + // tid gets reset to 0 on thread exit by CLONE_CHILD_CLEARTID. + if (tid == 0 || tid == -1) return ESRCH; return (tgkill(getpid(), tid, sig) == -1) ? errno : 0; } diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index fc8945ce8..e68f1ff03 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -31,6 +31,7 @@ #include <unwind.h> #include <atomic> +#include <future> #include <vector> #include <android-base/parseint.h> @@ -539,6 +540,25 @@ TEST(pthread, pthread_kill__in_signal_handler) { ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); } +TEST(pthread, pthread_kill__exited_thread) { + static std::promise<pid_t> tid_promise; + pthread_t thread; + ASSERT_EQ(0, pthread_create(&thread, nullptr, + [](void*) -> void* { + tid_promise.set_value(gettid()); + return nullptr; + }, + nullptr)); + + pid_t tid = tid_promise.get_future().get(); + while (TEMP_FAILURE_RETRY(syscall(__NR_tgkill, getpid(), tid, 0)) != -1) { + continue; + } + ASSERT_EQ(ESRCH, errno); + + ASSERT_EQ(ESRCH, pthread_kill(thread, 0)); +} + TEST_F(pthread_DeathTest, pthread_detach__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); |