コード例 #1
0
/**
 * Call this function when thread tid stops to exist, such that the
 * "last owner" field can be cleared if it still refers to that thread.
 */
static void mutex_delete_thread(struct mutex_info* p, const DrdThreadId tid)
{
   tl_assert(p);

   if (p->owner == tid && p->recursion_count > 0)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              MutexErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Mutex still locked at thread exit",
                              &MEI);
      p->owner = VG_INVALID_THREADID;
   }
}
コード例 #2
0
/**
 * Initialize the memory 'vc' points at as a vector clock with size 'size'.
 * If the pointer 'vcelem' is not null, it is assumed to be an array with
 * 'size' elements and it becomes the initial value of the vector clock.
 */
void DRD_(vc_init)(VectorClock* const vc,
                   const VCElem* const vcelem,
                   const unsigned size)
{
   tl_assert(vc);
   vc->size = 0;
   vc->capacity = 0;
   vc->vc = 0;
   DRD_(vc_reserve)(vc, size);
   tl_assert(size == 0 || vc->vc != 0);
   if (vcelem)
   {
      VG_(memcpy)(vc->vc, vcelem, size * sizeof(vcelem[0]));
      vc->size = size;
   }
}
コード例 #3
0
/** Called before pthread_mutex_lock() is invoked. If a data structure for
 *  the client-side object was not yet created, do this now. Also check whether
 *  an attempt is made to lock recursively a synchronization object that must
 *  not be locked recursively.
 */
void DRD_(mutex_pre_lock)(const Addr mutex, MutexT mutex_type,
                          const Bool trylock)
{
   struct mutex_info* p;

   p = DRD_(mutex_get_or_allocate)(mutex, mutex_type);
   if (mutex_type == mutex_type_unknown)
      mutex_type = p->mutex_type;

   if (s_trace_mutex)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d] %s %s 0x%lx rc %d owner %d\n",
                   DRD_(thread_get_running_tid)(),
                   trylock ? "pre_mutex_lock " : "mutex_trylock  ",
                   p ? DRD_(mutex_get_typename)(p) : "(?)",
                   mutex,
                   p ? p->recursion_count : -1,
                   p ? p->owner : DRD_INVALID_THREADID);
   }

   if (p == 0)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   tl_assert(p);

   if (mutex_type == mutex_type_invalid_mutex)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   if (! trylock
       && p->owner == DRD_(thread_get_running_tid)()
       && p->recursion_count >= 1
       && mutex_type != mutex_type_recursive_mutex)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              MutexErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Recursive locking not allowed",
                              &MEI);
   }
}
コード例 #4
0
void DRD_(stop_tracing_address_range)(const Addr a1, const Addr a2)
{
   tl_assert(a1 < a2);

   DRD_(bm_clear_load)(DRD_(s_suppressed), a1, a2);
   if (DRD_(g_any_address_traced))
   {
      DRD_(g_any_address_traced)
         = DRD_(bm_has_any_load)(DRD_(s_suppressed), 0, ~(Addr)0);
   }
}
コード例 #5
0
ファイル: drd_main.c プロジェクト: svn2github/valgrind-3
static __inline__
void drd_start_using_mem(const Addr a1, const SizeT len,
                         const Bool is_stack_mem)
{
    const Addr a2 = a1 + len;

    tl_assert(a1 <= a2);

    if (!is_stack_mem && s_trace_alloc)
        DRD_(trace_msg)("Started using memory range 0x%lx + %ld%s",
                        a1, len, DRD_(running_thread_inside_pthread_create)()
                        ? " (inside pthread_create())" : "");

#if 0
    if (!is_stack_mem && DRD_(g_free_is_write))
        DRD_(thread_stop_using_mem)(a1, a2);
#else
    /*
     * Sometimes it happens that a client starts using a memory range that has
     * been accessed before but for which drd_stop_using_mem() has not been
     * called for the entire range. It is not yet clear whether this is an
     * out-of-range access by the client, an issue in the Valgrind core or an
     * issue in DRD. Avoid that this issue triggers false positive reports by
     * always clearing accesses for newly allocated memory ranges. See also
     * http://bugs.kde.org/show_bug.cgi?id=297147.
     */
    DRD_(thread_stop_using_mem)(a1, a2);
#endif

    if (UNLIKELY(DRD_(any_address_is_traced)()))
    {
        DRD_(trace_mem_access)(a1, len, eStart, 0, 0);
    }

    if (UNLIKELY(DRD_(running_thread_inside_pthread_create)()))
    {
        DRD_(start_suppression)(a1, a2, "pthread_create()");
    }
}
コード例 #6
0
ファイル: drd_semaphore.c プロジェクト: svn2github/valgrind-3
/**
 * Called after sem_wait() finished.
 * @note Do not rely on the value of 'waited' -- some glibc versions do
 *       not set it correctly.
 */
