blob: 0bd0a1013dc77183af050a9905eb528644d2e217 [file] [log] [blame]
bart922304f2011-03-13 12:02:44 +00001/* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
sewardjaf44c822007-11-25 14:01:38 +00002/*
bart86562bd2009-02-16 19:43:56 +00003 This file is part of drd, a thread error detector.
sewardjaf44c822007-11-25 14:01:38 +00004
bart922304f2011-03-13 12:02:44 +00005 Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.
sewardjaf44c822007-11-25 14:01:38 +00006
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
bart886b87c2008-06-28 13:40:41 +000026#include "drd_clientobj.h" /* struct mutex_info */
sewardjaf44c822007-11-25 14:01:38 +000027#include "drd_error.h"
28#include "drd_malloc_wrappers.h"
bart886b87c2008-06-28 13:40:41 +000029#include "drd_mutex.h"
30#include "drd_suppression.h" /* drd_start_suppression() */
31#include "pub_drd_bitmap.h" /* LHS_W, ... */
sewardjaf44c822007-11-25 14:01:38 +000032#include "pub_tool_vki.h"
33#include "pub_tool_basics.h"
bart886b87c2008-06-28 13:40:41 +000034#include "pub_tool_libcassert.h" /* tl_assert() */
35#include "pub_tool_libcbase.h" /* strlen() */
36#include "pub_tool_libcfile.h" /* VG_(get_startup_wd)() */
37#include "pub_tool_libcprint.h" /* VG_(printf)() */
sewardjaf44c822007-11-25 14:01:38 +000038#include "pub_tool_machine.h"
bart886b87c2008-06-28 13:40:41 +000039#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
bartb92ff0f2011-10-08 08:29:29 +000040#include "pub_tool_options.h" /* VG_(clo_xml) */
bart886b87c2008-06-28 13:40:41 +000041#include "pub_tool_threadstate.h" /* VG_(get_pthread_id)() */
42#include "pub_tool_tooliface.h" /* VG_(needs_tool_errors)() */
sewardjaf44c822007-11-25 14:01:38 +000043
44
bart16d76e52008-03-18 17:08:08 +000045/* Local variables. */
46
bartd2c5eae2009-02-21 15:27:04 +000047static Bool s_show_conflicting_segments = True;
bart16d76e52008-03-18 17:08:08 +000048
49
bart246fbf22009-02-15 14:46:17 +000050void DRD_(set_show_conflicting_segments)(const Bool scs)
bart16d76e52008-03-18 17:08:08 +000051{
bartbedfd232009-03-26 19:07:15 +000052 s_show_conflicting_segments = scs;
bart16d76e52008-03-18 17:08:08 +000053}
54
bartb92ff0f2011-10-08 08:29:29 +000055void DRD_(trace_msg)(const char* format, ...)
56{
57 va_list vargs;
58 va_start(vargs, format);
59 VG_(vmessage)(Vg_UserMsg, format, vargs);
60 va_end(vargs);
61}
62
bart246fbf22009-02-15 14:46:17 +000063/**
bart61d36ff2009-07-27 14:17:33 +000064 * Describe the client address a as good as possible, putting the result in ai.
bart886b87c2008-06-28 13:40:41 +000065 */
bartff1252a2008-03-16 17:27:25 +000066static
bart61d36ff2009-07-27 14:17:33 +000067void describe_malloced_addr(Addr const a, AddrInfo* const ai)
sewardjaf44c822007-11-25 14:01:38 +000068{
bart61d36ff2009-07-27 14:17:33 +000069 Addr heap_block_start;
sewardjaf44c822007-11-25 14:01:38 +000070
bart61d36ff2009-07-27 14:17:33 +000071 if (DRD_(heap_addrinfo)(a, &heap_block_start, &ai->size, &ai->lastchange))
bartbedfd232009-03-26 19:07:15 +000072 {
73 ai->akind = eMallocd;
bart61d36ff2009-07-27 14:17:33 +000074 ai->rwoffset = a - heap_block_start;
bartbedfd232009-03-26 19:07:15 +000075 }
76 else
77 {
78 ai->akind = eUnknown;
79 }
sewardjaf44c822007-11-25 14:01:38 +000080}
81
bart246fbf22009-02-15 14:46:17 +000082/**
bart61d36ff2009-07-27 14:17:33 +000083 * Report where a client synchronization object has been observed for the first
84 * time. The printed call stack will either refer to a pthread_*_init() or a
85 * pthread_*lock() call.
bart886b87c2008-06-28 13:40:41 +000086 */
bartd2c5eae2009-02-21 15:27:04 +000087static void first_observed(const Addr obj)
bart886b87c2008-06-28 13:40:41 +000088{
bartbedfd232009-03-26 19:07:15 +000089 DrdClientobj* cl;
bart886b87c2008-06-28 13:40:41 +000090
bartbedfd232009-03-26 19:07:15 +000091 cl = DRD_(clientobj_get_any)(obj);
92 if (cl)
93 {
94 tl_assert(cl->any.first_observed_at);
95 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +000096 "%s 0x%lx was first observed at:\n",
bartbedfd232009-03-26 19:07:15 +000097 DRD_(clientobj_type_name)(cl->any.type),
98 obj);
99 VG_(pp_ExeContext)(cl->any.first_observed_at);
100 }
bart886b87c2008-06-28 13:40:41 +0000101}
102
sewardjaf44c822007-11-25 14:01:38 +0000103static
bartd2c5eae2009-02-21 15:27:04 +0000104void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
sewardjaf44c822007-11-25 14:01:38 +0000105{
bartbedfd232009-03-26 19:07:15 +0000106 AddrInfo ai;
sewardj1e29ebc2009-07-15 14:49:17 +0000107
108 XArray* /* of HChar */ descr1
109 = VG_(newXA)( VG_(malloc), "drd.error.drdr2.1",
110 VG_(free), sizeof(HChar) );
111 XArray* /* of HChar */ descr2
112 = VG_(newXA)( VG_(malloc), "drd.error.drdr2.2",
113 VG_(free), sizeof(HChar) );
sewardjaf44c822007-11-25 14:01:38 +0000114
bartbedfd232009-03-26 19:07:15 +0000115 tl_assert(dri);
116 tl_assert(dri->addr);
117 tl_assert(dri->size > 0);
118 tl_assert(descr1);
119 tl_assert(descr2);
bartb515eb12008-03-07 18:52:38 +0000120
sewardj1e29ebc2009-07-15 14:49:17 +0000121 (void) VG_(get_data_description)(descr1, descr2, dri->addr);
122 /* If there's nothing in descr1/2, free them. Why is it safe to to
123 VG_(indexXA) at zero here? Because VG_(get_data_description)
124 guarantees to zero terminate descr1/2 regardless of the outcome
125 of the call. So there's always at least one element in each XA
126 after the call.
127 */
128 if (0 == VG_(strlen)( VG_(indexXA)( descr1, 0 ))) {
129 VG_(deleteXA)( descr1 );
130 descr1 = NULL;
131 }
132 if (0 == VG_(strlen)( VG_(indexXA)( descr2, 0 ))) {
133 VG_(deleteXA)( descr2 );
134 descr2 = NULL;
135 }
136 /* Assume (assert) that VG_(get_data_description) fills in descr1
137 before it fills in descr2 */
138 if (descr1 == NULL)
139 tl_assert(descr2 == NULL);
140 /* So anyway. Do we have something useful? */
141 if (descr1 == NULL)
bartbedfd232009-03-26 19:07:15 +0000142 {
sewardj1e29ebc2009-07-15 14:49:17 +0000143 /* No. Do Plan B. */
bart61d36ff2009-07-27 14:17:33 +0000144 describe_malloced_addr(dri->addr, &ai);
bartbedfd232009-03-26 19:07:15 +0000145 }
146 VG_(message)(Vg_UserMsg,
bart63c92ea2009-07-19 17:53:56 +0000147 "Conflicting %s by thread %d at 0x%08lx size %ld\n",
bartbedfd232009-03-26 19:07:15 +0000148 dri->access_type == eStore ? "store" : "load",
bartbedfd232009-03-26 19:07:15 +0000149 dri->tid,
150 dri->addr,
151 dri->size);
152 VG_(pp_ExeContext)(VG_(get_error_where)(err));
sewardj1e29ebc2009-07-15 14:49:17 +0000153 if (descr1 != NULL)
bartbedfd232009-03-26 19:07:15 +0000154 {
sewardj1e29ebc2009-07-15 14:49:17 +0000155 VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr1, 0));
156 if (descr2 != NULL)
157 VG_(message)(Vg_UserMsg, "%s\n", (HChar*)VG_(indexXA)(descr2, 0));
bartbedfd232009-03-26 19:07:15 +0000158 }
159 else if (ai.akind == eMallocd && ai.lastchange)
160 {
bartfca00e52008-07-09 12:43:35 +0000161 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000162 "Address 0x%lx is at offset %ld from 0x%lx."
sewardj1e29ebc2009-07-15 14:49:17 +0000163 " Allocation context:\n",
bartbedfd232009-03-26 19:07:15 +0000164 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
165 VG_(pp_ExeContext)(ai.lastchange);
166 }
167 else
168 {
169 char sect_name[64];
170 VgSectKind sect_kind;
bartf993b872008-04-01 18:19:50 +0000171
sewardje3f1e592009-07-31 09:41:29 +0000172 sect_kind = VG_(DebugInfo_sect_kind)(sect_name, sizeof(sect_name),
173 dri->addr);
bartbedfd232009-03-26 19:07:15 +0000174 if (sect_kind != Vg_SectUnknown)
175 {
176 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000177 "Allocation context: %s section of %s\n",
bartbedfd232009-03-26 19:07:15 +0000178 VG_(pp_SectKind)(sect_kind),
179 sect_name);
180 }
181 else
182 {
sewardj1e29ebc2009-07-15 14:49:17 +0000183 VG_(message)(Vg_UserMsg, "Allocation context: unknown.\n");
bartbedfd232009-03-26 19:07:15 +0000184 }
185 }
186 if (s_show_conflicting_segments)
187 {
188 DRD_(thread_report_conflicting_segments)(dri->tid,
189 dri->addr, dri->size,
190 dri->access_type);
191 }
192
sewardj1e29ebc2009-07-15 14:49:17 +0000193 if (descr2)
194 VG_(deleteXA)(descr2);
195 if (descr1)
196 VG_(deleteXA)(descr1);
sewardjaf44c822007-11-25 14:01:38 +0000197}
198
bart61d36ff2009-07-27 14:17:33 +0000199/**
200 * Compare two error contexts. The core function VG_(maybe_record_error)()
201 * calls this function to compare error contexts such that errors that occur
bart31b983d2010-02-21 14:52:59 +0000202 * repeatedly are only printed once. This function is only called by the core
bart61d36ff2009-07-27 14:17:33 +0000203 * if the error kind of e1 and e2 matches and if the ExeContext's of e1 and
204 * e2 also match.
205 */
206static Bool drd_compare_error_contexts(VgRes res, Error* e1, Error* e2)
sewardjaf44c822007-11-25 14:01:38 +0000207{
bartb80fa962009-07-31 08:45:02 +0000208 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
209
210 switch (VG_(get_error_kind)(e1))
211 {
212 case DataRaceErr:
213 {
214 const DataRaceErrInfo* const dri1 = VG_(get_error_extra)(e1);
215 const DataRaceErrInfo* const dri2 = VG_(get_error_extra)(e2);
216 return dri1->access_type == dri2->access_type
217 && dri1->size == dri2->size;
218 }
bart94fb8d22009-07-31 18:45:49 +0000219 case MutexErr:
220 {
221 const MutexErrInfo* const mei1 = VG_(get_error_extra)(e1);
222 const MutexErrInfo* const mei2 = VG_(get_error_extra)(e2);
223 return mei1->mutex == mei2->mutex;
224 }
bartb80fa962009-07-31 08:45:02 +0000225 default:
226 return True;
227 }
sewardjaf44c822007-11-25 14:01:38 +0000228}
229
bart61d36ff2009-07-27 14:17:33 +0000230/**
231 * Called by the core just before an error message will be printed. Used by
232 * DRD to print the thread number as a preamble.
233 */
sewardj1e29ebc2009-07-15 14:49:17 +0000234static void drd_tool_error_before_pp(Error* const e)
235{
bartd45d9952009-05-31 18:53:54 +0000236 static DrdThreadId s_last_tid_printed = 1;
237 DrdThreadId* err_extra;
238
239 err_extra = VG_(get_error_extra)(e);
240
241 if (err_extra && *err_extra != s_last_tid_printed)
242 {
sewardj1e29ebc2009-07-15 14:49:17 +0000243 VG_(umsg)("%s:\n", DRD_(thread_get_name)(*err_extra));
bartd45d9952009-05-31 18:53:54 +0000244 s_last_tid_printed = *err_extra;
245 }
bart61d36ff2009-07-27 14:17:33 +0000246}
bartd45d9952009-05-31 18:53:54 +0000247
bart61d36ff2009-07-27 14:17:33 +0000248/** Report an error to the user. */
249static void drd_tool_error_pp(Error* const e)
250{
bartbedfd232009-03-26 19:07:15 +0000251 switch (VG_(get_error_kind)(e))
252 {
253 case DataRaceErr: {
254 drd_report_data_race(e, VG_(get_error_extra)(e));
255 break;
256 }
257 case MutexErr: {
258 MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
259 tl_assert(p);
260 if (p->recursion_count >= 0)
261 {
262 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000263 "%s: mutex 0x%lx, recursion count %d, owner %d.\n",
bartbedfd232009-03-26 19:07:15 +0000264 VG_(get_error_string)(e),
265 p->mutex,
266 p->recursion_count,
267 p->owner);
268 }
269 else
270 {
271 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000272 "The object at address 0x%lx is not a mutex.\n",
bartbedfd232009-03-26 19:07:15 +0000273 p->mutex);
274 }
275 VG_(pp_ExeContext)(VG_(get_error_where)(e));
276 first_observed(p->mutex);
277 break;
278 }
279 case CondErr: {
280 CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
bart6b717612008-03-24 09:29:38 +0000281 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000282 "%s: cond 0x%lx\n",
bart6b717612008-03-24 09:29:38 +0000283 VG_(get_error_string)(e),
bartbedfd232009-03-26 19:07:15 +0000284 cdei->cond);
285 VG_(pp_ExeContext)(VG_(get_error_where)(e));
286 first_observed(cdei->cond);
287 break;
288 }
289 case CondDestrErr: {
290 CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
bart6b717612008-03-24 09:29:38 +0000291 VG_(message)(Vg_UserMsg,
bart63c92ea2009-07-19 17:53:56 +0000292 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d\n",
bartbedfd232009-03-26 19:07:15 +0000293 VG_(get_error_string)(e),
294 cdi->cond, cdi->mutex,
bart63c92ea2009-07-19 17:53:56 +0000295 cdi->owner);
bartbedfd232009-03-26 19:07:15 +0000296 VG_(pp_ExeContext)(VG_(get_error_where)(e));
297 first_observed(cdi->mutex);
298 break;
299 }
300 case CondRaceErr: {
301 CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
bartd2c5eae2009-02-21 15:27:04 +0000302 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000303 "Probably a race condition: condition variable 0x%lx has"
304 " been signaled but the associated mutex 0x%lx is not"
sewardj1e29ebc2009-07-15 14:49:17 +0000305 " locked by the signalling thread.\n",
bartbedfd232009-03-26 19:07:15 +0000306 cei->cond, cei->mutex);
307 VG_(pp_ExeContext)(VG_(get_error_where)(e));
308 first_observed(cei->cond);
309 first_observed(cei->mutex);
310 break;
311 }
312 case CondWaitErr: {
313 CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
314 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000315 "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx\n",
bartbedfd232009-03-26 19:07:15 +0000316 VG_(get_error_string)(e),
317 cwei->cond,
318 cwei->mutex1,
319 cwei->mutex2);
320 VG_(pp_ExeContext)(VG_(get_error_where)(e));
321 first_observed(cwei->cond);
322 first_observed(cwei->mutex1);
323 first_observed(cwei->mutex2);
324 break;
325 }
326 case SemaphoreErr: {
327 SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
328 tl_assert(sei);
329 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000330 "%s: semaphore 0x%lx\n",
bartbedfd232009-03-26 19:07:15 +0000331 VG_(get_error_string)(e),
332 sei->semaphore);
333 VG_(pp_ExeContext)(VG_(get_error_where)(e));
334 first_observed(sei->semaphore);
335 break;
336 }
337 case BarrierErr: {
338 BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e));
339 tl_assert(bei);
340 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000341 "%s: barrier 0x%lx\n",
bartbedfd232009-03-26 19:07:15 +0000342 VG_(get_error_string)(e),
343 bei->barrier);
344 VG_(pp_ExeContext)(VG_(get_error_where)(e));
345 if (bei->other_context)
346 {
347 VG_(message)(Vg_UserMsg,
bart63c92ea2009-07-19 17:53:56 +0000348 "Conflicting wait call by thread %d:\n",
bartbedfd232009-03-26 19:07:15 +0000349 bei->other_tid);
350 VG_(pp_ExeContext)(bei->other_context);
351 }
352 first_observed(bei->barrier);
353 break;
354 }
355 case RwlockErr: {
356 RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
357 tl_assert(p);
358 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000359 "%s: rwlock 0x%lx.\n",
bartbedfd232009-03-26 19:07:15 +0000360 VG_(get_error_string)(e),
361 p->rwlock);
362 VG_(pp_ExeContext)(VG_(get_error_where)(e));
363 first_observed(p->rwlock);
364 break;
365 }
366 case HoldtimeErr: {
367 HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
368 tl_assert(p);
369 tl_assert(p->acquired_at);
sewardj1e29ebc2009-07-15 14:49:17 +0000370 VG_(message)(Vg_UserMsg, "Acquired at:\n");
bartbedfd232009-03-26 19:07:15 +0000371 VG_(pp_ExeContext)(p->acquired_at);
372 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000373 "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).\n",
bartbedfd232009-03-26 19:07:15 +0000374 VG_(get_error_string)(e),
375 p->synchronization_object,
376 p->hold_time_ms,
377 p->threshold_ms);
378 VG_(pp_ExeContext)(VG_(get_error_where)(e));
379 first_observed(p->synchronization_object);
380 break;
381 }
382 case GenericErr: {
bart62cc2322010-03-07 10:54:21 +0000383 GenericErrInfo* gei = (GenericErrInfo*)(VG_(get_error_extra)(e));
sewardj1e29ebc2009-07-15 14:49:17 +0000384 VG_(message)(Vg_UserMsg, "%s\n", VG_(get_error_string)(e));
bartbedfd232009-03-26 19:07:15 +0000385 VG_(pp_ExeContext)(VG_(get_error_where)(e));
bart62cc2322010-03-07 10:54:21 +0000386 if (gei->addr)
387 first_observed(gei->addr);
bartbedfd232009-03-26 19:07:15 +0000388 break;
389 }
bartb48bde22009-07-31 08:26:17 +0000390 case InvalidThreadId: {
391 InvalidThreadIdInfo* iti =(InvalidThreadIdInfo*)(VG_(get_error_extra)(e));
392 VG_(message)(Vg_UserMsg,
393 "%s 0x%llx\n", VG_(get_error_string)(e), iti->ptid);
394 VG_(pp_ExeContext)(VG_(get_error_where)(e));
395 break;
396 }
bart141a7ed2010-03-21 17:28:10 +0000397 case UnimpHgClReq: {
bart66f196d2009-08-15 10:50:35 +0000398 UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
399 VG_(message)(Vg_UserMsg,
400 "The annotation macro %s has not yet been implemented in"
bartffb9d022009-08-27 06:16:24 +0000401 " <valgrind/helgrind.h>\n",
bart66f196d2009-08-15 10:50:35 +0000402 /*VG_(get_error_string)(e),*/ uicr->descr);
403 VG_(pp_ExeContext)(VG_(get_error_where)(e));
404 break;
405 }
bart141a7ed2010-03-21 17:28:10 +0000406 case UnimpDrdClReq: {
407 UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
408 VG_(message)(Vg_UserMsg,
409 "The annotation macro %s has not yet been implemented in"
410 " <valgrind/drd.h>\n",
411 uicr->descr);
412 VG_(pp_ExeContext)(VG_(get_error_where)(e));
413 break;
414 }
bartbedfd232009-03-26 19:07:15 +0000415 default:
416 VG_(message)(Vg_UserMsg,
sewardj1e29ebc2009-07-15 14:49:17 +0000417 "%s\n",
bartbedfd232009-03-26 19:07:15 +0000418 VG_(get_error_string)(e));
419 VG_(pp_ExeContext)(VG_(get_error_where)(e));
420 break;
421 }
sewardjaf44c822007-11-25 14:01:38 +0000422}
423
bartd2c5eae2009-02-21 15:27:04 +0000424static UInt drd_tool_error_update_extra(Error* e)
sewardjaf44c822007-11-25 14:01:38 +0000425{
bartbedfd232009-03-26 19:07:15 +0000426 switch (VG_(get_error_kind)(e))
427 {
428 case DataRaceErr:
429 return sizeof(DataRaceErrInfo);
430 case MutexErr:
431 return sizeof(MutexErrInfo);
432 case CondErr:
433 return sizeof(CondErrInfo);
434 case CondDestrErr:
435 return sizeof(CondDestrErrInfo);
436 case CondRaceErr:
437 return sizeof(CondRaceErrInfo);
438 case CondWaitErr:
439 return sizeof(CondWaitErrInfo);
440 case SemaphoreErr:
441 return sizeof(SemaphoreErrInfo);
442 case BarrierErr:
443 return sizeof(BarrierErrInfo);
444 case RwlockErr:
445 return sizeof(RwlockErrInfo);
446 case HoldtimeErr:
447 return sizeof(HoldtimeErrInfo);
448 case GenericErr:
449 return sizeof(GenericErrInfo);
bartb48bde22009-07-31 08:26:17 +0000450 case InvalidThreadId:
451 return sizeof(InvalidThreadIdInfo);
bart141a7ed2010-03-21 17:28:10 +0000452 case UnimpHgClReq:
453 return sizeof(UnimpClReqInfo);
454 case UnimpDrdClReq:
bart66f196d2009-08-15 10:50:35 +0000455 return sizeof(UnimpClReqInfo);
bartbedfd232009-03-26 19:07:15 +0000456 default:
457 tl_assert(False);
458 break;
459 }
sewardjaf44c822007-11-25 14:01:38 +0000460}
461
bart61d36ff2009-07-27 14:17:33 +0000462/**
463 * Parse suppression name.
464 *
465 * The suppression types recognized by DRD are the same types as the error
466 * types supported by DRD. So try to match the suppression name against the
467 * names of DRD error types.
468 */
469static Bool drd_is_recognized_suppression(Char* const name, Supp* const supp)
sewardjaf44c822007-11-25 14:01:38 +0000470{
bart61d36ff2009-07-27 14:17:33 +0000471 DrdErrorKind skind = 0;
sewardjaf44c822007-11-25 14:01:38 +0000472
bartbedfd232009-03-26 19:07:15 +0000473 if (VG_(strcmp)(name, STR_DataRaceErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000474 skind = DataRaceErr;
bartbedfd232009-03-26 19:07:15 +0000475 else if (VG_(strcmp)(name, STR_MutexErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000476 skind = MutexErr;
bartbedfd232009-03-26 19:07:15 +0000477 else if (VG_(strcmp)(name, STR_CondErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000478 skind = CondErr;
bartbedfd232009-03-26 19:07:15 +0000479 else if (VG_(strcmp)(name, STR_CondDestrErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000480 skind = CondDestrErr;
bartbedfd232009-03-26 19:07:15 +0000481 else if (VG_(strcmp)(name, STR_CondRaceErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000482 skind = CondRaceErr;
bartbedfd232009-03-26 19:07:15 +0000483 else if (VG_(strcmp)(name, STR_CondWaitErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000484 skind = CondWaitErr;
bartbedfd232009-03-26 19:07:15 +0000485 else if (VG_(strcmp)(name, STR_SemaphoreErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000486 skind = SemaphoreErr;
bartbedfd232009-03-26 19:07:15 +0000487 else if (VG_(strcmp)(name, STR_BarrierErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000488 skind = BarrierErr;
bartbedfd232009-03-26 19:07:15 +0000489 else if (VG_(strcmp)(name, STR_RwlockErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000490 skind = RwlockErr;
bartbedfd232009-03-26 19:07:15 +0000491 else if (VG_(strcmp)(name, STR_HoldtimeErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000492 skind = HoldtimeErr;
bartbedfd232009-03-26 19:07:15 +0000493 else if (VG_(strcmp)(name, STR_GenericErr) == 0)
bart61d36ff2009-07-27 14:17:33 +0000494 skind = GenericErr;
bartb48bde22009-07-31 08:26:17 +0000495 else if (VG_(strcmp)(name, STR_InvalidThreadId) == 0)
496 skind = InvalidThreadId;
bart141a7ed2010-03-21 17:28:10 +0000497 else if (VG_(strcmp)(name, STR_UnimpHgClReq) == 0)
498 skind = UnimpHgClReq;
499 else if (VG_(strcmp)(name, STR_UnimpDrdClReq) == 0)
500 skind = UnimpDrdClReq;
bartbedfd232009-03-26 19:07:15 +0000501 else
502 return False;
sewardjaf44c822007-11-25 14:01:38 +0000503
bartbedfd232009-03-26 19:07:15 +0000504 VG_(set_supp_kind)(supp, skind);
505 return True;
sewardjaf44c822007-11-25 14:01:38 +0000506}
507
bart61d36ff2009-07-27 14:17:33 +0000508/**
509 * Read additional suppression information from the suppression file.
510 *
511 * None of the suppression patterns recognized by DRD has 'extra' lines
512 * of information in the suppression file, so just return True to indicate
513 * that reading the 'extra' lines succeeded.
514 */
bart246fbf22009-02-15 14:46:17 +0000515static
bart61d36ff2009-07-27 14:17:33 +0000516Bool drd_read_extra_suppression_info(Int fd, Char** bufpp,
517 SizeT* nBufp, Supp* supp)
sewardjaf44c822007-11-25 14:01:38 +0000518{
bartbedfd232009-03-26 19:07:15 +0000519 return True;
sewardjaf44c822007-11-25 14:01:38 +0000520}
521
bart61d36ff2009-07-27 14:17:33 +0000522/**
523 * Determine whether or not the types of the given error message and the
524 * given suppression match.
525 */
526static Bool drd_error_matches_suppression(Error* const e, Supp* const supp)
sewardjaf44c822007-11-25 14:01:38 +0000527{
bart61d36ff2009-07-27 14:17:33 +0000528 return VG_(get_supp_kind)(supp) == VG_(get_error_kind)(e);
sewardjaf44c822007-11-25 14:01:38 +0000529}
530
bart61d36ff2009-07-27 14:17:33 +0000531static Char* drd_get_error_name(Error* e)
sewardjaf44c822007-11-25 14:01:38 +0000532{
bartbedfd232009-03-26 19:07:15 +0000533 switch (VG_(get_error_kind)(e))
534 {
535 case DataRaceErr: return VGAPPEND(STR_, DataRaceErr);
536 case MutexErr: return VGAPPEND(STR_, MutexErr);
537 case CondErr: return VGAPPEND(STR_, CondErr);
538 case CondDestrErr: return VGAPPEND(STR_, CondDestrErr);
539 case CondRaceErr: return VGAPPEND(STR_, CondRaceErr);
540 case CondWaitErr: return VGAPPEND(STR_, CondWaitErr);
541 case SemaphoreErr: return VGAPPEND(STR_, SemaphoreErr);
542 case BarrierErr: return VGAPPEND(STR_, BarrierErr);
543 case RwlockErr: return VGAPPEND(STR_, RwlockErr);
544 case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
545 case GenericErr: return VGAPPEND(STR_, GenericErr);
bartb48bde22009-07-31 08:26:17 +0000546 case InvalidThreadId: return VGAPPEND(STR_, InvalidThreadId);
bart141a7ed2010-03-21 17:28:10 +0000547 case UnimpHgClReq: return VGAPPEND(STR_, UnimpHgClReq);
548 case UnimpDrdClReq: return VGAPPEND(STR_, UnimpDrdClReq);
bartbedfd232009-03-26 19:07:15 +0000549 default:
550 tl_assert(0);
551 }
552 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000553}
554
bart61d36ff2009-07-27 14:17:33 +0000555/**
sewardj588adef2009-08-15 22:41:51 +0000556 * Return extra suppression information.
bart61d36ff2009-07-27 14:17:33 +0000557 *
558 * Invoked while printing a suppression pattern because the user
559 * specified --gen-suppressions=yes or all on the command line. DRD does not
560 * define any 'extra' suppression information.
561 */
sewardj588adef2009-08-15 22:41:51 +0000562static
563Bool drd_get_extra_suppression_info(Error* e,
564 /*OUT*/Char* buf, Int nBuf)
565{
566 return False;
567}
sewardjaf44c822007-11-25 14:01:38 +0000568
bart61d36ff2009-07-27 14:17:33 +0000569/** Tell the Valgrind core about DRD's error handlers. */
bart1335ecc2009-02-14 16:10:53 +0000570void DRD_(register_error_handlers)(void)
sewardjaf44c822007-11-25 14:01:38 +0000571{
bart61d36ff2009-07-27 14:17:33 +0000572 VG_(needs_tool_errors)(drd_compare_error_contexts,
sewardj1e29ebc2009-07-15 14:49:17 +0000573 drd_tool_error_before_pp,
bartbedfd232009-03-26 19:07:15 +0000574 drd_tool_error_pp,
bartd45d9952009-05-31 18:53:54 +0000575 False,
bartbedfd232009-03-26 19:07:15 +0000576 drd_tool_error_update_extra,
bart61d36ff2009-07-27 14:17:33 +0000577 drd_is_recognized_suppression,
578 drd_read_extra_suppression_info,
579 drd_error_matches_suppression,
580 drd_get_error_name,
sewardj588adef2009-08-15 22:41:51 +0000581 drd_get_extra_suppression_info);
sewardjaf44c822007-11-25 14:01:38 +0000582}