~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to memcheck/mc_leakcheck.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
   This file is part of MemCheck, a heavyweight Valgrind tool for
8
8
   detecting memory errors.
9
9
 
10
 
   Copyright (C) 2000-2006 Julian Seward 
 
10
   Copyright (C) 2000-2007 Julian Seward 
11
11
      jseward@acm.org
12
12
 
13
13
   This program is free software; you can redistribute it and/or
29
29
*/
30
30
 
31
31
#include "pub_tool_basics.h"
 
32
#include "pub_tool_vki.h"
32
33
#include "pub_tool_aspacemgr.h"
33
34
#include "pub_tool_execontext.h"
34
35
#include "pub_tool_hashtable.h"
108
109
/*--- Detecting leaked (unreachable) malloc'd blocks.      ---*/
109
110
/*------------------------------------------------------------*/
110
111
 
111
 
/* A block is either 
112
 
   -- Proper-ly reached; a pointer to its start has been found
113
 
   -- Interior-ly reached; only an interior pointer to it has been found
114
 
   -- Unreached; so far, no pointers to any part of it have been found. 
115
 
   -- IndirectLeak; leaked, but referred to by another leaked block
116
 
*/
117
 
typedef 
118
 
   enum { 
119
 
      Unreached    =0, 
120
 
      IndirectLeak =1,
121
 
      Interior     =2, 
122
 
      Proper       =3
123
 
  }
124
 
  Reachedness;
125
 
 
126
112
/* An entry in the mark stack */
127
113
typedef 
128
114
   struct {
132
118
   } 
133
119
   MarkStack;
134
120
 
135
 
/* A block record, used for generating err msgs. */
136
 
typedef
137
 
   struct _LossRecord {
138
 
      struct _LossRecord* next;
139
 
      /* Where these lost blocks were allocated. */
140
 
      ExeContext*  allocated_at;
141
 
      /* Their reachability. */
142
 
      Reachedness  loss_mode;
143
 
      /* Number of blocks and total # bytes involved. */
144
 
      SizeT        total_bytes;
145
 
      SizeT        indirect_bytes;
146
 
      UInt         num_blocks;
147
 
   }
148
 
   LossRecord;
149
 
 
150
 
/* The 'extra' struct for leak errors. */
151
 
typedef 
152
 
   struct {
153
 
      UInt        n_this_record;
154
 
      UInt        n_total_records;
155
 
      LossRecord* lossRecord;
156
 
   }
157
 
   LeakExtra;
158
 
 
159
121
/* Find the i such that ptr points at or inside the block described by
160
122
   shadows[i].  Return -1 if none found.  This assumes that shadows[]
161
123
   has been sorted on the ->data field. */
174
136
   for (i = 0; i < n_shadows; i++) {
175
137
      PROF_EVENT(71, "find_shadow_for_OLD(loop)");
176
138
      a_lo = shadows[i]->data;
177
 
      a_hi = ((Addr)shadows[i]->data) + shadows[i]->size;
 
139
      a_hi = ((Addr)shadows[i]->data) + shadows[i]->szB;
178
140
      if (a_lo <= ptr && ptr < a_hi)
179
141
         return i;
180
142
   }
200
162
 
201
163
      mid      = (lo + hi) / 2;
202
164
      a_mid_lo = shadows[mid]->data;
203
 
      a_mid_hi = shadows[mid]->data + shadows[mid]->size;
 
165
      a_mid_hi = shadows[mid]->data + shadows[mid]->szB;
204
166
      /* Extent of block 'mid' is [a_mid_lo .. a_mid_hi).
205
167
         Special-case zero-sized blocks - treat them as if they had
206
168
         size 1.  Not doing so causes them to not cover any address
207
169
         range at all and so will never be identified as the target of
208
170
         any pointer, which causes them to be incorrectly reported as
209
171
         definitely leaked. */
210
 
      if (shadows[mid]->size == 0)
 
172
      if (shadows[mid]->szB == 0)
211
173
         a_mid_hi++;
212
174
 