void DRD_(semaphore_post_wait)(const DrdThreadId tid, const Addr semaphore,
                               const Bool waited)
{
   struct semaphore_info* p;
   Segment* sg;

   p = DRD_(semaphore_get)(semaphore);
   if (s_trace_semaphore)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d/%d] semaphore_wait      0x%lx value %u -> %u",
                   VG_(get_running_tid)(),
                   DRD_(thread_get_running_tid)(),
                   semaphore,
                   p ? p->value : 0,
                   p ? p->value - 1 : 0);
   }
   tl_assert(p);
   tl_assert(p->waiters > 0);
   p->waiters--;
   tl_assert((int)p->waiters >= 0);
   tl_assert((int)p->value >= 0);
   if (p->value == 0)
   {
      SemaphoreErrInfo sei = { semaphore };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              SemaphoreErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Invalid semaphore",
                              &sei);
      return;
   }
   p->value--;
   tl_assert((int)p->value >= 0);
   if (p->waits_to_skip > 0)
      p->waits_to_skip--;
   else
   {
      sg = DRD_(segment_pop)(p);
      tl_assert(sg);
      if (sg)
      {
         if (p->last_sem_post_tid != tid
             && p->last_sem_post_tid != DRD_INVALID_THREADID)
         {
            DRD_(thread_combine_vc2)(tid, &sg->vc);
         }
         DRD_(sg_put)(sg);
         DRD_(thread_new_segment)(tid);
         s_semaphore_segment_creation_count++;
      }
   }
}
コード例 #7
0
/**
 * Initialize the memory 'sg' points at.
 *
 * @note The creator and created thread ID's may be equal.
 * @note This function copies the vector clock of thread 'creator', a technique
 *   also known as clock snooping. This will only work reliably if the thread
 *   that called pthread_create() waits until the created thread has copied
 *   the vector clock.
 */
