blob: 1928b6d71525884c684bd1bfa4aeea2db4ab3eca [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
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
bart86562bd2009-02-16 19:43:56 +00005 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
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) */
40#include "pub_tool_threadstate.h" /* VG_(get_pthread_id)() */
41#include "pub_tool_tooliface.h" /* VG_(needs_tool_errors)() */
sewardjaf44c822007-11-25 14:01:38 +000042
43
bart16d76e52008-03-18 17:08:08 +000044/* Local variables. */
45
bartd2c5eae2009-02-21 15:27:04 +000046static Bool s_show_conflicting_segments = True;
bart16d76e52008-03-18 17:08:08 +000047
48
bart246fbf22009-02-15 14:46:17 +000049void DRD_(set_show_conflicting_segments)(const Bool scs)
bart16d76e52008-03-18 17:08:08 +000050{
bartbedfd232009-03-26 19:07:15 +000051 s_show_conflicting_segments = scs;
bart16d76e52008-03-18 17:08:08 +000052}
53
bart246fbf22009-02-15 14:46:17 +000054/**
55 * Describe a data address range [a,a+len[ as good as possible, for error
56 * messages, putting the result in ai.
bart886b87c2008-06-28 13:40:41 +000057 */
bartff1252a2008-03-16 17:27:25 +000058static
bartd2c5eae2009-02-21 15:27:04 +000059void describe_malloced_addr(Addr const a, SizeT const len, AddrInfo* const ai)
sewardjaf44c822007-11-25 14:01:38 +000060{
bartbedfd232009-03-26 19:07:15 +000061 Addr data;
sewardjaf44c822007-11-25 14:01:38 +000062
bartbedfd232009-03-26 19:07:15 +000063 if (DRD_(heap_addrinfo)(a, &data, &ai->size, &ai->lastchange))
64 {
65 ai->akind = eMallocd;
66 ai->rwoffset = a - data;
67 }
68 else
69 {
70 ai->akind = eUnknown;
71 }
sewardjaf44c822007-11-25 14:01:38 +000072}
73
bart246fbf22009-02-15 14:46:17 +000074/**
75 * Report where an object has been observed for the first time. The printed
76 * call stack will either refer to a pthread_*_init() or a pthread_*lock()
77 * call.
bart886b87c2008-06-28 13:40:41 +000078 */
bartd2c5eae2009-02-21 15:27:04 +000079static void first_observed(const Addr obj)
bart886b87c2008-06-28 13:40:41 +000080{
bartbedfd232009-03-26 19:07:15 +000081 DrdClientobj* cl;
bart886b87c2008-06-28 13:40:41 +000082
bartbedfd232009-03-26 19:07:15 +000083 cl = DRD_(clientobj_get_any)(obj);
84 if (cl)
85 {
86 tl_assert(cl->any.first_observed_at);
87 VG_(message)(Vg_UserMsg,
88 "%s 0x%lx was first observed at:",
89 DRD_(clientobj_type_name)(cl->any.type),
90 obj);
91 VG_(pp_ExeContext)(cl->any.first_observed_at);
92 }
bart886b87c2008-06-28 13:40:41 +000093}
94
sewardjaf44c822007-11-25 14:01:38 +000095static
bartd2c5eae2009-02-21 15:27:04 +000096void drd_report_data_race(Error* const err, const DataRaceErrInfo* const dri)
sewardjaf44c822007-11-25 14:01:38 +000097{
bartbedfd232009-03-26 19:07:15 +000098 AddrInfo ai;
99 const unsigned descr_size = 256;
100 Char* descr1 = VG_(malloc)("drd.error.drdr2.1", descr_size);
101 Char* descr2 = VG_(malloc)("drd.error.drdr2.2", descr_size);
sewardjaf44c822007-11-25 14:01:38 +0000102
bartbedfd232009-03-26 19:07:15 +0000103 tl_assert(dri);
104 tl_assert(dri->addr);
105 tl_assert(dri->size > 0);
106 tl_assert(descr1);
107 tl_assert(descr2);
bartb515eb12008-03-07 18:52:38 +0000108
bartbedfd232009-03-26 19:07:15 +0000109 descr1[0] = 0;
110 descr2[0] = 0;
111 VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
112 if (descr1[0] == 0)
113 {
114 describe_malloced_addr(dri->addr, dri->size, &ai);
115 }
116 VG_(message)(Vg_UserMsg,
117 "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
118 dri->access_type == eStore ? "store" : "load",
119 DRD_(DrdThreadIdToVgThreadId)(dri->tid),
120 dri->tid,
121 dri->addr,
122 dri->size);
123 VG_(pp_ExeContext)(VG_(get_error_where)(err));
124 if (descr1[0])
125 {
126 VG_(message)(Vg_UserMsg, "%s", descr1);
127 VG_(message)(Vg_UserMsg, "%s", descr2);
128 }
129 else if (ai.akind == eMallocd && ai.lastchange)
130 {
bartfca00e52008-07-09 12:43:35 +0000131 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000132 "Address 0x%lx is at offset %ld from 0x%lx."
133 " Allocation context:",
134 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
135 VG_(pp_ExeContext)(ai.lastchange);
136 }
137 else
138 {
139 char sect_name[64];
140 VgSectKind sect_kind;
bartf993b872008-04-01 18:19:50 +0000141
bartbedfd232009-03-26 19:07:15 +0000142 sect_kind = VG_(seginfo_sect_kind)(sect_name, sizeof(sect_name),
143 dri->addr);
144 if (sect_kind != Vg_SectUnknown)
145 {
146 VG_(message)(Vg_UserMsg,
147 "Allocation context: %s section of %s",
148 VG_(pp_SectKind)(sect_kind),
149 sect_name);
150 }
151 else
152 {
153 VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
154 }
155 }
156 if (s_show_conflicting_segments)
157 {
158 DRD_(thread_report_conflicting_segments)(dri->tid,
159 dri->addr, dri->size,
160 dri->access_type);
161 }
162
163 VG_(free)(descr2);
164 VG_(free)(descr1);
sewardjaf44c822007-11-25 14:01:38 +0000165}
166
bartd2c5eae2009-02-21 15:27:04 +0000167static Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2)
sewardjaf44c822007-11-25 14:01:38 +0000168{
bartbedfd232009-03-26 19:07:15 +0000169 return False;
sewardjaf44c822007-11-25 14:01:38 +0000170}
171
bartd2c5eae2009-02-21 15:27:04 +0000172static void drd_tool_error_pp(Error* const e)
sewardjaf44c822007-11-25 14:01:38 +0000173{
bartd45d9952009-05-31 18:53:54 +0000174 static DrdThreadId s_last_tid_printed = 1;
175 DrdThreadId* err_extra;
176
177 err_extra = VG_(get_error_extra)(e);
178
179 if (err_extra && *err_extra != s_last_tid_printed)
180 {
181 VG_UMSG("%s:", DRD_(thread_get_name)(*err_extra));
182 s_last_tid_printed = *err_extra;
183 }
184
bartbedfd232009-03-26 19:07:15 +0000185 switch (VG_(get_error_kind)(e))
186 {
187 case DataRaceErr: {
188 drd_report_data_race(e, VG_(get_error_extra)(e));
189 break;
190 }
191 case MutexErr: {
192 MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
193 tl_assert(p);
194 if (p->recursion_count >= 0)
195 {
196 VG_(message)(Vg_UserMsg,
197 "%s: mutex 0x%lx, recursion count %d, owner %d.",
198 VG_(get_error_string)(e),
199 p->mutex,
200 p->recursion_count,
201 p->owner);
202 }
203 else
204 {
205 VG_(message)(Vg_UserMsg,
206 "The object at address 0x%lx is not a mutex.",
207 p->mutex);
208 }
209 VG_(pp_ExeContext)(VG_(get_error_where)(e));
210 first_observed(p->mutex);
211 break;
212 }
213 case CondErr: {
214 CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
bart6b717612008-03-24 09:29:38 +0000215 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000216 "%s: cond 0x%lx",
bart6b717612008-03-24 09:29:38 +0000217 VG_(get_error_string)(e),
bartbedfd232009-03-26 19:07:15 +0000218 cdei->cond);
219 VG_(pp_ExeContext)(VG_(get_error_where)(e));
220 first_observed(cdei->cond);
221 break;
222 }
223 case CondDestrErr: {
224 CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
bart6b717612008-03-24 09:29:38 +0000225 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000226 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d",
227 VG_(get_error_string)(e),
228 cdi->cond, cdi->mutex,
bartd45d9952009-05-31 18:53:54 +0000229 DRD_(DrdThreadIdToVgThreadId)(cdi->owner), cdi->owner);
bartbedfd232009-03-26 19:07:15 +0000230 VG_(pp_ExeContext)(VG_(get_error_where)(e));
231 first_observed(cdi->mutex);
232 break;
233 }
234 case CondRaceErr: {
235 CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
bartd2c5eae2009-02-21 15:27:04 +0000236 VG_(message)(Vg_UserMsg,
bartbedfd232009-03-26 19:07:15 +0000237 "Probably a race condition: condition variable 0x%lx has"
238 " been signaled but the associated mutex 0x%lx is not"
239 " locked by the signalling thread.",
240 cei->cond, cei->mutex);
241 VG_(pp_ExeContext)(VG_(get_error_where)(e));
242 first_observed(cei->cond);
243 first_observed(cei->mutex);
244 break;
245 }
246 case CondWaitErr: {
247 CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
248 VG_(message)(Vg_UserMsg,
249 "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx",
250 VG_(get_error_string)(e),
251 cwei->cond,
252 cwei->mutex1,
253 cwei->mutex2);
254 VG_(pp_ExeContext)(VG_(get_error_where)(e));
255 first_observed(cwei->cond);
256 first_observed(cwei->mutex1);
257 first_observed(cwei->mutex2);
258 break;
259 }
260 case SemaphoreErr: {
261 SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
262 tl_assert(sei);
263 VG_(message)(Vg_UserMsg,
264 "%s: semaphore 0x%lx",
265 VG_(get_error_string)(e),
266 sei->semaphore);
267 VG_(pp_ExeContext)(VG_(get_error_where)(e));
268 first_observed(sei->semaphore);
269 break;
270 }
271 case BarrierErr: {
272 BarrierErrInfo* bei = (BarrierErrInfo*)(VG_(get_error_extra)(e));
273 tl_assert(bei);
274 VG_(message)(Vg_UserMsg,
275 "%s: barrier 0x%lx",
276 VG_(get_error_string)(e),
277 bei->barrier);
278 VG_(pp_ExeContext)(VG_(get_error_where)(e));
279 if (bei->other_context)
280 {
281 VG_(message)(Vg_UserMsg,
282 "Conflicting wait call by thread %d/%d:",
283 DRD_(DrdThreadIdToVgThreadId)(bei->other_tid),
284 bei->other_tid);
285 VG_(pp_ExeContext)(bei->other_context);
286 }
287 first_observed(bei->barrier);
288 break;
289 }
290 case RwlockErr: {
291 RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
292 tl_assert(p);
293 VG_(message)(Vg_UserMsg,
294 "%s: rwlock 0x%lx.",
295 VG_(get_error_string)(e),
296 p->rwlock);
297 VG_(pp_ExeContext)(VG_(get_error_where)(e));
298 first_observed(p->rwlock);
299 break;
300 }
301 case HoldtimeErr: {
302 HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
303 tl_assert(p);
304 tl_assert(p->acquired_at);
305 VG_(message)(Vg_UserMsg, "Acquired at:");
306 VG_(pp_ExeContext)(p->acquired_at);
307 VG_(message)(Vg_UserMsg,
308 "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).",
309 VG_(get_error_string)(e),
310 p->synchronization_object,
311 p->hold_time_ms,
312 p->threshold_ms);
313 VG_(pp_ExeContext)(VG_(get_error_where)(e));
314 first_observed(p->synchronization_object);
315 break;
316 }
317 case GenericErr: {
318 //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
319 VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
320 VG_(pp_ExeContext)(VG_(get_error_where)(e));
321 break;
322 }
323 default:
324 VG_(message)(Vg_UserMsg,
325 "%s",
326 VG_(get_error_string)(e));
327 VG_(pp_ExeContext)(VG_(get_error_where)(e));
328 break;
329 }
sewardjaf44c822007-11-25 14:01:38 +0000330}
331
bartd2c5eae2009-02-21 15:27:04 +0000332static UInt drd_tool_error_update_extra(Error* e)
sewardjaf44c822007-11-25 14:01:38 +0000333{
bartbedfd232009-03-26 19:07:15 +0000334 switch (VG_(get_error_kind)(e))
335 {
336 case DataRaceErr:
337 return sizeof(DataRaceErrInfo);
338 case MutexErr:
339 return sizeof(MutexErrInfo);
340 case CondErr:
341 return sizeof(CondErrInfo);
342 case CondDestrErr:
343 return sizeof(CondDestrErrInfo);
344 case CondRaceErr:
345 return sizeof(CondRaceErrInfo);
346 case CondWaitErr:
347 return sizeof(CondWaitErrInfo);
348 case SemaphoreErr:
349 return sizeof(SemaphoreErrInfo);
350 case BarrierErr:
351 return sizeof(BarrierErrInfo);
352 case RwlockErr:
353 return sizeof(RwlockErrInfo);
354 case HoldtimeErr:
355 return sizeof(HoldtimeErrInfo);
356 case GenericErr:
357 return sizeof(GenericErrInfo);
358 default:
359 tl_assert(False);
360 break;
361 }
sewardjaf44c822007-11-25 14:01:38 +0000362}
363
bartd2c5eae2009-02-21 15:27:04 +0000364static Bool drd_tool_error_recog(Char* const name, Supp* const supp)
sewardjaf44c822007-11-25 14:01:38 +0000365{
bartbedfd232009-03-26 19:07:15 +0000366 SuppKind skind = 0;
sewardjaf44c822007-11-25 14:01:38 +0000367
bartbedfd232009-03-26 19:07:15 +0000368 if (VG_(strcmp)(name, STR_DataRaceErr) == 0)
369 ;
370 else if (VG_(strcmp)(name, STR_MutexErr) == 0)
371 ;
372 else if (VG_(strcmp)(name, STR_CondErr) == 0)
373 ;
374 else if (VG_(strcmp)(name, STR_CondDestrErr) == 0)
375 ;
376 else if (VG_(strcmp)(name, STR_CondRaceErr) == 0)
377 ;
378 else if (VG_(strcmp)(name, STR_CondWaitErr) == 0)
379 ;
380 else if (VG_(strcmp)(name, STR_SemaphoreErr) == 0)
381 ;
382 else if (VG_(strcmp)(name, STR_BarrierErr) == 0)
383 ;
384 else if (VG_(strcmp)(name, STR_RwlockErr) == 0)
385 ;
386 else if (VG_(strcmp)(name, STR_HoldtimeErr) == 0)
387 ;
388 else if (VG_(strcmp)(name, STR_GenericErr) == 0)
389 ;
390 else
391 return False;
sewardjaf44c822007-11-25 14:01:38 +0000392
bartbedfd232009-03-26 19:07:15 +0000393 VG_(set_supp_kind)(supp, skind);
394 return True;
sewardjaf44c822007-11-25 14:01:38 +0000395}
396
bart246fbf22009-02-15 14:46:17 +0000397static
bartd2c5eae2009-02-21 15:27:04 +0000398Bool drd_tool_error_read_extra(Int fd, Char* buf, Int nBuf, Supp* supp)
sewardjaf44c822007-11-25 14:01:38 +0000399{
bartbedfd232009-03-26 19:07:15 +0000400 return True;
sewardjaf44c822007-11-25 14:01:38 +0000401}
402
bartd2c5eae2009-02-21 15:27:04 +0000403static Bool drd_tool_error_matches(Error* const e, Supp* const supp)
sewardjaf44c822007-11-25 14:01:38 +0000404{
bartbedfd232009-03-26 19:07:15 +0000405 switch (VG_(get_supp_kind)(supp))
406 {
407 }
408 return True;
sewardjaf44c822007-11-25 14:01:38 +0000409}
410
bartd2c5eae2009-02-21 15:27:04 +0000411static Char* drd_tool_error_name(Error* e)
sewardjaf44c822007-11-25 14:01:38 +0000412{
bartbedfd232009-03-26 19:07:15 +0000413 switch (VG_(get_error_kind)(e))
414 {
415 case DataRaceErr: return VGAPPEND(STR_, DataRaceErr);
416 case MutexErr: return VGAPPEND(STR_, MutexErr);
417 case CondErr: return VGAPPEND(STR_, CondErr);
418 case CondDestrErr: return VGAPPEND(STR_, CondDestrErr);
419 case CondRaceErr: return VGAPPEND(STR_, CondRaceErr);
420 case CondWaitErr: return VGAPPEND(STR_, CondWaitErr);
421 case SemaphoreErr: return VGAPPEND(STR_, SemaphoreErr);
422 case BarrierErr: return VGAPPEND(STR_, BarrierErr);
423 case RwlockErr: return VGAPPEND(STR_, RwlockErr);
424 case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
425 case GenericErr: return VGAPPEND(STR_, GenericErr);
426 default:
427 tl_assert(0);
428 }
429 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000430}
431
bartd2c5eae2009-02-21 15:27:04 +0000432static void drd_tool_error_print_extra(Error* e)
bart246fbf22009-02-15 14:46:17 +0000433{ }
sewardjaf44c822007-11-25 14:01:38 +0000434
bart1335ecc2009-02-14 16:10:53 +0000435void DRD_(register_error_handlers)(void)
sewardjaf44c822007-11-25 14:01:38 +0000436{
bartbedfd232009-03-26 19:07:15 +0000437 // Tool error reporting.
438 VG_(needs_tool_errors)(drd_tool_error_eq,
439 drd_tool_error_pp,
bartd45d9952009-05-31 18:53:54 +0000440 False,
bartbedfd232009-03-26 19:07:15 +0000441 drd_tool_error_update_extra,
442 drd_tool_error_recog,
443 drd_tool_error_read_extra,
444 drd_tool_error_matches,
445 drd_tool_error_name,
446 drd_tool_error_print_extra);
sewardjaf44c822007-11-25 14:01:38 +0000447}