blob: 29772a24851ce4e4b62082b985c122d02865fbb8 [file] [log] [blame]
njn5c004e42002-11-18 11:04:50 +00001
2/*--------------------------------------------------------------------*/
3/*--- Code that is shared between MemCheck and AddrCheck. ---*/
njn43c799e2003-04-08 00:08:52 +00004/*--- mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +00005/*--------------------------------------------------------------------*/
6
7/*
nethercote137bc552003-11-14 17:47:54 +00008 This file is part of MemCheck, a heavyweight Valgrind tool for
9 detecting memory errors, and AddrCheck, a lightweight Valgrind tool
njn5c004e42002-11-18 11:04:50 +000010 for detecting memory errors.
11
nethercotebb1c9912004-01-04 16:43:23 +000012 Copyright (C) 2000-2004 Julian Seward
njn5c004e42002-11-18 11:04:50 +000013 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
32
33
njn43c799e2003-04-08 00:08:52 +000034#include "mac_shared.h"
njn5c004e42002-11-18 11:04:50 +000035
njn47363ab2003-04-21 13:24:40 +000036#include "memcheck.h" /* for VG_USERREQ__* */
37
njn5c004e42002-11-18 11:04:50 +000038/*------------------------------------------------------------*/
39/*--- Defns ---*/
40/*------------------------------------------------------------*/
41
42/* These many bytes below %ESP are considered addressible if we're
43 doing the --workaround-gcc296-bugs hack. */
44#define VG_GCC296_BUG_STACK_SLOP 1024
45
46/*------------------------------------------------------------*/
47/*--- Command line options ---*/
48/*------------------------------------------------------------*/
49
njn43c799e2003-04-08 00:08:52 +000050Bool MAC_(clo_partial_loads_ok) = True;
51Int MAC_(clo_freelist_vol) = 1000000;
52Bool MAC_(clo_leak_check) = False;
53VgRes MAC_(clo_leak_resolution) = Vg_LowRes;
54Bool MAC_(clo_show_reachable) = False;
55Bool MAC_(clo_workaround_gcc296_bugs) = False;
njn5c004e42002-11-18 11:04:50 +000056
njn43c799e2003-04-08 00:08:52 +000057Bool MAC_(process_common_cmd_line_option)(Char* arg)
njn5c004e42002-11-18 11:04:50 +000058{
nethercote27fec902004-06-16 21:26:32 +000059 VG_BOOL_CLO("--leak-check", MAC_(clo_leak_check))
60 else VG_BOOL_CLO("--partial-loads-ok", MAC_(clo_partial_loads_ok))
61 else VG_BOOL_CLO("--show-reachable", MAC_(clo_show_reachable))
62 else VG_BOOL_CLO("--workaround-gcc296-bugs",MAC_(clo_workaround_gcc296_bugs))
63
64 else VG_BNUM_CLO("--freelist-vol", MAC_(clo_freelist_vol), 0, 1000000000)
65
njn43c799e2003-04-08 00:08:52 +000066 else if (VG_CLO_STREQ(arg, "--leak-resolution=low"))
67 MAC_(clo_leak_resolution) = Vg_LowRes;
68 else if (VG_CLO_STREQ(arg, "--leak-resolution=med"))
69 MAC_(clo_leak_resolution) = Vg_MedRes;
70 else if (VG_CLO_STREQ(arg, "--leak-resolution=high"))
71 MAC_(clo_leak_resolution) = Vg_HighRes;
njn5c004e42002-11-18 11:04:50 +000072
73 else
njn3e884182003-04-15 13:03:23 +000074 return VG_(replacement_malloc_process_cmd_line_option)(arg);
njn5c004e42002-11-18 11:04:50 +000075
76 return True;
njn43c799e2003-04-08 00:08:52 +000077}
njn5c004e42002-11-18 11:04:50 +000078
njn3e884182003-04-15 13:03:23 +000079void MAC_(print_common_usage)(void)
njn43c799e2003-04-08 00:08:52 +000080{
njn3e884182003-04-15 13:03:23 +000081 VG_(printf)(
82" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n"
83" --freelist-vol=<number> volume of freed blocks queue [1000000]\n"
84" --leak-check=no|yes search for memory leaks at exit? [no]\n"
85" --leak-resolution=low|med|high how much bt merging in leak check [low]\n"
86" --show-reachable=no|yes show reachable blocks in leak check? [no]\n"
87" --workaround-gcc296-bugs=no|yes self explanatory [no]\n"
88 );
89 VG_(replacement_malloc_print_usage)();
njn43c799e2003-04-08 00:08:52 +000090}
91
njn3e884182003-04-15 13:03:23 +000092void MAC_(print_common_debug_usage)(void)
njn43c799e2003-04-08 00:08:52 +000093{
njn3e884182003-04-15 13:03:23 +000094 VG_(replacement_malloc_print_debug_usage)();
njn5c004e42002-11-18 11:04:50 +000095}
96
97/*------------------------------------------------------------*/
98/*--- Comparing and printing errors ---*/
99/*------------------------------------------------------------*/
100
101static __inline__
102void clear_AddrInfo ( AddrInfo* ai )
103{
104 ai->akind = Unknown;
105 ai->blksize = 0;
106 ai->rwoffset = 0;
107 ai->lastchange = NULL;
108 ai->stack_tid = VG_INVALID_THREADID;
109 ai->maybe_gcc = False;
110}
111
njn43c799e2003-04-08 00:08:52 +0000112void MAC_(clear_MAC_Error) ( MAC_Error* err_extra )
njn5c004e42002-11-18 11:04:50 +0000113{
114 err_extra->axskind = ReadAxs;
115 err_extra->size = 0;
116 clear_AddrInfo ( &err_extra->addrinfo );
117 err_extra->isWrite = False;
118}
119
120__attribute__ ((unused))
121static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
122{
123 if (ai1->akind != Undescribed
124 && ai2->akind != Undescribed
125 && ai1->akind != ai2->akind)
126 return False;
127 if (ai1->akind == Freed || ai1->akind == Mallocd) {
128 if (ai1->blksize != ai2->blksize)
129 return False;
130 if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
131 return False;
132 }
133 return True;
134}
135
136/* Compare error contexts, to detect duplicates. Note that if they
137 are otherwise the same, the faulting addrs and associated rwoffsets
138 are allowed to be different. */
139
140Bool SK_(eq_SkinError) ( VgRes res, Error* e1, Error* e2 )
141{
njn43c799e2003-04-08 00:08:52 +0000142 MAC_Error* e1_extra = VG_(get_error_extra)(e1);
143 MAC_Error* e2_extra = VG_(get_error_extra)(e2);
njn7cc53a82002-11-19 16:19:32 +0000144
145 /* Guaranteed by calling function */
146 sk_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
njn5c004e42002-11-18 11:04:50 +0000147
148 switch (VG_(get_error_kind)(e1)) {
149 case CoreMemErr: {
150 Char *e1s, *e2s;
151 if (e1_extra->isWrite != e2_extra->isWrite) return False;
njn5c004e42002-11-18 11:04:50 +0000152 e1s = VG_(get_error_string)(e1);
153 e2s = VG_(get_error_string)(e2);
154 if (e1s == e2s) return True;
155 if (0 == VG_(strcmp)(e1s, e2s)) return True;
156 return False;
157 }
158
159 case UserErr:
160 case ParamErr:
161 if (e1_extra->isWrite != e2_extra->isWrite) return False;
162 if (VG_(get_error_kind)(e1) == ParamErr
163 && 0 != VG_(strcmp)(VG_(get_error_string)(e1),
164 VG_(get_error_string)(e2))) return False;
165 return True;
166
167 case FreeErr:
168 case FreeMismatchErr:
169 /* JRS 2002-Aug-26: comparing addrs seems overkill and can
170 cause excessive duplication of errors. Not even AddrErr
171 below does that. So don't compare either the .addr field
172 or the .addrinfo fields. */
173 /* if (e1->addr != e2->addr) return False; */
174 /* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
175 return False;
176 */
177 return True;
178
179 case AddrErr:
180 /* if (e1_extra->axskind != e2_extra->axskind) return False; */
181 if (e1_extra->size != e2_extra->size) return False;
182 /*
183 if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
184 return False;
185 */
186 return True;
187
188 case ValueErr:
189 if (e1_extra->size != e2_extra->size) return False;
190 return True;
191
njn34419c12003-05-02 17:24:29 +0000192 case OverlapErr:
193 return True;
194
njn43c799e2003-04-08 00:08:52 +0000195 case LeakErr:
196 VG_(skin_panic)("Shouldn't get LeakErr in SK_(eq_SkinError),\n"
197 "since it's handled with VG_(unique_error)()!");
198
njn5c004e42002-11-18 11:04:50 +0000199 default:
200 VG_(printf)("Error:\n unknown error code %d\n",
201 VG_(get_error_kind)(e1));
202 VG_(skin_panic)("unknown error code in SK_(eq_SkinError)");
203 }
204}
205
njn43c799e2003-04-08 00:08:52 +0000206void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai )
njn5c004e42002-11-18 11:04:50 +0000207{
208 switch (ai->akind) {
209 case Stack:
210 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000211 " Address 0x%x is on thread %d's stack",
njn5c004e42002-11-18 11:04:50 +0000212 a, ai->stack_tid);
213 break;
214 case Unknown:
215 if (ai->maybe_gcc) {
216 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000217 " Address 0x%x is just below %%esp. Possibly a bug in GCC/G++",
njn5c004e42002-11-18 11:04:50 +0000218 a);
219 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000220 " v 2.96 or 3.0.X. To suppress, use: --workaround-gcc296-bugs=yes");
njn5c004e42002-11-18 11:04:50 +0000221 } else {
222 VG_(message)(Vg_UserMsg,
nethercotef798eee2004-04-13 08:36:35 +0000223 " Address 0x%x is not stack'd, malloc'd or (recently) free'd",a);
njn5c004e42002-11-18 11:04:50 +0000224 }
225 break;
sewardja81709d2002-12-28 12:55:48 +0000226 case Freed: case Mallocd: case UserG: {
njn5c004e42002-11-18 11:04:50 +0000227 UInt delta;
228 UChar* relative;
229 if (ai->rwoffset < 0) {
230 delta = (UInt)(- ai->rwoffset);
231 relative = "before";
232 } else if (ai->rwoffset >= ai->blksize) {
233 delta = ai->rwoffset - ai->blksize;
234 relative = "after";
235 } else {
236 delta = ai->rwoffset;
237 relative = "inside";
238 }
sewardja81709d2002-12-28 12:55:48 +0000239 VG_(message)(Vg_UserMsg,
nethercote3b390c72003-11-13 17:53:43 +0000240 " Address 0x%x is %d bytes %s a block of size %d %s",
sewardja81709d2002-12-28 12:55:48 +0000241 a, delta, relative,
242 ai->blksize,
243 ai->akind==Mallocd ? "alloc'd"
244 : ai->akind==Freed ? "free'd"
245 : "client-defined");
njn5c004e42002-11-18 11:04:50 +0000246 VG_(pp_ExeContext)(ai->lastchange);
247 break;
248 }
249 default:
njn43c799e2003-04-08 00:08:52 +0000250 VG_(skin_panic)("MAC_(pp_AddrInfo)");
251 }
252}
253
254/* This prints out the message for the error types where Memcheck and
255 Addrcheck have identical messages */
256void MAC_(pp_shared_SkinError) ( Error* err )
257{
258 MAC_Error* err_extra = VG_(get_error_extra)(err);
259
260 switch (VG_(get_error_kind)(err)) {
261 case FreeErr:
njn10785452003-05-20 16:38:24 +0000262 VG_(message)(Vg_UserMsg, "Invalid free() / delete / delete[]");
njn43c799e2003-04-08 00:08:52 +0000263 /* fall through */
264 case FreeMismatchErr:
265 if (VG_(get_error_kind)(err) == FreeMismatchErr)
266 VG_(message)(Vg_UserMsg,
267 "Mismatched free() / delete / delete []");
268 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
269 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
270 break;
271
njn89409f82003-09-26 14:55:31 +0000272 case AddrErr:
273 switch (err_extra->axskind) {
274 case ReadAxs:
275 VG_(message)(Vg_UserMsg, "Invalid read of size %d",
276 err_extra->size );
277 break;
278 case WriteAxs:
279 VG_(message)(Vg_UserMsg, "Invalid write of size %d",
280 err_extra->size );
281 break;
282 case ExecAxs:
283 VG_(message)(Vg_UserMsg, "Jump to the invalid address "
284 "stated on the next line");
285 break;
286 default:
287 VG_(skin_panic)("SK_(pp_SkinError)(axskind)");
288 }
289 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
290 MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
291 break;
292
njnb6cae9f2003-09-04 20:50:47 +0000293 case OverlapErr: {
294 OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
295 if (ov_extra->len == -1)
296 VG_(message)(Vg_UserMsg,
297 "Source and destination overlap in %s(%p, %p)",
298 VG_(get_error_string)(err),
299 ov_extra->dst, ov_extra->src);
300 else
301 VG_(message)(Vg_UserMsg,
302 "Source and destination overlap in %s(%p, %p, %d)",
303 VG_(get_error_string)(err),
304 ov_extra->dst, ov_extra->src, ov_extra->len);
njn66fe05a2003-07-22 09:12:33 +0000305 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
306 break;
njnb6cae9f2003-09-04 20:50:47 +0000307 }
njn43c799e2003-04-08 00:08:52 +0000308 case LeakErr: {
309 /* Totally abusing the types of these spare fields... oh well. */
310 UInt n_this_record = (UInt)VG_(get_error_address)(err);
311 UInt n_total_records = (UInt)VG_(get_error_string) (err);
312
313 MAC_(pp_LeakError)(err_extra, n_this_record, n_total_records);
314 break;
315 }
316
317 default:
318 VG_(printf)("Error:\n unknown Memcheck/Addrcheck error code %d\n",
319 VG_(get_error_kind)(err));
320 VG_(skin_panic)("unknown error code in MAC_(pp_shared_SkinError)");
njn5c004e42002-11-18 11:04:50 +0000321 }
322}
323
324/*------------------------------------------------------------*/
325/*--- Recording errors ---*/
326/*------------------------------------------------------------*/
327
njn43c799e2003-04-08 00:08:52 +0000328/* Additional description function for describe_addr(); used by
329 MemCheck for user blocks, which Addrcheck doesn't support. */
330Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
331
njn43c799e2003-04-08 00:08:52 +0000332/* Describe an address as best you can, for error messages,
333 putting the result in ai. */
334static void describe_addr ( Addr a, AddrInfo* ai )
335{
njn3e884182003-04-15 13:03:23 +0000336 MAC_Chunk* sc;
337 ThreadId tid;
njn43c799e2003-04-08 00:08:52 +0000338
339 /* Nested functions, yeah. Need the lexical scoping of 'a'. */
njn3e884182003-04-15 13:03:23 +0000340
njn43c799e2003-04-08 00:08:52 +0000341 /* Closure for searching thread stacks */
342 Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
343 {
344 return (stack_min <= a && a <= stack_max);
345 }
njn3e884182003-04-15 13:03:23 +0000346 /* Closure for searching free'd list */
347 Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc)
njn43c799e2003-04-08 00:08:52 +0000348 {
njn3e884182003-04-15 13:03:23 +0000349 return VG_(addr_is_in_block)( a, mc->data, mc->size );
350 }
351 /* Closure for searching malloc'd lists */
352 Bool addr_is_in_HashNode(VgHashNode* sh_ch)
353 {
354 return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch );
njn43c799e2003-04-08 00:08:52 +0000355 }
356
357 /* Perhaps it's a user-def'd block ? (only check if requested, though) */
358 if (NULL != MAC_(describe_addr_supp)) {
359 if (MAC_(describe_addr_supp)( a, ai ))
360 return;
361 }
362 /* Perhaps it's on a thread's stack? */
363 tid = VG_(first_matching_thread_stack)(addr_is_in_bounds);
364 if (tid != VG_INVALID_THREADID) {
365 ai->akind = Stack;
366 ai->stack_tid = tid;
367 return;
368 }
369 /* Search for a recently freed block which might bracket it. */
njn3e884182003-04-15 13:03:23 +0000370 sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk);
371 if (NULL != sc) {
njn43c799e2003-04-08 00:08:52 +0000372 ai->akind = Freed;
njn3e884182003-04-15 13:03:23 +0000373 ai->blksize = sc->size;
374 ai->rwoffset = (Int)a - (Int)sc->data;
375 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000376 return;
377 }
378 /* Search for a currently malloc'd block which might bracket it. */
njn3e884182003-04-15 13:03:23 +0000379 sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode);
njn43c799e2003-04-08 00:08:52 +0000380 if (NULL != sc) {
381 ai->akind = Mallocd;
njn3e884182003-04-15 13:03:23 +0000382 ai->blksize = sc->size;
383 ai->rwoffset = (Int)(a) - (Int)sc->data;
384 ai->lastchange = sc->where;
njn43c799e2003-04-08 00:08:52 +0000385 return;
386 }
387 /* Clueless ... */
388 ai->akind = Unknown;
389 return;
390}
391
njn5c004e42002-11-18 11:04:50 +0000392/* Is this address within some small distance below %ESP? Used only
393 for the --workaround-gcc296-bugs kludge. */
394static Bool is_just_below_ESP( Addr esp, Addr aa )
395{
396 if ((UInt)esp > (UInt)aa
397 && ((UInt)esp - (UInt)aa) <= VG_GCC296_BUG_STACK_SLOP)
398 return True;
399 else
400 return False;
401}
402
sewardjaf48a602003-07-06 00:54:47 +0000403/* This one called from generated code and non-generated code. */
njn5c004e42002-11-18 11:04:50 +0000404
njn72718642003-07-24 08:45:32 +0000405void MAC_(record_address_error) ( ThreadId tid, Addr a, Int size,
sewardjaf48a602003-07-06 00:54:47 +0000406 Bool isWrite )
njn5c004e42002-11-18 11:04:50 +0000407{
njn43c799e2003-04-08 00:08:52 +0000408 MAC_Error err_extra;
409 Bool just_below_esp;
njn5c004e42002-11-18 11:04:50 +0000410
411 just_below_esp = is_just_below_ESP( VG_(get_stack_pointer)(), a );
412
413 /* If this is caused by an access immediately below %ESP, and the
414 user asks nicely, we just ignore it. */
njn43c799e2003-04-08 00:08:52 +0000415 if (MAC_(clo_workaround_gcc296_bugs) && just_below_esp)
njn5c004e42002-11-18 11:04:50 +0000416 return;
417
njn43c799e2003-04-08 00:08:52 +0000418 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000419 err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
420 err_extra.size = size;
421 err_extra.addrinfo.akind = Undescribed;
422 err_extra.addrinfo.maybe_gcc = just_below_esp;
njn72718642003-07-24 08:45:32 +0000423 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000424}
425
426/* These ones are called from non-generated code */
427
428/* This is for memory errors in pthread functions, as opposed to pthread API
429 errors which are found by the core. */
njn72718642003-07-24 08:45:32 +0000430void MAC_(record_core_mem_error) ( ThreadId tid, Bool isWrite, Char* msg )
njn5c004e42002-11-18 11:04:50 +0000431{
njn43c799e2003-04-08 00:08:52 +0000432 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000433
njn43c799e2003-04-08 00:08:52 +0000434 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000435 err_extra.isWrite = isWrite;
njn72718642003-07-24 08:45:32 +0000436 VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000437}
438
njn72718642003-07-24 08:45:32 +0000439void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isWrite,
njn5c004e42002-11-18 11:04:50 +0000440 Char* msg )
441{
njn43c799e2003-04-08 00:08:52 +0000442 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000443
njn72718642003-07-24 08:45:32 +0000444 sk_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000445 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000446 err_extra.addrinfo.akind = Undescribed;
447 err_extra.isWrite = isWrite;
njn72718642003-07-24 08:45:32 +0000448 VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000449}
450
njn72718642003-07-24 08:45:32 +0000451void MAC_(record_jump_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000452{
njn43c799e2003-04-08 00:08:52 +0000453 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000454
njn72718642003-07-24 08:45:32 +0000455 sk_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000456 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000457 err_extra.axskind = ExecAxs;
nethercote7250b8f2004-04-13 08:47:35 +0000458 err_extra.size = 1; // size only used for suppressions
njn5c004e42002-11-18 11:04:50 +0000459 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000460 VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000461}
462
njn72718642003-07-24 08:45:32 +0000463void MAC_(record_free_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000464{
njn43c799e2003-04-08 00:08:52 +0000465 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000466
njn72718642003-07-24 08:45:32 +0000467 sk_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000468 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000469 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000470 VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000471}
472
njn72718642003-07-24 08:45:32 +0000473void MAC_(record_freemismatch_error) ( ThreadId tid, Addr a )
njn5c004e42002-11-18 11:04:50 +0000474{
njn43c799e2003-04-08 00:08:52 +0000475 MAC_Error err_extra;
njn5c004e42002-11-18 11:04:50 +0000476
njn72718642003-07-24 08:45:32 +0000477 sk_assert(VG_INVALID_THREADID != tid);
njn43c799e2003-04-08 00:08:52 +0000478 MAC_(clear_MAC_Error)( &err_extra );
njn5c004e42002-11-18 11:04:50 +0000479 err_extra.addrinfo.akind = Undescribed;
njn72718642003-07-24 08:45:32 +0000480 VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
njn5c004e42002-11-18 11:04:50 +0000481}
482
njn66fe05a2003-07-22 09:12:33 +0000483
njn72718642003-07-24 08:45:32 +0000484// This one not passed a ThreadId, so it grabs it itself.
njnb6cae9f2003-09-04 20:50:47 +0000485void MAC_(record_overlap_error) ( Char* function, OverlapExtra* ov_extra )
njn66fe05a2003-07-22 09:12:33 +0000486{
njn72718642003-07-24 08:45:32 +0000487 VG_(maybe_record_error)( VG_(get_current_or_recent_tid)(),
njnb6cae9f2003-09-04 20:50:47 +0000488 OverlapErr, /*addr*/0, /*s*/function, ov_extra );
njn66fe05a2003-07-22 09:12:33 +0000489}
490
491
njnb6cae9f2003-09-04 20:50:47 +0000492/* Updates the copy with address info if necessary (but not for all errors). */
njn43c799e2003-04-08 00:08:52 +0000493UInt SK_(update_extra)( Error* err )
494{
njnb6cae9f2003-09-04 20:50:47 +0000495 switch (VG_(get_error_kind)(err)) {
496 case ValueErr:
497 case CoreMemErr:
498 case AddrErr:
499 case ParamErr:
500 case UserErr:
501 case FreeErr:
502 case FreeMismatchErr: {
503 MAC_Error* extra = (MAC_Error*)VG_(get_error_extra)(err);
504 if (extra != NULL && Undescribed == extra->addrinfo.akind) {
505 describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
506 }
507 return sizeof(MAC_Error);
508 }
njn43c799e2003-04-08 00:08:52 +0000509 /* Don't need to return the correct size -- LeakErrs are always shown with
510 VG_(unique_error)() so they're not copied anyway. */
njnb6cae9f2003-09-04 20:50:47 +0000511 case LeakErr: return 0;
512 case OverlapErr: return sizeof(OverlapExtra);
513 default: VG_(skin_panic)("update_extra: bad errkind");
njn43c799e2003-04-08 00:08:52 +0000514 }
njn43c799e2003-04-08 00:08:52 +0000515}
516
517
njn5c004e42002-11-18 11:04:50 +0000518/*------------------------------------------------------------*/
519/*--- Suppressions ---*/
520/*------------------------------------------------------------*/
521
njn43c799e2003-04-08 00:08:52 +0000522Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su )
523{
524 SuppKind skind;
525
526 if (VG_STREQ(name, "Param")) skind = ParamSupp;
527 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
528 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
529 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
530 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
531 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
njnc0616662003-06-12 09:58:41 +0000532 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
njn43c799e2003-04-08 00:08:52 +0000533 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
534 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
njne9cab142003-09-19 08:10:07 +0000535 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
njn43c799e2003-04-08 00:08:52 +0000536 else
537 return False;
538
539 VG_(set_supp_kind)(su, skind);
540 return True;
541}
542
njn5c004e42002-11-18 11:04:50 +0000543Bool SK_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su )
544{
545 Bool eof;
546
547 if (VG_(get_supp_kind)(su) == ParamSupp) {
548 eof = VG_(get_line) ( fd, buf, nBuf );
549 if (eof) return False;
550 VG_(set_supp_string)(su, VG_(strdup)(buf));
551 }
552 return True;
553}
554
sewardj99aac972002-12-26 01:53:45 +0000555Bool SK_(error_matches_suppression)(Error* err, Supp* su)
njn5c004e42002-11-18 11:04:50 +0000556{
sewardj05bcdcb2003-05-18 10:05:38 +0000557 Int su_size;
njn43c799e2003-04-08 00:08:52 +0000558 MAC_Error* err_extra = VG_(get_error_extra)(err);
559 ErrorKind ekind = VG_(get_error_kind )(err);
njn5c004e42002-11-18 11:04:50 +0000560
561 switch (VG_(get_supp_kind)(su)) {
562 case ParamSupp:
563 return (ekind == ParamErr
njn43c799e2003-04-08 00:08:52 +0000564 && VG_STREQ(VG_(get_error_string)(err),
565 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000566
567 case CoreMemSupp:
568 return (ekind == CoreMemErr
njn43c799e2003-04-08 00:08:52 +0000569 && VG_STREQ(VG_(get_error_string)(err),
570 VG_(get_supp_string)(su)));
njn5c004e42002-11-18 11:04:50 +0000571
572 case Value0Supp: su_size = 0; goto value_case;
573 case Value1Supp: su_size = 1; goto value_case;
574 case Value2Supp: su_size = 2; goto value_case;
575 case Value4Supp: su_size = 4; goto value_case;
576 case Value8Supp: su_size = 8; goto value_case;
njnc0616662003-06-12 09:58:41 +0000577 case Value16Supp:su_size =16; goto value_case;
njn5c004e42002-11-18 11:04:50 +0000578 value_case:
579 return (ekind == ValueErr && err_extra->size == su_size);
580
581 case Addr1Supp: su_size = 1; goto addr_case;
582 case Addr2Supp: su_size = 2; goto addr_case;
583 case Addr4Supp: su_size = 4; goto addr_case;
584 case Addr8Supp: su_size = 8; goto addr_case;
njnc0616662003-06-12 09:58:41 +0000585 case Addr16Supp:su_size =16; goto addr_case;
njn5c004e42002-11-18 11:04:50 +0000586 addr_case:
587 return (ekind == AddrErr && err_extra->size == su_size);
588
589 case FreeSupp:
590 return (ekind == FreeErr || ekind == FreeMismatchErr);
591
njn34419c12003-05-02 17:24:29 +0000592 case OverlapSupp:
593 return (ekind = OverlapErr);
594
sewardj4a19e2f2002-12-26 11:50:21 +0000595 case LeakSupp:
njn43c799e2003-04-08 00:08:52 +0000596 return (ekind == LeakErr);
sewardj4a19e2f2002-12-26 11:50:21 +0000597
njn5c004e42002-11-18 11:04:50 +0000598 default:
599 VG_(printf)("Error:\n"
600 " unknown suppression type %d\n",
601 VG_(get_supp_kind)(su));
602 VG_(skin_panic)("unknown suppression type in "
603 "SK_(error_matches_suppression)");
604 }
605}
606
njn43c799e2003-04-08 00:08:52 +0000607Char* SK_(get_error_name) ( Error* err )
608{
609 Char* s;
610 switch (VG_(get_error_kind)(err)) {
611 case ParamErr: return "Param";
612 case UserErr: return NULL; /* Can't suppress User errors */
613 case FreeMismatchErr: return "Free";
614 case FreeErr: return "Free";
615 case AddrErr:
616 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
617 case 1: return "Addr1";
618 case 2: return "Addr2";
619 case 4: return "Addr4";
620 case 8: return "Addr8";
njnc0616662003-06-12 09:58:41 +0000621 case 16: return "Addr16";
njn43c799e2003-04-08 00:08:52 +0000622 default: VG_(skin_panic)("unexpected size for Addr");
623 }
624
625 case ValueErr:
626 switch ( ((MAC_Error*)VG_(get_error_extra)(err))->size ) {
627 case 0: return "Cond";
628 case 1: return "Value1";
629 case 2: return "Value2";
630 case 4: return "Value4";
631 case 8: return "Value8";
njnc0616662003-06-12 09:58:41 +0000632 case 16: return "Value16";
njn43c799e2003-04-08 00:08:52 +0000633 default: VG_(skin_panic)("unexpected size for Value");
634 }
635 case CoreMemErr: return "CoreMem";
njn34419c12003-05-02 17:24:29 +0000636 case OverlapErr: return "Overlap";
njn43c799e2003-04-08 00:08:52 +0000637 case LeakErr: return "Leak";
638 default: VG_(skin_panic)("get_error_name: unexpected type");
639 }
640 VG_(printf)(s);
641}
642
643void SK_(print_extra_suppression_info) ( Error* err )
644{
645 if (ParamErr == VG_(get_error_kind)(err)) {
646 VG_(printf)(" %s\n", VG_(get_error_string)(err));
647 }
648}
njn5c004e42002-11-18 11:04:50 +0000649
650/*------------------------------------------------------------*/
651/*--- Crude profiling machinery. ---*/
652/*------------------------------------------------------------*/
653
654/* Event index. If just the name of the fn is given, this means the
655 number of calls to the fn. Otherwise it is the specified event.
656 Ones marked 'M' are MemCheck only. Ones marked 'A' are AddrCheck only.
657 The rest are shared.
658
659 10 alloc_secondary_map
660
661 20 get_abit
662M 21 get_vbyte
663 22 set_abit
664M 23 set_vbyte
665 24 get_abits4_ALIGNED
666M 25 get_vbytes4_ALIGNED
667
668 30 set_address_range_perms
669 31 set_address_range_perms(lower byte loop)
670 32 set_address_range_perms(quadword loop)
671 33 set_address_range_perms(upper byte loop)
672
673 35 make_noaccess
674 36 make_writable
675 37 make_readable
676A 38 make_accessible
677
678 40 copy_address_range_state
679 41 copy_address_range_state(byte loop)
680 42 check_writable
681 43 check_writable(byte loop)
682 44 check_readable
683 45 check_readable(byte loop)
684 46 check_readable_asciiz
685 47 check_readable_asciiz(byte loop)
686A 48 check_accessible
687A 49 check_accessible(byte loop)
688
689 50 make_noaccess_aligned
690 51 make_writable_aligned
691
692M 60 helperc_LOADV4
693M 61 helperc_STOREV4
694M 62 helperc_LOADV2
695M 63 helperc_STOREV2
696M 64 helperc_LOADV1
697M 65 helperc_STOREV1
698
699A 66 helperc_ACCESS4
700A 67 helperc_ACCESS2
701A 68 helperc_ACCESS1
702
703M 70 rim_rd_V4_SLOWLY
704M 71 rim_wr_V4_SLOWLY
705M 72 rim_rd_V2_SLOWLY
706M 73 rim_wr_V2_SLOWLY
707M 74 rim_rd_V1_SLOWLY
708M 75 rim_wr_V1_SLOWLY
709
710A 76 ACCESS4_SLOWLY
711A 77 ACCESS2_SLOWLY
712A 78 ACCESS1_SLOWLY
713
714 80 fpu_read
715 81 fpu_read aligned 4
716 82 fpu_read aligned 8
717 83 fpu_read 2
jsewardfca60182004-01-04 23:30:55 +0000718 84 fpu_read 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000719
720M 85 fpu_write
721M 86 fpu_write aligned 4
722M 87 fpu_write aligned 8
723M 88 fpu_write 2
jsewardfca60182004-01-04 23:30:55 +0000724M 89 fpu_write 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000725
726 90 fpu_access
727 91 fpu_access aligned 4
728 92 fpu_access aligned 8
729 93 fpu_access 2
jsewardfca60182004-01-04 23:30:55 +0000730 94 fpu_access 10/28/108/512
njn5c004e42002-11-18 11:04:50 +0000731
732 100 fpu_access_check_SLOWLY
733 101 fpu_access_check_SLOWLY(byte loop)
njn9b007f62003-04-07 14:40:25 +0000734
735 110 new_mem_stack_4
736 111 new_mem_stack_8
737 112 new_mem_stack_12
738 113 new_mem_stack_16
739 114 new_mem_stack_32
740 115 new_mem_stack
741
742 120 die_mem_stack_4
743 121 die_mem_stack_8
744 122 die_mem_stack_12
745 123 die_mem_stack_16
746 124 die_mem_stack_32
747 125 die_mem_stack
njn5c004e42002-11-18 11:04:50 +0000748*/
749
njn43c799e2003-04-08 00:08:52 +0000750#ifdef MAC_PROFILE_MEMORY
njn5c004e42002-11-18 11:04:50 +0000751
njn43c799e2003-04-08 00:08:52 +0000752UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn5c004e42002-11-18 11:04:50 +0000753
njnb4aee052003-04-15 14:09:58 +0000754static void init_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000755{
756 Int i;
757 for (i = 0; i < N_PROF_EVENTS; i++)
njn43c799e2003-04-08 00:08:52 +0000758 MAC_(event_ctr)[i] = 0;
njn5c004e42002-11-18 11:04:50 +0000759}
760
njnb4aee052003-04-15 14:09:58 +0000761static void done_prof_mem ( void )
njn5c004e42002-11-18 11:04:50 +0000762{
763 Int i;
764 for (i = 0; i < N_PROF_EVENTS; i++) {
765 if ((i % 10) == 0)
766 VG_(printf)("\n");
njn43c799e2003-04-08 00:08:52 +0000767 if (MAC_(event_ctr)[i] > 0)
768 VG_(printf)( "prof mem event %2d: %d\n", i, MAC_(event_ctr)[i] );
njn5c004e42002-11-18 11:04:50 +0000769 }
770 VG_(printf)("\n");
771}
772
773#else
774
njnb4aee052003-04-15 14:09:58 +0000775static void init_prof_mem ( void ) { }
776static void done_prof_mem ( void ) { }
njn5c004e42002-11-18 11:04:50 +0000777
njn5c004e42002-11-18 11:04:50 +0000778#endif
779
780/*------------------------------------------------------------*/
njn3e884182003-04-15 13:03:23 +0000781/*--- Common initialisation + finalisation ---*/
782/*------------------------------------------------------------*/
783
784void MAC_(common_pre_clo_init)(void)
785{
786 MAC_(malloc_list) = VG_(HT_construct)();
787 init_prof_mem();
788}
789
790void MAC_(common_fini)(void (*leak_check)(void))
791{
792 MAC_(print_malloc_stats)();
793
794 if (VG_(clo_verbosity) == 1) {
795 if (!MAC_(clo_leak_check))
796 VG_(message)(Vg_UserMsg,
797 "For a detailed leak analysis, rerun with: --leak-check=yes");
798
799 VG_(message)(Vg_UserMsg,
800 "For counts of detected errors, rerun with: -v");
801 }
802 if (MAC_(clo_leak_check)) leak_check();
803
804 done_prof_mem();
805}
806
807/*------------------------------------------------------------*/
njn47363ab2003-04-21 13:24:40 +0000808/*--- Common client request handling ---*/
809/*------------------------------------------------------------*/
810
njn72718642003-07-24 08:45:32 +0000811Bool MAC_(handle_common_client_requests)(ThreadId tid, UInt* arg, UInt* ret )
njn47363ab2003-04-21 13:24:40 +0000812{
njnd7994182003-10-02 13:44:04 +0000813 Char* err =
814 "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
815 " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
816 " program to incorporate the updates in the Valgrind header files.\n"
817 " You shouldn't need to change the text of your program at all.\n"
818 " Everything should then work as before. Sorry for the bother.\n";
njn72718642003-07-24 08:45:32 +0000819
820 // Not using 'tid' here because MAC_(new_block)() and MAC_(handle_free)()
821 // grab it themselves. But what they grab should match 'tid', check
822 // this.
823 sk_assert(tid == VG_(get_current_or_recent_tid)());
njn47363ab2003-04-21 13:24:40 +0000824
825 switch (arg[0]) {
njn10785452003-05-20 16:38:24 +0000826 case VG_USERREQ__COUNT_LEAKS: { /* count leaked bytes */
827 UInt** argp = (UInt**)arg;
njne8b5c052003-07-22 22:03:58 +0000828 // MAC_(bytes_leaked) et al were set by the last leak check (or zero
829 // if no prior leak checks performed).
830 *argp[1] = MAC_(bytes_leaked);
831 *argp[2] = MAC_(bytes_dubious);
832 *argp[3] = MAC_(bytes_reachable);
833 *argp[4] = MAC_(bytes_suppressed);
njn47363ab2003-04-21 13:24:40 +0000834 *ret = 0;
835 return True;
njn10785452003-05-20 16:38:24 +0000836 }
njnd7994182003-10-02 13:44:04 +0000837 case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
838 case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
839 VG_(skin_panic)(err);
840
njn10785452003-05-20 16:38:24 +0000841 case VG_USERREQ__MALLOCLIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000842 Addr p = (Addr)arg[1];
843 UInt sizeB = arg[2];
844 UInt rzB = arg[3];
845 Bool is_zeroed = (Bool)arg[4];
njn47363ab2003-04-21 13:24:40 +0000846
njn72718642003-07-24 08:45:32 +0000847 MAC_(new_block) ( p, sizeB, rzB, is_zeroed, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000848 return True;
849 }
850 case VG_USERREQ__FREELIKE_BLOCK: {
njnd7994182003-10-02 13:44:04 +0000851 Addr p = (Addr)arg[1];
852 UInt rzB = arg[2];
njn10785452003-05-20 16:38:24 +0000853
njn72718642003-07-24 08:45:32 +0000854 MAC_(handle_free) ( p, rzB, MAC_AllocCustom );
njn10785452003-05-20 16:38:24 +0000855 return True;
856 }
njnd7994182003-10-02 13:44:04 +0000857
nethercotee3a53722004-05-05 10:46:22 +0000858 case _VG_USERREQ__MEMCHECK_GET_RECORD_OVERLAP:
859 *ret = (Addr)MAC_(record_overlap_error);
860 return True;
861
njn47363ab2003-04-21 13:24:40 +0000862 default:
863 return False;
864 }
865}
866
867/*------------------------------------------------------------*/
njn5c004e42002-11-18 11:04:50 +0000868/*--- Syscall wrappers ---*/
869/*------------------------------------------------------------*/
870
871void* SK_(pre_syscall) ( ThreadId tid, UInt syscallno, Bool isBlocking )
872{
873 Int sane = SK_(cheap_sanity_check)();
874 return (void*)sane;
875}
876
877void SK_(post_syscall) ( ThreadId tid, UInt syscallno,
878 void* pre_result, Int res, Bool isBlocking )
879{
880 Int sane_before_call = (Int)pre_result;
881 Bool sane_after_call = SK_(cheap_sanity_check)();
882
883 if ((Int)sane_before_call && (!sane_after_call)) {
884 VG_(message)(Vg_DebugMsg, "post-syscall: ");
885 VG_(message)(Vg_DebugMsg,
886 "probable sanity check failure for syscall number %d\n",
887 syscallno );
888 VG_(skin_panic)("aborting due to the above ... bye!");
889 }
890}
891
njn5c004e42002-11-18 11:04:50 +0000892/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000893/*--- end mac_needs.c ---*/
njn5c004e42002-11-18 11:04:50 +0000894/*--------------------------------------------------------------------*/