static void sg_init(Segment* const sg,
                    const DrdThreadId creator,
                    const DrdThreadId created)
{
   Segment* creator_sg;
   ThreadId vg_created = DRD_(DrdThreadIdToVgThreadId)(created);

   tl_assert(sg);
   tl_assert(creator == DRD_INVALID_THREADID
             || DRD_(IsValidDrdThreadId)(creator));

   creator_sg = (creator != DRD_INVALID_THREADID
                 ? DRD_(thread_get_segment)(creator) : 0);

   sg->g_next = NULL;
   sg->g_prev = NULL;
   sg->thr_next = NULL;
   sg->thr_prev = NULL;
   sg->tid = created;
   sg->refcnt = 1;

   if (vg_created != VG_INVALID_THREADID && VG_(get_SP)(vg_created) != 0)
      sg->stacktrace = VG_(record_ExeContext)(vg_created, 0);
   else
      sg->stacktrace = 0;

   if (creator_sg)
      DRD_(vc_copy)(&sg->vc, &creator_sg->vc);
   else
      DRD_(vc_init)(&sg->vc, 0, 0);
   DRD_(vc_increment)(&sg->vc, created);
   DRD_(bm_init)(&sg->bm);

   if (s_trace_segment)
   {
      HChar* vc;

      vc = DRD_(vc_aprint)(&sg->vc);
      VG_(message)(Vg_DebugMsg, "New segment for thread %u with vc %s\n",
                   created, vc);
      VG_(free)(vc);
   }
}
コード例 #8
0
ファイル: drd_barrier.c プロジェクト: svn2github/valgrind-3
/** Called when thread tid stops to exist. */
static void barrier_delete_thread(struct barrier_info* const p,
                                  const DrdThreadId tid)
{
   struct barrier_thread_info* q;
   const UWord word_tid = tid;

   q = VG_(OSetGen_Remove)(p->oset, &word_tid);

   /*
    * q is only non-zero if the barrier object has been used by thread tid
    * after the barrier_init() call and before the thread finished.
    */
   if (q)
   {
      DRD_(barrier_thread_destroy)(q);
      VG_(OSetGen_FreeNode)(p->oset, q);
   }
}
コード例 #9
0
static __always_inline
int pthread_mutex_init_intercept(pthread_mutex_t *mutex,
                                 const pthread_mutexattr_t* attr)
{
   int ret;
   OrigFn fn;
   int mt;
   VALGRIND_GET_ORIG_FN(fn);
   mt = PTHREAD_MUTEX_DEFAULT;
   if (attr)
      pthread_mutexattr_gettype(attr, &mt);
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_INIT,
                                   mutex, DRD_(pthread_to_drd_mutex_type)(mt),
                                   0, 0, 0);
   CALL_FN_W_WW(ret, fn, mutex, attr);
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_INIT,
                                   mutex, 0, 0, 0, 0);
   return ret;
}
コード例 #10
0
ファイル: drd_main.c プロジェクト: cherry-wb/SmartFuzz
static void DRD_(print_usage)(void)
{
   VG_(printf)(
"    --check-stack-var=yes|no  Whether or not to report data races on\n"
"                              stack variables [no].\n"
"    --exclusive-threshold=<n> Print an error message if any mutex or\n"
"        writer lock is held longer than the specified time (in milliseconds).\n"
"    --first-race-only=yes|no  Only report the first data race that occurs on\n"
"                              a memory location instead of all races [no].\n"
"    --report-signal-unlocked=yes|no Whether to report calls to\n"
"                              pthread_cond_signal() where the mutex associated\n"
"                              with the signal via pthread_cond_wait() is not\n"
"                              locked at the time the signal is sent [yes].\n"
"    --segment-merging=yes|no  Controls segment merging [yes].\n"
"        Segment merging is an algorithm to limit memory usage of the\n"
"        data race detection algorithm. Disabling segment merging may\n"
"        improve the accuracy of the so-called 'other segments' displayed\n"
"        in race reports but can also trigger an out of memory error.\n"
"    --segment-merging-interval=<n> Perform segment merging every time n new\n"
"        segments have been created. Default: %d.\n"
"    --shared-threshold=<n>    Print an error message if a reader lock\n"
"        is held longer than the specified time (in milliseconds).\n"
"    --show-confl-seg=yes|no   Show conflicting segments in race reports [yes].\n"
"    --show-stack-usage=yes|no Print stack usage at thread exit time [no].\n"
"    --var-info=yes|no         Display the names of global, static and\n"
"        stack variables when a race is reported on such a variable. This\n"
"        information is by default not displayed since for big programs\n"
"        reading in all debug information at once may cause an out of\n"
"        memory error [no].\n"
"\n"
"  drd options for monitoring process behavior:\n"
"    --trace-addr=<address>    Trace all load and store activity for the.\n"
"                              specified address [off].\n"
"    --trace-barrier=yes|no    Trace all barrier activity [no].\n"
"    --trace-cond=yes|no       Trace all condition variable activity [no].\n"
"    --trace-fork-join=yes|no  Trace all thread fork/join activity [no].\n"
"    --trace-mutex=yes|no      Trace all mutex activity [no].\n"
"    --trace-rwlock=yes|no     Trace all reader-writer lock activity[no].\n"
"    --trace-semaphore=yes|no  Trace all semaphore activity [no].\n",
DRD_(thread_get_segment_merge_interval)()
);
   VG_(replacement_malloc_print_usage)();
}
コード例 #11
0
ファイル: drd_clientobj.c プロジェクト: Zekom/valgrind
/**
 * Remove the information that was stored about the client object p.
 *
 * @note The order of operations below is important. The client object is
 *   removed from the client object set after the cleanup function has been
 *   called such that if the cleanup function can still use the function
 *   DRD_(clientobj_get_any)(). This happens e.g. in the function
 *   first_observed() in drd_error.c.
 */
