From: Bart Van Assche Date: Sun, 25 Mar 2012 17:51:59 +0000 (+0000) Subject: Check whether the big lock is held before invoking pre_thread_ll_create. X-Git-Tag: svn/VALGRIND_3_8_0~395 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=563f0acd21927a4efd9841cc8aa5da7cbaefce62;p=thirdparty%2Fvalgrind.git Check whether the big lock is held before invoking pre_thread_ll_create. If the pre_thread_ll_create tracking function would be invoked without the big lock being held, that would trigger a race condition in the tools that implement this tracking function. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12458 --- diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c index 4548db0a0a..be2ae59066 100644 --- a/coregrind/m_scheduler/scheduler.c +++ b/coregrind/m_scheduler/scheduler.c @@ -326,6 +326,12 @@ void VG_(release_BigLock_LL) ( HChar* who ) ML_(release_sched_lock)(the_BigLock); } +Bool VG_(owns_BigLock_LL) ( ThreadId tid ) +{ + return (ML_(get_sched_lock_owner)(the_BigLock) + == VG_(threads)[tid].os_state.lwpid); +} + /* Clear out the ThreadState and release the semaphore. Leaves the ThreadState in VgTs_Zombie state, so that it doesn't get diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 6408185d09..39a69484dc 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -289,6 +289,7 @@ static SysRes do_clone ( ThreadId ptid, know that this thread has come into existence. If the clone fails, we'll send out a ll_exit notification for it at the out: label below, to clean up. */ + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 4c1137fb6c..a416b1169e 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -228,6 +228,7 @@ static SysRes do_clone ( ThreadId ptid, ctst->client_stack_szB = 0; } + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index 96a83571ee..a6db239837 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -6483,6 +6483,7 @@ POST(bsdthread_create) // should be in pthread_hijack instead, just before the call to // start_thread_NORETURN(), call_on_new_stack_0_1(), but we don't have the // parent tid value there... + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, tid, tst->tid ); } diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index efa272fb3e..715e685dd1 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -335,6 +335,7 @@ static SysRes do_clone ( ThreadId ptid, know that this thread has come into existence. If the clone fails, we'll send out a ll_exit notification for it at the out: label below, to clean up. */ + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index b55bee6728..75137f2f01 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -363,6 +363,7 @@ static SysRes do_clone ( ThreadId ptid, know that this thread has come into existence. If the clone fails, we'll send out a ll_exit notification for it at the out: label below, to clean up. */ + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index ae8b1a4dbd..15f8f23803 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -287,6 +287,7 @@ static SysRes do_clone ( ThreadId ptid, know that this thread has come into existence. If the clone fails, we'll send out a ll_exit notification for it at the out: label below, to clean up. */ + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 2e64200866..a79bc45124 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -303,6 +303,7 @@ static SysRes do_clone ( ThreadId ptid, if we don't state the new thread exists prior to that point. If the clone fails, we'll send out a ll_exit notification for it at the out: label below, to clean up. */ + vg_assert(VG_(owns_BigLock_LL)(ptid)); VG_TRACK ( pre_thread_ll_create, ptid, ctid ); if (flags & VKI_CLONE_SETTLS) { diff --git a/coregrind/pub_core_scheduler.h b/coregrind/pub_core_scheduler.h index 8d3d97c5ac..5e6042a324 100644 --- a/coregrind/pub_core_scheduler.h +++ b/coregrind/pub_core_scheduler.h @@ -78,6 +78,9 @@ extern void VG_(release_BigLock) ( ThreadId tid, /* Matching function to acquire_BigLock_LL. */ extern void VG_(release_BigLock_LL) ( HChar* who ); +/* Whether the specified thread owns the big lock. */ +extern Bool VG_(owns_BigLock_LL) ( ThreadId tid ); + /* Yield the CPU for a while. Drops/acquires the lock using the normal (non _LL) functions. */ extern void VG_(vg_yield)(void);