|
From: <sv...@va...> - 2009-07-31 08:35:15
|
Author: bart
Date: 2009-07-31 09:26:17 +0100 (Fri, 31 Jul 2009)
New Revision: 10674
Log:
Report an error message instead of triggering an assertion failure when a non-existing thread ID is passed to pthread_join() or pthread_cancel().
Modified:
trunk/drd/drd_clientreq.c
trunk/drd/drd_error.c
trunk/drd/drd_error.h
trunk/drd/drd_pthread_intercepts.c
trunk/drd/drd_thread.c
Modified: trunk/drd/drd_clientreq.c
===================================================================
--- trunk/drd/drd_clientreq.c 2009-07-31 07:50:17 UTC (rev 10673)
+++ trunk/drd/drd_clientreq.c 2009-07-31 08:26:17 UTC (rev 10674)
@@ -83,11 +83,11 @@
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 @@
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:
Modified: trunk/drd/drd_error.c
===================================================================
--- trunk/drd/drd_error.c 2009-07-31 07:50:17 UTC (rev 10673)
+++ trunk/drd/drd_error.c 2009-07-31 08:26:17 UTC (rev 10674)
@@ -361,6 +361,13 @@
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 @@
return sizeof(HoldtimeErrInfo);
case GenericErr:
return sizeof(GenericErrInfo);
+ case InvalidThreadId:
+ return sizeof(InvalidThreadIdInfo);
default:
tl_assert(False);
break;
@@ -435,6 +444,8 @@
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 @@
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);
}
Modified: trunk/drd/drd_error.h
===================================================================
--- trunk/drd/drd_error.h 2009-07-31 07:50:17 UTC (rev 10673)
+++ trunk/drd/drd_error.h 2009-07-31 08:26:17 UTC (rev 10674)
@@ -59,6 +59,8 @@
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 @@
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);
Modified: trunk/drd/drd_pthread_intercepts.c
===================================================================
--- trunk/drd/drd_pthread_intercepts.c 2009-07-31 07:50:17 UTC (rev 10673)
+++ trunk/drd/drd_pthread_intercepts.c 2009-07-31 08:26:17 UTC (rev 10674)
@@ -438,8 +438,9 @@
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;
Modified: trunk/drd/drd_thread.c
===================================================================
--- trunk/drd/drd_thread.c 2009-07-31 07:50:17 UTC (rev 10673)
+++ trunk/drd/drd_thread.c 2009-07-31 08:26:17 UTC (rev 10674)
@@ -209,14 +209,15 @@
{
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;
|