static Bool clientobj_remove_obj(DrdClientobj* const p)
{
   tl_assert(p);

   if (s_trace_clientobj) {
      DRD_(trace_msg)("Removing client object 0x%lx of type %d", p->any.a1,
                      p->any.type);
#if 0
      VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(),
                                 VG_(clo_backtrace_size));
#endif
   }

   tl_assert(p->any.cleanup);
   (*p->any.cleanup)(p);
   VG_(OSetGen_Remove)(s_clientobj_set, &p->any.a1);
   VG_(OSetGen_FreeNode)(s_clientobj_set, p);
   return True;
}
コード例 #12
0
ファイル: unit_bitmap.c プロジェクト: 520SRig/valgrind
void bm_test1(void)
{
  struct bitmap* bm;
  struct bitmap* bm2;
  unsigned i, j;

  bm = DRD_(bm_new)();

  for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
  {
    DRD_(bm_access_range)(bm,
                          s_test1_args[i].address,
                          s_test1_args[i].address + s_test1_args[i].size,
                          s_test1_args[i].access_type);
  }

  for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
  {
    for (j = 0;
         first_address_with_higher_lsb(j) <= s_test1_args[i].size;
         j = first_address_with_higher_lsb(j))
    {
      tl_assert(DRD_(bm_has_1)(bm,
                               s_test1_args[i].address + j,
                               s_test1_args[i].access_type));
    }
  }

  bm2 = DRD_(bm_new)();
  DRD_(bm_merge2)(bm2, bm);
  DRD_(bm_merge2)(bm2, bm);
  assert(bm_equal_print_diffs(bm2, bm));

  if (s_verbose)
    VG_(printf)("Deleting bitmap bm\n");
  DRD_(bm_delete)(bm);
  if (s_verbose)
    VG_(printf)("Deleting bitmap bm2\n");
  DRD_(bm_delete)(bm2);
}
コード例 #13
0
ファイル: drd_main.c プロジェクト: Legend/Elune
static void drd_pre_mem_read_asciiz(const CorePart part,
                                    const ThreadId tid,
                                    Char* const s,
                                    const Addr a)
{
   const char* p = (void*)a;
   SizeT size = 0;

   /* Note: the expression '*p' reads client memory and may crash if the */
   /* client provided an invalid pointer !                               */
   while (*p)
   {
      p++;
      size++;
   }
   if (size > 0)
   {
      DRD_(trace_load)(a, size);
   }
}
コード例 #14
0
/**
 * Combine the vector clock corresponding to the last unlock operation of
 * reader-writer lock p into the vector clock of thread 'tid'.
 */
static void DRD_(rwlock_combine_other_vc)(struct rwlock_info* const p,
                                          const DrdThreadId tid,
                                          const Bool readers_too)
{
   struct rwlock_thread_info* q;
   VectorClock old_vc;

   DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(tid));
   VG_(OSetGen_ResetIter)(p->thread_info);
   for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; ) {
      if (q->tid != tid) {
         if (q->latest_wrlocked_segment)
            DRD_(vc_combine)(DRD_(thread_get_vc)(tid),
                             &q->latest_wrlocked_segment->vc);
         if (readers_too && q->latest_rdlocked_segment)
            DRD_(vc_combine)(DRD_(thread_get_vc)(tid),
                             &q->latest_rdlocked_segment->vc);
      }
   }
   DRD_(thread_update_conflict_set)(tid, &old_vc);
   DRD_(vc_cleanup)(&old_vc);
}
コード例 #15
0
// pthread_mutex_init
PTH_FUNC(int, pthreadZumutexZuinit,
         pthread_mutex_t *mutex,
         const pthread_mutexattr_t* attr)
{
   int ret;
   int res;
   OrigFn fn;
   int mt;
   VALGRIND_GET_ORIG_FN(fn);
   mt = PTHREAD_MUTEX_DEFAULT;
   if (attr)
      pthread_mutexattr_gettype(attr, &mt);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT,
                              mutex, DRD_(pthread_to_drd_mutex_type)(mt),
                              0, 0, 0);
   CALL_FN_W_WW(ret, fn, mutex, attr);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
                              mutex, 0, 0, 0, 0);
   return ret;
}
コード例 #16
0
ファイル: drd_main.c プロジェクト: svn2github/valgrind-3
static
void drd_pre_thread_create(const ThreadId creator, const ThreadId created)
{
    const DrdThreadId drd_creator = DRD_(VgThreadIdToDrdThreadId)(creator);
    tl_assert(created != VG_INVALID_THREADID);
    DRD_(thread_pre_create)(drd_creator, created);
    if (DRD_(IsValidDrdThreadId)(drd_creator))
    {
        DRD_(thread_new_segment)(drd_creator);
    }
    if (DRD_(thread_get_trace_fork_join)())
    {
        DRD_(trace_msg)("drd_pre_thread_create creator = %d, created = %d",
                        drd_creator, created);
    }
}
コード例 #17
0
ファイル: drd_main.c プロジェクト: cherry-wb/SmartFuzz
static void drd_pre_mem_read_asciiz(const CorePart part,
                                    const ThreadId tid,
                                    Char* const s,
                                    const Addr a)
{
   const char* p = (void*)a;
   SizeT size = 0;

   /* Note: the expression '*p' reads client memory and may crash if the */
   /* client provided an invalid pointer !                               */
   while (*p)
   {
      p++;
      size++;
   }
   // To do: find out what a reasonable upper limit on 'size' is.
   tl_assert(size < 4096);
   if (size > 0)
   {
      DRD_(trace_load)(a, size);
   }
}
コード例 #18
0
ファイル: drd_clientobj.c プロジェクト: Zekom/valgrind
/**
 * Clean up all client objects p for which their start address p->any.a1 fits
 * inside the address range [ a1, a2 [.
 *
 * @note The implementation of this function relies on the fact that the
 *   data in s_clientobj_set is sorted on the start address of client objects.
 */
