• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2015 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 */
58  Bool MC_(any_value_errors) = False;
59  
60  
61  /* ------------------ Errors ----------------------- */
62  
63  /* What kind of error it is. */
64  typedef
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  
84  typedef struct _MC_Error MC_Error;
85  
86  struct _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  */
MC_(before_pp_Error)204  void 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  */
emit_WRK(const HChar * format,va_list vargs)210  static 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  }
218  static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2);
emit(const HChar * format,...)219  static 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  
str_leak_lossmode(Reachedness lossmode)228  static 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  
xml_leak_kind(Reachedness lossmode)240  static 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  
252  const HChar* MC_(parse_leak_kinds_tokens) =
253     "reachable,possible,indirect,definite";
254  
MC_(all_Reachedness)255  UInt 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  
pp_Reachedness_for_leak_kinds(Reachedness r)271  static 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  
mc_pp_origin(ExeContext * ec,UInt okind)282  static 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  
MC_(snprintf_delta)305  HChar * 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  
pp_LossRecord(UInt n_this_record,UInt n_total_records,LossRecord * lr,Bool xml)325  static 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>%lu</leakedbytes>\n", lr->szB);
379           emit( "    <leakedblocks>%u</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  
MC_(pp_LossRecord)408  void 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  
MC_(pp_Error)414  void 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 %lu</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 %lu\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 %lu</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 %lu\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. */
is_just_below_ESP(Addr esp,Addr aa)726  static 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  
MC_(record_address_error)737  void 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  
MC_(record_value_error)763  void 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  
MC_(record_cond_error)775  void 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. */
MC_(record_core_mem_error)789  void 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  
MC_(record_regparam_error)794  void 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  
MC_(record_memparam_error)805  void 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  
MC_(record_jump_error)823  void 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  
MC_(record_free_error)831  void 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  
MC_(record_freemismatch_error)839  void 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  
MC_(record_illegal_mempool_error)856  void 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  
MC_(record_overlap_error)864  void 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  
MC_(record_leak_error)876  Bool 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  
MC_(record_fishy_value_error)890  Bool 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  
MC_(record_user_error)909  void 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.  */
MC_(eq_Error)935  Bool 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 */
1004  static
addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk * mc,Addr a)1005  Bool 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  }
1010  static
addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk * mc,Addr a,SizeT rzB)1011  Bool 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
1018  static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
1019  static 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. */
describe_addr(Addr a,AddrInfo * ai)1024  static 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  
MC_(pp_describe_addr)1082  void 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. */
update_origin(ExeContext ** origin_ec,UInt otag)1094  static 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). */
MC_(update_Error_extra)1105  UInt 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  
client_block_maybe_describe(Addr a,AddrInfo * ai)1186  static 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  
mempool_block_maybe_describe(Addr a,AddrInfo * ai)1218  static 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  
1252  typedef
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, Value32Supp,
1260  
1261        // Undefined value error in conditional.
1262        CondSupp,
1263  
1264        // Unaddressable read/write attempt at given size
1265        Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp,
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  
MC_(is_recognised_suppression)1276  Bool 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, "Addr32"))  skind = Addr32Supp;
1289     else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
1290     else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
1291     else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
1292     else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
1293     else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
1294     else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
1295     else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
1296     else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
1297     else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
1298     else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
1299     else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
1300     else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
1301     else if (VG_STREQ(name, "Value32")) skind = Value32Supp;
1302     else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp;
1303     else
1304        return False;
1305  
1306     VG_(set_supp_kind)(su, skind);
1307     return True;
1308  }
1309  
1310  typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra;
1311  
1312  struct _MC_LeakSuppExtra {
1313     UInt match_leak_kinds;
1314  
1315     /* Maintains nr of blocks and bytes suppressed with this suppression
1316        during the leak search identified by leak_search_gen.
1317        blocks_suppressed and bytes_suppressed are reset to 0 when
1318        used the first time during a leak search. */
1319     SizeT blocks_suppressed;
1320     SizeT bytes_suppressed;
1321     UInt  leak_search_gen;
1322  };
1323  
1324  typedef struct {
1325     const HChar *function_name;
1326     const HChar *argument_name;
1327  } MC_FishyValueExtra;
1328  
MC_(read_extra_suppression_info)1329  Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
1330                                          SizeT* nBufp, Int* lineno, Supp *su )
1331  {
1332     Bool eof;
1333     Int i;
1334  
1335     if (VG_(get_supp_kind)(su) == ParamSupp) {
1336        eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1337        if (eof) return False;
1338        VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
1339     } else if (VG_(get_supp_kind)(su) == LeakSupp) {
1340        // We might have the optional match-leak-kinds line
1341        MC_LeakSuppExtra* lse;
1342        lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
1343        lse->match_leak_kinds = MC_(all_Reachedness)();
1344        lse->blocks_suppressed = 0;
1345        lse->bytes_suppressed = 0;
1346        lse->leak_search_gen = 0;
1347        VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
1348        eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1349        if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
1350        if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) {
1351           i = 17;
1352           while ((*bufpp)[i] && VG_(isspace((*bufpp)[i])))
1353              i++;
1354           if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
1355                                    True/*allow_all*/,
1356                                    (*bufpp)+i, &lse->match_leak_kinds)) {
1357              return False;
1358           }
1359        } else {
1360           return False; // unknown extra line.
1361        }
1362     } else if (VG_(get_supp_kind)(su) == FishyValueSupp) {
1363        MC_FishyValueExtra *extra;
1364        HChar *p, *function_name, *argument_name = NULL;
1365  
1366        eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1367        if (eof) return True;
1368  
1369        // The suppression string is: function_name(argument_name)
1370        function_name = VG_(strdup)("mv.resi.4", *bufpp);
1371        p = VG_(strchr)(function_name, '(');
1372        if (p != NULL) {
1373           *p++ = '\0';
1374           argument_name = p;
1375           p = VG_(strchr)(p, ')');
1376           if (p != NULL)
1377              *p = '\0';
1378        }
1379        if (p == NULL) {    // malformed suppression string
1380           VG_(free)(function_name);
1381           return False;
1382        }
1383  
1384        extra = VG_(malloc)("mc.resi.3", sizeof *extra);
1385        extra->function_name = function_name;
1386        extra->argument_name = argument_name;
1387  
1388        VG_(set_supp_extra)(su, extra);
1389     }
1390     return True;
1391  }
1392  
MC_(error_matches_suppression)1393  Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su )
1394  {
1395     Int       su_szB;
1396     MC_Error* extra = VG_(get_error_extra)(err);
1397     ErrorKind ekind = VG_(get_error_kind )(err);
1398  
1399     switch (VG_(get_supp_kind)(su)) {
1400        case ParamSupp:
1401           return ((ekind == Err_RegParam || ekind == Err_MemParam)
1402                && VG_STREQ(VG_(get_error_string)(err),
1403                            VG_(get_supp_string)(su)));
1404  
1405        case UserSupp:
1406           return (ekind == Err_User);
1407  
1408        case CoreMemSupp:
1409           return (ekind == Err_CoreMem
1410                && VG_STREQ(VG_(get_error_string)(err),
1411                            VG_(get_supp_string)(su)));
1412  
1413        case Value1Supp: su_szB = 1; goto value_case;
1414        case Value2Supp: su_szB = 2; goto value_case;
1415        case Value4Supp: su_szB = 4; goto value_case;
1416        case Value8Supp: su_szB = 8; goto value_case;
1417        case Value16Supp:su_szB =16; goto value_case;
1418        case Value32Supp:su_szB =32; goto value_case;
1419        value_case:
1420           return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
1421  
1422        case CondSupp:
1423           return (ekind == Err_Cond);
1424  
1425        case Addr1Supp: su_szB = 1; goto addr_case;
1426        case Addr2Supp: su_szB = 2; goto addr_case;
1427        case Addr4Supp: su_szB = 4; goto addr_case;
1428        case Addr8Supp: su_szB = 8; goto addr_case;
1429        case Addr16Supp:su_szB =16; goto addr_case;
1430        case Addr32Supp:su_szB =32; goto addr_case;
1431        addr_case:
1432           return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
1433  
1434        case JumpSupp:
1435           return (ekind == Err_Jump);
1436  
1437        case FreeSupp:
1438           return (ekind == Err_Free || ekind == Err_FreeMismatch);
1439  
1440        case OverlapSupp:
1441           return (ekind == Err_Overlap);
1442  
1443        case LeakSupp:
1444           if (ekind == Err_Leak) {
1445              MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
1446              if (lse->leak_search_gen != MC_(leak_search_gen)) {
1447                 // First time we see this suppression during this leak search.
1448                 // => reset the counters to 0.
1449                 lse->blocks_suppressed = 0;
1450                 lse->bytes_suppressed = 0;
1451                 lse->leak_search_gen = MC_(leak_search_gen);
1452              }
1453              return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
1454           } else
1455              return False;
1456  
1457        case MempoolSupp:
1458           return (ekind == Err_IllegalMempool);
1459  
1460        case FishyValueSupp: {
1461           MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su);
1462  
1463           return (ekind == Err_FishyValue) &&
1464                  VG_STREQ(extra->Err.FishyValue.function_name,
1465                           supp_extra->function_name) &&
1466                  VG_STREQ(extra->Err.FishyValue.argument_name,
1467                           supp_extra->argument_name);
1468        }
1469  
1470        default:
1471           VG_(printf)("Error:\n"
1472                       "  unknown suppression type %d\n",
1473                       VG_(get_supp_kind)(su));
1474           VG_(tool_panic)("unknown suppression type in "
1475                           "MC_(error_matches_suppression)");
1476     }
1477  }
1478  
MC_(get_error_name)1479  const HChar* MC_(get_error_name) ( const Error* err )
1480  {
1481     switch (VG_(get_error_kind)(err)) {
1482     case Err_RegParam:       return "Param";
1483     case Err_MemParam:       return "Param";
1484     case Err_User:           return "User";
1485     case Err_FreeMismatch:   return "Free";
1486     case Err_IllegalMempool: return "Mempool";
1487     case Err_Free:           return "Free";
1488     case Err_Jump:           return "Jump";
1489     case Err_CoreMem:        return "CoreMem";
1490     case Err_Overlap:        return "Overlap";
1491     case Err_Leak:           return "Leak";
1492     case Err_Cond:           return "Cond";
1493     case Err_FishyValue:     return "FishyValue";
1494     case Err_Addr: {
1495        MC_Error* extra = VG_(get_error_extra)(err);
1496        switch ( extra->Err.Addr.szB ) {
1497        case 1:               return "Addr1";
1498        case 2:               return "Addr2";
1499        case 4:               return "Addr4";
1500        case 8:               return "Addr8";
1501        case 16:              return "Addr16";
1502        case 32:              return "Addr32";
1503        default:              VG_(tool_panic)("unexpected size for Addr");
1504        }
1505     }
1506     case Err_Value: {
1507        MC_Error* extra = VG_(get_error_extra)(err);
1508        switch ( extra->Err.Value.szB ) {
1509        case 1:               return "Value1";
1510        case 2:               return "Value2";
1511        case 4:               return "Value4";
1512        case 8:               return "Value8";
1513        case 16:              return "Value16";
1514        case 32:              return "Value32";
1515        default:              VG_(tool_panic)("unexpected size for Value");
1516        }
1517     }
1518     default:                 VG_(tool_panic)("get_error_name: unexpected type");
1519     }
1520  }
1521  
MC_(get_extra_suppression_info)1522  SizeT MC_(get_extra_suppression_info) ( const Error* err,
1523                                          /*OUT*/HChar* buf, Int nBuf )
1524  {
1525     ErrorKind ekind = VG_(get_error_kind )(err);
1526     tl_assert(buf);
1527     tl_assert(nBuf >= 1);
1528  
1529     if (Err_RegParam == ekind || Err_MemParam == ekind) {
1530        const HChar* errstr = VG_(get_error_string)(err);
1531        tl_assert(errstr);
1532        return VG_(snprintf)(buf, nBuf, "%s", errstr);
1533     } else if (Err_Leak == ekind) {
1534        MC_Error* extra = VG_(get_error_extra)(err);
1535        return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s",
1536            pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state));
1537     } else if (Err_FishyValue == ekind) {
1538        MC_Error* extra = VG_(get_error_extra)(err);
1539        return VG_(snprintf) (buf, nBuf, "%s(%s)",
1540                              extra->Err.FishyValue.function_name,
1541                              extra->Err.FishyValue.argument_name);
1542     } else {
1543        buf[0] = '\0';
1544        return 0;
1545     }
1546  }
1547  
MC_(print_extra_suppression_use)1548  SizeT MC_(print_extra_suppression_use) ( const Supp *su,
1549                                           /*OUT*/HChar *buf, Int nBuf )
1550  {
1551     tl_assert(nBuf >= 1);
1552  
1553     if (VG_(get_supp_kind)(su) == LeakSupp) {
1554        MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1555  
1556        if (lse->leak_search_gen == MC_(leak_search_gen)
1557            && lse->blocks_suppressed > 0) {
1558           return VG_(snprintf) (buf, nBuf,
1559                                 "suppressed: %'lu bytes in %'lu blocks",
1560                                 lse->bytes_suppressed,
1561                                 lse->blocks_suppressed);
1562        }
1563     }
1564  
1565     buf[0] = '\0';
1566     return 0;
1567  }
1568  
MC_(update_extra_suppression_use)1569  void MC_(update_extra_suppression_use) ( const Error* err, const Supp* su)
1570  {
1571     if (VG_(get_supp_kind)(su) == LeakSupp) {
1572        MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1573        MC_Error* extra = VG_(get_error_extra)(err);
1574  
1575        tl_assert (lse->leak_search_gen == MC_(leak_search_gen));
1576        lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
1577        lse->bytes_suppressed
1578           += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
1579     }
1580  }
1581  
1582  /*--------------------------------------------------------------------*/
1583  /*--- end                                              mc_errors.c ---*/
1584  /*--------------------------------------------------------------------*/
1585