drd_error.c revision 86562bd89ac23ce795d19c71fabcb9d1c8f956d3
1af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/*
286562bd89ac23ce795d19c71fabcb9d1c8f956d3bart  This file is part of drd, a thread error detector.
3af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
486562bd89ac23ce795d19c71fabcb9d1c8f956d3bart  Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
5af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
6af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  This program is free software; you can redistribute it and/or
7af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  modify it under the terms of the GNU General Public License as
8af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  published by the Free Software Foundation; either version 2 of the
9af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  License, or (at your option) any later version.
10af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
11af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  This program is distributed in the hope that it will be useful, but
12af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  WITHOUT ANY WARRANTY; without even the implied warranty of
13af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  General Public License for more details.
15af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
16af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  You should have received a copy of the GNU General Public License
17af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  along with this program; if not, write to the Free Software
18af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  02111-1307, USA.
20af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
21af44c8236f7a73e71b16b707bba56f33af4d01cesewardj  The GNU General Public License is contained in the file COPYING.
22af44c8236f7a73e71b16b707bba56f33af4d01cesewardj*/
23af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
24af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
25886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_clientobj.h"        /* struct mutex_info        */
26af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_error.h"
27af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_malloc_wrappers.h"
28886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_mutex.h"
29886b87c5e1adfa6657d24404283f7b79576e690cbart#include "drd_suppression.h"      /* drd_start_suppression()  */
30886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_drd_bitmap.h"       /* LHS_W, ...               */
31af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_vki.h"
32af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_basics.h"
33886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcassert.h"  /* tl_assert()              */
34886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcbase.h"    /* strlen()                 */
35886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcfile.h"    /* VG_(get_startup_wd)()    */
36886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_libcprint.h"   /* VG_(printf)()            */
37af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_machine.h"
38886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_mallocfree.h"  /* VG_(malloc), VG_(free)   */
39886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_threadstate.h" /* VG_(get_pthread_id)()    */
40886b87c5e1adfa6657d24404283f7b79576e690cbart#include "pub_tool_tooliface.h"   /* VG_(needs_tool_errors)() */
41af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
42af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
4316d76e507231c5edd065cd66b597bf372adbf7a4bart/* Local variables. */
4416d76e507231c5edd065cd66b597bf372adbf7a4bart
45246fbf2655328fc150e528b701223b7a1eafe471bartstatic Bool DRD_(s_show_conflicting_segments) = True;
4616d76e507231c5edd065cd66b597bf372adbf7a4bart
4716d76e507231c5edd065cd66b597bf372adbf7a4bart
48246fbf2655328fc150e528b701223b7a1eafe471bartvoid DRD_(set_show_conflicting_segments)(const Bool scs)
4916d76e507231c5edd065cd66b597bf372adbf7a4bart{
50246fbf2655328fc150e528b701223b7a1eafe471bart  DRD_(s_show_conflicting_segments) = scs;
5116d76e507231c5edd065cd66b597bf372adbf7a4bart}
5216d76e507231c5edd065cd66b597bf372adbf7a4bart
53246fbf2655328fc150e528b701223b7a1eafe471bart/**
54246fbf2655328fc150e528b701223b7a1eafe471bart * Describe a data address range [a,a+len[ as good as possible, for error
55246fbf2655328fc150e528b701223b7a1eafe471bart * messages, putting the result in ai.
56886b87c5e1adfa6657d24404283f7b79576e690cbart */
57ff1252ae10754371ac3428fdf8d7704c39acc23dbartstatic
58246fbf2655328fc150e528b701223b7a1eafe471bartvoid DRD_(describe_malloced_addr)(Addr const a, SizeT const len,
59246fbf2655328fc150e528b701223b7a1eafe471bart                                  AddrInfo* const ai)
60af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
61ff1252ae10754371ac3428fdf8d7704c39acc23dbart  Addr data;
623772a98a8da0365a751c6886a340a1e4adb32be9bart
63246fbf2655328fc150e528b701223b7a1eafe471bart  if (DRD_(heap_addrinfo)(a, &data, &ai->size, &ai->lastchange))
643772a98a8da0365a751c6886a340a1e4adb32be9bart  {
65ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->akind = eMallocd;
66ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->rwoffset = a - data;
673772a98a8da0365a751c6886a340a1e4adb32be9bart  }
68ff1252ae10754371ac3428fdf8d7704c39acc23dbart  else
693772a98a8da0365a751c6886a340a1e4adb32be9bart  {
70ff1252ae10754371ac3428fdf8d7704c39acc23dbart    ai->akind = eUnknown;
713772a98a8da0365a751c6886a340a1e4adb32be9bart  }
72af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
73af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
74246fbf2655328fc150e528b701223b7a1eafe471bart/**
75246fbf2655328fc150e528b701223b7a1eafe471bart * Report where an object has been observed for the first time. The printed
76246fbf2655328fc150e528b701223b7a1eafe471bart * call stack will either refer to a pthread_*_init() or a pthread_*lock()
77246fbf2655328fc150e528b701223b7a1eafe471bart * call.
78886b87c5e1adfa6657d24404283f7b79576e690cbart */
79246fbf2655328fc150e528b701223b7a1eafe471bartstatic void DRD_(first_observed)(const Addr obj)
80886b87c5e1adfa6657d24404283f7b79576e690cbart{
81391d9dc7a641ae3fe11f695372f710fe81155232bart  DrdClientobj* cl;
82886b87c5e1adfa6657d24404283f7b79576e690cbart
83195e41fe2b9e02e142a0461113bfa55c89d24c5ebart  cl = DRD_(clientobj_get_any)(obj);
84391d9dc7a641ae3fe11f695372f710fe81155232bart  if (cl)
85886b87c5e1adfa6657d24404283f7b79576e690cbart  {
86391d9dc7a641ae3fe11f695372f710fe81155232bart    tl_assert(cl->any.first_observed_at);
87886b87c5e1adfa6657d24404283f7b79576e690cbart    VG_(message)(Vg_UserMsg,
88391d9dc7a641ae3fe11f695372f710fe81155232bart                 "%s 0x%lx was first observed at:",
89195e41fe2b9e02e142a0461113bfa55c89d24c5ebart                 DRD_(clientobj_type_name)(cl->any.type),
90391d9dc7a641ae3fe11f695372f710fe81155232bart                 obj);
91391d9dc7a641ae3fe11f695372f710fe81155232bart    VG_(pp_ExeContext)(cl->any.first_observed_at);
92886b87c5e1adfa6657d24404283f7b79576e690cbart  }
93886b87c5e1adfa6657d24404283f7b79576e690cbart}
94886b87c5e1adfa6657d24404283f7b79576e690cbart
95af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic
96246fbf2655328fc150e528b701223b7a1eafe471bartvoid DRD_(drd_report_data_race)(Error* const err,
97246fbf2655328fc150e528b701223b7a1eafe471bart                                const DataRaceErrInfo* const dri)
98af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
993772a98a8da0365a751c6886a340a1e4adb32be9bart  AddrInfo ai;
100f993b876cabaac87af8b988a93a61e6e27f888fcbart  const unsigned descr_size = 256;
1019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  Char* descr1 = VG_(malloc)("drd.error.drdr2.1", descr_size);
1029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  Char* descr2 = VG_(malloc)("drd.error.drdr2.2", descr_size);
1033772a98a8da0365a751c6886a340a1e4adb32be9bart
1043772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri);
1053772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri->addr);
1063772a98a8da0365a751c6886a340a1e4adb32be9bart  tl_assert(dri->size > 0);
107fdd8d4ed5058b941528a95a809851623b9137fc8bart  tl_assert(descr1);
108fdd8d4ed5058b941528a95a809851623b9137fc8bart  tl_assert(descr2);
1093772a98a8da0365a751c6886a340a1e4adb32be9bart
1103772a98a8da0365a751c6886a340a1e4adb32be9bart  descr1[0] = 0;
1113772a98a8da0365a751c6886a340a1e4adb32be9bart  descr2[0] = 0;
112f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
1133772a98a8da0365a751c6886a340a1e4adb32be9bart  if (descr1[0] == 0)
1143772a98a8da0365a751c6886a340a1e4adb32be9bart  {
115246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(describe_malloced_addr)(dri->addr, dri->size, &ai);
1163772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1173772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(message)(Vg_UserMsg,
118aa97a546a0824285dfb8488edafb4fa9a14677b2bart               "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
1193772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->access_type == eStore ? "store" : "load",
12062a784c9382fdf7184065ad76ae8d3b905605f21bart               DRD_(DrdThreadIdToVgThreadId)(dri->tid),
121aa97a546a0824285dfb8488edafb4fa9a14677b2bart               dri->tid,
1223772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->addr,
1233772a98a8da0365a751c6886a340a1e4adb32be9bart               dri->size);
1243772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(pp_ExeContext)(VG_(get_error_where)(err));
1253772a98a8da0365a751c6886a340a1e4adb32be9bart  if (descr1[0])
1263772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1273772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", descr1);
1283772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", descr2);
1293772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1303772a98a8da0365a751c6886a340a1e4adb32be9bart  else if (ai.akind == eMallocd && ai.lastchange)
1313772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1323772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
1333772a98a8da0365a751c6886a340a1e4adb32be9bart                 "Address 0x%lx is at offset %ld from 0x%lx."
1343772a98a8da0365a751c6886a340a1e4adb32be9bart                 " Allocation context:",
1353772a98a8da0365a751c6886a340a1e4adb32be9bart                 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
1363772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(ai.lastchange);
1373772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1383772a98a8da0365a751c6886a340a1e4adb32be9bart  else
1393772a98a8da0365a751c6886a340a1e4adb32be9bart  {
140fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    char sect_name[64];
141fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    VgSectKind sect_kind;
142fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart
143fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    sect_kind = VG_(seginfo_sect_kind)(sect_name, sizeof(sect_name), dri->addr);
144fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    if (sect_kind != Vg_SectUnknown)
145fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    {
146fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart      VG_(message)(Vg_UserMsg,
147fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   "Allocation context: %s section of %s",
148fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   VG_(pp_SectKind)(sect_kind),
149fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart                   sect_name);
150fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    }
151fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    else
152fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    {
153fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart      VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
154fca00e5b1485d8c6807936ccb44b2ed94c2e5852bart    }
1553772a98a8da0365a751c6886a340a1e4adb32be9bart  }
156246fbf2655328fc150e528b701223b7a1eafe471bart  if (DRD_(s_show_conflicting_segments))
15716d76e507231c5edd065cd66b597bf372adbf7a4bart  {
15862a784c9382fdf7184065ad76ae8d3b905605f21bart    DRD_(thread_report_conflicting_segments)(dri->tid,
15962a784c9382fdf7184065ad76ae8d3b905605f21bart                                             dri->addr, dri->size,
16062a784c9382fdf7184065ad76ae8d3b905605f21bart                                             dri->access_type);
16116d76e507231c5edd065cd66b597bf372adbf7a4bart  }
162f993b876cabaac87af8b988a93a61e6e27f888fcbart
163f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(free)(descr2);
164f993b876cabaac87af8b988a93a61e6e27f888fcbart  VG_(free)(descr1);
165af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
166af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
167246fbf2655328fc150e528b701223b7a1eafe471bartstatic Bool DRD_(drd_tool_error_eq)(VgRes res, Error* e1, Error* e2)
168af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
1693772a98a8da0365a751c6886a340a1e4adb32be9bart  return False;
170af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
171af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
172246fbf2655328fc150e528b701223b7a1eafe471bartstatic void DRD_(drd_tool_error_pp)(Error* const e)
173af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
1743772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
1753772a98a8da0365a751c6886a340a1e4adb32be9bart  {
1763772a98a8da0365a751c6886a340a1e4adb32be9bart  case DataRaceErr: {
177246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(drd_report_data_race)(e, VG_(get_error_extra)(e));
1783772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
1793772a98a8da0365a751c6886a340a1e4adb32be9bart  }
1803772a98a8da0365a751c6886a340a1e4adb32be9bart  case MutexErr: {
1813772a98a8da0365a751c6886a340a1e4adb32be9bart    MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
1823772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(p);
1836b71761ccfaa90b5d415dc7c19569568cf4579b4bart    if (p->recursion_count >= 0)
1846b71761ccfaa90b5d415dc7c19569568cf4579b4bart    {
1856b71761ccfaa90b5d415dc7c19569568cf4579b4bart      VG_(message)(Vg_UserMsg,
1866b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   "%s: mutex 0x%lx, recursion count %d, owner %d.",
1876b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   VG_(get_error_string)(e),
1886b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->mutex,
1896b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->recursion_count,
1906b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->owner);
1916b71761ccfaa90b5d415dc7c19569568cf4579b4bart    }
1926b71761ccfaa90b5d415dc7c19569568cf4579b4bart    else
1936b71761ccfaa90b5d415dc7c19569568cf4579b4bart    {
1946b71761ccfaa90b5d415dc7c19569568cf4579b4bart      VG_(message)(Vg_UserMsg,
19552e82915a3a8491cd64ca13ce9fae0b5b4cd645abart                   "The object at address 0x%lx is not a mutex.",
1966b71761ccfaa90b5d415dc7c19569568cf4579b4bart                   p->mutex);
1976b71761ccfaa90b5d415dc7c19569568cf4579b4bart    }
1983772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
199246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(p->mutex);
2003772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2013772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2023772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondErr: {
2033772a98a8da0365a751c6886a340a1e4adb32be9bart    CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
2043772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2053772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: cond 0x%lx",
206be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 VG_(get_error_string)(e),
207be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 cdei->cond);
2083772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
209246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cdei->cond);
2103772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2113772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2123bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondDestrErr: {
2133bb1cecb5ed12da201d9e027de44c050c0422ba3bart    CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
2143bb1cecb5ed12da201d9e027de44c050c0422ba3bart    VG_(message)(Vg_UserMsg,
2153bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d",
2163bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 VG_(get_error_string)(e),
2173bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cdi->cond, cdi->mutex,
21862a784c9382fdf7184065ad76ae8d3b905605f21bart                 DRD_(DrdThreadIdToVgThreadId)(cdi->tid), cdi->tid);
2193bb1cecb5ed12da201d9e027de44c050c0422ba3bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
220246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cdi->mutex);
2213bb1cecb5ed12da201d9e027de44c050c0422ba3bart    break;
2223bb1cecb5ed12da201d9e027de44c050c0422ba3bart  }
2233772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondRaceErr: {
2243772a98a8da0365a751c6886a340a1e4adb32be9bart    CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
2253772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
22646b5fcebcf676fcc950a359d9dee5ac0d5755afcbart                 "Probably a race condition: condition variable 0x%lx has been"
227886b87c5e1adfa6657d24404283f7b79576e690cbart                 " signaled but the associated mutex 0x%lx is not locked"
228886b87c5e1adfa6657d24404283f7b79576e690cbart                 " by the signalling thread.",
2293772a98a8da0365a751c6886a340a1e4adb32be9bart                 cei->cond, cei->mutex);
2303772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
231246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cei->cond);
232246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cei->mutex);
2333772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2343772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2353bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr: {
2363bb1cecb5ed12da201d9e027de44c050c0422ba3bart    CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
2373772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2383bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx",
239be8a12c79ae6d6f59fba840b91d8b0310ce05b71bart                 VG_(get_error_string)(e),
2403bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->cond,
2413bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->mutex1,
2423bb1cecb5ed12da201d9e027de44c050c0422ba3bart                 cwei->mutex2);
2433772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
244246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cwei->cond);
245246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cwei->mutex1);
246246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(cwei->mutex2);
2473772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2483772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2493772a98a8da0365a751c6886a340a1e4adb32be9bart  case SemaphoreErr: {
250886b87c5e1adfa6657d24404283f7b79576e690cbart    SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
2513772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(sei);
2523772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2533772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: semaphore 0x%lx",
2543772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
2553772a98a8da0365a751c6886a340a1e4adb32be9bart                 sei->semaphore);
2563772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
257246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(sei->semaphore);
2583772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2593772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2603772a98a8da0365a751c6886a340a1e4adb32be9bart  case BarrierErr: {
261391d9dc7a641ae3fe11f695372f710fe81155232bart    BarrierErrInfo* bei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
262391d9dc7a641ae3fe11f695372f710fe81155232bart    tl_assert(bei);
2633772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2643772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: barrier 0x%lx",
2653772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
266391d9dc7a641ae3fe11f695372f710fe81155232bart                 bei->barrier);
2673772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
268246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(bei->barrier);
2693772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2703772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2713772a98a8da0365a751c6886a340a1e4adb32be9bart  case RwlockErr: {
2723772a98a8da0365a751c6886a340a1e4adb32be9bart    RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
2733772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(p);
2743772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
2753772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s: rwlock 0x%lx.",
2763772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e),
2773772a98a8da0365a751c6886a340a1e4adb32be9bart                 p->rwlock);
2783772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
279246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(p->rwlock);
2803772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
2813772a98a8da0365a751c6886a340a1e4adb32be9bart  }
2829d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr: {
2839d5b7969d87e5dbb46b3c51934a6e367421932b0bart    HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
2849d5b7969d87e5dbb46b3c51934a6e367421932b0bart    tl_assert(p);
2859d5b7969d87e5dbb46b3c51934a6e367421932b0bart    tl_assert(p->acquired_at);
2869d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(message)(Vg_UserMsg, "Acquired at:");
2879d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(pp_ExeContext)(p->acquired_at);
2889d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(message)(Vg_UserMsg,
2899d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).",
2909d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 VG_(get_error_string)(e),
2919d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->synchronization_object,
2929d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->hold_time_ms,
2939d5b7969d87e5dbb46b3c51934a6e367421932b0bart                 p->threshold_ms);
2949d5b7969d87e5dbb46b3c51934a6e367421932b0bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
295246fbf2655328fc150e528b701223b7a1eafe471bart    DRD_(first_observed)(p->synchronization_object);
2969d5b7969d87e5dbb46b3c51934a6e367421932b0bart    break;
2979d5b7969d87e5dbb46b3c51934a6e367421932b0bart  }
2983772a98a8da0365a751c6886a340a1e4adb32be9bart  case GenericErr: {
2993772a98a8da0365a751c6886a340a1e4adb32be9bart    //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
3003772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
3013772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
3023772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3033772a98a8da0365a751c6886a340a1e4adb32be9bart  }
3043772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
3053772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(message)(Vg_UserMsg,
3063772a98a8da0365a751c6886a340a1e4adb32be9bart                 "%s",
3073772a98a8da0365a751c6886a340a1e4adb32be9bart                 VG_(get_error_string)(e));
3083772a98a8da0365a751c6886a340a1e4adb32be9bart    VG_(pp_ExeContext)(VG_(get_error_where)(e));
3093772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3103772a98a8da0365a751c6886a340a1e4adb32be9bart  }
311af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
312af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
313246fbf2655328fc150e528b701223b7a1eafe471bartstatic UInt DRD_(drd_tool_error_update_extra)(Error* e)
314af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3153772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
3163772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3173772a98a8da0365a751c6886a340a1e4adb32be9bart  case DataRaceErr:
3183772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(DataRaceErrInfo);
3193772a98a8da0365a751c6886a340a1e4adb32be9bart  case MutexErr:
3203772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(MutexErrInfo);
3213772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondErr:
3223772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(CondErrInfo);
3233772a98a8da0365a751c6886a340a1e4adb32be9bart  case CondDestrErr:
3243772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(CondDestrErrInfo);
3253bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondRaceErr:
3263bb1cecb5ed12da201d9e027de44c050c0422ba3bart    return sizeof(CondRaceErrInfo);
3273bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr:
3283bb1cecb5ed12da201d9e027de44c050c0422ba3bart    return sizeof(CondWaitErrInfo);
3293772a98a8da0365a751c6886a340a1e4adb32be9bart  case SemaphoreErr:
3303772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(SemaphoreErrInfo);
3313772a98a8da0365a751c6886a340a1e4adb32be9bart  case BarrierErr:
3323772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(BarrierErrInfo);
3333772a98a8da0365a751c6886a340a1e4adb32be9bart  case RwlockErr:
3343772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(RwlockErrInfo);
3359d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr:
3369d5b7969d87e5dbb46b3c51934a6e367421932b0bart    return sizeof(HoldtimeErrInfo);
3373772a98a8da0365a751c6886a340a1e4adb32be9bart  case GenericErr:
3383772a98a8da0365a751c6886a340a1e4adb32be9bart    return sizeof(GenericErrInfo);
3393772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
3403772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(False);
3413772a98a8da0365a751c6886a340a1e4adb32be9bart    break;
3423772a98a8da0365a751c6886a340a1e4adb32be9bart  }
343af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
344af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
345246fbf2655328fc150e528b701223b7a1eafe471bartstatic Bool DRD_(drd_tool_error_recog)(Char* const name, Supp* const supp)
346af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3475fc70e62b3bac5350c499d35b78f462f080d8032bart  SuppKind skind = 0;
348af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
3495fc70e62b3bac5350c499d35b78f462f080d8032bart  if (VG_(strcmp)(name, STR_DataRaceErr) == 0)
3505fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3515fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_MutexErr) == 0)
3525fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3535fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_CondErr) == 0)
3545fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3553bb1cecb5ed12da201d9e027de44c050c0422ba3bart  else if (VG_(strcmp)(name, STR_CondDestrErr) == 0)
3563bb1cecb5ed12da201d9e027de44c050c0422ba3bart    ;
3575fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_CondRaceErr) == 0)
3585fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3593bb1cecb5ed12da201d9e027de44c050c0422ba3bart  else if (VG_(strcmp)(name, STR_CondWaitErr) == 0)
3605fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3615fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_SemaphoreErr) == 0)
3625fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3635fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_BarrierErr) == 0)
3645fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3655fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_RwlockErr) == 0)
3665fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3679d5b7969d87e5dbb46b3c51934a6e367421932b0bart  else if (VG_(strcmp)(name, STR_HoldtimeErr) == 0)
3689d5b7969d87e5dbb46b3c51934a6e367421932b0bart    ;
3695fc70e62b3bac5350c499d35b78f462f080d8032bart  else if (VG_(strcmp)(name, STR_GenericErr) == 0)
3705fc70e62b3bac5350c499d35b78f462f080d8032bart    ;
3713772a98a8da0365a751c6886a340a1e4adb32be9bart  else
3723772a98a8da0365a751c6886a340a1e4adb32be9bart    return False;
373af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
3743772a98a8da0365a751c6886a340a1e4adb32be9bart  VG_(set_supp_kind)(supp, skind);
3753772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
376af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
377af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
378246fbf2655328fc150e528b701223b7a1eafe471bartstatic
379246fbf2655328fc150e528b701223b7a1eafe471bartBool DRD_(drd_tool_error_read_extra)(Int fd, Char* buf, Int nBuf, Supp* supp)
380af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3813772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
382af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
383af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
384246fbf2655328fc150e528b701223b7a1eafe471bartstatic Bool DRD_(drd_tool_error_matches)(Error* const e, Supp* const supp)
385af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3863772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_supp_kind)(supp))
3873772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3883772a98a8da0365a751c6886a340a1e4adb32be9bart  }
3893772a98a8da0365a751c6886a340a1e4adb32be9bart  return True;
390af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
391af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
392246fbf2655328fc150e528b701223b7a1eafe471bartstatic Char* DRD_(drd_tool_error_name)(Error* e)
393af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
3943772a98a8da0365a751c6886a340a1e4adb32be9bart  switch (VG_(get_error_kind)(e))
3953772a98a8da0365a751c6886a340a1e4adb32be9bart  {
3965fc70e62b3bac5350c499d35b78f462f080d8032bart  case DataRaceErr:  return VGAPPEND(STR_, DataRaceErr);
3975fc70e62b3bac5350c499d35b78f462f080d8032bart  case MutexErr:     return VGAPPEND(STR_, MutexErr);
3985fc70e62b3bac5350c499d35b78f462f080d8032bart  case CondErr:      return VGAPPEND(STR_, CondErr);
3995fc70e62b3bac5350c499d35b78f462f080d8032bart  case CondDestrErr: return VGAPPEND(STR_, CondDestrErr);
4003bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondRaceErr:  return VGAPPEND(STR_, CondRaceErr);
4013bb1cecb5ed12da201d9e027de44c050c0422ba3bart  case CondWaitErr:  return VGAPPEND(STR_, CondWaitErr);
4025fc70e62b3bac5350c499d35b78f462f080d8032bart  case SemaphoreErr: return VGAPPEND(STR_, SemaphoreErr);
4035fc70e62b3bac5350c499d35b78f462f080d8032bart  case BarrierErr:   return VGAPPEND(STR_, BarrierErr);
4045fc70e62b3bac5350c499d35b78f462f080d8032bart  case RwlockErr:    return VGAPPEND(STR_, RwlockErr);
4059d5b7969d87e5dbb46b3c51934a6e367421932b0bart  case HoldtimeErr:  return VGAPPEND(STR_, HoldtimeErr);
4065fc70e62b3bac5350c499d35b78f462f080d8032bart  case GenericErr:   return VGAPPEND(STR_, GenericErr);
4073772a98a8da0365a751c6886a340a1e4adb32be9bart  default:
4083772a98a8da0365a751c6886a340a1e4adb32be9bart    tl_assert(0);
4093772a98a8da0365a751c6886a340a1e4adb32be9bart  }
4103772a98a8da0365a751c6886a340a1e4adb32be9bart  return 0;
411af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
412af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
413246fbf2655328fc150e528b701223b7a1eafe471bartstatic void DRD_(drd_tool_error_print_extra)(Error* e)
414246fbf2655328fc150e528b701223b7a1eafe471bart{ }
415af44c8236f7a73e71b16b707bba56f33af4d01cesewardj
4161335ecca5095dea85be94095885082b80573df8cbartvoid DRD_(register_error_handlers)(void)
417af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{
4183772a98a8da0365a751c6886a340a1e4adb32be9bart  // Tool error reporting.
419246fbf2655328fc150e528b701223b7a1eafe471bart  VG_(needs_tool_errors)(DRD_(drd_tool_error_eq),
420246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_pp),
4213772a98a8da0365a751c6886a340a1e4adb32be9bart                         True,
422246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_update_extra),
423246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_recog),
424246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_read_extra),
425246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_matches),
426246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_name),
427246fbf2655328fc150e528b701223b7a1eafe471bart                         DRD_(drd_tool_error_print_extra));
428af44c8236f7a73e71b16b707bba56f33af4d01cesewardj}
429