blob: ef72522746fff482101c8c0da7560a38b851c749 [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
26#include "drd_error.h"
27#include "drd_malloc_wrappers.h"
28#include "drd_mutex.h" // struct mutex_info
29#include "drd_suppression.h" // drd_start_suppression()
30#include "pub_drd_bitmap.h" // LHS_W, ...
31#include "pub_tool_vki.h"
32#include "pub_tool_basics.h"
33#include "pub_tool_libcassert.h" // tl_assert()
34#include "pub_tool_libcbase.h" // strlen()
35#include "pub_tool_libcfile.h" // VG_(get_startup_wd)()
36#include "pub_tool_libcprint.h" // VG_(printf)()
37#include "pub_tool_machine.h"
38#include "pub_tool_threadstate.h" // VG_(get_pthread_id)()
39#include "pub_tool_tooliface.h" // VG_(needs_tool_errors)()
40
41
42typedef enum {
bart3772a982008-03-15 08:11:03 +000043 ConflictingAccessSupp
sewardjaf44c822007-11-25 14:01:38 +000044} DRD_SuppKind;
45
46
bartff1252a2008-03-16 17:27:25 +000047/* Describe a data address range [a,a+len[ as good as possible, for error */
sewardjaf44c822007-11-25 14:01:38 +000048/* messages, putting the result in ai. */
bartff1252a2008-03-16 17:27:25 +000049static
50void describe_malloced_addr(Addr const a, SizeT const len, AddrInfo* const ai)
sewardjaf44c822007-11-25 14:01:38 +000051{
bartff1252a2008-03-16 17:27:25 +000052 Addr data;
sewardjaf44c822007-11-25 14:01:38 +000053
bartff1252a2008-03-16 17:27:25 +000054 if (drd_heap_addrinfo(a, &data, &ai->size, &ai->lastchange))
bart3772a982008-03-15 08:11:03 +000055 {
bartff1252a2008-03-16 17:27:25 +000056 ai->akind = eMallocd;
57 ai->rwoffset = a - data;
bart3772a982008-03-15 08:11:03 +000058 }
bartff1252a2008-03-16 17:27:25 +000059 else
bart3772a982008-03-15 08:11:03 +000060 {
bartff1252a2008-03-16 17:27:25 +000061 ai->akind = eUnknown;
bart3772a982008-03-15 08:11:03 +000062 }
sewardjaf44c822007-11-25 14:01:38 +000063}
64
sewardjaf44c822007-11-25 14:01:38 +000065static
66void drd_report_data_race2(Error* const err, const DataRaceErrInfo* const dri)
67{
bart3772a982008-03-15 08:11:03 +000068 AddrInfo ai;
69 Char descr1[256];
70 Char descr2[256];
sewardjaf44c822007-11-25 14:01:38 +000071
bart3772a982008-03-15 08:11:03 +000072 tl_assert(dri);
73 tl_assert(dri->addr);
74 tl_assert(dri->size > 0);
bartb515eb12008-03-07 18:52:38 +000075
bart3772a982008-03-15 08:11:03 +000076 descr1[0] = 0;
77 descr2[0] = 0;
78 VG_(get_data_description)(descr1, descr2, sizeof(descr1), dri->addr);
79 if (descr1[0] == 0)
80 {
bartff1252a2008-03-16 17:27:25 +000081 describe_malloced_addr(dri->addr, dri->size, &ai);
bart3772a982008-03-15 08:11:03 +000082 }
83 VG_(message)(Vg_UserMsg,
bartaa97a542008-03-16 17:57:01 +000084 "Conflicting %s by thread %d/%d at 0x%08lx size %ld",
bart3772a982008-03-15 08:11:03 +000085 dri->access_type == eStore ? "store" : "load",
bart354009c2008-03-16 10:42:33 +000086 DrdThreadIdToVgThreadId(dri->tid),
bartaa97a542008-03-16 17:57:01 +000087 dri->tid,
bart3772a982008-03-15 08:11:03 +000088 dri->addr,
89 dri->size);
90 VG_(pp_ExeContext)(VG_(get_error_where)(err));
91 if (descr1[0])
92 {
93 VG_(message)(Vg_UserMsg, "%s", descr1);
94 VG_(message)(Vg_UserMsg, "%s", descr2);
95 }
96 else if (ai.akind == eMallocd && ai.lastchange)
97 {
98 VG_(message)(Vg_UserMsg,
99 "Address 0x%lx is at offset %ld from 0x%lx."
100 " Allocation context:",
101 dri->addr, ai.rwoffset, dri->addr - ai.rwoffset);
102 VG_(pp_ExeContext)(ai.lastchange);
103 }
104 else
105 {
106 VG_(message)(Vg_UserMsg, "Allocation context: unknown.");
107 }
bart354009c2008-03-16 10:42:33 +0000108 thread_report_conflicting_segments(dri->tid,
bart3772a982008-03-15 08:11:03 +0000109 dri->addr, dri->size, dri->access_type);
sewardjaf44c822007-11-25 14:01:38 +0000110}
111
112static Bool drd_tool_error_eq(VgRes res, Error* e1, Error* e2)
113{
bart3772a982008-03-15 08:11:03 +0000114 return False;
sewardjaf44c822007-11-25 14:01:38 +0000115}
116
117static void drd_tool_error_pp(Error* const e)
118{
bart3772a982008-03-15 08:11:03 +0000119 switch (VG_(get_error_kind)(e))
120 {
121 case DataRaceErr: {
122 drd_report_data_race2(e, VG_(get_error_extra)(e));
123 break;
124 }
125 case MutexErr: {
126 MutexErrInfo* p = (MutexErrInfo*)(VG_(get_error_extra)(e));
127 tl_assert(p);
128 VG_(message)(Vg_UserMsg,
129 "%s: mutex 0x%lx, recursion count %d, owner %d.",
130 VG_(get_error_string)(e),
131 p->mutex,
132 p->recursion_count,
133 p->owner);
134 VG_(pp_ExeContext)(VG_(get_error_where)(e));
135 break;
136 }
137 case CondErr: {
138 CondErrInfo* cdei =(CondErrInfo*)(VG_(get_error_extra)(e));
139 VG_(message)(Vg_UserMsg,
140 "%s: cond 0x%lx",
141 cdei->cond,
142 VG_(get_error_string)(e));
143 VG_(pp_ExeContext)(VG_(get_error_where)(e));
144 break;
145 }
146 case CondRaceErr: {
147 CondRaceErrInfo* cei = (CondRaceErrInfo*)(VG_(get_error_extra)(e));
148 VG_(message)(Vg_UserMsg,
149 "Race condition: condition variable 0x%lx has been"
150 " signalled but the associated mutex 0x%lx is not locked"
151 " by the signalling thread",
152 cei->cond, cei->mutex);
153 VG_(pp_ExeContext)(VG_(get_error_where)(e));
154 break;
155 }
156 case CondDestrErr: {
157 CondDestrErrInfo* cdi = (CondDestrErrInfo*)(VG_(get_error_extra)(e));
158 VG_(message)(Vg_UserMsg,
bartaa97a542008-03-16 17:57:01 +0000159 "%s: cond 0x%lx, mutex 0x%lx locked by thread %d/%d",
160 cdi->cond, cdi->mutex,
161 DrdThreadIdToVgThreadId(cdi->tid), cdi->tid);
bart3772a982008-03-15 08:11:03 +0000162 VG_(pp_ExeContext)(VG_(get_error_where)(e));
163 break;
164 }
165 case SemaphoreErr: {
166 SemaphoreErrInfo* sei =(SemaphoreErrInfo*)(VG_(get_error_extra)(e));
167 tl_assert(sei);
168 VG_(message)(Vg_UserMsg,
169 "%s: semaphore 0x%lx",
170 VG_(get_error_string)(e),
171 sei->semaphore);
172 VG_(pp_ExeContext)(VG_(get_error_where)(e));
173 break;
174 }
175 case BarrierErr: {
176 BarrierErrInfo* sei =(BarrierErrInfo*)(VG_(get_error_extra)(e));
177 tl_assert(sei);
178 VG_(message)(Vg_UserMsg,
179 "%s: barrier 0x%lx",
180 VG_(get_error_string)(e),
181 sei->barrier);
182 VG_(pp_ExeContext)(VG_(get_error_where)(e));
183 break;
184 }
185 case RwlockErr: {
186 RwlockErrInfo* p = (RwlockErrInfo*)(VG_(get_error_extra)(e));
187 tl_assert(p);
188 VG_(message)(Vg_UserMsg,
189 "%s: rwlock 0x%lx.",
190 VG_(get_error_string)(e),
191 p->rwlock);
192 VG_(pp_ExeContext)(VG_(get_error_where)(e));
193 break;
194 }
195 case GenericErr: {
196 //GenericErrInfo* gei =(GenericErrInfo*)(VG_(get_error_extra)(e));
197 VG_(message)(Vg_UserMsg, "%s", VG_(get_error_string)(e));
198 VG_(pp_ExeContext)(VG_(get_error_where)(e));
199 break;
200 }
201 default:
202 VG_(message)(Vg_UserMsg,
203 "%s",
204 VG_(get_error_string)(e));
205 VG_(pp_ExeContext)(VG_(get_error_where)(e));
206 break;
207 }
sewardjaf44c822007-11-25 14:01:38 +0000208}
209
210static UInt drd_tool_error_update_extra(Error* e)
211{
bart3772a982008-03-15 08:11:03 +0000212 switch (VG_(get_error_kind)(e))
213 {
214 case DataRaceErr:
215 return sizeof(DataRaceErrInfo);
216 case MutexErr:
217 return sizeof(MutexErrInfo);
218 case CondErr:
219 return sizeof(CondErrInfo);
220 case CondRaceErr:
221 return sizeof(CondRaceErrInfo);
222 case CondDestrErr:
223 return sizeof(CondDestrErrInfo);
224 case SemaphoreErr:
225 return sizeof(SemaphoreErrInfo);
226 case BarrierErr:
227 return sizeof(BarrierErrInfo);
228 case RwlockErr:
229 return sizeof(RwlockErrInfo);
230 case GenericErr:
231 return sizeof(GenericErrInfo);
232 default:
233 tl_assert(False);
234 break;
235 }
sewardjaf44c822007-11-25 14:01:38 +0000236}
237
238static Bool drd_tool_error_recog(Char* const name, Supp* const supp)
239{
bart3772a982008-03-15 08:11:03 +0000240 SuppKind skind;
sewardjaf44c822007-11-25 14:01:38 +0000241
bart3772a982008-03-15 08:11:03 +0000242 if (VG_(strcmp)(name, "ConflictingAccess") == 0)
243 skind = ConflictingAccessSupp;
244 else
245 return False;
sewardjaf44c822007-11-25 14:01:38 +0000246
bart3772a982008-03-15 08:11:03 +0000247 VG_(set_supp_kind)(supp, skind);
248 return True;
sewardjaf44c822007-11-25 14:01:38 +0000249}
250
251static Bool drd_tool_error_read_extra(Int fd, Char* buf, Int nBuf, Supp* supp)
252{
bart3772a982008-03-15 08:11:03 +0000253 return True;
sewardjaf44c822007-11-25 14:01:38 +0000254}
255
256static Bool drd_tool_error_matches(Error* const e, Supp* const supp)
257{
bart3772a982008-03-15 08:11:03 +0000258 switch (VG_(get_supp_kind)(supp))
259 {
260 }
261 return True;
sewardjaf44c822007-11-25 14:01:38 +0000262}
263
264static Char* drd_tool_error_name(Error* e)
265{
bart3772a982008-03-15 08:11:03 +0000266 switch (VG_(get_error_kind)(e))
267 {
bartff1252a2008-03-16 17:27:25 +0000268 case DataRaceErr: return "ConflictingAccess";
bart3772a982008-03-15 08:11:03 +0000269 case MutexErr: return "MutexErr";
270 case CondErr: return "CondErr";
271 case CondRaceErr: return "CondRaceErr";
272 case CondDestrErr: return "CondDestrErr";
273 case SemaphoreErr: return "SemaphoreErr";
274 case BarrierErr: return "BarrierErr";
275 case RwlockErr: return "RwlockErr";
276 case GenericErr: return "GenericErr";
277 default:
278 tl_assert(0);
279 }
280 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000281}
282
283static void drd_tool_error_print_extra(Error* e)
284{
bart3772a982008-03-15 08:11:03 +0000285 switch (VG_(get_error_kind)(e))
286 {
287 // VG_(printf)(" %s\n", VG_(get_error_string)(err));
288 }
sewardjaf44c822007-11-25 14:01:38 +0000289}
290
291void drd_register_error_handlers(void)
292{
bart3772a982008-03-15 08:11:03 +0000293 // Tool error reporting.
294 VG_(needs_tool_errors)(drd_tool_error_eq,
295 drd_tool_error_pp,
296 True,
297 drd_tool_error_update_extra,
298 drd_tool_error_recog,
299 drd_tool_error_read_extra,
300 drd_tool_error_matches,
301 drd_tool_error_name,
302 drd_tool_error_print_extra);
sewardjaf44c822007-11-25 14:01:38 +0000303}