213
175
      if (ptr < a_mid_lo) {
242
204
static Bool       (*lc_is_within_valid_secondary) (Addr addr);
243
205
static Bool       (*lc_is_valid_aligned_word)     (Addr addr);
244
206
 
245
 
static const HChar* str_lossmode ( Reachedness lossmode )
246
 
{
247
 
   const HChar *loss = "?";
248
 
   switch (lossmode) {
249
 
      case Unreached:    loss = "definitely lost"; break;
250
 
      case IndirectLeak: loss = "indirectly lost"; break;
251
 
      case Interior:     loss = "possibly lost"; break;
252
 
      case Proper:       loss = "still reachable"; break;
253
 
   }
254
 
   return loss;
255
 
}
256
 
 
257
 
static const HChar* xml_kind ( Reachedness lossmode )
258
 
{
259
 
   const HChar *loss = "?";
260
 
   switch (lossmode) {
261
 
      case Unreached:    loss = "Leak_DefinitelyLost"; break;
262
 
      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
263
 
      case Interior:     loss = "Leak_PossiblyLost"; break;
264
 
      case Proper:       loss = "Leak_StillReachable"; break;
265
 
   }
266
 
   return loss;
267
 
}
268
 
 
269
 
 
270
 
/* Used for printing leak errors, avoids exposing the LossRecord type (which
271
 
   comes in as void*, requiring a cast. */
272
 
void MC_(pp_LeakError)(void* vextra)
273
 
{
274
 
   HChar* xpre  = VG_(clo_xml) ? "  <what>" : "";
275
 
   HChar* xpost = VG_(clo_xml) ? "</what>"  : "";
276
 
 
277
 
   LeakExtra* extra = (LeakExtra*)vextra;
278
 
   LossRecord* l    = extra->lossRecord;
279
 
   const Char *loss = str_lossmode(l->loss_mode);
280
 
 
281
 
   if (VG_(clo_xml)) {
282
 
      VG_(message)(Vg_UserMsg, "  <kind>%t</kind>", xml_kind(l->loss_mode));
283
 
   } else {
284
 
      VG_(message)(Vg_UserMsg, "");
285
 
   }
286
 
 
287
 
   if (l->indirect_bytes) {
288
 
      VG_(message)(Vg_UserMsg, 
289
 
         "%s%,lu (%,lu direct, %,lu indirect) bytes in %,u blocks"
290
 
         " are %s in loss record %,u of %,u%s",
291
 
         xpre,
292
 
         l->total_bytes + l->indirect_bytes, 
293
 
         l->total_bytes, l->indirect_bytes, l->num_blocks,
294
 
         loss, extra->n_this_record, extra->n_total_records,
295
 
         xpost
296
 
      );
297
 
      if (VG_(clo_xml)) {
298
 
         // Nb: don't put commas in these XML numbers 
299
 
         VG_(message)(Vg_UserMsg, "  <leakedbytes>%lu</leakedbytes>", 
300
 
                                  l->total_bytes + l->indirect_bytes);
301
 
         VG_(message)(Vg_UserMsg, "  <leakedblocks>%u</leakedblocks>", 
302
 
                                  l->num_blocks);
303
 
      }
304
 
   } else {
305
 
      VG_(message)(
306
 
         Vg_UserMsg, 
307
 
         "%s%,lu bytes in %,u blocks are %s in loss record %,u of %,u%s",
308
 
         xpre,
309
 
         l->total_bytes, l->num_blocks,
310
 
         loss, extra->n_this_record, extra->n_total_records,
311
 
         xpost
312
 
      );
313
 
      if (VG_(clo_xml)) {
314
 
         VG_(message)(Vg_UserMsg, "  <leakedbytes>%d</leakedbytes>", 
315
 
                                  l->total_bytes);
316
 
         VG_(message)(Vg_UserMsg, "  <leakedblocks>%d</leakedblocks>", 
317
 
                                  l->num_blocks);
318
 
      }
319
 
   }
320
 
   VG_(pp_ExeContext)(l->allocated_at);
321
 
}
322
207
 
323
208
SizeT MC_(bytes_leaked)     = 0;
324
209
SizeT MC_(bytes_indirect)   = 0;
355
240
   tl_assert(sh_no >= 0 && sh_no < lc_n_shadows);
356
241
   tl_assert(ptr >= lc_shadows[sh_no]->data);
357
242
   tl_assert(ptr < lc_shadows[sh_no]->data 
358
 
                   + lc_shadows[sh_no]->size
359
 
                   + (lc_shadows[sh_no]->size==0  ? 1  : 0));
 
243
                   + lc_shadows[sh_no]->szB
 
244
                   + (lc_shadows[sh_no]->szB==0  ? 1  : 0));
360
245
 
361
246
   if (lc_markstack[sh_no].state == Unreached) {
362
247
      if (0)
363
248
         VG_(printf)("pushing %p-%p\n", lc_shadows[sh_no]->data, 
364
 
                     lc_shadows[sh_no]->data + lc_shadows[sh_no]->size);
 
249
                     lc_shadows[sh_no]->data + lc_shadows[sh_no]->szB);
365
250
 
366
251
      tl_assert(lc_markstack[sh_no].next == -1);
367
252
      lc_markstack[sh_no].next = lc_markstack_top;
