drd_error.c revision 62a784c9382fdf7184065ad76ae8d3b905605f21
1af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/*
2af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  This file is part of drd, a data race detector.
3af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
48564292ac4b9adf51c45517cca2878732feb5bb4sewardj  Copyright (C) 2006-2008 Bart Van Assche
5af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  bart.vanassche@gmail.com
6af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
7af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  This program is free software; you can redistribute it and/or
8af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  modify it under the terms of the GNU General Public License as
9af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  published by the Free Software Foundation; either version 2 of the
10af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  License, or (at your option) any later version.
11af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
12af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  This program is distributed in the hope that it will be useful, but
13af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  WITHOUT ANY WARRANTY; without even the implied warranty of
14af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  General Public License for more details.
16af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
17af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  You should have received a copy of the GNU General Public License
18af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  along with this program; if not, write to the Free Software
19af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  02111-1307, USA.
21af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
22af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  The GNU General Public License is contained in the file COPYING.
23af44c8236f7a73e71b16b707bba56f33af4d01cesewardj*/
24af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
25af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
26886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_clientobj.h"        /* struct mutex_info        */
27af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_error.h"
28af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_malloc_wrappers.h"
29886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_mutex.h"
30886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_suppression.h"      /* drd_start_suppression()  */
31886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_drd_bitmap.h"       /* LHS_W, ...               */
32af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_vki.h"
33af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_basics.h"
34886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcassert.h"  /* tl_assert()              */
35886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcbase.h"    /* strlen()                 */
36886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcfile.h"    /* VG_(get_startup_wd)()    */
37886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcprint.h"   /* VG_(printf)()            */
38af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_machine.h"
39886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_mallocfree.h"  /* VG_(malloc), VG_(free)   */
40886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_threadstate.h" /* VG_(get_pthread_id)()    */
41886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_tooliface.h"   /* VG_(needs_tool_errors)() */
42af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
43af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
4416d76e507231c5edd065cd66b597bf372adbf7a4bart/* Local variables. */
4516d76e507231c5edd065cd66b597bf372adbf7a4bart
4616d76e507231c5edd065cd66b597bf372adbf7a4bartstatic Bool s_drd_show_conflicting_segments = True;
4716d76e507231c5edd065cd66b597bf372adbf7a4bart
4816d76e507231c5edd065cd66b597bf372adbf7a4bart
4916d76e507231c5edd065cd66b597bf372adbf7a4bartvoid set_show_conflicting_segments(const Bool scs)
5016d76e507231c5edd065cd66b597bf372adbf7a4bart{
5116d76e507231c5edd065cd66b597bf372adbf7a4bart  s_drd_show_conflicting_segments = scs;
5216d76e507231c5edd065cd66b597bf372adbf7a4bart}
5316d76e507231c5edd065cd66b597bf372adbf7a4bart
54886b87c5e1adfa6657d24404283f7b79576e690cbart/** Describe a data address range [a,a+len[ as good as possible, for error
55886b87c5e1adfa6657d24404283f7b79576e690cbart *  messages, putting the result in ai.
56886b87c5e1adfa6657d24404283f7b79576e690cbart */
57ff1252ae10754371ac3428fdf8d7704c39acc23dbartstatic
58ff1252ae10754371ac3428fdf8d7704c39acc23dbartvoid describe_malloced_addr(Addr const a, SizeT const len, AddrInfo* const ai)
59af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
60ff1252ae10754371ac3428fdf8d7704c39acc23dbart  Addr data;
613772a98a8da0365a751c6886a340a1e4adb32be9bart
62ff1252ae10754371ac3428fdf8d7704c39acc23dbart  if (drd_heap_addrinfo(a, &data, &ai->size, &ai->lastchange))
633772a98a8da0365a751c6886a340a1e4adb32be9bart  {
64ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->akind = eMallocd;
65ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->rwoffset = a - data;
663772a98a8da0365a751c6886a340a1e4adb32be9bart  }
67ff1252ae10754371ac3428fdf8d7704c39acc23dbart  else
683772a98a8da0365a751c6886a340a1e4adb32be9bart  {
69ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->akind = eUnknown;
703772a98a8da0365a751c6886a340a1e4adb32be9bart  }
71af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
72af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
73391d9dc7a641ae3fe11f695372f710fe81155232bart/** Report where an object has been observed for the first time. The printed
74391d9dc7a641ae3fe11f695372f710fe81155232bart *  call stack will either refer to a pthread_*_init() or a pthread_*lock()
75391d9dc7a641ae3fe11f695372f710fe81155232bart *  call.
76886b87c5e1adfa6657d24404283f7b79576e690cbart */
77391d9dc7a641ae3fe11f695372f710fe81155232bartstatic void first_observed(const Addr obj)
78886b87c5e1adfa6657d24404283f7b79576e690cbart{
79391d9dc7a641ae3fe11f695372f710fe81155232bart  DrdClientobj* cl;
80886b87c5e1adfa6657d24404283f7b79576e690cbart
81195e41fe2b9e02e142a0461113bfa55c89d24c5ebart  cl = DRD_(clientobj_get_any)(obj);
82391d9dc7a641ae3fe11f695372f710fe81155232bart  if (cl)
83886b87c5e1adfa6657d24404283f7b79576e690cbart  {
84391d9dc7a641ae3fe11f695372f710fe81155232bart    tl_assert(cl->any.first_observed_at);
85886b87c5e1adfa6657d24404283f7b79576e690cbart    VG_(message)(Vg_UserMsg,
86391d9dc7a641ae3fe11f695372f710fe81155232bart                 "%s 0x%lx was first observed at:",
87195e41fe2b9e02e142a0461113bfa55c89d24c5ebart                 DRD_(clientobj_type_name)(cl->any.type),
88391d9dc7a641ae3fe11f695372f710fe81155232bart                 obj);
89391d9dc7a641ae3fe11f695372f710fe81155232bart    VG_(pp_ExeContext)(cl->any.first_observed_at);
90886b87c5e1adfa6657d24404283f7b79576e690cbart  }
91886b87c5e1adfa6657d24404283f7b79576e690cbart}
92886b87c5e1adfa6657d24404283f7b79576e690cbart
93af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic
94af44c8236f7a73e71b16b707bba56f33af4d01cesewardjvoid drd_report_data_race2(Error* const err, const DataRaceErrInfo* const dri)
95af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
963772a98a8da0365a751c6886a340a1e4adb32be9bart  AddrInfo ai;
97f993b876cabaac87af8b988a93a61e6e27f888fcbart  const unsigned descr_size = 256;
989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  Char* descr1 = VG_(malloc)("drd.error.drdr2.1", descr_size);
999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  Char* descr2 = VG_(malloc)("drd.error.drdr2.2", descr_size);
1003772a98a8da0365a751c6886a340a1e4adb32be9bart
1013772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri);
1023772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri->addr);
1033772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri->size > 0);
104fdd8d4ed5058b941528a95a809851623b9137fc8bart  tl_assert(descr1);
105fdd8d4ed5058b941528a95a809851623b9137fc8bart  tl_assert(descr2);
1063772a98a8da0365a751c6886a340a1e4adb32be9bart
1073772a98a8da0365a751c6886a340a1e4adb32be9bart  descr1[0] = 0;
1083772a98a8da0365a751c6886a340a1e4adb32be9bart  descr2[0] = 0;
109f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
1103772a98a8da0365a751c6886a340a1e4adb32be9bart  if (descr1[0] == 0)
1113772a98a8da0365a751c6886a340a1e4adb32be9bart  {
112ff1252ae10754371ac3428fdf8d7704c39acc23dbart    describe_malloced_addr(dri->addr, dri->size, &ai);
1133772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1143772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(message)(Vg_UserMsg,
115aa97a546a0824285dfb8488edafb4fa9a14677b2bart               "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
1163772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->access_type == eStore ? "store" : "load",
11762a784c9382fdf7184065ad76ae8d3b905605f21bart               DRD_(DrdThreadIdToVgThreadId)(dri->tid),
118aa97a546a0824285dfb8488edafb4fa9a14677b2bart               dri->tid,
1193772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->addr,
1203772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->size);
1213772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(pp_ExeContext)(VG_(get_error_where)(err));
1223772a98a8da0365a751c6886a340a1e4adb32be9bart  if (descr1[0])
1233772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1243772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", descr1);
1253772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", descr2);
1263772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1273772a98a8da0365a751c6886a340a1e4adb32be9bart  else if (ai.akind == eMallocd && ai.lastchange)
1283772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1293772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
1303772a98a8da0365a751c6886a340a1e4adb32be9bart                 "Address 0x%lx is at offset %ld from 0x%lx."
1313772a98a8da0365a751c6886a340a1e4adb32be9bart                 " Allocation context:",
1323772a98a8da0365a751c6886a340a1e4adb32be9bart                 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
1333772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(ai.lastchange);
1343772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1353772a98a8da0365a751c6886a340a1e4adb32be9bart  else
1363772a98a8da0365a751c6886a340a1e4adb32be9bart  {
137fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    char sect_name[64];
138fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    VgSectKind sect_kind;
139fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart
140fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    sect_kind = VG_(seginfo_sect_kind)(sect_name, sizeof(sect_name), dri->addr);
141fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    if (sect_kind != Vg_SectUnknown)
142fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    {
143fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart      VG_(message)(Vg_UserMsg,
144fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   "Allocation context: %s section of %s",
145fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   VG_(pp_SectKind)(sect_kind),
146fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   sect_name);
147fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    }
148fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    else
149fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    {
150fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart      VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
151fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    }
1523772a98a8da0365a751c6886a340a1e4adb32be9bart  }
15316d76e507231c5edd065cd66b597bf372adbf7a4bart  if (s_drd_show_conflicting_segments)
15416d76e507231c5edd065cd66b597bf372adbf7a4bart  {
15562a784c9382fdf7184065ad76ae8d3b905605f21bart    DRD_(thread_report_conflicting_segments)(dri->tid,
15662a784c9382fdf7184065ad76ae8d3b905605f21bart                                             dri->addr, dri->size,
15762a784c9382fdf7184065ad76ae8d3b905605f21bart                                             dri->access_type);
15816d76e507231c5edd065cd66b597bf372adbf7a4bart  }
159f993b876cabaac87af8b988a93a61e6e27f888fcbart
160f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(free)(descr2);
161f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(free)(descr1);
162af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
163af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
164af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2)
165af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
1663772a98a8da0365a751c6886a340a1e4adb32be9bart  return False;
167af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
168af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
169af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic void drd_tool_error_pp(Error* const e)
170af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
1713772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
1723772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1733772a98a8da0365a751c6886a340a1e4adb32be9bart  case DataRaceErr: {
1743772a98a8da0365a751c6886a340a1e4adb32be9bart    drd_report_data_race2(e, VG_(get_error_extra)(e));
1753772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
1763772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1773772a98a8da0365a751c6886a340a1e4adb32be9bart  case MutexErr: {
1783772a98a8da0365a751c6886a340a1e4adb32be9bart    MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
1793772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(p);
1806b71761ccfaa90b5d415dc7c19569568cf4579b4bart    if (p->recursion_count >= 0)
1816b71761ccfaa90b5d415dc7c19569568cf4579b4bart    {
1826b71761ccfaa90b5d415dc7c19569568cf4579b4bart      VG_(message)(Vg_UserMsg,
1836b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   "%s: mutex 0x%lx, recursion count %d, owner %d.",
1846b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   VG_(get_error_string)(e),
1856b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->mutex,
1866b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->recursion_count,
1876b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->owner);
1886b71761ccfaa90b5d415dc7c19569568cf4579b4bart    }
1896b71761ccfaa90b5d415dc7c19569568cf4579b4bart    else
1906b71761ccfaa90b5d415dc7c19569568cf4579b4bart    {
1916b71761ccfaa90b5d415dc7c19569568cf4579b4bart      VG_(message)(Vg_UserMsg,
19252e82915a3a8491cd64ca13ce9fae0b5b4cd645abart                   "The object at address 0x%lx is not a mutex.",
1936b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->mutex);
1946b71761ccfaa90b5d415dc7c19569568cf4579b4bart    }
1953772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
196391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(p->mutex);
1973772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
1983772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1993772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondErr: {
2003772a98a8da0365a751c6886a340a1e4adb32be9bart    CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
2013772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2023772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: cond 0x%lx",
203be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 VG_(get_error_string)(e),
204be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 cdei->cond);
2053772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
206391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cdei->cond);
2073772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2083772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2093bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondDestrErr: {
2103bb1cecb5ed12da201d9e027de44c050c0422ba3bart    CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
2113bb1cecb5ed12da201d9e027de44c050c0422ba3bart    VG_(message)(Vg_UserMsg,
2123bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d",
2133bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 VG_(get_error_string)(e),
2143bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cdi->cond, cdi->mutex,
21562a784c9382fdf7184065ad76ae8d3b905605f21bart                 DRD_(DrdThreadIdToVgThreadId)(cdi->tid), cdi->tid);
2163bb1cecb5ed12da201d9e027de44c050c0422ba3bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
217391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cdi->mutex);
2183bb1cecb5ed12da201d9e027de44c050c0422ba3bart    break;
2193bb1cecb5ed12da201d9e027de44c050c0422ba3bart  }
2203772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondRaceErr: {
2213772a98a8da0365a751c6886a340a1e4adb32be9bart    CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
2223772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
22346b5fcebcf676fcc950a359d9dee5ac0d5755afcbart                 "Probably a race condition: condition variable 0x%lx has been"
224886b87c5e1adfa6657d24404283f7b79576e690cbart                 " signaled but the associated mutex 0x%lx is not locked"
225886b87c5e1adfa6657d24404283f7b79576e690cbart                 " by the signalling thread.",
2263772a98a8da0365a751c6886a340a1e4adb32be9bart                 cei->cond, cei->mutex);
2273772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
228391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cei->cond);
229391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cei->mutex);
2303772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2313772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2323bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr: {
2333bb1cecb5ed12da201d9e027de44c050c0422ba3bart    CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
2343772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2353bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx",
236be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 VG_(get_error_string)(e),
2373bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->cond,
2383bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->mutex1,
2393bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->mutex2);
2403772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
241391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cwei->cond);
242391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cwei->mutex1);
243391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(cwei->mutex2);
2443772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2453772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2463772a98a8da0365a751c6886a340a1e4adb32be9bart  case SemaphoreErr: {
247886b87c5e1adfa6657d24404283f7b79576e690cbart    SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
2483772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(sei);
2493772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2503772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: semaphore 0x%lx",
2513772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
2523772a98a8da0365a751c6886a340a1e4adb32be9bart                 sei->semaphore);
2533772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
254b48b4c58ed92d2d9e5679718ade8a9b1c553ba49bart    first_observed(sei->semaphore);
2553772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2563772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2573772a98a8da0365a751c6886a340a1e4adb32be9bart  case BarrierErr: {
258391d9dc7a641ae3fe11f695372f710fe81155232bart    BarrierErrInfo* bei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
259391d9dc7a641ae3fe11f695372f710fe81155232bart    tl_assert(bei);
2603772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2613772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: barrier 0x%lx",
2623772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
263391d9dc7a641ae3fe11f695372f710fe81155232bart                 bei->barrier);
2643772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
265391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(bei->barrier);
2663772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2673772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2683772a98a8da0365a751c6886a340a1e4adb32be9bart  case RwlockErr: {
2693772a98a8da0365a751c6886a340a1e4adb32be9bart    RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
2703772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(p);
2713772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2723772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: rwlock 0x%lx.",
2733772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
2743772a98a8da0365a751c6886a340a1e4adb32be9bart                 p->rwlock);
2753772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
276391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(p->rwlock);
2773772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2783772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2799d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr: {
2809d5b7969d87e5dbb46b3c51934a6e367421932b0bart    HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
2819d5b7969d87e5dbb46b3c51934a6e367421932b0bart    tl_assert(p);
2829d5b7969d87e5dbb46b3c51934a6e367421932b0bart    tl_assert(p->acquired_at);
2839d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(message)(Vg_UserMsg, "Acquired at:");
2849d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(pp_ExeContext)(p->acquired_at);
2859d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(message)(Vg_UserMsg,
2869d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).",
2879d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 VG_(get_error_string)(e),
2889d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->synchronization_object,
2899d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->hold_time_ms,
2909d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->threshold_ms);
2919d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
292391d9dc7a641ae3fe11f695372f710fe81155232bart    first_observed(p->synchronization_object);
2939d5b7969d87e5dbb46b3c51934a6e367421932b0bart    break;
2949d5b7969d87e5dbb46b3c51934a6e367421932b0bart  }
2953772a98a8da0365a751c6886a340a1e4adb32be9bart  case GenericErr: {
2963772a98a8da0365a751c6886a340a1e4adb32be9bart    //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
2973772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
2983772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
2993772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3003772a98a8da0365a751c6886a340a1e4adb32be9bart  }
3013772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
3023772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
3033772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s",
3043772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e));
3053772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
3063772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3073772a98a8da0365a751c6886a340a1e4adb32be9bart  }
308af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
309af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
310af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic UInt drd_tool_error_update_extra(Error* e)
311af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3123772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
3133772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3143772a98a8da0365a751c6886a340a1e4adb32be9bart  case DataRaceErr:
3153772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(DataRaceErrInfo);
3163772a98a8da0365a751c6886a340a1e4adb32be9bart  case MutexErr:
3173772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(MutexErrInfo);
3183772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondErr:
3193772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(CondErrInfo);
3203772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondDestrErr:
3213772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(CondDestrErrInfo);
3223bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondRaceErr:
3233bb1cecb5ed12da201d9e027de44c050c0422ba3bart    return sizeof(CondRaceErrInfo);
3243bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr:
3253bb1cecb5ed12da201d9e027de44c050c0422ba3bart    return sizeof(CondWaitErrInfo);
3263772a98a8da0365a751c6886a340a1e4adb32be9bart  case SemaphoreErr:
3273772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(SemaphoreErrInfo);
3283772a98a8da0365a751c6886a340a1e4adb32be9bart  case BarrierErr:
3293772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(BarrierErrInfo);
3303772a98a8da0365a751c6886a340a1e4adb32be9bart  case RwlockErr:
3313772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(RwlockErrInfo);
3329d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr:
3339d5b7969d87e5dbb46b3c51934a6e367421932b0bart    return sizeof(HoldtimeErrInfo);
3343772a98a8da0365a751c6886a340a1e4adb32be9bart  case GenericErr:
3353772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(GenericErrInfo);
3363772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
3373772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(False);
3383772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3393772a98a8da0365a751c6886a340a1e4adb32be9bart  }
340af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
341af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
342af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic Bool drd_tool_error_recog(Char* const name, Supp* const supp)
343af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3445fc70e62b3bac5350c499d35b78f462f080d8032bart  SuppKind skind = 0;
345af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
3465fc70e62b3bac5350c499d35b78f462f080d8032bart  if (VG_(strcmp)(name, STR_DataRaceErr) == 0)
3475fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3485fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_MutexErr) == 0)
3495fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3505fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_CondErr) == 0)
3515fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3523bb1cecb5ed12da201d9e027de44c050c0422ba3bart  else if (VG_(strcmp)(name, STR_CondDestrErr) == 0)
3533bb1cecb5ed12da201d9e027de44c050c0422ba3bart    ;
3545fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_CondRaceErr) == 0)
3555fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3563bb1cecb5ed12da201d9e027de44c050c0422ba3bart  else if (VG_(strcmp)(name, STR_CondWaitErr) == 0)
3575fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3585fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_SemaphoreErr) == 0)
3595fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3605fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_BarrierErr) == 0)
3615fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3625fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_RwlockErr) == 0)
3635fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3649d5b7969d87e5dbb46b3c51934a6e367421932b0bart  else if (VG_(strcmp)(name, STR_HoldtimeErr) == 0)
3659d5b7969d87e5dbb46b3c51934a6e367421932b0bart    ;
3665fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_GenericErr) == 0)
3675fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3683772a98a8da0365a751c6886a340a1e4adb32be9bart  else
3693772a98a8da0365a751c6886a340a1e4adb32be9bart    return False;
370af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
3713772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(set_supp_kind)(supp, skind);
3723772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
373af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
374af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
375af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic Bool drd_tool_error_read_extra(Int fd, Char* buf, Int nBuf, Supp* supp)
376af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3773772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
378af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
379af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
380af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic Bool drd_tool_error_matches(Error* const e, Supp* const supp)
381af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3823772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_supp_kind)(supp))
3833772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3843772a98a8da0365a751c6886a340a1e4adb32be9bart  }
3853772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
386af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
387af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
388af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic Char* drd_tool_error_name(Error* e)
389af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3903772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
3913772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3925fc70e62b3bac5350c499d35b78f462f080d8032bart  case DataRaceErr:  return VGAPPEND(STR_, DataRaceErr);
3935fc70e62b3bac5350c499d35b78f462f080d8032bart  case MutexErr:     return VGAPPEND(STR_, MutexErr);
3945fc70e62b3bac5350c499d35b78f462f080d8032bart  case CondErr:      return VGAPPEND(STR_, CondErr);
3955fc70e62b3bac5350c499d35b78f462f080d8032bart  case CondDestrErr: return VGAPPEND(STR_, CondDestrErr);
3963bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondRaceErr:  return VGAPPEND(STR_, CondRaceErr);
3973bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr:  return VGAPPEND(STR_, CondWaitErr);
3985fc70e62b3bac5350c499d35b78f462f080d8032bart  case SemaphoreErr: return VGAPPEND(STR_, SemaphoreErr);
3995fc70e62b3bac5350c499d35b78f462f080d8032bart  case BarrierErr:   return VGAPPEND(STR_, BarrierErr);
4005fc70e62b3bac5350c499d35b78f462f080d8032bart  case RwlockErr:    return VGAPPEND(STR_, RwlockErr);
4019d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr:  return VGAPPEND(STR_, HoldtimeErr);
4025fc70e62b3bac5350c499d35b78f462f080d8032bart  case GenericErr:   return VGAPPEND(STR_, GenericErr);
4033772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
4043772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(0);
4053772a98a8da0365a751c6886a340a1e4adb32be9bart  }
4063772a98a8da0365a751c6886a340a1e4adb32be9bart  return 0;
407af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
408af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
409af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic void drd_tool_error_print_extra(Error* e)
410af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
4113772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
4123772a98a8da0365a751c6886a340a1e4adb32be9bart  {
4133772a98a8da0365a751c6886a340a1e4adb32be9bart    // VG_(printf)("   %s\n", VG_(get_error_string)(err));
4143772a98a8da0365a751c6886a340a1e4adb32be9bart  }
415af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
416af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
4171335ecca5095dea85be94095885082b80573df8cbartvoid DRD_(register_error_handlers)(void)
418af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
4193772a98a8da0365a751c6886a340a1e4adb32be9bart  // Tool error reporting.
4203772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(needs_tool_errors)(drd_tool_error_eq,
4213772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_pp,
4223772a98a8da0365a751c6886a340a1e4adb32be9bart                         True,
4233772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_update_extra,
4243772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_recog,
4253772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_read_extra,
4263772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_matches,
4273772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_name,
4283772a98a8da0365a751c6886a340a1e4adb32be9bart                         drd_tool_error_print_extra);
429af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
430