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;
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:
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",
return sizeof(HoldtimeErrInfo);
case GenericErr:
return sizeof(GenericErrInfo);
+ case InvalidThreadId:
+ return sizeof(InvalidThreadIdInfo);
default:
tl_assert(False);
break;
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;
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);
}
HoldtimeErr = 10,
#define STR_GenericErr "GenericErr"
GenericErr = 11,
+#define STR_InvalidThreadId "InvalidThreadId"
+ InvalidThreadId = 12,
} DrdErrorKind;
/* The classification of a faulting address. */
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);
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;
{
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;