void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2)
{
   Addr removed_at;
   DrdClientobj* p;

   tl_assert(s_clientobj_set);

   if (! DRD_(range_contains_suppression_or_hbvar)(a1, a2))
      return;

   VG_(OSetGen_ResetIterAt)(s_clientobj_set, &a1);
   for ( ; (p = VG_(OSetGen_Next)(s_clientobj_set)) != 0 && p->any.a1 < a2; )
   {
      tl_assert(a1 <= p->any.a1);
      removed_at = p->any.a1;
      clientobj_remove_obj(p);
      /*
       * The above call removes an element from the oset and hence
       * invalidates the iterator. Restore the iterator.
       */
      VG_(OSetGen_ResetIterAt)(s_clientobj_set, &removed_at);
   }
}
コード例 #19
0
static __always_inline
int pthread_create_intercept(pthread_t* thread, const pthread_attr_t* attr,
                             void* (*start)(void*), void* arg)
{
   int    ret;
   OrigFn fn;
   DrdSema wrapper_started;
   DrdPosixThreadArgs thread_args;

   VALGRIND_GET_ORIG_FN(fn);

   DRD_(sema_init)(&wrapper_started);
   thread_args.start           = start;
   thread_args.arg             = arg;
   thread_args.wrapper_started = &wrapper_started;
   /*
    * Find out whether the thread will be started as a joinable thread
    * or as a detached thread. If no thread attributes have been specified,
    * this means that the new thread will be started as a joinable thread.
    */
   thread_args.detachstate = PTHREAD_CREATE_JOINABLE;
   if (attr)
   {
      if (pthread_attr_getdetachstate(attr, &thread_args.detachstate) != 0)
         assert(0);
   }
   assert(thread_args.detachstate == PTHREAD_CREATE_JOINABLE
          || thread_args.detachstate == PTHREAD_CREATE_DETACHED);

   DRD_(entering_pthread_create)();
   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), &thread_args);
   DRD_(left_pthread_create)();

   if (ret == 0) {
      /* Wait until the thread wrapper started. */
      DRD_(sema_down)(&wrapper_started);
   }

   DRD_(sema_destroy)(&wrapper_started);

   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_NEW_SEGMENT,
                                   pthread_self(), 0, 0, 0, 0);

   return ret;
}
コード例 #20
0
ファイル: drd_main.c プロジェクト: cherry-wb/SmartFuzz
/* with arguments (0,1).                                                 */
static
void drd_post_thread_create(const ThreadId vg_created)
{
   DrdThreadId drd_created;

   tl_assert(vg_created != VG_INVALID_THREADID);

   drd_created = DRD_(thread_post_create)(vg_created);
   if (DRD_(thread_get_trace_fork_join)())
   {
      VG_(message)(Vg_DebugMsg,
                   "drd_post_thread_create created = %d/%d",
                   vg_created, drd_created);
   }
   if (! DRD_(get_check_stack_accesses)())
   {
      DRD_(start_suppression)(DRD_(thread_get_stack_max)(drd_created)
                              - DRD_(thread_get_stack_size)(drd_created),
                              DRD_(thread_get_stack_max)(drd_created),
                              "stack");
   }
}
コード例 #21
0
/**
 * Stop and print an error message in case a non-supported threading
 * library implementation (LinuxThreads) has been detected.
 */