388
273
         if (sh_no != clique) {
389
274
            if (VG_DEBUG_CLIQUE) {
390
275
               if (lc_markstack[sh_no].indirect)
391
 
                  VG_(printf)("  clique %d joining clique %d adding %d+%d bytes\n", 
 
276
                  VG_(printf)("  clique %d joining clique %d adding %lu+%lu bytes\n", 
392
277
                              sh_no, clique, 
393
 
                              lc_shadows[sh_no]->size, lc_markstack[sh_no].indirect);
 
278
                              lc_shadows[sh_no]->szB, lc_markstack[sh_no].indirect);
394
279
               else
395
 
                  VG_(printf)("  %d joining %d adding %d\n", 
396
 
                              sh_no, clique, lc_shadows[sh_no]->size);
 
280
                  VG_(printf)("  %d joining %d adding %lu\n", 
 
281
                              sh_no, clique, lc_shadows[sh_no]->szB);
397
282
            }
398
283
 
399
 
            lc_markstack[clique].indirect += lc_shadows[sh_no]->size;
 
284
            lc_markstack[clique].indirect += lc_shadows[sh_no]->szB;
400
285
            lc_markstack[clique].indirect += lc_markstack[sh_no].indirect;
401
286
            lc_markstack[sh_no].indirect = 0; /* shouldn't matter */
402
287
         }
502
387
      tl_assert(top >= 0 && top < lc_n_shadows);      
503
388
      tl_assert(lc_markstack[top].state != Unreached);
504
389
 
505
 
      lc_scan_memory_WRK(lc_shadows[top]->data, lc_shadows[top]->size, clique);
 
390
      lc_scan_memory_WRK(lc_shadows[top]->data, lc_shadows[top]->szB, clique);
506
391
   }
507
392
}
508
393
 
519
404
   LossRecord* errlist;
520
405
   LossRecord* p;
521
406
   Bool   is_suppressed;
522
 
   LeakExtra leak_extra;
523
407
 
524
408
   /* Go through and group lost structures into cliques.  For each
525
409
      Unreached block, push it onto the mark stack, and find all the
529
413
      pass), then the cliques are merged. */
530
414
   for (i = 0; i < lc_n_shadows; i++) {
531
415
      if (VG_DEBUG_CLIQUE)
532
 
         VG_(printf)("cliques: %d at %p -> %s\n",
533
 
                     i, lc_shadows[i]->data, str_lossmode(lc_markstack[i].state));
 
416
         VG_(printf)("cliques: %d at %p -> Loss state %d\n",
 
417
                     i, lc_shadows[i]->data, lc_markstack[i].state);
534
418
      if (lc_markstack[i].state != Unreached)
535
419
         continue;
536
420
 
577
461
      }
