/** Report an error to the user. */ static void drd_tool_error_pp(Error* const e) { const Bool xml = VG_(clo_xml); const HChar* const what_prefix = xml ? " <what>" : ""; const HChar* const what_suffix = xml ? "</what>" : ""; if (xml) VG_(printf_xml)( " <kind>%pS</kind>\n", drd_get_error_name(e)); switch (VG_(get_error_kind)(e)) { case DataRaceErr: { drd_report_data_race(e, VG_(get_error_extra)(e)); break; } case MutexErr: { MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); if (p->recursion_count >= 0) { print_err_detail("%s%s: mutex 0x%lx, recursion count %d, owner %d." "%s\n", what_prefix, VG_(get_error_string)(e), p->mutex, p->recursion_count, p->owner, what_suffix); } else { print_err_detail("%sThe object at address 0x%lx is not a mutex.%s\n", what_prefix, p->mutex, what_suffix); } VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->mutex); break; } case CondErr: { CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e)); print_err_detail("%s%s: cond 0x%lx%s\n", what_prefix, VG_(get_error_string)(e), cdei->cond, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cdei->cond); break; } case CondDestrErr: { CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e)); print_err_detail("%s%s: cond 0x%lx, mutex 0x%lx locked by thread %d%s\n", what_prefix, VG_(get_error_string)(e), cdi->cond, cdi->mutex, cdi->owner, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cdi->mutex); break; } case CondRaceErr: { CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e)); print_err_detail("%sProbably a race condition: condition variable 0x%lx" " has been signaled but the associated mutex 0x%lx is" " not locked by the signalling thread.%s\n", what_prefix, cei->cond, cei->mutex, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cei->cond); first_observed(cei->mutex); break; } case CondWaitErr: { CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e)); print_err_detail("%s%s: condition variable 0x%lx, mutexes 0x%lx and" " 0x%lx%s\n", what_prefix, VG_(get_error_string)(e), cwei->cond, cwei->mutex1, cwei->mutex2, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cwei->cond); first_observed(cwei->mutex1); first_observed(cwei->mutex2); break; } case SemaphoreErr: { SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e)); tl_assert(sei); print_err_detail("%s%s: semaphore 0x%lx%s\n", what_prefix, VG_(get_error_string)(e), sei->semaphore, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(sei->semaphore); break; } case BarrierErr: { BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e)); tl_assert(bei); print_err_detail("%s%s: barrier 0x%lx%s\n", what_prefix, VG_(get_error_string)(e), bei->barrier, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); if (bei->other_context) { if (xml) print_err_detail(" <confl_wait_call>\n"); print_err_detail("%sConflicting wait call by thread %d:%s\n", what_prefix, bei->other_tid, what_suffix); VG_(pp_ExeContext)(bei->other_context); if (xml) print_err_detail(" </confl_wait_call>\n"); } first_observed(bei->barrier); break; } case RwlockErr: { RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); print_err_detail("%s%s: rwlock 0x%lx.%s\n", what_prefix, VG_(get_error_string)(e), p->rwlock, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->rwlock); break; } case HoldtimeErr: { HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); tl_assert(p->acquired_at); if (xml) print_err_detail(" <acquired_at>\n"); else print_err_detail("Acquired at:\n"); VG_(pp_ExeContext)(p->acquired_at); if (xml) print_err_detail(" </acquired_at>\n"); print_err_detail("%sLock on %s 0x%lx was held during %d ms" " (threshold: %d ms).%s\n", what_prefix, VG_(get_error_string)(e), p->synchronization_object, p->hold_time_ms, p->threshold_ms, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->synchronization_object); break; } case GenericErr: { GenericErrInfo* gei = (GenericErrInfo*)(VG_(get_error_extra)(e)); print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e), what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); if (gei->addr) first_observed(gei->addr); break; } case InvalidThreadId: { InvalidThreadIdInfo* iti =(InvalidThreadIdInfo*)(VG_(get_error_extra)(e)); print_err_detail("%s%s 0x%llx%s\n", what_prefix, VG_(get_error_string)(e), iti->ptid, what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } case UnimpHgClReq: { UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e)); print_err_detail("%sThe annotation macro %s has not yet been implemented" " in %ps%s\n", what_prefix, uicr->descr, "<valgrind/helgrind.h>", what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } case UnimpDrdClReq: { UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e)); print_err_detail("%sThe annotation macro %s has not yet been implemented" " in %ps%s\n", what_prefix, uicr->descr, "<valgrind/drd.h>", what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } default: print_err_detail("%s%s%s\n", what_prefix, VG_(get_error_string)(e), what_suffix); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } }
static void drd_tool_error_pp(Error* const e) { static DrdThreadId s_last_tid_printed = 1; DrdThreadId* err_extra; err_extra = VG_(get_error_extra)(e); if (err_extra && *err_extra != s_last_tid_printed) { VG_UMSG("%s:", DRD_(thread_get_name)(*err_extra)); s_last_tid_printed = *err_extra; } switch (VG_(get_error_kind)(e)) { case DataRaceErr: { drd_report_data_race(e, VG_(get_error_extra)(e)); break; } case MutexErr: { MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); if (p->recursion_count >= 0) { VG_(message)(Vg_UserMsg, "%s: mutex 0x%lx, recursion count %d, owner %d.", VG_(get_error_string)(e), p->mutex, p->recursion_count, p->owner); } else { VG_(message)(Vg_UserMsg, "The object at address 0x%lx is not a mutex.", p->mutex); } VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->mutex); break; } case CondErr: { CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "%s: cond 0x%lx", VG_(get_error_string)(e), cdei->cond); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cdei->cond); break; } case CondDestrErr: { CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d", VG_(get_error_string)(e), cdi->cond, cdi->mutex, DRD_(DrdThreadIdToVgThreadId)(cdi->owner), cdi->owner); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cdi->mutex); break; } case CondRaceErr: { CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "Probably a race condition: condition variable 0x%lx has" " been signaled but the associated mutex 0x%lx is not" " locked by the signalling thread.", cei->cond, cei->mutex); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cei->cond); first_observed(cei->mutex); break; } case CondWaitErr: { CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx", VG_(get_error_string)(e), cwei->cond, cwei->mutex1, cwei->mutex2); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(cwei->cond); first_observed(cwei->mutex1); first_observed(cwei->mutex2); break; } case SemaphoreErr: { SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e)); tl_assert(sei); VG_(message)(Vg_UserMsg, "%s: semaphore 0x%lx", VG_(get_error_string)(e), sei->semaphore); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(sei->semaphore); break; } case BarrierErr: { BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e)); tl_assert(bei); VG_(message)(Vg_UserMsg, "%s: barrier 0x%lx", VG_(get_error_string)(e), bei->barrier); VG_(pp_ExeContext)(VG_(get_error_where)(e)); if (bei->other_context) { VG_(message)(Vg_UserMsg, "Conflicting wait call by thread %d/%d:", DRD_(DrdThreadIdToVgThreadId)(bei->other_tid), bei->other_tid); VG_(pp_ExeContext)(bei->other_context); } first_observed(bei->barrier); break; } case RwlockErr: { RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); VG_(message)(Vg_UserMsg, "%s: rwlock 0x%lx.", VG_(get_error_string)(e), p->rwlock); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->rwlock); break; } case HoldtimeErr: { HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e)); tl_assert(p); tl_assert(p->acquired_at); VG_(message)(Vg_UserMsg, "Acquired at:"); VG_(pp_ExeContext)(p->acquired_at); VG_(message)(Vg_UserMsg, "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).", VG_(get_error_string)(e), p->synchronization_object, p->hold_time_ms, p->threshold_ms); VG_(pp_ExeContext)(VG_(get_error_where)(e)); first_observed(p->synchronization_object); break; } case GenericErr: { //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e)); VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e)); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } default: VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e)); VG_(pp_ExeContext)(VG_(get_error_where)(e)); break; } }