static void DRD_(check_threading_library)(void)
{
   if (DRD_(detected_linuxthreads)())
   {
      if (getenv("LD_ASSUME_KERNEL"))
      {
         fprintf(stderr,
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
"after having unset the environment variable LD_ASSUME_KERNEL. Giving up.\n"
);
      }
      else
      {
         fprintf(stderr,
"Detected the LinuxThreads threading library. Sorry, but DRD only supports\n"
"the newer NPTL (Native POSIX Threads Library). Please try to rerun DRD\n"
"after having upgraded to a newer version of your Linux distribution.\n"
"Giving up.\n"
);
      }
      abort();
   }
}
コード例 #22
0
/**
 * Compare the type of the rwlock specified at initialization time with
 * the type passed as an argument, and complain if these two types do not
 * match.
 */
static Bool drd_rwlock_check_type(struct rwlock_info* const p,
                                  const RwLockT rwlock_type)
{
   tl_assert(p);
   /* The code below has to be updated if additional rwlock types are added. */
   tl_assert(rwlock_type == pthread_rwlock || rwlock_type == user_rwlock);
   tl_assert(p->rwlock_type == pthread_rwlock || p->rwlock_type == user_rwlock);

   if (p->rwlock_type == rwlock_type)
      return True;

   {
      RwlockErrInfo REI = { DRD_(thread_get_running_tid)(), p->a1 };
      VG_(maybe_record_error)
         (VG_(get_running_tid)(),
          RwlockErr,
          VG_(get_IP)(VG_(get_running_tid)()),
          rwlock_type == pthread_rwlock
          ? "Attempt to use a user-defined rwlock as a POSIX rwlock"
          : "Attempt to use a POSIX rwlock as a user-defined rwlock",
          &REI);
   }
   return False;
}
コード例 #23
0
ファイル: drd_main.c プロジェクト: cherry-wb/SmartFuzz
static __inline__
void drd_stop_using_mem(const Addr a1, const SizeT len,
                        const Bool is_stack_mem)
{
   const Addr a2 = a1 + len;

   tl_assert(a1 < a2);

   if (UNLIKELY(DRD_(any_address_is_traced)()))
   {
      DRD_(trace_mem_access)(a1, len, eEnd);
   }
   if (! is_stack_mem || DRD_(get_check_stack_accesses)())
   {
      DRD_(thread_stop_using_mem)(a1, a2);
      DRD_(clientobj_stop_using_mem)(a1, a2);
      DRD_(suppression_stop_using_mem)(a1, a2);
   }
}
コード例 #24
0
ファイル: drd_main.c プロジェクト: Legend/Elune
static __inline__
void drd_stop_using_mem(const Addr a1, const SizeT len,
                        const Bool is_stack_mem)
{
   const Addr a2 = a1 + len;

   tl_assert(a1 <= a2);

   if (UNLIKELY(DRD_(any_address_is_traced)()))
      DRD_(trace_mem_access)(a1, len, eEnd);

   if (!is_stack_mem && s_trace_alloc)
      VG_(message)(Vg_UserMsg, "Stopped using memory range 0x%lx + %ld\n",
                   a1, len);

   if (!is_stack_mem || DRD_(get_check_stack_accesses)())
   {
      DRD_(thread_stop_using_mem)(a1, a2, !is_stack_mem && s_free_is_write);
      DRD_(clientobj_stop_using_mem)(a1, a2);
      DRD_(suppression_stop_using_mem)(a1, a2);
   }
   if (!is_stack_mem && s_free_is_write)
      DRD_(trace_store)(a1, len);
}
コード例 #25
0
/**
 * Deallocate the memory owned by the struct barrier_info object and also
 * all the nodes in the OSet p->oset.
 *
 * Called by clientobj_destroy().
 */