578
462
      if (p != NULL) {
579
463
         p->num_blocks  ++;
580
 
         p->total_bytes += lc_shadows[i]->size;
 
464
         p->total_bytes += lc_shadows[i]->szB;
581
465
         p->indirect_bytes += lc_markstack[i].indirect;
582
466
      } else {
583
467
         n_lossrecords ++;
584
468
         p = VG_(malloc)(sizeof(LossRecord));
585
469
         p->loss_mode    = lc_markstack[i].state;
586
470
         p->allocated_at = where;
587
 
         p->total_bytes  = lc_shadows[i]->size;
 
471
         p->total_bytes  = lc_shadows[i]->szB;
588
472
         p->indirect_bytes = lc_markstack[i].indirect;
589
473
         p->num_blocks   = 1;
590
474
         p->next         = errlist;
618
502
      // Nb: because VG_(unique_error) does all the error processing
619
503
      // immediately, and doesn't save the error, leakExtra can be
620
504
      // stack-allocated.
621
 
      leak_extra.n_this_record   = i+1;
622
 
      leak_extra.n_total_records = n_lossrecords;
623
 
      leak_extra.lossRecord      = p_min;
624
505
      is_suppressed = 
625
 
         MC_(record_leak_error) ( tid, &leak_extra, p_min->allocated_at,
 
506
         MC_(record_leak_error) ( tid, i+1, n_lossrecords, p_min,
626
507
                                  print_record );
627
508
 
628
509
      if (is_suppressed) {
658
539
   Int i;
659
540
 
660
541
   for(i = 0; i < lc_n_shadows; i++) {
661
 
      SizeT size = lc_shadows[i]->size;
 
542
      SizeT size = lc_shadows[i]->szB;
662
543
 
663
544
      switch(lc_markstack[i].state) {
664
545
      case Unreached:
744
625
         }
745
626
 
746
627
         /* Possibly invalidate the malloc holding the end of this chunk. */
747
 
         if (mc->size > 1) {
748
 
            m = find_shadow_for(mc->data + (mc->size - 1), mallocs, n_mallocs);
 
628
         if (mc->szB > 1) {
 
629
            m = find_shadow_for(mc->data + (mc->szB - 1), mallocs, n_mallocs);
749
630
            if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
750
631
               tl_assert(*n_shadows > 0);
751
632
               --(*n_shadows);
811
692
      tl_assert( lc_shadows[i]->data <= lc_shadows[i+1]->data);
812
693
   }
813
694
 
814
 
   /* Sanity check -- make sure they don't overlap */
 
695
   /* Sanity check -- make sure they don't overlap.  But do allow
 
696
      exact duplicates.  If this assertion fails, it may mean that the
 
697
      application has done something stupid with
 
698
      VALGRIND_MALLOCLIKE_BLOCK client requests, specifically, has
 
699
      made overlapping requests (which are nonsensical).  Another way
 
700
      to screw up is to use VALGRIND_MALLOCLIKE_BLOCK for stack
 
701
      locations; again nonsensical. */
815
702
   for (i = 0; i < lc_n_shadows-1; i++) {
816
 
      tl_assert( lc_shadows[i]->data + lc_shadows[i]->size
817
 
                 <= lc_shadows[i+1]->data );
 
703
      tl_assert( /* normal case - no overlap */
 
704
                 (lc_shadows[i]->data + lc_shadows[i]->szB
 
705
                  <= lc_shadows[i+1]->data )
 
706
                 ||
 
707
                 /* degenerate case: exact duplicates */
 
708
                 (lc_shadows[i]->data == lc_shadows[i+1]->data
 
709
                  && lc_shadows[i]->szB == lc_shadows[i+1]->szB)
 
710
               );
818
711
   }
819
712
 
820
713
   if (lc_n_shadows == 0) {
833
726
 
834
727
   lc_min_mallocd_addr = lc_shadows[0]->data;
835
728
   lc_max_mallocd_addr = lc_shadows[lc_n_shadows-1]->data
836
 
                         + lc_shadows[lc_n_shadows-1]->size;
 
729
                         + lc_shadows[lc_n_shadows-1]->szB;
837
730
 
838
731
   lc_markstack = VG_(malloc)( lc_n_shadows * sizeof(*lc_markstack) );
839
732
   for (i = 0; i < lc_n_shadows; i++) {
858
751
      categorisation, which [if the users ever manage to understand it]
859
752
      is really useful for detecting lost cycles.
860
753
   */
861
 
   { NSegment* seg;
862
 
     Addr*     seg_starts;
 
754
   { Addr*     seg_starts;
863
755
     Int       n_seg_starts;
864
756
     seg_starts = get_seg_starts( &n_seg_starts );
865
757
     tl_assert(seg_starts && n_seg_starts > 0);
866
758
     /* VG_(am_show_nsegments)( 0,"leakcheck"); */
867
759
     for (i = 0; i < n_seg_starts; i++) {
868
 
        seg = VG_(am_find_nsegment)( seg_starts[i] );
 
760
        NSegment const* seg = VG_(am_find_nsegment)( seg_starts[i] );
869
761
        tl_assert(seg);
870
762
        if (seg->kind != SkFileC && seg->kind != SkAnonC) 
871
763
           continue;
879
771
           memory by explicitly mapping /dev/zero. */
880
772
        if (seg->kind == SkFileC 
881
773
            && (VKI_S_ISCHR(seg->mode) || VKI_S_ISBLK(seg->mode))) {
882
 
           HChar* dev_name = VG_(am_get_filename)( seg );
 
774
           HChar* dev_name = VG_(am_get_filename)( (NSegment*)seg );
883
775
           if (dev_name && 0 == VG_(strcmp)(dev_name, "/dev/zero")) {
884
776
              /* don't skip /dev/zero */
885
777
           } else {
928
820
                               MC_(bytes_reachable), blocks_reachable );
929
821
      VG_(message)(Vg_UserMsg, "        suppressed: %,lu bytes in %,lu blocks.",
930
822
                               MC_(bytes_suppressed), blocks_suppressed );
931
 
      if (mode == LC_Summary && blocks_leaked > 0)
932
 
         VG_(message)(Vg_UserMsg,
933
 
                      "Use --leak-check=full to see details of leaked memory.");
934
 
      else if (!MC_(clo_show_reachable)) {
 
823
      if (mode == LC_Summary 
 
824
          && (blocks_leaked + blocks_indirect 
 
825
              + blocks_dubious + blocks_reachable) > 0) {
 
826
         VG_(message)(Vg_UserMsg,
 
827
                      "Rerun with --leak-check=full to see details of leaked memory.");
 
828
      }
 
829
      if (blocks_reachable > 0 && !MC_(clo_show_reachable) && mode == LC_Full) {
935
830
         VG_(message)(Vg_UserMsg, 
936
831
           "Reachable blocks (those to which a pointer was found) are not shown.");
937
832
         VG_(message)(Vg_UserMsg, 
938
 
            "To see them, rerun with: --show-reachable=yes");
 
833
            "To see them, rerun with: --leak-check=full --show-reachable=yes");
939
834
      }
940
835
   }
941
836