From: Bart Van Assche Date: Fri, 31 Jul 2009 08:26:17 +0000 (+0000) Subject: Report an error message instead of triggering an assertion failure when a non-existin... X-Git-Tag: svn/VALGRIND_3_5_0~176 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fd574c0b25041997a38fc5c7250ed63e68ed3f4f;p=thirdparty%2Fvalgrind.git Report an error message instead of triggering an assertion failure when a non-existing thread ID is passed to pthread_join() or pthread_cancel(). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10674 --- diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c index 14f0b47b22..7b1ffafc55 100644 --- a/drd/drd_clientreq.c +++ b/drd/drd_clientreq.c @@ -83,11 +83,11 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret) if (arg[1] && ! DRD_(freelike_block)(vg_tid, arg[1]/*addr*/)) { GenericErrInfo GEI = { DRD_(thread_get_running_tid)() }; - VG_(maybe_record_error)(vg_tid, - GenericErr, - VG_(get_IP)(vg_tid), - "Invalid VG_USERREQ__FREELIKE_BLOCK request", - &GEI); + VG_(maybe_record_error)(vg_tid, + GenericErr, + VG_(get_IP)(vg_tid), + "Invalid VG_USERREQ__FREELIKE_BLOCK request", + &GEI); } break; @@ -212,17 +212,44 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret) break; case VG_USERREQ__POST_THREAD_JOIN: - tl_assert(arg[1]); - DRD_(thread_post_join)(drd_tid, DRD_(PtThreadIdToDrdThreadId)(arg[1])); + { + const DrdThreadId thread_to_join = DRD_(PtThreadIdToDrdThreadId)(arg[1]); + if (thread_to_join == DRD_INVALID_THREADID) + { + InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] }; + VG_(maybe_record_error)(vg_tid, + InvalidThreadId, + VG_(get_IP)(vg_tid), + "pthread_join(): invalid thread ID", + &ITI); + } + else + { + DRD_(thread_post_join)(drd_tid, thread_to_join); + } break; + } case VG_USERREQ__PRE_THREAD_CANCEL: - tl_assert(arg[1]); - DRD_(thread_pre_cancel)(drd_tid); + { + const DrdThreadId thread_to_cancel =DRD_(PtThreadIdToDrdThreadId)(arg[1]); + if (thread_to_cancel == DRD_INVALID_THREADID) + { + InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] }; + VG_(maybe_record_error)(vg_tid, + InvalidThreadId, + VG_(get_IP)(vg_tid), + "pthread_cancel(): invalid thread ID", + &ITI); + } + else + { + DRD_(thread_pre_cancel)(thread_to_cancel); + } break; + } case VG_USERREQ__POST_THREAD_CANCEL: - tl_assert(arg[1]); break; case VG_USERREQ__PRE_MUTEX_INIT: diff --git a/drd/drd_error.c b/drd/drd_error.c index a4d17f5280..899a5fb818 100644 --- a/drd/drd_error.c +++ b/drd/drd_error.c @@ -361,6 +361,13 @@ static void drd_tool_error_pp(Error* const e) VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } + case InvalidThreadId: { + InvalidThreadIdInfo* iti =(InvalidThreadIdInfo*)(VG_(get_error_extra)(e)); + VG_(message)(Vg_UserMsg, + "%s 0x%llx\n", VG_(get_error_string)(e), iti->ptid); + VG_(pp_ExeContext)(VG_(get_error_where)(e)); + break; + } default: VG_(message)(Vg_UserMsg, "%s\n", @@ -396,6 +403,8 @@ static UInt drd_tool_error_update_extra(Error* e) return sizeof(HoldtimeErrInfo); case GenericErr: return sizeof(GenericErrInfo); + case InvalidThreadId: + return sizeof(InvalidThreadIdInfo); default: tl_assert(False); break; @@ -435,6 +444,8 @@ static Bool drd_is_recognized_suppression(Char* const name, Supp* const supp) skind = HoldtimeErr; else if (VG_(strcmp)(name, STR_GenericErr) == 0) skind = GenericErr; + else if (VG_(strcmp)(name, STR_InvalidThreadId) == 0) + skind = InvalidThreadId; else return False; @@ -480,6 +491,7 @@ static Char* drd_get_error_name(Error* e) case RwlockErr: return VGAPPEND(STR_, RwlockErr); case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr); case GenericErr: return VGAPPEND(STR_, GenericErr); + case InvalidThreadId: return VGAPPEND(STR_, InvalidThreadId); default: tl_assert(0); } diff --git a/drd/drd_error.h b/drd/drd_error.h index c9d89fda36..cc3fcd0007 100644 --- a/drd/drd_error.h +++ b/drd/drd_error.h @@ -59,6 +59,8 @@ typedef enum { HoldtimeErr = 10, #define STR_GenericErr "GenericErr" GenericErr = 11, +#define STR_InvalidThreadId "InvalidThreadId" + InvalidThreadId = 12, } DrdErrorKind; /* The classification of a faulting address. */ @@ -161,6 +163,10 @@ typedef struct { DrdThreadId tid; } GenericErrInfo; +typedef struct { + DrdThreadId tid; + ULong ptid; +} InvalidThreadIdInfo; void DRD_(set_show_conflicting_segments)(const Bool scs); void DRD_(register_error_handlers)(void); diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index a3cda4cab2..94cd862fa2 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -438,8 +438,9 @@ PTH_FUNC(int, pthreadZudetach, pthread_t pt_thread) return ret; } -// pthread_cancel* -PTH_FUNC(int, pthreadZucancelZa, pthread_t pt_thread) +// pthread_cancel +// Note: make sure not to intercept pthread_cancel_init() on Linux ! +PTH_FUNC(int, pthreadZucancel, pthread_t pt_thread) { int res; int ret; diff --git a/drd/drd_thread.c b/drd/drd_thread.c index 519efe5881..e497db5e11 100644 --- a/drd/drd_thread.c +++ b/drd/drd_thread.c @@ -209,14 +209,15 @@ DrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid) { int i; - tl_assert(tid != INVALID_POSIX_THREADID); - - for (i = 1; i < DRD_N_THREADS; i++) + if (tid != INVALID_POSIX_THREADID) { - if (DRD_(g_threadinfo)[i].posix_thread_exists - && DRD_(g_threadinfo)[i].pt_threadid == tid) + for (i = 1; i < DRD_N_THREADS; i++) { - return i; + if (DRD_(g_threadinfo)[i].posix_thread_exists + && DRD_(g_threadinfo)[i].pt_threadid == tid) + { + return i; + } } } return DRD_INVALID_THREADID;