From 03324780aae9ff28c8acf52debf0ea39120e5ab8 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Tue, 24 Mar 2015 17:43:14 -0700 Subject: [PATCH] Cause Fatal error when invalid pthread_id is detected. This is a patch testing whether we can use abort() instead of returning ESRCH for invalid pthread ids. It is an intermediate step to remove g_thread_list/g_thread_list_lock. Bug: 19636317 Change-Id: Idd8e4a346c7ce91e1be0c2ebcb78ce51c0d0a31d --- libc/bionic/pthread_internal.cpp | 12 ++++++--- tests/pthread_test.cpp | 46 +++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp index 1967ccf8c..afafad84c 100644 --- a/libc/bionic/pthread_internal.cpp +++ b/libc/bionic/pthread_internal.cpp @@ -81,12 +81,16 @@ void __pthread_internal_remove_and_free(pthread_internal_t* thread) { pthread_internal_t* __pthread_internal_find(pthread_t thread_id) { pthread_internal_t* thread = reinterpret_cast(thread_id); - ScopedPthreadMutexLocker locker(&g_thread_list_lock); + { + ScopedPthreadMutexLocker locker(&g_thread_list_lock); - for (pthread_internal_t* t = g_thread_list; t != NULL; t = t->next) { - if (t == thread) { - return thread; + for (pthread_internal_t* t = g_thread_list; t != NULL; t = t->next) { + if (t == thread) { + return thread; + } } } + // TODO: Remove g_thread_list/g_thread_list_lock when the fatal error below doesn't happen. + __libc_fatal("No such thread: %p", thread); return NULL; } diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 4eb352d8e..b4667f939 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -399,12 +399,17 @@ TEST(pthread, pthread_setname_np__other) { ASSERT_EQ(0, pthread_setname_np(t1, "short 2")); } -TEST(pthread, pthread_setname_np__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_setname_np__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); // Call pthread_setname_np after thread has already exited. +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_setname_np(dead_thread, "short 3"), testing::KilledBySignal(SIGABRT), + "No such thread"); +#else ASSERT_EQ(ENOENT, pthread_setname_np(dead_thread, "short 3")); +#endif } TEST(pthread, pthread_kill__0) { @@ -430,11 +435,15 @@ TEST(pthread, pthread_kill__in_signal_handler) { ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM)); } -TEST(pthread, pthread_detach__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_detach__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_detach(dead_thread), testing::KilledBySignal(SIGABRT), "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_detach(dead_thread)); +#endif } TEST(pthread, pthread_detach_no_leak) { @@ -485,44 +494,67 @@ TEST(pthread, pthread_getcpuclockid__clock_gettime) { ASSERT_EQ(0, clock_gettime(c, &ts)); } -TEST(pthread, pthread_getcpuclockid__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_getcpuclockid__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); clockid_t c; +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_getcpuclockid(dead_thread, &c), testing::KilledBySignal(SIGABRT), + "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_getcpuclockid(dead_thread, &c)); +#endif } -TEST(pthread, pthread_getschedparam__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_getschedparam__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); int policy; sched_param param; +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_getschedparam(dead_thread, &policy, ¶m), testing::KilledBySignal(SIGABRT), + "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_getschedparam(dead_thread, &policy, ¶m)); +#endif } -TEST(pthread, pthread_setschedparam__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_setschedparam__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); int policy = 0; sched_param param; +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_setschedparam(dead_thread, policy, ¶m), testing::KilledBySignal(SIGABRT), + "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_setschedparam(dead_thread, policy, ¶m)); +#endif } -TEST(pthread, pthread_join__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_join__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_join(dead_thread, NULL), testing::KilledBySignal(SIGABRT), "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_join(dead_thread, NULL)); +#endif } -TEST(pthread, pthread_kill__no_such_thread) { +TEST_F(pthread_DeathTest, pthread_kill__no_such_thread) { pthread_t dead_thread; MakeDeadThread(dead_thread); +#if defined(__BIONIC__) + ASSERT_EXIT(pthread_kill(dead_thread, 0), testing::KilledBySignal(SIGABRT), "No such thread"); +#else ASSERT_EQ(ESRCH, pthread_kill(dead_thread, 0)); +#endif } TEST(pthread, pthread_join__multijoin) {