void HG_(print_access) (StackTrace ips, UInt n_ips, Thr* thr_a, Addr ga, SizeT SzB, Bool isW, WordSetID locksHeldW ) { Thread* threadp; threadp = libhb_get_Thr_hgthread( thr_a ); tl_assert(threadp); if (!threadp->announced) { /* This is for interactive use. We announce the thread if needed, but reset it to not announced afterwards, because we want the thread to be announced on the error output/log if needed. */ announce_one_thread (threadp); threadp->announced = False; } announce_one_thread (threadp); VG_(printf) ("%s of size %d at %p by thread #%d", isW ? "write" : "read", (int)SzB, (void*)ga, threadp->errmsg_index); if (threadp->coretid == VG_INVALID_THREADID) VG_(printf)(" tid (exited)\n"); else VG_(printf)(" tid %u\n", threadp->coretid); { Lock** locksHeldW_P; locksHeldW_P = enumerate_WordSet_into_LockP_vector( HG_(get_univ_lsets)(), locksHeldW, True/*allowed_to_be_invalid*/ ); show_LockP_summary_textmode( locksHeldW_P, "" ); HG_(free) (locksHeldW_P); } VG_(pp_StackTrace) (ips, n_ips); VG_(printf) ("\n"); }
/* This is the "this error is due to be printed shortly; so have a look at it any print any preamble you want" function. We use it to announce any previously un-announced threads in the upcoming error message. */ void HG_(before_pp_Error) ( Error* err ) { XError* xe; tl_assert(err); xe = (XError*)VG_(get_error_extra)(err); tl_assert(xe); switch (VG_(get_error_kind)(err)) { case XE_Misc: announce_one_thread( xe->XE.Misc.thr ); break; case XE_LockOrder: announce_one_thread( xe->XE.LockOrder.thr ); break; case XE_PthAPIerror: announce_one_thread( xe->XE.PthAPIerror.thr ); break; case XE_UnlockBogus: announce_one_thread( xe->XE.UnlockBogus.thr ); break; case XE_UnlockForeign: announce_one_thread( xe->XE.UnlockForeign.thr ); announce_one_thread( xe->XE.UnlockForeign.owner ); break; case XE_UnlockUnlocked: announce_one_thread( xe->XE.UnlockUnlocked.thr ); break; case XE_Race: announce_one_thread( xe->XE.Race.thr ); if (xe->XE.Race.h2_ct) announce_one_thread( xe->XE.Race.h2_ct ); if (xe->XE.Race.h1_ct) announce_one_thread( xe->XE.Race.h1_ct ); break; default: tl_assert(0); } }
/* This is the "this error is due to be printed shortly; so have a look at it any print any preamble you want" function. We use it to announce any previously un-announced threads in the upcoming error message. */ void HG_(before_pp_Error) ( const Error* err ) { XError* xe; tl_assert(err); xe = (XError*)VG_(get_error_extra)(err); tl_assert(xe); switch (VG_(get_error_kind)(err)) { case XE_Misc: announce_one_thread( xe->XE.Misc.thr ); break; case XE_LockOrder: announce_one_thread( xe->XE.LockOrder.thr ); break; case XE_PthAPIerror: announce_one_thread( xe->XE.PthAPIerror.thr ); break; case XE_UnlockBogus: announce_one_thread( xe->XE.UnlockBogus.thr ); break; case XE_UnlockForeign: announce_one_thread( xe->XE.UnlockForeign.thr ); announce_one_thread( xe->XE.UnlockForeign.owner ); break; case XE_UnlockUnlocked: announce_one_thread( xe->XE.UnlockUnlocked.thr ); break; case XE_Race: announce_one_thread( xe->XE.Race.thr ); if (xe->XE.Race.h2_ct) announce_one_thread( xe->XE.Race.h2_ct ); if (xe->XE.Race.h1_ct) announce_one_thread( xe->XE.Race.h1_ct ); if (xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) { Thread* thr = get_admin_threads(); while (thr) { if (thr->errmsg_index == xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) { announce_one_thread (thr); break; } thr = thr->admin; } } break; default: tl_assert(0); } }