blob: e66fdac5762c8c3f3d5c8c3191b799ac5734934b [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
2 This file is part of drd, a data race detector.
3
sewardj85642922008-01-14 11:54:56 +00004 Copyright (C) 2006-2008 Bart Van Assche
sewardjaf44c822007-11-25 14:01:38 +00005 bart.vanassche@gmail.com
6
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
46static Bool s_drd_show_conflicting_segments = True;
47
48
49void set_show_conflicting_segments(const Bool scs)
50{
51 s_drd_show_conflicting_segments = scs;
52}
53
bart886b87c2008-06-28 13:40:41 +000054/** Describe a data address range [a,a+len[ as good as possible, for error
55 * messages, putting the result in ai.
56 */
bartff1252a2008-03-16 17:27:25 +000057static
58void describe_malloced_addr(Addr const a, SizeT const len, AddrInfo* const ai)
sewardjaf44c822007-11-25 14:01:38 +000059{
bartff1252a2008-03-16 17:27:25 +000060 Addr data;
sewardjaf44c822007-11-25 14:01:38 +000061
bartff1252a2008-03-16 17:27:25 +000062 if (drd_heap_addrinfo(a, &data, &ai->size, &ai->lastchange))
bart3772a982008-03-15 08:11:03 +000063 {
bartff1252a2008-03-16 17:27:25 +000064 ai->akind = eMallocd;
65 ai->rwoffset = a - data;
bart3772a982008-03-15 08:11:03 +000066 }
bartff1252a2008-03-16 17:27:25 +000067 else
bart3772a982008-03-15 08:11:03 +000068 {
bartff1252a2008-03-16 17:27:25 +000069 ai->akind = eUnknown;
bart3772a982008-03-15 08:11:03 +000070 }
sewardjaf44c822007-11-25 14:01:38 +000071}
72
bart886b87c2008-06-28 13:40:41 +000073/** Report where a mutex has been observed for the first time. The printed
74 * call stack will either refer to a pthread_mutex_init() or a
75 * pthread_mutex_lock() call.
76 */
77static void mutex_first_observed(const Addr mutex)
78{
79 struct mutex_info* mi;
80
81 mi = mutex_get(mutex);
82 if (mi)
83 {
84 tl_assert(mi->first_observed_at);
85 VG_(message)(Vg_UserMsg,
86 "Mutex 0x%lx was first observed at:", mutex);
87 VG_(pp_ExeContext)(mi->first_observed_at);
88 }
89}
90
sewardjaf44c822007-11-25 14:01:38 +000091static
92void drd_report_data_race2(Error* const err, const DataRaceErrInfo* const dri)
93{
bart3772a982008-03-15 08:11:03 +000094 AddrInfo ai;
bartf993b872008-04-01 18:19:50 +000095 const unsigned descr_size = 256;
96 Char* descr1 = VG_(malloc)(descr_size);
97 Char* descr2 = VG_(malloc)(descr_size);
sewardjaf44c822007-11-25 14:01:38 +000098
bart3772a982008-03-15 08:11:03 +000099 tl_assert(dri);
100 tl_assert(dri->addr);
101 tl_assert(dri->size > 0);
bartfdd8d4e2008-04-01 18:38:29 +0000102 tl_assert(descr1);
103 tl_assert(descr2);
bartb515eb12008-03-07 18:52:38 +0000104
bart3772a982008-03-15 08:11:03 +0000105 descr1[0] = 0;
106 descr2[0] = 0;
bartf993b872008-04-01 18:19:50 +0000107 VG_(get_data_description)(descr1, descr2, descr_size, dri->addr);
bart3772a982008-03-15 08:11:03 +0000108 if (descr1[0] == 0)
109 {
bartff1252a2008-03-16 17:27:25 +0000110 describe_malloced_addr(dri->addr, dri->size, &ai);
bart3772a982008-03-15 08:11:03 +0000111 }
112 VG_(message)(Vg_UserMsg,
bartaa97a542008-03-16 17:57:01 +0000113 "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
bart3772a982008-03-15 08:11:03 +0000114 dri->access_type == eStore ? "store" : "load",
bart354009c2008-03-16 10:42:33 +0000115 DrdThreadIdToVgThreadId(dri->tid),
bartaa97a542008-03-16 17:57:01 +0000116 dri->tid,
bart3772a982008-03-15 08:11:03 +0000117 dri->addr,
118 dri->size);
119 VG_(pp_ExeContext)(VG_(get_error_where)(err));
120 if (descr1[0])
121 {
122 VG_(message)(Vg_UserMsg, "%s", descr1);
123 VG_(message)(Vg_UserMsg, "%s", descr2);
124 }
125 else if (ai.akind == eMallocd && ai.lastchange)
126 {
127 VG_(message)(Vg_UserMsg,
128 "Address 0x%lx is at offset %ld from 0x%lx."
129 " Allocation context:",
130 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
131 VG_(pp_ExeContext)(ai.lastchange);
132 }
133 else
134 {
135 VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
136 }
bart16d76e52008-03-18 17:08:08 +0000137 if (s_drd_show_conflicting_segments)
138 {
139 thread_report_conflicting_segments(dri->tid,
140 dri->addr, dri->size, dri->access_type);
141 }
bartf993b872008-04-01 18:19:50 +0000142
143 VG_(free)(descr2);
144 VG_(free)(descr1);
sewardjaf44c822007-11-25 14:01:38 +0000145}
146
147static Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2)
148{
bart3772a982008-03-15 08:11:03 +0000149 return False;
sewardjaf44c822007-11-25 14:01:38 +0000150}
151
152static void drd_tool_error_pp(Error* const e)
153{
bart3772a982008-03-15 08:11:03 +0000154 switch (VG_(get_error_kind)(e))
155 {
156 case DataRaceErr: {
157 drd_report_data_race2(e, VG_(get_error_extra)(e));
158 break;
159 }
160 case MutexErr: {
161 MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
162 tl_assert(p);
bart6b717612008-03-24 09:29:38 +0000163 if (p->recursion_count >= 0)
164 {
165 VG_(message)(Vg_UserMsg,
166 "%s: mutex 0x%lx, recursion count %d, owner %d.",
167 VG_(get_error_string)(e),
168 p->mutex,
169 p->recursion_count,
170 p->owner);
171 }
172 else
173 {
174 VG_(message)(Vg_UserMsg,
bart52e82912008-03-24 19:31:33 +0000175 "The object at address 0x%lx is not a mutex.",
bart6b717612008-03-24 09:29:38 +0000176 p->mutex);
177 }
bart3772a982008-03-15 08:11:03 +0000178 VG_(pp_ExeContext)(VG_(get_error_where)(e));
179 break;
180 }
181 case CondErr: {
182 CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
183 VG_(message)(Vg_UserMsg,
184 "%s: cond 0x%lx",
bartbe8a12c2008-03-17 18:36:55 +0000185 VG_(get_error_string)(e),
186 cdei->cond);
bart3772a982008-03-15 08:11:03 +0000187 VG_(pp_ExeContext)(VG_(get_error_where)(e));
188 break;
189 }
bart3bb1cec2008-06-28 16:01:43 +0000190 case CondDestrErr: {
191 CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
192 VG_(message)(Vg_UserMsg,
193 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d",
194 VG_(get_error_string)(e),
195 cdi->cond, cdi->mutex,
196 DrdThreadIdToVgThreadId(cdi->tid), cdi->tid);
197 VG_(pp_ExeContext)(VG_(get_error_where)(e));
198 mutex_first_observed(cdi->mutex);
199 break;
200 }
bart3772a982008-03-15 08:11:03 +0000201 case CondRaceErr: {
202 CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
203 VG_(message)(Vg_UserMsg,
bart46b5fce2008-06-28 13:01:30 +0000204 "Probably a race condition: condition variable 0x%lx has been"
bart886b87c2008-06-28 13:40:41 +0000205 " signaled but the associated mutex 0x%lx is not locked"
206 " by the signalling thread.",
bart3772a982008-03-15 08:11:03 +0000207 cei->cond, cei->mutex);
208 VG_(pp_ExeContext)(VG_(get_error_where)(e));
bart886b87c2008-06-28 13:40:41 +0000209 mutex_first_observed(cei->mutex);
bart3772a982008-03-15 08:11:03 +0000210 break;
211 }
bart3bb1cec2008-06-28 16:01:43 +0000212 case CondWaitErr: {
213 CondWaitErrInfo* cwei = (CondWaitErrInfo*)(VG_(get_error_extra)(e));
bart3772a982008-03-15 08:11:03 +0000214 VG_(message)(Vg_UserMsg,
bart3bb1cec2008-06-28 16:01:43 +0000215 "%s: condition variable 0x%lx, mutexes 0x%lx and 0x%lx",
bartbe8a12c2008-03-17 18:36:55 +0000216 VG_(get_error_string)(e),
bart3bb1cec2008-06-28 16:01:43 +0000217 cwei->cond,
218 cwei->mutex1,
219 cwei->mutex2);
bart3772a982008-03-15 08:11:03 +0000220 VG_(pp_ExeContext)(VG_(get_error_where)(e));
bart3bb1cec2008-06-28 16:01:43 +0000221 mutex_first_observed(cwei->mutex1);
222 mutex_first_observed(cwei->mutex2);
bart3772a982008-03-15 08:11:03 +0000223 break;
224 }
225 case SemaphoreErr: {
bart886b87c2008-06-28 13:40:41 +0000226 SemaphoreErrInfo* sei = (SemaphoreErrInfo*)(VG_(get_error_extra)(e));
bart3772a982008-03-15 08:11:03 +0000227 tl_assert(sei);
228 VG_(message)(Vg_UserMsg,
229 "%s: semaphore 0x%lx",
230 VG_(get_error_string)(e),
231 sei->semaphore);
232 VG_(pp_ExeContext)(VG_(get_error_where)(e));
233 break;
234 }
235 case BarrierErr: {
236 BarrierErrInfo* sei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
237 tl_assert(sei);
238 VG_(message)(Vg_UserMsg,
239 "%s: barrier 0x%lx",
240 VG_(get_error_string)(e),
241 sei->barrier);
242 VG_(pp_ExeContext)(VG_(get_error_where)(e));
243 break;
244 }
245 case RwlockErr: {
246 RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
247 tl_assert(p);
248 VG_(message)(Vg_UserMsg,
249 "%s: rwlock 0x%lx.",
250 VG_(get_error_string)(e),
251 p->rwlock);
252 VG_(pp_ExeContext)(VG_(get_error_where)(e));
253 break;
254 }
bart9d5b7962008-05-14 12:25:00 +0000255 case HoldtimeErr: {
256 HoldtimeErrInfo* p =(HoldtimeErrInfo*)(VG_(get_error_extra)(e));
257 tl_assert(p);
258 tl_assert(p->acquired_at);
259 VG_(message)(Vg_UserMsg, "Acquired at:");
260 VG_(pp_ExeContext)(p->acquired_at);
261 VG_(message)(Vg_UserMsg,
262 "Lock on %s 0x%lx was held during %d ms (threshold: %d ms).",
263 VG_(get_error_string)(e),
264 p->synchronization_object,
265 p->hold_time_ms,
266 p->threshold_ms);
267 VG_(pp_ExeContext)(VG_(get_error_where)(e));
268 break;
269 }
bart3772a982008-03-15 08:11:03 +0000270 case GenericErr: {
271 //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
272 VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
273 VG_(pp_ExeContext)(VG_(get_error_where)(e));
274 break;
275 }
276 default:
277 VG_(message)(Vg_UserMsg,
278 "%s",
279 VG_(get_error_string)(e));
280 VG_(pp_ExeContext)(VG_(get_error_where)(e));
281 break;
282 }
sewardjaf44c822007-11-25 14:01:38 +0000283}
284
285static UInt drd_tool_error_update_extra(Error* e)
286{
bart3772a982008-03-15 08:11:03 +0000287 switch (VG_(get_error_kind)(e))
288 {
289 case DataRaceErr:
290 return sizeof(DataRaceErrInfo);
291 case MutexErr:
292 return sizeof(MutexErrInfo);
293 case CondErr:
294 return sizeof(CondErrInfo);
bart3772a982008-03-15 08:11:03 +0000295 case CondDestrErr:
296 return sizeof(CondDestrErrInfo);
bart3bb1cec2008-06-28 16:01:43 +0000297 case CondRaceErr:
298 return sizeof(CondRaceErrInfo);
299 case CondWaitErr:
300 return sizeof(CondWaitErrInfo);
bart3772a982008-03-15 08:11:03 +0000301 case SemaphoreErr:
302 return sizeof(SemaphoreErrInfo);
303 case BarrierErr:
304 return sizeof(BarrierErrInfo);
305 case RwlockErr:
306 return sizeof(RwlockErrInfo);
bart9d5b7962008-05-14 12:25:00 +0000307 case HoldtimeErr:
308 return sizeof(HoldtimeErrInfo);
bart3772a982008-03-15 08:11:03 +0000309 case GenericErr:
310 return sizeof(GenericErrInfo);
311 default:
312 tl_assert(False);
313 break;
314 }
sewardjaf44c822007-11-25 14:01:38 +0000315}
316
317static Bool drd_tool_error_recog(Char* const name, Supp* const supp)
318{
bart5fc70e62008-03-23 07:54:02 +0000319 SuppKind skind = 0;
sewardjaf44c822007-11-25 14:01:38 +0000320
bart5fc70e62008-03-23 07:54:02 +0000321 if (VG_(strcmp)(name, STR_DataRaceErr) == 0)
322 ;
323 else if (VG_(strcmp)(name, STR_MutexErr) == 0)
324 ;
325 else if (VG_(strcmp)(name, STR_CondErr) == 0)
326 ;
bart3bb1cec2008-06-28 16:01:43 +0000327 else if (VG_(strcmp)(name, STR_CondDestrErr) == 0)
328 ;
bart5fc70e62008-03-23 07:54:02 +0000329 else if (VG_(strcmp)(name, STR_CondRaceErr) == 0)
330 ;
bart3bb1cec2008-06-28 16:01:43 +0000331 else if (VG_(strcmp)(name, STR_CondWaitErr) == 0)
bart5fc70e62008-03-23 07:54:02 +0000332 ;
333 else if (VG_(strcmp)(name, STR_SemaphoreErr) == 0)
334 ;
335 else if (VG_(strcmp)(name, STR_BarrierErr) == 0)
336 ;
337 else if (VG_(strcmp)(name, STR_RwlockErr) == 0)
338 ;
bart9d5b7962008-05-14 12:25:00 +0000339 else if (VG_(strcmp)(name, STR_HoldtimeErr) == 0)
340 ;
bart5fc70e62008-03-23 07:54:02 +0000341 else if (VG_(strcmp)(name, STR_GenericErr) == 0)
342 ;
bart3772a982008-03-15 08:11:03 +0000343 else
344 return False;
sewardjaf44c822007-11-25 14:01:38 +0000345
bart3772a982008-03-15 08:11:03 +0000346 VG_(set_supp_kind)(supp, skind);
347 return True;
sewardjaf44c822007-11-25 14:01:38 +0000348}
349
350static Bool drd_tool_error_read_extra(Int fd, Char* buf, Int nBuf, Supp* supp)
351{
bart3772a982008-03-15 08:11:03 +0000352 return True;
sewardjaf44c822007-11-25 14:01:38 +0000353}
354
355static Bool drd_tool_error_matches(Error* const e, Supp* const supp)
356{
bart3772a982008-03-15 08:11:03 +0000357 switch (VG_(get_supp_kind)(supp))
358 {
359 }
360 return True;
sewardjaf44c822007-11-25 14:01:38 +0000361}
362
363static Char* drd_tool_error_name(Error* e)
364{
bart3772a982008-03-15 08:11:03 +0000365 switch (VG_(get_error_kind)(e))
366 {
bart5fc70e62008-03-23 07:54:02 +0000367 case DataRaceErr: return VGAPPEND(STR_, DataRaceErr);
368 case MutexErr: return VGAPPEND(STR_, MutexErr);
369 case CondErr: return VGAPPEND(STR_, CondErr);
bart5fc70e62008-03-23 07:54:02 +0000370 case CondDestrErr: return VGAPPEND(STR_, CondDestrErr);
bart3bb1cec2008-06-28 16:01:43 +0000371 case CondRaceErr: return VGAPPEND(STR_, CondRaceErr);
372 case CondWaitErr: return VGAPPEND(STR_, CondWaitErr);
bart5fc70e62008-03-23 07:54:02 +0000373 case SemaphoreErr: return VGAPPEND(STR_, SemaphoreErr);
374 case BarrierErr: return VGAPPEND(STR_, BarrierErr);
375 case RwlockErr: return VGAPPEND(STR_, RwlockErr);
bart9d5b7962008-05-14 12:25:00 +0000376 case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
bart5fc70e62008-03-23 07:54:02 +0000377 case GenericErr: return VGAPPEND(STR_, GenericErr);
bart3772a982008-03-15 08:11:03 +0000378 default:
379 tl_assert(0);
380 }
381 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000382}
383
384static void drd_tool_error_print_extra(Error* e)
385{
bart3772a982008-03-15 08:11:03 +0000386 switch (VG_(get_error_kind)(e))
387 {
388 // VG_(printf)(" %s\n", VG_(get_error_string)(err));
389 }
sewardjaf44c822007-11-25 14:01:38 +0000390}
391
392void drd_register_error_handlers(void)
393{
bart3772a982008-03-15 08:11:03 +0000394 // Tool error reporting.
395 VG_(needs_tool_errors)(drd_tool_error_eq,
396 drd_tool_error_pp,
397 True,
398 drd_tool_error_update_extra,
399 drd_tool_error_recog,
400 drd_tool_error_read_extra,
401 drd_tool_error_matches,
402 drd_tool_error_name,
403 drd_tool_error_print_extra);
sewardjaf44c822007-11-25 14:01:38 +0000404}