-/* -*- mode: C; c-basic-offset: 3; -*- */
+/* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
/*
This file is part of drd, a thread error detector.
- Copyright (C) 2006-2010 Bart Van Assche <bart.vanassche@gmail.com>.
+ Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "pub_tool_tooliface.h" // VG_(needs_...)()
+/* Global variables. */
+
+Bool DRD_(g_free_is_write);
+
+
/* Local function declarations. */
static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret);
switch (arg[0])
{
case VG_USERREQ__MALLOCLIKE_BLOCK:
+ if (DRD_(g_free_is_write)) {
+ GenericErrInfo GEI = {
+ .tid = DRD_(thread_get_running_tid)(),
+ .addr = 0,
+ };
+ VG_(maybe_record_error)(vg_tid,
+ GenericErr,
+ VG_(get_IP)(vg_tid),
+ "--free-is-write=yes is incompatible with"
+ " custom memory allocator client requests",
+ &GEI);
+ }
if (arg[1])
DRD_(malloclike_block)(vg_tid, arg[1]/*addr*/, arg[2]/*size*/);
break;
+ case VG_USERREQ__RESIZEINPLACE_BLOCK:
+ if (!DRD_(freelike_block)(vg_tid, arg[1]/*addr*/, False))
+ {
+ GenericErrInfo GEI = {
+ .tid = DRD_(thread_get_running_tid)(),
+ .addr = 0,
+ };
+ VG_(maybe_record_error)(vg_tid,
+ GenericErr,
+ VG_(get_IP)(vg_tid),
+ "Invalid VG_USERREQ__RESIZEINPLACE_BLOCK request",
+ &GEI);
+ }
+ DRD_(malloclike_block)(vg_tid, arg[1]/*addr*/, arg[3]/*newSize*/);
+ break;
+
case VG_USERREQ__FREELIKE_BLOCK:
- if (arg[1] && ! DRD_(freelike_block)(vg_tid, arg[1]/*addr*/))
+ if (arg[1] && ! DRD_(freelike_block)(vg_tid, arg[1]/*addr*/, False))
{
GenericErrInfo GEI = {
.tid = DRD_(thread_get_running_tid)(),
break;
case VG_USERREQ__DRD_START_SUPPRESSION:
+ /*_VG_USERREQ__HG_ARANGE_MAKE_UNTRACKED*/
+ case VG_USERREQ_TOOL_BASE('H','G') + 256 + 39:
DRD_(start_suppression)(arg[1], arg[1] + arg[2], "client");
break;
case VG_USERREQ__DRD_FINISH_SUPPRESSION:
+ /*_VG_USERREQ__HG_ARANGE_MAKE_TRACKED*/
+ case VG_USERREQ_TOOL_BASE('H','G') + 256 + 40:
DRD_(finish_suppression)(arg[1], arg[1] + arg[2]);
break;
break;
case VG_USERREQ__SET_JOINABLE:
- DRD_(thread_set_joinable)(DRD_(PtThreadIdToDrdThreadId)(arg[1]),
- (Bool)arg[2]);
+ {
+ const DrdThreadId drd_joinable = DRD_(PtThreadIdToDrdThreadId)(arg[1]);
+ if (drd_joinable != DRD_INVALID_THREADID)
+ DRD_(thread_set_joinable)(drd_joinable, (Bool)arg[2]);
+ else {
+ InvalidThreadIdInfo ITI = { DRD_(thread_get_running_tid)(), arg[1] };
+ VG_(maybe_record_error)(vg_tid,
+ InvalidThreadId,
+ VG_(get_IP)(vg_tid),
+ "pthread_detach(): invalid thread ID",
+ &ITI);
+ }
break;
+ }
case VG_USERREQ__ENTERING_PTHREAD_CREATE:
DRD_(thread_entering_pthread_create)(drd_tid);