aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2018-10-18 17:47:17 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-10-18 17:47:17 +0000
commit7ff7d03286dcf8abc6b4bd0455c428256493c96d (patch)
tree54e9ee60ee1a9268eb490ae69eeb5c5467324556
parent89376008975d88e771c048db57ac749d9d4ace55 (diff)
parentddf757e35eb36d684b16273f0ddfe2d387983e8e (diff)
downloadbionic-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.cpp4
-rw-r--r--tests/pthread_test.cpp20
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);