1
2/*--------------------------------------------------------------------*/
3/*--- Management, printing, etc, of errors and suppressions.       ---*/
4/*---                                                  mc_errors.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8   This file is part of MemCheck, a heavyweight Valgrind tool for
9   detecting memory errors.
10
11   Copyright (C) 2000-2013 Julian Seward
12      jseward@acm.org
13
14   This program is free software; you can redistribute it and/or
15   modify it under the terms of the GNU General Public License as
16   published by the Free Software Foundation; either version 2 of the
17   License, or (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful, but
20   WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22   General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program; if not, write to the Free Software
26   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27   02111-1307, USA.
28
29   The GNU General Public License is contained in the file COPYING.
30*/
31
32#include "pub_tool_basics.h"
33#include "pub_tool_gdbserver.h"
34#include "pub_tool_poolalloc.h"     // For mc_include.h
35#include "pub_tool_hashtable.h"     // For mc_include.h
36#include "pub_tool_libcbase.h"
37#include "pub_tool_libcassert.h"
38#include "pub_tool_libcprint.h"
39#include "pub_tool_machine.h"
40#include "pub_tool_mallocfree.h"
41#include "pub_tool_options.h"
42#include "pub_tool_replacemalloc.h"
43#include "pub_tool_tooliface.h"
44#include "pub_tool_threadstate.h"
45#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
46#include "pub_tool_xarray.h"
47#include "pub_tool_aspacemgr.h"
48#include "pub_tool_addrinfo.h"
49
50#include "mc_include.h"
51
52
53/*------------------------------------------------------------*/
54/*--- Error types                                          ---*/
55/*------------------------------------------------------------*/
56
57/* See comment in mc_include.h */
58Bool MC_(any_value_errors) = False;
59
60
61/* ------------------ Errors ----------------------- */
62
63/* What kind of error it is. */
64typedef
65   enum {
66      Err_Value,
67      Err_Cond,
68      Err_CoreMem,
69      Err_Addr,
70      Err_Jump,
71      Err_RegParam,
72      Err_MemParam,
73      Err_User,
74      Err_Free,
75      Err_FreeMismatch,
76      Err_Overlap,
77      Err_Leak,
78      Err_IllegalMempool,
79      Err_FishyValue,
80   }
81   MC_ErrorTag;
82
83
84typedef struct _MC_Error MC_Error;
85
86struct _MC_Error {
87   // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
88   //MC_ErrorTag tag;
89
90   union {
91      // Use of an undefined value:
92      // - as a pointer in a load or store
93      // - as a jump target
94      struct {
95         SizeT szB;   // size of value in bytes
96         // Origin info
97         UInt        otag;      // origin tag
98         ExeContext* origin_ec; // filled in later
99      } Value;
100
101      // Use of an undefined value in a conditional branch or move.
102      struct {
103         // Origin info
104         UInt        otag;      // origin tag
105         ExeContext* origin_ec; // filled in later
106      } Cond;
107
108      // Addressability error in core (signal-handling) operation.
109      // It would be good to get rid of this error kind, merge it with
110      // another one somehow.
111      struct {
112      } CoreMem;
113
114      // Use of an unaddressable memory location in a load or store.
115      struct {
116         Bool     isWrite;    // read or write?
117         SizeT    szB;        // not used for exec (jump) errors
118         Bool     maybe_gcc;  // True if just below %esp -- could be a gcc bug
119         AddrInfo ai;
120      } Addr;
121
122      // Jump to an unaddressable memory location.
123      struct {
124         AddrInfo ai;
125      } Jump;
126
127      // System call register input contains undefined bytes.
128      struct {
129         // Origin info
130         UInt        otag;      // origin tag
131         ExeContext* origin_ec; // filled in later
132      } RegParam;
133
134      // System call memory input contains undefined/unaddressable bytes
135      struct {
136         Bool     isAddrErr;  // Addressability or definedness error?
137         AddrInfo ai;
138         // Origin info
139         UInt        otag;      // origin tag
140         ExeContext* origin_ec; // filled in later
141      } MemParam;
142
143      // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
144      struct {
145         Bool     isAddrErr;  // Addressability or definedness error?
146         AddrInfo ai;
147         // Origin info
148         UInt        otag;      // origin tag
149         ExeContext* origin_ec; // filled in later
150      } User;
151
152      // Program tried to free() something that's not a heap block (this
153      // covers double-frees). */
154      struct {
155         AddrInfo ai;
156      } Free;
157
158      // Program allocates heap block with one function
159      // (malloc/new/new[]/custom) and deallocates with not the matching one.
160      struct {
161         AddrInfo ai;
162      } FreeMismatch;
163
164      // Call to strcpy, memcpy, etc, with overlapping blocks.
165      struct {
166         Addr  src;   // Source block
167         Addr  dst;   // Destination block
168         SizeT szB;   // Size in bytes;  0 if unused.
169      } Overlap;
170
171      // A memory leak.
172      struct {
173         UInt        n_this_record;
174         UInt        n_total_records;
175         LossRecord* lr;
176      } Leak;
177
178      // A memory pool error.
179      struct {
180         AddrInfo ai;
181      } IllegalMempool;
182
183      // A fishy function argument value
184      // An argument value is considered fishy if the corresponding
185      // parameter has SizeT type and the value when interpreted as a
186      // signed number is negative.
187     struct {
188         const HChar *function_name;
189         const HChar *argument_name;
190         SizeT value;
191      } FishyValue;
192   } Err;
193};
194
195
196/*------------------------------------------------------------*/
197/*--- Printing errors                                      ---*/
198/*------------------------------------------------------------*/
199
200/* This is the "this error is due to be printed shortly; so have a
201   look at it any print any preamble you want" function.  Which, in
202   Memcheck, we don't use.  Hence a no-op.
203*/
204void MC_(before_pp_Error) ( const Error* err ) {
205}
206
207/* Do a printf-style operation on either the XML or normal output
208   channel, depending on the setting of VG_(clo_xml).
209*/
210static void emit_WRK ( const HChar* format, va_list vargs )
211{
212   if (VG_(clo_xml)) {
213      VG_(vprintf_xml)(format, vargs);
214   } else {
215      VG_(vmessage)(Vg_UserMsg, format, vargs);
216   }
217}
218static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2);
219static void emit ( const HChar* format, ... )
220{
221   va_list vargs;
222   va_start(vargs, format);
223   emit_WRK(format, vargs);
224   va_end(vargs);
225}
226
227
228static const HChar* str_leak_lossmode ( Reachedness lossmode )
229{
230   const HChar *loss = "?";
231   switch (lossmode) {
232      case Unreached:    loss = "definitely lost"; break;
233      case IndirectLeak: loss = "indirectly lost"; break;
234      case Possible:     loss = "possibly lost"; break;
235      case Reachable:    loss = "still reachable"; break;
236   }
237   return loss;
238}
239
240static const HChar* xml_leak_kind ( Reachedness lossmode )
241{
242   const HChar *loss = "?";
243   switch (lossmode) {
244      case Unreached:    loss = "Leak_DefinitelyLost"; break;
245      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
246      case Possible:     loss = "Leak_PossiblyLost"; break;
247      case Reachable:    loss = "Leak_StillReachable"; break;
248   }
249   return loss;
250}
251
252const HChar* MC_(parse_leak_kinds_tokens) =
253   "reachable,possible,indirect,definite";
254
255UInt MC_(all_Reachedness)(void)
256{
257   static UInt all;
258
259   if (all == 0) {
260      // Compute a set with all values by doing a parsing of the "all" keyword.
261      Bool parseok = VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
262                                         True,/*allow_all*/
263                                         "all",
264                                         &all);
265      tl_assert (parseok && all);
266   }
267
268   return all;
269}
270
271static const HChar* pp_Reachedness_for_leak_kinds(Reachedness r)
272{
273   switch(r) {
274   case Reachable:    return "reachable";
275   case Possible:     return "possible";
276   case IndirectLeak: return "indirect";
277   case Unreached:    return "definite";
278   default:           tl_assert(0);
279   }
280}
281
282static void mc_pp_origin ( ExeContext* ec, UInt okind )
283{
284   const HChar* src = NULL;
285   tl_assert(ec);
286
287   switch (okind) {
288      case MC_OKIND_STACK:   src = " by a stack allocation"; break;
289      case MC_OKIND_HEAP:    src = " by a heap allocation"; break;
290      case MC_OKIND_USER:    src = " by a client request"; break;
291      case MC_OKIND_UNKNOWN: src = ""; break;
292   }
293   tl_assert(src); /* guards against invalid 'okind' */
294
295   if (VG_(clo_xml)) {
296      emit( "  <auxwhat>Uninitialised value was created%s</auxwhat>\n",
297            src);
298      VG_(pp_ExeContext)( ec );
299   } else {
300      emit( " Uninitialised value was created%s\n", src);
301      VG_(pp_ExeContext)( ec );
302   }
303}
304
305HChar * MC_(snprintf_delta) (HChar * buf, Int size,
306                             SizeT current_val, SizeT old_val,
307                             LeakCheckDeltaMode delta_mode)
308{
309   // Make sure the buffer size is large enough. With old_val == 0 and
310   // current_val == ULLONG_MAX the delta including inserted commas is:
311   // 18,446,744,073,709,551,615
312   // whose length is 26. Therefore:
313   tl_assert(size >= 26 + 4 + 1);
314
315   if (delta_mode == LCD_Any)
316      buf[0] = '\0';
317   else if (current_val >= old_val)
318      VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val);
319   else
320      VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val);
321
322   return buf;
323}
324
325static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
326                          LossRecord* lr, Bool xml)
327{
328   // char arrays to produce the indication of increase/decrease in case
329   // of delta_mode != LCD_Any
330   HChar d_bytes[31];
331   HChar d_direct_bytes[31];
332   HChar d_indirect_bytes[31];
333   HChar d_num_blocks[31];
334
335   MC_(snprintf_delta) (d_bytes, sizeof(d_bytes),
336                        lr->szB + lr->indirect_szB,
337                        lr->old_szB + lr->old_indirect_szB,
338                        MC_(detect_memory_leaks_last_delta_mode));
339   MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes),
340                        lr->szB,
341                        lr->old_szB,
342                        MC_(detect_memory_leaks_last_delta_mode));
343   MC_(snprintf_delta) (d_indirect_bytes, sizeof(d_indirect_bytes),
344                        lr->indirect_szB,
345                        lr->old_indirect_szB,
346                        MC_(detect_memory_leaks_last_delta_mode));
347   MC_(snprintf_delta) (d_num_blocks, sizeof(d_num_blocks),
348                        (SizeT) lr->num_blocks,
349                        (SizeT) lr->old_num_blocks,
350                        MC_(detect_memory_leaks_last_delta_mode));
351
352   if (xml) {
353      emit("  <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
354      if (lr->indirect_szB > 0) {
355         emit( "  <xwhat>\n" );
356         emit( "    <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
357               "in %'u%s blocks"
358               " are %s in loss record %'u of %'u</text>\n",
359               lr->szB + lr->indirect_szB, d_bytes,
360               lr->szB, d_direct_bytes,
361               lr->indirect_szB, d_indirect_bytes,
362               lr->num_blocks, d_num_blocks,
363               str_leak_lossmode(lr->key.state),
364               n_this_record, n_total_records );
365         // Nb: don't put commas in these XML numbers
366         emit( "    <leakedbytes>%lu</leakedbytes>\n",
367               lr->szB + lr->indirect_szB );
368         emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
369         emit( "  </xwhat>\n" );
370      } else {
371         emit( "  <xwhat>\n" );
372         emit( "    <text>%'lu%s bytes in %'u%s blocks"
373               " are %s in loss record %'u of %'u</text>\n",
374               lr->szB, d_direct_bytes,
375               lr->num_blocks, d_num_blocks,
376               str_leak_lossmode(lr->key.state),
377               n_this_record, n_total_records );
378         emit( "    <leakedbytes>%ld</leakedbytes>\n", lr->szB);
379         emit( "    <leakedblocks>%d</leakedblocks>\n", lr->num_blocks);
380         emit( "  </xwhat>\n" );
381      }
382      VG_(pp_ExeContext)(lr->key.allocated_at);
383   } else { /* ! if (xml) */
384      if (lr->indirect_szB > 0) {
385         emit(
386            "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
387            " are %s in loss record %'u of %'u\n",
388            lr->szB + lr->indirect_szB, d_bytes,
389            lr->szB, d_direct_bytes,
390            lr->indirect_szB, d_indirect_bytes,
391            lr->num_blocks, d_num_blocks,
392            str_leak_lossmode(lr->key.state),
393            n_this_record, n_total_records
394         );
395      } else {
396         emit(
397            "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
398            lr->szB, d_direct_bytes,
399            lr->num_blocks, d_num_blocks,
400            str_leak_lossmode(lr->key.state),
401            n_this_record, n_total_records
402         );
403      }
404      VG_(pp_ExeContext)(lr->key.allocated_at);
405   } /* if (xml) */
406}
407
408void MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records,
409                        LossRecord* l)
410{
411   pp_LossRecord (n_this_record, n_total_records, l, /* xml */ False);
412}
413
414void MC_(pp_Error) ( const Error* err )
415{
416   const Bool xml  = VG_(clo_xml); /* a shorthand */
417   MC_Error* extra = VG_(get_error_extra)(err);
418
419   switch (VG_(get_error_kind)(err)) {
420      case Err_CoreMem:
421         /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
422         /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
423            signal handler frame.  --njn */
424         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
425         // the following code is untested.  Bad.
426         if (xml) {
427            emit( "  <kind>CoreMemError</kind>\n" );
428            emit( "  <what>%pS contains unaddressable byte(s)</what>\n",
429                  VG_(get_error_string)(err));
430            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
431         } else {
432            emit( "%s contains unaddressable byte(s)\n",
433                  VG_(get_error_string)(err));
434            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
435         }
436         break;
437
438      case Err_Value:
439         MC_(any_value_errors) = True;
440         if (xml) {
441            emit( "  <kind>UninitValue</kind>\n" );
442            emit( "  <what>Use of uninitialised value of size %ld</what>\n",
443                  extra->Err.Value.szB );
444            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
445            if (extra->Err.Value.origin_ec)
446               mc_pp_origin( extra->Err.Value.origin_ec,
447                            extra->Err.Value.otag & 3 );
448         } else {
449            /* Could also show extra->Err.Cond.otag if debugging origin
450               tracking */
451            emit( "Use of uninitialised value of size %ld\n",
452                  extra->Err.Value.szB );
453            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
454            if (extra->Err.Value.origin_ec)
455               mc_pp_origin( extra->Err.Value.origin_ec,
456                            extra->Err.Value.otag & 3 );
457         }
458         break;
459
460      case Err_Cond:
461         MC_(any_value_errors) = True;
462         if (xml) {
463            emit( "  <kind>UninitCondition</kind>\n" );
464            emit( "  <what>Conditional jump or move depends"
465                  " on uninitialised value(s)</what>\n" );
466            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
467            if (extra->Err.Cond.origin_ec)
468               mc_pp_origin( extra->Err.Cond.origin_ec,
469                             extra->Err.Cond.otag & 3 );
470         } else {
471            /* Could also show extra->Err.Cond.otag if debugging origin
472               tracking */
473            emit( "Conditional jump or move depends"
474                  " on uninitialised value(s)\n" );
475            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
476            if (extra->Err.Cond.origin_ec)
477               mc_pp_origin( extra->Err.Cond.origin_ec,
478                             extra->Err.Cond.otag & 3 );
479         }
480         break;
481
482      case Err_RegParam:
483         MC_(any_value_errors) = True;
484         if (xml) {
485            emit( "  <kind>SyscallParam</kind>\n" );
486            emit( "  <what>Syscall param %pS contains "
487                  "uninitialised byte(s)</what>\n",
488                  VG_(get_error_string)(err) );
489            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
490            if (extra->Err.RegParam.origin_ec)
491               mc_pp_origin( extra->Err.RegParam.origin_ec,
492                             extra->Err.RegParam.otag & 3 );
493         } else {
494            emit( "Syscall param %s contains uninitialised byte(s)\n",
495                  VG_(get_error_string)(err) );
496            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
497            if (extra->Err.RegParam.origin_ec)
498               mc_pp_origin( extra->Err.RegParam.origin_ec,
499                             extra->Err.RegParam.otag & 3 );
500         }
501         break;
502
503      case Err_MemParam:
504         if (!extra->Err.MemParam.isAddrErr)
505            MC_(any_value_errors) = True;
506         if (xml) {
507            emit( "  <kind>SyscallParam</kind>\n" );
508            emit( "  <what>Syscall param %pS points to %s byte(s)</what>\n",
509                  VG_(get_error_string)(err),
510                  extra->Err.MemParam.isAddrErr
511                     ? "unaddressable" : "uninitialised" );
512            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
513            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
514                                &extra->Err.MemParam.ai, False);
515            if (extra->Err.MemParam.origin_ec
516                && !extra->Err.MemParam.isAddrErr)
517               mc_pp_origin( extra->Err.MemParam.origin_ec,
518                             extra->Err.MemParam.otag & 3 );
519         } else {
520            emit( "Syscall param %s points to %s byte(s)\n",
521                  VG_(get_error_string)(err),
522                  extra->Err.MemParam.isAddrErr
523                     ? "unaddressable" : "uninitialised" );
524            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
525            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
526                                &extra->Err.MemParam.ai, False);
527            if (extra->Err.MemParam.origin_ec
528                && !extra->Err.MemParam.isAddrErr)
529               mc_pp_origin( extra->Err.MemParam.origin_ec,
530                             extra->Err.MemParam.otag & 3 );
531         }
532         break;
533
534      case Err_User:
535         if (!extra->Err.User.isAddrErr)
536            MC_(any_value_errors) = True;
537         if (xml) {
538            emit( "  <kind>ClientCheck</kind>\n" );
539            emit( "  <what>%s byte(s) found "
540                  "during client check request</what>\n",
541                   extra->Err.User.isAddrErr
542                      ? "Unaddressable" : "Uninitialised" );
543            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
544            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
545                                False);
546            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
547               mc_pp_origin( extra->Err.User.origin_ec,
548                             extra->Err.User.otag & 3 );
549         } else {
550            emit( "%s byte(s) found during client check request\n",
551                   extra->Err.User.isAddrErr
552                      ? "Unaddressable" : "Uninitialised" );
553            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
554            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
555                                False);
556            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
557               mc_pp_origin( extra->Err.User.origin_ec,
558                             extra->Err.User.otag & 3 );
559         }
560         break;
561
562      case Err_Free:
563         if (xml) {
564            emit( "  <kind>InvalidFree</kind>\n" );
565            emit( "  <what>Invalid free() / delete / delete[]"
566                  " / realloc()</what>\n" );
567            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
568            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
569                                 &extra->Err.Free.ai, False );
570         } else {
571            emit( "Invalid free() / delete / delete[] / realloc()\n" );
572            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
573            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
574                                 &extra->Err.Free.ai, False );
575         }
576         break;
577
578      case Err_FreeMismatch:
579         if (xml) {
580            emit( "  <kind>MismatchedFree</kind>\n" );
581            emit( "  <what>Mismatched free() / delete / delete []</what>\n" );
582            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
583            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
584                                &extra->Err.FreeMismatch.ai, False);
585         } else {
586            emit( "Mismatched free() / delete / delete []\n" );
587            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
588            VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
589                                &extra->Err.FreeMismatch.ai, False);
590         }
591         break;
592
593      case Err_Addr:
594         if (xml) {
595            emit( "  <kind>Invalid%s</kind>\n",
596                  extra->Err.Addr.isWrite ? "Write" : "Read"  );
597            emit( "  <what>Invalid %s of size %ld</what>\n",
598                  extra->Err.Addr.isWrite ? "write" : "read",
599                  extra->Err.Addr.szB );
600            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
601            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
602                                 &extra->Err.Addr.ai,
603                                 extra->Err.Addr.maybe_gcc );
604         } else {
605            emit( "Invalid %s of size %ld\n",
606                  extra->Err.Addr.isWrite ? "write" : "read",
607                  extra->Err.Addr.szB );
608            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
609
610            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
611                                 &extra->Err.Addr.ai,
612                                 extra->Err.Addr.maybe_gcc );
613         }
614         break;
615
616      case Err_Jump:
617         if (xml) {
618            emit( "  <kind>InvalidJump</kind>\n" );
619            emit( "  <what>Jump to the invalid address stated "
620                  "on the next line</what>\n" );
621            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
622            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
623                                 False );
624         } else {
625            emit( "Jump to the invalid address stated on the next line\n" );
626            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
627            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
628                                 False );
629         }
630         break;
631
632      case Err_Overlap:
633         if (xml) {
634            emit( "  <kind>Overlap</kind>\n" );
635            if (extra->Err.Overlap.szB == 0) {
636               emit( "  <what>Source and destination overlap "
637                     "in %pS(%#lx, %#lx)\n</what>\n",
638                     VG_(get_error_string)(err),
639                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
640            } else {
641               emit( "  <what>Source and destination overlap "
642                     "in %pS(%#lx, %#lx, %lu)</what>\n",
643                     VG_(get_error_string)(err),
644                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
645                     extra->Err.Overlap.szB );
646            }
647            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
648         } else {
649            if (extra->Err.Overlap.szB == 0) {
650               emit( "Source and destination overlap in %s(%#lx, %#lx)\n",
651                     VG_(get_error_string)(err),
652                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
653            } else {
654               emit( "Source and destination overlap in %s(%#lx, %#lx, %lu)\n",
655                     VG_(get_error_string)(err),
656                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
657                     extra->Err.Overlap.szB );
658            }
659            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
660         }
661         break;
662
663      case Err_IllegalMempool:
664         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
665         // the following code is untested.  Bad.
666         if (xml) {
667            emit( "  <kind>InvalidMemPool</kind>\n" );
668            emit( "  <what>Illegal memory pool address</what>\n" );
669            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
670            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
671                                 &extra->Err.IllegalMempool.ai, False );
672         } else {
673            emit( "Illegal memory pool address\n" );
674            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
675            VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
676                                 &extra->Err.IllegalMempool.ai, False );
677         }
678         break;
679
680      case Err_Leak: {
681         UInt        n_this_record   = extra->Err.Leak.n_this_record;
682         UInt        n_total_records = extra->Err.Leak.n_total_records;
683         LossRecord* lr              = extra->Err.Leak.lr;
684         pp_LossRecord (n_this_record, n_total_records, lr, xml);
685         break;
686      }
687
688      case Err_FishyValue:
689         if (xml) {
690            emit( "  <kind>FishyValue</kind>\n" );
691            emit( "  <what>");
692            emit( "Argument '%s' of function %s has a fishy "
693                  "(possibly negative) value: %ld\n",
694                  extra->Err.FishyValue.argument_name,
695                  extra->Err.FishyValue.function_name,
696                  (SSizeT)extra->Err.FishyValue.value);
697            emit( "</what>");
698            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
699         } else {
700            emit( "Argument '%s' of function %s has a fishy "
701                  "(possibly negative) value: %ld\n",
702                  extra->Err.FishyValue.argument_name,
703                  extra->Err.FishyValue.function_name,
704                  (SSizeT)extra->Err.FishyValue.value);
705            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
706         }
707         break;
708
709      default:
710         VG_(printf)("Error:\n  unknown Memcheck error code %d\n",
711                     VG_(get_error_kind)(err));
712         VG_(tool_panic)("unknown error code in mc_pp_Error)");
713   }
714}
715
716/*------------------------------------------------------------*/
717/*--- Recording errors                                     ---*/
718/*------------------------------------------------------------*/
719
720/* These many bytes below %ESP are considered addressible if we're
721   doing the --workaround-gcc296-bugs hack. */
722#define VG_GCC296_BUG_STACK_SLOP 1024
723
724/* Is this address within some small distance below %ESP?  Used only
725   for the --workaround-gcc296-bugs kludge. */
726static Bool is_just_below_ESP( Addr esp, Addr aa )
727{
728   esp -= VG_STACK_REDZONE_SZB;
729   if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
730      return True;
731   else
732      return False;
733}
734
735/* --- Called from generated and non-generated code --- */
736
737void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
738                                 Bool isWrite )
739{
740   MC_Error extra;
741   Bool     just_below_esp;
742
743   if (MC_(in_ignored_range)(a))
744      return;
745
746   if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB))
747      return;
748
749   just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
750
751   /* If this is caused by an access immediately below %ESP, and the
752      user asks nicely, we just ignore it. */
753   if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
754      return;
755
756   extra.Err.Addr.isWrite   = isWrite;
757   extra.Err.Addr.szB       = szB;
758   extra.Err.Addr.maybe_gcc = just_below_esp;
759   extra.Err.Addr.ai.tag    = Addr_Undescribed;
760   VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
761}
762
763void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
764{
765   MC_Error extra;
766   tl_assert( MC_(clo_mc_level) >= 2 );
767   if (otag > 0)
768      tl_assert( MC_(clo_mc_level) == 3 );
769   extra.Err.Value.szB       = szB;
770   extra.Err.Value.otag      = otag;
771   extra.Err.Value.origin_ec = NULL;  /* Filled in later */
772   VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
773}
774
775void MC_(record_cond_error) ( ThreadId tid, UInt otag )
776{
777   MC_Error extra;
778   tl_assert( MC_(clo_mc_level) >= 2 );
779   if (otag > 0)
780      tl_assert( MC_(clo_mc_level) == 3 );
781   extra.Err.Cond.otag      = otag;
782   extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
783   VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
784}
785
786/* --- Called from non-generated code --- */
787
788/* This is for memory errors in signal-related memory. */
789void MC_(record_core_mem_error) ( ThreadId tid, const HChar* msg )
790{
791   VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
792}
793
794void MC_(record_regparam_error) ( ThreadId tid, const HChar* msg, UInt otag )
795{
796   MC_Error extra;
797   tl_assert(VG_INVALID_THREADID != tid);
798   if (otag > 0)
799      tl_assert( MC_(clo_mc_level) == 3 );
800   extra.Err.RegParam.otag      = otag;
801   extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
802   VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
803}
804
805void MC_(record_memparam_error) ( ThreadId tid, Addr a,
806                                  Bool isAddrErr, const HChar* msg, UInt otag )
807{
808   MC_Error extra;
809   tl_assert(VG_INVALID_THREADID != tid);
810   if (!isAddrErr)
811      tl_assert( MC_(clo_mc_level) >= 2 );
812   if (otag != 0) {
813      tl_assert( MC_(clo_mc_level) == 3 );
814      tl_assert( !isAddrErr );
815   }
816   extra.Err.MemParam.isAddrErr = isAddrErr;
817   extra.Err.MemParam.ai.tag    = Addr_Undescribed;
818   extra.Err.MemParam.otag      = otag;
819   extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
820   VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
821}
822
823void MC_(record_jump_error) ( ThreadId tid, Addr a )
824{
825   MC_Error extra;
826   tl_assert(VG_INVALID_THREADID != tid);
827   extra.Err.Jump.ai.tag = Addr_Undescribed;
828   VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
829}
830
831void MC_(record_free_error) ( ThreadId tid, Addr a )
832{
833   MC_Error extra;
834   tl_assert(VG_INVALID_THREADID != tid);
835   extra.Err.Free.ai.tag = Addr_Undescribed;
836   VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
837}
838
839void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
840{
841   MC_Error extra;
842   AddrInfo* ai = &extra.Err.FreeMismatch.ai;
843   tl_assert(VG_INVALID_THREADID != tid);
844   ai->tag = Addr_Block;
845   ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
846   ai->Addr.Block.block_desc = "block";
847   ai->Addr.Block.block_szB  = mc->szB;
848   ai->Addr.Block.rwoffset   = 0;
849   ai->Addr.Block.allocated_at = MC_(allocated_at) (mc);
850   VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
851   ai->Addr.Block.freed_at = MC_(freed_at) (mc);
852   VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
853                            &extra );
854}
855
856void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
857{
858   MC_Error extra;
859   tl_assert(VG_INVALID_THREADID != tid);
860   extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
861   VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
862}
863
864void MC_(record_overlap_error) ( ThreadId tid, const HChar* function,
865                                 Addr src, Addr dst, SizeT szB )
866{
867   MC_Error extra;
868   tl_assert(VG_INVALID_THREADID != tid);
869   extra.Err.Overlap.src = src;
870   extra.Err.Overlap.dst = dst;
871   extra.Err.Overlap.szB = szB;
872   VG_(maybe_record_error)(
873      tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
874}
875
876Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
877                              UInt n_total_records, LossRecord* lr,
878                              Bool print_record, Bool count_error )
879{
880   MC_Error extra;
881   extra.Err.Leak.n_this_record   = n_this_record;
882   extra.Err.Leak.n_total_records = n_total_records;
883   extra.Err.Leak.lr              = lr;
884   return
885   VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
886                       lr->key.allocated_at, print_record,
887                       /*allow_GDB_attach*/False, count_error );
888}
889
890Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name,
891                                     const HChar *argument_name, SizeT value)
892{
893   MC_Error extra;
894
895   tl_assert(VG_INVALID_THREADID != tid);
896
897   if ((SSizeT)value >= 0) return False;  // not a fishy value
898
899   extra.Err.FishyValue.function_name = function_name;
900   extra.Err.FishyValue.argument_name = argument_name;
901   extra.Err.FishyValue.value = value;
902
903   VG_(maybe_record_error)(
904      tid, Err_FishyValue, /*addr*/0, /*s*/NULL, &extra );
905
906   return True;
907}
908
909void MC_(record_user_error) ( ThreadId tid, Addr a,
910                              Bool isAddrErr, UInt otag )
911{
912   MC_Error extra;
913   if (otag != 0) {
914      tl_assert(!isAddrErr);
915      tl_assert( MC_(clo_mc_level) == 3 );
916   }
917   if (!isAddrErr) {
918      tl_assert( MC_(clo_mc_level) >= 2 );
919   }
920   tl_assert(VG_INVALID_THREADID != tid);
921   extra.Err.User.isAddrErr = isAddrErr;
922   extra.Err.User.ai.tag    = Addr_Undescribed;
923   extra.Err.User.otag      = otag;
924   extra.Err.User.origin_ec = NULL;  /* Filled in later */
925   VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
926}
927
928/*------------------------------------------------------------*/
929/*--- Other error operations                               ---*/
930/*------------------------------------------------------------*/
931
932/* Compare error contexts, to detect duplicates.  Note that if they
933   are otherwise the same, the faulting addrs and associated rwoffsets
934   are allowed to be different.  */
935Bool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 )
936{
937   MC_Error* extra1 = VG_(get_error_extra)(e1);
938   MC_Error* extra2 = VG_(get_error_extra)(e2);
939
940   /* Guaranteed by calling function */
941   tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
942
943   switch (VG_(get_error_kind)(e1)) {
944      case Err_CoreMem: {
945         const HChar *e1s, *e2s;
946         e1s = VG_(get_error_string)(e1);
947         e2s = VG_(get_error_string)(e2);
948         if (e1s == e2s)                   return True;
949         if (VG_STREQ(e1s, e2s))           return True;
950         return False;
951      }
952
953      case Err_RegParam:
954         return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
955
956      // Perhaps we should also check the addrinfo.akinds for equality.
957      // That would result in more error reports, but only in cases where
958      // a register contains uninitialised bytes and points to memory
959      // containing uninitialised bytes.  Currently, the 2nd of those to be
960      // detected won't be reported.  That is (nearly?) always the memory
961      // error, which is good.
962      case Err_MemParam:
963         if (!VG_STREQ(VG_(get_error_string)(e1),
964                       VG_(get_error_string)(e2))) return False;
965         // fall through
966      case Err_User:
967         return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
968                ? True : False );
969
970      case Err_Free:
971      case Err_FreeMismatch:
972      case Err_Jump:
973      case Err_IllegalMempool:
974      case Err_Overlap:
975      case Err_Cond:
976         return True;
977
978      case Err_FishyValue:
979         return VG_STREQ(extra1->Err.FishyValue.function_name,
980                         extra2->Err.FishyValue.function_name) &&
981                VG_STREQ(extra1->Err.FishyValue.argument_name,
982                         extra2->Err.FishyValue.argument_name);
983
984      case Err_Addr:
985         return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
986                ? True : False );
987
988      case Err_Value:
989         return ( extra1->Err.Value.szB == extra2->Err.Value.szB
990                ? True : False );
991
992      case Err_Leak:
993         VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
994                         "since it's handled with VG_(unique_error)()!");
995
996      default:
997         VG_(printf)("Error:\n  unknown error code %d\n",
998                     VG_(get_error_kind)(e1));
999         VG_(tool_panic)("unknown error code in mc_eq_Error");
1000   }
1001}
1002
1003/* Functions used when searching MC_Chunk lists */
1004static
1005Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
1006{
1007   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1008                                 MC_(Malloc_Redzone_SzB) );
1009}
1010static
1011Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
1012{
1013   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1014                                 rzB );
1015}
1016
1017// Forward declarations
1018static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
1019static Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
1020
1021
1022/* Describe an address as best you can, for error messages,
1023   putting the result in ai. */
1024static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
1025{
1026   MC_Chunk*  mc;
1027
1028   tl_assert(Addr_Undescribed == ai->tag);
1029
1030   /* -- Perhaps it's a user-named block? -- */
1031   if (client_block_maybe_describe( a, ai )) {
1032      return;
1033   }
1034   /* -- Perhaps it's in mempool block? -- */
1035   if (mempool_block_maybe_describe( a, ai )) {
1036      return;
1037   }
1038   /* Blocks allocated by memcheck malloc functions are either
1039      on the recently freed list or on the malloc-ed list.
1040      Custom blocks can be on both : a recently freed block might
1041      have been just re-allocated.
1042      So, first search the malloc-ed block, as the most recent
1043      block is the probable cause of error.
1044      We however detect and report that this is a recently re-allocated
1045      block. */
1046   /* -- Search for a currently malloc'd block which might bracket it. -- */
1047   VG_(HT_ResetIter)(MC_(malloc_list));
1048   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
1049      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
1050         ai->tag = Addr_Block;
1051         ai->Addr.Block.block_kind = Block_Mallocd;
1052         if (MC_(get_freed_block_bracketting)( a ))
1053            ai->Addr.Block.block_desc = "recently re-allocated block";
1054         else
1055            ai->Addr.Block.block_desc = "block";
1056         ai->Addr.Block.block_szB  = mc->szB;
1057         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1058         ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
1059         VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
1060         ai->Addr.Block.freed_at = MC_(freed_at)(mc);
1061         return;
1062      }
1063   }
1064   /* -- Search for a recently freed block which might bracket it. -- */
1065   mc = MC_(get_freed_block_bracketting)( a );
1066   if (mc) {
1067      ai->tag = Addr_Block;
1068      ai->Addr.Block.block_kind = Block_Freed;
1069      ai->Addr.Block.block_desc = "block";
1070      ai->Addr.Block.block_szB  = mc->szB;
1071      ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1072      ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
1073      VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
1074      ai->Addr.Block.freed_at = MC_(freed_at)(mc);
1075      return;
1076   }
1077
1078   /* No block found. Search a non-heap block description. */
1079   VG_(describe_addr) (a, ai);
1080}
1081
1082void MC_(pp_describe_addr) ( Addr a )
1083{
1084   AddrInfo ai;
1085
1086   ai.tag = Addr_Undescribed;
1087   describe_addr (a, &ai);
1088   VG_(pp_addrinfo_mc) (a, &ai, /* maybe_gcc */ False);
1089   VG_(clear_addrinfo) (&ai);
1090}
1091
1092/* Fill in *origin_ec as specified by otag, or NULL it out if otag
1093   does not refer to a known origin. */
1094static void update_origin ( /*OUT*/ExeContext** origin_ec,
1095                            UInt otag )
1096{
1097   UInt ecu = otag & ~3;
1098   *origin_ec = NULL;
1099   if (VG_(is_plausible_ECU)(ecu)) {
1100      *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
1101   }
1102}
1103
1104/* Updates the copy with address info if necessary (but not for all errors). */
1105UInt MC_(update_Error_extra)( const Error* err )
1106{
1107   MC_Error* extra = VG_(get_error_extra)(err);
1108
1109   switch (VG_(get_error_kind)(err)) {
1110   // These ones don't have addresses associated with them, and so don't
1111   // need any updating.
1112   case Err_CoreMem:
1113   //case Err_Value:
1114   //case Err_Cond:
1115   case Err_Overlap:
1116   case Err_FishyValue:
1117   // For Err_Leaks the returned size does not matter -- they are always
1118   // shown with VG_(unique_error)() so they 'extra' not copied.  But
1119   // we make it consistent with the others.
1120   case Err_Leak:
1121      return sizeof(MC_Error);
1122
1123   // For value errors, get the ExeContext corresponding to the
1124   // origin tag.  Note that it is a kludge to assume that
1125   // a length-1 trace indicates a stack origin.  FIXME.
1126   case Err_Value:
1127      update_origin( &extra->Err.Value.origin_ec,
1128                     extra->Err.Value.otag );
1129      return sizeof(MC_Error);
1130   case Err_Cond:
1131      update_origin( &extra->Err.Cond.origin_ec,
1132                     extra->Err.Cond.otag );
1133      return sizeof(MC_Error);
1134   case Err_RegParam:
1135      update_origin( &extra->Err.RegParam.origin_ec,
1136                     extra->Err.RegParam.otag );
1137      return sizeof(MC_Error);
1138
1139   // These ones always involve a memory address.
1140   case Err_Addr:
1141      describe_addr ( VG_(get_error_address)(err),
1142                      &extra->Err.Addr.ai );
1143      return sizeof(MC_Error);
1144   case Err_MemParam:
1145      describe_addr ( VG_(get_error_address)(err),
1146                      &extra->Err.MemParam.ai );
1147      update_origin( &extra->Err.MemParam.origin_ec,
1148                     extra->Err.MemParam.otag );
1149      return sizeof(MC_Error);
1150   case Err_Jump:
1151      describe_addr ( VG_(get_error_address)(err),
1152                      &extra->Err.Jump.ai );
1153      return sizeof(MC_Error);
1154   case Err_User:
1155      describe_addr ( VG_(get_error_address)(err),
1156                      &extra->Err.User.ai );
1157      update_origin( &extra->Err.User.origin_ec,
1158                     extra->Err.User.otag );
1159      return sizeof(MC_Error);
1160   case Err_Free:
1161      describe_addr ( VG_(get_error_address)(err),
1162                      &extra->Err.Free.ai );
1163      return sizeof(MC_Error);
1164   case Err_IllegalMempool:
1165      describe_addr ( VG_(get_error_address)(err),
1166                      &extra->Err.IllegalMempool.ai );
1167      return sizeof(MC_Error);
1168
1169   // Err_FreeMismatches have already had their address described;  this is
1170   // possible because we have the MC_Chunk on hand when the error is
1171   // detected.  However, the address may be part of a user block, and if so
1172   // we override the pre-determined description with a user block one.
1173   case Err_FreeMismatch: {
1174      tl_assert(extra && Block_Mallocd ==
1175                extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
1176      (void)client_block_maybe_describe( VG_(get_error_address)(err),
1177                                        &extra->Err.FreeMismatch.ai );
1178      return sizeof(MC_Error);
1179   }
1180
1181   default: VG_(tool_panic)("mc_update_extra: bad errkind");
1182   }
1183}
1184
1185
1186static Bool client_block_maybe_describe( Addr a,
1187                                         /*OUT*/AddrInfo* ai )
1188{
1189   UWord      i;
1190   CGenBlock* cgbs = NULL;
1191   UWord      cgb_used = 0;
1192
1193   MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
1194   if (cgbs == NULL)
1195      tl_assert(cgb_used == 0);
1196
1197   /* Perhaps it's a general block ? */
1198   for (i = 0; i < cgb_used; i++) {
1199      if (cgbs[i].start == 0 && cgbs[i].size == 0)
1200         continue;
1201      // Use zero as the redzone for client blocks.
1202      if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
1203         ai->tag = Addr_Block;
1204         ai->Addr.Block.block_kind = Block_UserG;
1205         ai->Addr.Block.block_desc = cgbs[i].desc;
1206         ai->Addr.Block.block_szB  = cgbs[i].size;
1207         ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
1208         ai->Addr.Block.allocated_at = cgbs[i].where;
1209         VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
1210         ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
1211         return True;
1212      }
1213   }
1214   return False;
1215}
1216
1217
1218static Bool mempool_block_maybe_describe( Addr a,
1219                                          /*OUT*/AddrInfo* ai )
1220{
1221   MC_Mempool* mp;
1222   tl_assert( MC_(mempool_list) );
1223
1224   VG_(HT_ResetIter)( MC_(mempool_list) );
1225   while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
1226      if (mp->chunks != NULL) {
1227         MC_Chunk* mc;
1228         VG_(HT_ResetIter)(mp->chunks);
1229         while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
1230            if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
1231               ai->tag = Addr_Block;
1232               ai->Addr.Block.block_kind = Block_MempoolChunk;
1233               ai->Addr.Block.block_desc = "block";
1234               ai->Addr.Block.block_szB  = mc->szB;
1235               ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1236               ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
1237               VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
1238               ai->Addr.Block.freed_at = MC_(freed_at)(mc);
1239               return True;
1240            }
1241         }
1242      }
1243   }
1244   return False;
1245}
1246
1247
1248/*------------------------------------------------------------*/
1249/*--- Suppressions                                         ---*/
1250/*------------------------------------------------------------*/
1251
1252typedef
1253   enum {
1254      ParamSupp,     // Bad syscall params
1255      UserSupp,      // Errors arising from client-request checks
1256      CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
1257
1258      // Undefined value errors of given size
1259      Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
1260
1261      // Undefined value error in conditional.
1262      CondSupp,
1263
1264      // Unaddressable read/write attempt at given size
1265      Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
1266
1267      JumpSupp,      // Jump to unaddressable target
1268      FreeSupp,      // Invalid or mismatching free
1269      OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
1270      LeakSupp,      // Something to be suppressed in a leak check.
1271      MempoolSupp,   // Memory pool suppression.
1272      FishyValueSupp,// Fishy value suppression.
1273   }
1274   MC_SuppKind;
1275
1276Bool MC_(is_recognised_suppression) ( const HChar* name, Supp* su )
1277{
1278   SuppKind skind;
1279
1280   if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
1281   else if (VG_STREQ(name, "User"))    skind = UserSupp;
1282   else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
1283   else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
1284   else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
1285   else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
1286   else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
1287   else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
1288   else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
1289   else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
1290   else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
1291   else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
1292   else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
1293   else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
1294   else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
1295   else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
1296   else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
1297   else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
1298   else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
1299   else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
1300   else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp;
1301   else
1302      return False;
1303
1304   VG_(set_supp_kind)(su, skind);
1305   return True;
1306}
1307
1308typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra;
1309
1310struct _MC_LeakSuppExtra {
1311   UInt match_leak_kinds;
1312
1313   /* Maintains nr of blocks and bytes suppressed with this suppression
1314      during the leak search identified by leak_search_gen.
1315      blocks_suppressed and bytes_suppressed are reset to 0 when
1316      used the first time during a leak search. */
1317   SizeT blocks_suppressed;
1318   SizeT bytes_suppressed;
1319   UInt  leak_search_gen;
1320};
1321
1322typedef struct {
1323   const HChar *function_name;
1324   const HChar *argument_name;
1325} MC_FishyValueExtra;
1326
1327Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
1328                                        SizeT* nBufp, Int* lineno, Supp *su )
1329{
1330   Bool eof;
1331   Int i;
1332
1333   if (VG_(get_supp_kind)(su) == ParamSupp) {
1334      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1335      if (eof) return False;
1336      VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
1337   } else if (VG_(get_supp_kind)(su) == LeakSupp) {
1338      // We might have the optional match-leak-kinds line
1339      MC_LeakSuppExtra* lse;
1340      lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
1341      lse->match_leak_kinds = MC_(all_Reachedness)();
1342      lse->blocks_suppressed = 0;
1343      lse->bytes_suppressed = 0;
1344      lse->leak_search_gen = 0;
1345      VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
1346      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1347      if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
1348      if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) {
1349         i = 17;
1350         while ((*bufpp)[i] && VG_(isspace((*bufpp)[i])))
1351            i++;
1352         if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
1353                                  True/*allow_all*/,
1354                                  (*bufpp)+i, &lse->match_leak_kinds)) {
1355            return False;
1356         }
1357      } else {
1358         return False; // unknown extra line.
1359      }
1360   } else if (VG_(get_supp_kind)(su) == FishyValueSupp) {
1361      MC_FishyValueExtra *extra;
1362      HChar *p, *function_name, *argument_name = NULL;
1363
1364      eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1365      if (eof) return True;
1366
1367      // The suppression string is: function_name(argument_name)
1368      function_name = VG_(strdup)("mv.resi.4", *bufpp);
1369      p = VG_(strchr)(function_name, '(');
1370      if (p != NULL) {
1371         *p++ = '\0';
1372         argument_name = p;
1373         p = VG_(strchr)(p, ')');
1374         if (p != NULL)
1375            *p = '\0';
1376      }
1377      if (p == NULL) {    // malformed suppression string
1378         VG_(free)(function_name);
1379         return False;
1380      }
1381
1382      extra = VG_(malloc)("mc.resi.3", sizeof *extra);
1383      extra->function_name = function_name;
1384      extra->argument_name = argument_name;
1385
1386      VG_(set_supp_extra)(su, extra);
1387   }
1388   return True;
1389}
1390
1391Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su )
1392{
1393   Int       su_szB;
1394   MC_Error* extra = VG_(get_error_extra)(err);
1395   ErrorKind ekind = VG_(get_error_kind )(err);
1396
1397   switch (VG_(get_supp_kind)(su)) {
1398      case ParamSupp:
1399         return ((ekind == Err_RegParam || ekind == Err_MemParam)
1400              && VG_STREQ(VG_(get_error_string)(err),
1401                          VG_(get_supp_string)(su)));
1402
1403      case UserSupp:
1404         return (ekind == Err_User);
1405
1406      case CoreMemSupp:
1407         return (ekind == Err_CoreMem
1408              && VG_STREQ(VG_(get_error_string)(err),
1409                          VG_(get_supp_string)(su)));
1410
1411      case Value1Supp: su_szB = 1; goto value_case;
1412      case Value2Supp: su_szB = 2; goto value_case;
1413      case Value4Supp: su_szB = 4; goto value_case;
1414      case Value8Supp: su_szB = 8; goto value_case;
1415      case Value16Supp:su_szB =16; goto value_case;
1416      value_case:
1417         return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
1418
1419      case CondSupp:
1420         return (ekind == Err_Cond);
1421
1422      case Addr1Supp: su_szB = 1; goto addr_case;
1423      case Addr2Supp: su_szB = 2; goto addr_case;
1424      case Addr4Supp: su_szB = 4; goto addr_case;
1425      case Addr8Supp: su_szB = 8; goto addr_case;
1426      case Addr16Supp:su_szB =16; goto addr_case;
1427      addr_case:
1428         return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
1429
1430      case JumpSupp:
1431         return (ekind == Err_Jump);
1432
1433      case FreeSupp:
1434         return (ekind == Err_Free || ekind == Err_FreeMismatch);
1435
1436      case OverlapSupp:
1437         return (ekind == Err_Overlap);
1438
1439      case LeakSupp:
1440         if (ekind == Err_Leak) {
1441            MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
1442            if (lse->leak_search_gen != MC_(leak_search_gen)) {
1443               // First time we see this suppression during this leak search.
1444               // => reset the counters to 0.
1445               lse->blocks_suppressed = 0;
1446               lse->bytes_suppressed = 0;
1447               lse->leak_search_gen = MC_(leak_search_gen);
1448            }
1449            return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
1450         } else
1451            return False;
1452
1453      case MempoolSupp:
1454         return (ekind == Err_IllegalMempool);
1455
1456      case FishyValueSupp: {
1457         MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su);
1458
1459         return (ekind == Err_FishyValue) &&
1460                VG_STREQ(extra->Err.FishyValue.function_name,
1461                         supp_extra->function_name) &&
1462                VG_STREQ(extra->Err.FishyValue.argument_name,
1463                         supp_extra->argument_name);
1464      }
1465
1466      default:
1467         VG_(printf)("Error:\n"
1468                     "  unknown suppression type %d\n",
1469                     VG_(get_supp_kind)(su));
1470         VG_(tool_panic)("unknown suppression type in "
1471                         "MC_(error_matches_suppression)");
1472   }
1473}
1474
1475const HChar* MC_(get_error_name) ( const Error* err )
1476{
1477   switch (VG_(get_error_kind)(err)) {
1478   case Err_RegParam:       return "Param";
1479   case Err_MemParam:       return "Param";
1480   case Err_User:           return "User";
1481   case Err_FreeMismatch:   return "Free";
1482   case Err_IllegalMempool: return "Mempool";
1483   case Err_Free:           return "Free";
1484   case Err_Jump:           return "Jump";
1485   case Err_CoreMem:        return "CoreMem";
1486   case Err_Overlap:        return "Overlap";
1487   case Err_Leak:           return "Leak";
1488   case Err_Cond:           return "Cond";
1489   case Err_FishyValue:     return "FishyValue";
1490   case Err_Addr: {
1491      MC_Error* extra = VG_(get_error_extra)(err);
1492      switch ( extra->Err.Addr.szB ) {
1493      case 1:               return "Addr1";
1494      case 2:               return "Addr2";
1495      case 4:               return "Addr4";
1496      case 8:               return "Addr8";
1497      case 16:              return "Addr16";
1498      default:              VG_(tool_panic)("unexpected size for Addr");
1499      }
1500   }
1501   case Err_Value: {
1502      MC_Error* extra = VG_(get_error_extra)(err);
1503      switch ( extra->Err.Value.szB ) {
1504      case 1:               return "Value1";
1505      case 2:               return "Value2";
1506      case 4:               return "Value4";
1507      case 8:               return "Value8";
1508      case 16:              return "Value16";
1509      default:              VG_(tool_panic)("unexpected size for Value");
1510      }
1511   }
1512   default:                 VG_(tool_panic)("get_error_name: unexpected type");
1513   }
1514}
1515
1516SizeT MC_(get_extra_suppression_info) ( const Error* err,
1517                                        /*OUT*/HChar* buf, Int nBuf )
1518{
1519   ErrorKind ekind = VG_(get_error_kind )(err);
1520   tl_assert(buf);
1521   tl_assert(nBuf >= 1);
1522
1523   if (Err_RegParam == ekind || Err_MemParam == ekind) {
1524      const HChar* errstr = VG_(get_error_string)(err);
1525      tl_assert(errstr);
1526      return VG_(snprintf)(buf, nBuf, "%s", errstr);
1527   } else if (Err_Leak == ekind) {
1528      MC_Error* extra = VG_(get_error_extra)(err);
1529      return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s",
1530          pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state));
1531   } else if (Err_FishyValue == ekind) {
1532      MC_Error* extra = VG_(get_error_extra)(err);
1533      return VG_(snprintf) (buf, nBuf, "%s(%s)",
1534                            extra->Err.FishyValue.function_name,
1535                            extra->Err.FishyValue.argument_name);
1536   } else {
1537      buf[0] = '\0';
1538      return 0;
1539   }
1540}
1541
1542SizeT MC_(print_extra_suppression_use) ( const Supp *su,
1543                                         /*OUT*/HChar *buf, Int nBuf )
1544{
1545   tl_assert(nBuf >= 1);
1546
1547   if (VG_(get_supp_kind)(su) == LeakSupp) {
1548      MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1549
1550      if (lse->leak_search_gen == MC_(leak_search_gen)
1551          && lse->blocks_suppressed > 0) {
1552         return VG_(snprintf) (buf, nBuf,
1553                               "suppressed: %'lu bytes in %'lu blocks",
1554                               lse->bytes_suppressed,
1555                               lse->blocks_suppressed);
1556      }
1557   }
1558
1559   buf[0] = '\0';
1560   return 0;
1561}
1562
1563void MC_(update_extra_suppression_use) ( const Error* err, const Supp* su)
1564{
1565   if (VG_(get_supp_kind)(su) == LeakSupp) {
1566      MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1567      MC_Error* extra = VG_(get_error_extra)(err);
1568
1569      tl_assert (lse->leak_search_gen == MC_(leak_search_gen));
1570      lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
1571      lse->bytes_suppressed
1572         += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
1573   }
1574}
1575
1576/*--------------------------------------------------------------------*/
1577/*--- end                                              mc_errors.c ---*/
1578/*--------------------------------------------------------------------*/
1579