static void barrier_cleanup(struct barrier_info* p)
{
    struct barrier_thread_info* q;
    Segment* latest_sg = 0;
    OSet* oset;
    int i;

    tl_assert(p);

    DRD_(thread_get_latest_segment)(&latest_sg, DRD_(thread_get_running_tid)());
    tl_assert(latest_sg);

    if (p->pre_waiters_left != p->count) {
        BarrierErrInfo bei = { DRD_(thread_get_running_tid)(), p->a1, 0, 0 };
        VG_(maybe_record_error)(VG_(get_running_tid)(),
                                BarrierErr,
                                VG_(get_IP)(VG_(get_running_tid)()),
                                "Destruction of barrier that is being waited"
                                " upon",
                                &bei);
    } else {
        oset = p->oset[1 - (p->pre_iteration & 1)];
        VG_(OSetGen_ResetIter)(oset);
        for ( ; (q = VG_(OSetGen_Next)(oset)) != 0; ) {
            if (q->post_wait_sg && !DRD_(vc_lte)(&q->post_wait_sg->vc,
                                                 &latest_sg->vc))
            {
                barrier_report_wait_delete_race(p, q);
            }
            DRD_(barrier_thread_destroy)(q);
        }
    }

    for (i = 0; i < 2; i++) {
        VG_(OSetGen_Destroy)(p->oset[i]);
        p->oset[i] = NULL;
    }

    DRD_(sg_put)(latest_sg);
}
コード例 #26
0
/** Called before pthread_mutex_init(). */
struct mutex_info*
DRD_(mutex_init)(const Addr mutex, const MutexT mutex_type)
{
   struct mutex_info* p;

   if (s_trace_mutex)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d] mutex_init      %s 0x%lx\n",
                   DRD_(thread_get_running_tid)(),
                   DRD_(mutex_type_name)(mutex_type),
                   mutex);
   }

   if (mutex_type == mutex_type_invalid_mutex)
   {
      DRD_(not_a_mutex)(mutex);
      return 0;
   }

   p = DRD_(mutex_get)(mutex);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid,
                              MutexErr,
                              VG_(get_IP)(vg_tid),
                              "Mutex reinitialization",
                              &MEI);
      p->mutex_type = mutex_type;
      return p;
   }
   p = DRD_(mutex_get_or_allocate)(mutex, mutex_type);

   return p;
}
コード例 #27
0
ファイル: drd_cond.c プロジェクト: qtekfun/htcDesire820Kernel
void DRD_(cond_set_trace)(const Bool trace_cond)
{
   DRD_(s_trace_cond) = trace_cond;
}
コード例 #28
0
ファイル: drd_cond.c プロジェクト: qtekfun/htcDesire820Kernel
void DRD_(cond_set_report_signal_unlocked)(const Bool r)
{
   DRD_(s_report_signal_unlocked) = r;
}
コード例 #29
0
ファイル: drd_cond.c プロジェクト: qtekfun/htcDesire820Kernel
	    q ? q->owner : DRD_INVALID_THREADID
	 };
         VG_(maybe_record_error)(VG_(get_running_tid)(),
                                 CondDestrErr,
                                 VG_(get_IP)(VG_(get_running_tid)()),
                                 "Destroying condition variable that is being"
                                 " waited upon",
                                 &cde);
      }
   }
}

static void wrong_type(const Addr addr)
{
   GenericErrInfo gei = {
      .tid  = DRD_(thread_get_running_tid)(),
      .addr = addr,
   };
   VG_(maybe_record_error)(VG_(get_running_tid)(),
                           GenericErr,
                           VG_(get_IP)(VG_(get_running_tid)()),
                           "wrong type of synchronization object",
                           &gei);
}

static struct cond_info* cond_get_or_allocate(const Addr cond)
{
   struct cond_info *p;

   tl_assert(offsetof(DrdClientobj, cond) == 0);
   p = &(DRD_(clientobj_get)(cond, ClientCondvar)->cond);
コード例 #30
0
/**
 * Deallocate the memory that is owned by members of
 * struct barrier_thread_info.
 */
static void DRD_(barrier_thread_destroy)(struct barrier_thread_info* const p)
{
    tl_assert(p);
    DRD_(sg_put)(p->sg);
    DRD_(sg_put)(p->post_wait_sg);
}