• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- The leak checker.                             mc_leakcheck.c ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of MemCheck, a heavyweight Valgrind tool for
8    detecting memory errors.
9 
10    Copyright (C) 2000-2012 Julian Seward
11       jseward@acm.org
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 #include "pub_tool_basics.h"
32 #include "pub_tool_vki.h"
33 #include "pub_tool_aspacehl.h"
34 #include "pub_tool_aspacemgr.h"
35 #include "pub_tool_execontext.h"
36 #include "pub_tool_hashtable.h"
37 #include "pub_tool_libcbase.h"
38 #include "pub_tool_libcassert.h"
39 #include "pub_tool_libcprint.h"
40 #include "pub_tool_libcsignal.h"
41 #include "pub_tool_machine.h"
42 #include "pub_tool_mallocfree.h"
43 #include "pub_tool_options.h"
44 #include "pub_tool_oset.h"
45 #include "pub_tool_poolalloc.h"
46 #include "pub_tool_signals.h"       // Needed for mc_include.h
47 #include "pub_tool_libcsetjmp.h"    // setjmp facilities
48 #include "pub_tool_tooliface.h"     // Needed for mc_include.h
49 
50 #include "mc_include.h"
51 
52 /*------------------------------------------------------------*/
53 /*--- An overview of leak checking.                        ---*/
54 /*------------------------------------------------------------*/
55 
56 // Leak-checking is a directed-graph traversal problem.  The graph has
57 // two kinds of nodes:
58 // - root-set nodes:
59 //   - GP registers of all threads;
60 //   - valid, aligned, pointer-sized data words in valid client memory,
61 //     including stacks, but excluding words within client heap-allocated
62 //     blocks (they are excluded so that later on we can differentiate
63 //     between heap blocks that are indirectly leaked vs. directly leaked).
64 // - heap-allocated blocks.  A block is a mempool chunk or a malloc chunk
65 //   that doesn't contain a mempool chunk.  Nb: the terms "blocks" and
66 //   "chunks" are used interchangeably below.
67 //
68 // There are two kinds of edges:
69 // - start-pointers, i.e. pointers to the start of a block;
70 // - interior-pointers, i.e. pointers to the interior of a block.
71 //
72 // We use "pointers" rather than "edges" below.
73 //
74 // Root set nodes only point to blocks.  Blocks only point to blocks;
75 // a block can point to itself.
76 //
77 // The aim is to traverse the graph and determine the status of each block.
78 //
79 // There are 9 distinct cases.  See memcheck/docs/mc-manual.xml for details.
80 // Presenting all nine categories to the user is probably too much.
81 // Currently we do this:
82 // - definitely lost:  case 3
83 // - indirectly lost:  case 4, 9
84 // - possibly lost:    cases 5..8
85 // - still reachable:  cases 1, 2
86 //
87 // It's far from clear that this is the best possible categorisation;  it's
88 // accreted over time without any central guiding principle.
89 
90 /*------------------------------------------------------------*/
91 /*--- XXX: Thoughts for improvement.                       ---*/
92 /*------------------------------------------------------------*/
93 
94 // From the user's point of view:
95 // - If they aren't using interior-pointers, they just have to fix the
96 //   directly lost blocks, and the indirectly lost ones will be fixed as
97 //   part of that.  Any possibly lost blocks will just be due to random
98 //   pointer garbage and can be ignored.
99 //
100 // - If they are using interior-pointers, the fact that they currently are not
101 //   being told which ones might be directly lost vs. indirectly lost makes
102 //   it hard to know where to begin.
103 //
104 // All this makes me wonder if new option is warranted:
105 // --follow-interior-pointers.  By default it would be off, the leak checker
106 // wouldn't follow interior-pointers and there would only be 3 categories:
107 // R, DL, IL.
108 //
109 // If turned on, then it would show 7 categories (R, DL, IL, DR/DL, IR/IL,
110 // IR/IL/DL, IL/DL).  That output is harder to understand but it's your own
111 // damn fault for using interior-pointers...
112 //
113 // ----
114 //
115 // Also, why are two blank lines printed between each loss record?
116 // [bug 197930]
117 //
118 // ----
119 //
120 // Also, --show-reachable is a bad name because it also turns on the showing
121 // of indirectly leaked blocks(!)  It would be better named --show-all or
122 // --show-all-heap-blocks, because that's the end result.
123 //
124 // ----
125 //
126 // Also, the VALGRIND_LEAK_CHECK and VALGRIND_QUICK_LEAK_CHECK aren't great
127 // names.  VALGRIND_FULL_LEAK_CHECK and VALGRIND_SUMMARY_LEAK_CHECK would be
128 // better.
129 //
130 // ----
131 //
132 // Also, VALGRIND_COUNT_LEAKS and VALGRIND_COUNT_LEAK_BLOCKS aren't great as
133 // they combine direct leaks and indirect leaks into one.  New, more precise
134 // ones (they'll need new names) would be good.  If more categories are
135 // used, as per the --follow-interior-pointers option, they should be
136 // updated accordingly.  And they should use a struct to return the values.
137 //
138 // ----
139 //
140 // Also, for this case:
141 //
142 //  (4)  p4      BBB ---> AAA
143 //
144 // BBB is definitely directly lost.  AAA is definitely indirectly lost.
145 // Here's the relevant loss records printed for a full check (each block is
146 // 16 bytes):
147 //
148 // ==20397== 16 bytes in 1 blocks are indirectly lost in loss record 9 of 15
149 // ==20397==    at 0x4C2694E: malloc (vg_replace_malloc.c:177)
150 // ==20397==    by 0x400521: mk (leak-cases.c:49)
151 // ==20397==    by 0x400578: main (leak-cases.c:72)
152 //
153 // ==20397== 32 (16 direct, 16 indirect) bytes in 1 blocks are definitely
154 // lost in loss record 14 of 15
155 // ==20397==    at 0x4C2694E: malloc (vg_replace_malloc.c:177)
156 // ==20397==    by 0x400521: mk (leak-cases.c:49)
157 // ==20397==    by 0x400580: main (leak-cases.c:72)
158 //
159 // The first one is fine -- it describes AAA.
160 //
161 // The second one is for BBB.  It's correct in that 16 bytes in 1 block are
162 // directly lost. It's also correct that 16 are indirectly lost as a result,
163 // but it means that AAA is being counted twice in the loss records.  (It's
164 // not, thankfully, counted twice in the summary counts).  Argh.
165 //
166 // This would be less confusing for the second one:
167 //
168 // ==20397== 16 bytes in 1 blocks are definitely lost in loss record 14
169 // of 15 (and 16 bytes in 1 block are indirectly lost as a result;  they
170 // are mentioned elsewhere (if --show-reachable=yes is given!))
171 // ==20397==    at 0x4C2694E: malloc (vg_replace_malloc.c:177)
172 // ==20397==    by 0x400521: mk (leak-cases.c:49)
173 // ==20397==    by 0x400580: main (leak-cases.c:72)
174 //
175 // But ideally we'd present the loss record for the directly lost block and
176 // then the resultant indirectly lost blocks and make it clear the
177 // dependence.  Double argh.
178 
179 /*------------------------------------------------------------*/
180 /*--- The actual algorithm.                                ---*/
181 /*------------------------------------------------------------*/
182 
183 // - Find all the blocks (a.k.a. chunks) to check.  Mempool chunks require
184 //   some special treatment because they can be within malloc'd blocks.
185 // - Scan every word in the root set (GP registers and valid
186 //   non-heap memory words).
187 //   - First, we skip if it doesn't point to valid memory.
188 //   - Then, we see if it points to the start or interior of a block.  If
189 //     so, we push the block onto the mark stack and mark it as having been
190 //     reached.
191 // - Then, we process the mark stack, repeating the scanning for each block;
192 //   this can push more blocks onto the mark stack.  We repeat until the
193 //   mark stack is empty.  Each block is marked as definitely or possibly
194 //   reachable, depending on whether interior-pointers were required to
195 //   reach it.
196 // - At this point we know for every block if it's reachable or not.
197 // - We then push each unreached block onto the mark stack, using the block
198 //   number as the "clique" number.
199 // - We process the mark stack again, this time grouping blocks into cliques
200 //   in order to facilitate the directly/indirectly lost categorisation.
201 // - We group blocks by their ExeContexts and categorisation, and print them
202 //   if --leak-check=full.  We also print summary numbers.
203 //
204 // A note on "cliques":
205 // - A directly lost block is one with no pointers to it.  An indirectly
206 //   lost block is one that is pointed to by a directly or indirectly lost
207 //   block.
208 // - Each directly lost block has zero or more indirectly lost blocks
209 //   hanging off it.  All these blocks together form a "clique".  The
210 //   directly lost block is called the "clique leader".  The clique number
211 //   is the number (in lc_chunks[]) of the clique leader.
212 // - Actually, a directly lost block may be pointed to if it's part of a
213 //   cycle.  In that case, there may be more than one choice for the clique
214 //   leader, and the choice is arbitrary.  Eg. if you have A-->B and B-->A
215 //   either A or B could be the clique leader.
216 // - Cliques cannot overlap, and will be truncated to avoid this.  Eg. if we
217 //   have A-->C and B-->C, the two cliques will be {A,C} and {B}, or {A} and
218 //   {B,C} (again the choice is arbitrary).  This is because we don't want
219 //   to count a block as indirectly lost more than once.
220 //
221 // A note on 'is_prior_definite':
222 // - This is a boolean used in various places that indicates if the chain
223 //   up to the prior node (prior to the one being considered) is definite.
224 // - In the clique == -1 case:
225 //   - if True it means that the prior node is a root-set node, or that the
226 //     prior node is a block which is reachable from the root-set via
227 //     start-pointers.
228 //   - if False it means that the prior node is a block that is only
229 //     reachable from the root-set via a path including at least one
230 //     interior-pointer.
231 // - In the clique != -1 case, currently it's always True because we treat
232 //   start-pointers and interior-pointers the same for direct/indirect leak
233 //   checking.  If we added a PossibleIndirectLeak state then this would
234 //   change.
235 
236 
237 // Define to debug the memory-leak-detector.
238 #define VG_DEBUG_LEAKCHECK 0
239 #define VG_DEBUG_CLIQUE    0
240 
241 
242 /*------------------------------------------------------------*/
243 /*--- Getting the initial chunks, and searching them.      ---*/
244 /*------------------------------------------------------------*/
245 
246 // Compare the MC_Chunks by 'data' (i.e. the address of the block).
compare_MC_Chunks(void * n1,void * n2)247 static Int compare_MC_Chunks(void* n1, void* n2)
248 {
249    MC_Chunk* mc1 = *(MC_Chunk**)n1;
250    MC_Chunk* mc2 = *(MC_Chunk**)n2;
251    if (mc1->data < mc2->data) return -1;
252    if (mc1->data > mc2->data) return  1;
253    return 0;
254 }
255 
256 #if VG_DEBUG_LEAKCHECK
257 // Used to sanity-check the fast binary-search mechanism.
258 static
find_chunk_for_OLD(Addr ptr,MC_Chunk ** chunks,Int n_chunks)259 Int find_chunk_for_OLD ( Addr       ptr,
260                          MC_Chunk** chunks,
261                          Int        n_chunks )
262 
263 {
264    Int  i;
265    Addr a_lo, a_hi;
266    PROF_EVENT(70, "find_chunk_for_OLD");
267    for (i = 0; i < n_chunks; i++) {
268       PROF_EVENT(71, "find_chunk_for_OLD(loop)");
269       a_lo = chunks[i]->data;
270       a_hi = ((Addr)chunks[i]->data) + chunks[i]->szB;
271       if (a_lo <= ptr && ptr < a_hi)
272          return i;
273    }
274    return -1;
275 }
276 #endif
277 
278 // Find the i such that ptr points at or inside the block described by
279 // chunks[i].  Return -1 if none found.  This assumes that chunks[]
280 // has been sorted on the 'data' field.
281 static
find_chunk_for(Addr ptr,MC_Chunk ** chunks,Int n_chunks)282 Int find_chunk_for ( Addr       ptr,
283                      MC_Chunk** chunks,
284                      Int        n_chunks )
285 {
286    Addr a_mid_lo, a_mid_hi;
287    Int lo, mid, hi, retVal;
288    // VG_(printf)("find chunk for %p = ", ptr);
289    retVal = -1;
290    lo = 0;
291    hi = n_chunks-1;
292    while (True) {
293       // Invariant: current unsearched space is from lo to hi, inclusive.
294       if (lo > hi) break; // not found
295 
296       mid      = (lo + hi) / 2;
297       a_mid_lo = chunks[mid]->data;
298       a_mid_hi = chunks[mid]->data + chunks[mid]->szB;
299       // Extent of block 'mid' is [a_mid_lo .. a_mid_hi).
300       // Special-case zero-sized blocks - treat them as if they had
301       // size 1.  Not doing so causes them to not cover any address
302       // range at all and so will never be identified as the target of
303       // any pointer, which causes them to be incorrectly reported as
304       // definitely leaked.
305       if (chunks[mid]->szB == 0)
306          a_mid_hi++;
307 
308       if (ptr < a_mid_lo) {
309          hi = mid-1;
310          continue;
311       }
312       if (ptr >= a_mid_hi) {
313          lo = mid+1;
314          continue;
315       }
316       tl_assert(ptr >= a_mid_lo && ptr < a_mid_hi);
317       retVal = mid;
318       break;
319    }
320 
321 #  if VG_DEBUG_LEAKCHECK
322    tl_assert(retVal == find_chunk_for_OLD ( ptr, chunks, n_chunks ));
323 #  endif
324    // VG_(printf)("%d\n", retVal);
325    return retVal;
326 }
327 
328 
329 static MC_Chunk**
find_active_chunks(UInt * pn_chunks)330 find_active_chunks(UInt* pn_chunks)
331 {
332    // Our goal is to construct a set of chunks that includes every
333    // mempool chunk, and every malloc region that *doesn't* contain a
334    // mempool chunk.
335    MC_Mempool *mp;
336    MC_Chunk **mallocs, **chunks, *mc;
337    UInt n_mallocs, n_chunks, m, s;
338    Bool *malloc_chunk_holds_a_pool_chunk;
339 
340    // First we collect all the malloc chunks into an array and sort it.
341    // We do this because we want to query the chunks by interior
342    // pointers, requiring binary search.
343    mallocs = (MC_Chunk**) VG_(HT_to_array)( MC_(malloc_list), &n_mallocs );
344    if (n_mallocs == 0) {
345       tl_assert(mallocs == NULL);
346       *pn_chunks = 0;
347       return NULL;
348    }
349    VG_(ssort)(mallocs, n_mallocs, sizeof(VgHashNode*), compare_MC_Chunks);
350 
351    // Then we build an array containing a Bool for each malloc chunk,
352    // indicating whether it contains any mempools.
353    malloc_chunk_holds_a_pool_chunk = VG_(calloc)( "mc.fas.1",
354                                                   n_mallocs, sizeof(Bool) );
355    n_chunks = n_mallocs;
356 
357    // Then we loop over the mempool tables. For each chunk in each
358    // pool, we set the entry in the Bool array corresponding to the
359    // malloc chunk containing the mempool chunk.
360    VG_(HT_ResetIter)(MC_(mempool_list));
361    while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
362       VG_(HT_ResetIter)(mp->chunks);
363       while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
364 
365          // We'll need to record this chunk.
366          n_chunks++;
367 
368          // Possibly invalidate the malloc holding the beginning of this chunk.
369          m = find_chunk_for(mc->data, mallocs, n_mallocs);
370          if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
371             tl_assert(n_chunks > 0);
372             n_chunks--;
373             malloc_chunk_holds_a_pool_chunk[m] = True;
374          }
375 
376          // Possibly invalidate the malloc holding the end of this chunk.
377          if (mc->szB > 1) {
378             m = find_chunk_for(mc->data + (mc->szB - 1), mallocs, n_mallocs);
379             if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
380                tl_assert(n_chunks > 0);
381                n_chunks--;
382                malloc_chunk_holds_a_pool_chunk[m] = True;
383             }
384          }
385       }
386    }
387    tl_assert(n_chunks > 0);
388 
389    // Create final chunk array.
390    chunks = VG_(malloc)("mc.fas.2", sizeof(VgHashNode*) * (n_chunks));
391    s = 0;
392 
393    // Copy the mempool chunks and the non-marked malloc chunks into a
394    // combined array of chunks.
395    VG_(HT_ResetIter)(MC_(mempool_list));
396    while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
397       VG_(HT_ResetIter)(mp->chunks);
398       while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
399          tl_assert(s < n_chunks);
400          chunks[s++] = mc;
401       }
402    }
403    for (m = 0; m < n_mallocs; ++m) {
404       if (!malloc_chunk_holds_a_pool_chunk[m]) {
405          tl_assert(s < n_chunks);
406          chunks[s++] = mallocs[m];
407       }
408    }
409    tl_assert(s == n_chunks);
410 
411    // Free temporaries.
412    VG_(free)(mallocs);
413    VG_(free)(malloc_chunk_holds_a_pool_chunk);
414 
415    *pn_chunks = n_chunks;
416 
417    return chunks;
418 }
419 
420 /*------------------------------------------------------------*/
421 /*--- The leak detector proper.                            ---*/
422 /*------------------------------------------------------------*/
423 
424 // Holds extra info about each block during leak checking.
425 typedef
426    struct {
427       UInt  state:2;    // Reachedness.
428       UInt  pending:1;  // Scan pending.
429       union {
430          SizeT indirect_szB : (sizeof(SizeT)*8)-3; // If Unreached, how many bytes
431                                                    //   are unreachable from here.
432          SizeT  clique :  (sizeof(SizeT)*8)-3;      // if IndirectLeak, clique leader
433                                                    // to which it belongs.
434       } IorC;
435    }
436    LC_Extra;
437 
438 // An array holding pointers to every chunk we're checking.  Sorted by address.
439 // lc_chunks is initialised during leak search. It is kept after leak search
440 // to support printing the list of blocks belonging to a loss record.
441 // lc_chunk array can only be used validly till the next "free" operation
442 // (as a free operation potentially destroys one or more chunks).
443 // To detect lc_chunk is valid, we store the nr of frees operations done
444 // when lc_chunk was build : lc_chunks (and lc_extras) stays valid as
445 // long as no free operations has been done since lc_chunks building.
446 static MC_Chunk** lc_chunks;
447 // How many chunks we're dealing with.
448 static Int        lc_n_chunks;
449 static SizeT lc_chunks_n_frees_marker;
450 // This has the same number of entries as lc_chunks, and each entry
451 // in lc_chunks corresponds with the entry here (ie. lc_chunks[i] and
452 // lc_extras[i] describe the same block).
453 static LC_Extra* lc_extras;
454 
455 // chunks will be converted and merged in loss record, maintained in lr_table
456 // lr_table elements are kept from one leak_search to another to implement
457 // the "print new/changed leaks" client request
458 static OSet*        lr_table;
459 // Array of sorted loss record (produced during last leak search).
460 static LossRecord** lr_array;
461 
462 
463 // DeltaMode used the last time we called detect_memory_leaks.
464 // The recorded leak errors must be output using a logic based on this delta_mode.
465 // The below avoids replicating the delta_mode in each LossRecord.
466 LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
467 
468 
469 // Records chunks that are currently being processed.  Each element in the
470 // stack is an index into lc_chunks and lc_extras.  Its size is
471 // 'lc_n_chunks' because in the worst case that's how many chunks could be
472 // pushed onto it (actually I think the maximum is lc_n_chunks-1 but let's
473 // be conservative).
474 static Int* lc_markstack;
475 // The index of the top element of the stack; -1 if the stack is empty, 0 if
476 // the stack has one element, 1 if it has two, etc.
477 static Int  lc_markstack_top;
478 
479 // Keeps track of how many bytes of memory we've scanned, for printing.
480 // (Nb: We don't keep track of how many register bytes we've scanned.)
481 static SizeT lc_scanned_szB;
482 
483 
484 SizeT MC_(bytes_leaked)     = 0;
485 SizeT MC_(bytes_indirect)   = 0;
486 SizeT MC_(bytes_dubious)    = 0;
487 SizeT MC_(bytes_reachable)  = 0;
488 SizeT MC_(bytes_suppressed) = 0;
489 
490 SizeT MC_(blocks_leaked)     = 0;
491 SizeT MC_(blocks_indirect)   = 0;
492 SizeT MC_(blocks_dubious)    = 0;
493 SizeT MC_(blocks_reachable)  = 0;
494 SizeT MC_(blocks_suppressed) = 0;
495 
496 // Determines if a pointer is to a chunk.  Returns the chunk number et al
497 // via call-by-reference.
498 static Bool
lc_is_a_chunk_ptr(Addr ptr,Int * pch_no,MC_Chunk ** pch,LC_Extra ** pex)499 lc_is_a_chunk_ptr(Addr ptr, Int* pch_no, MC_Chunk** pch, LC_Extra** pex)
500 {
501    Int ch_no;
502    MC_Chunk* ch;
503    LC_Extra* ex;
504 
505    // Quick filter. Note: implemented with am, not with get_vabits2
506    // as ptr might be random data pointing anywhere. On 64 bit
507    // platforms, getting va bits for random data can be quite costly
508    // due to the secondary map.
509    if (!VG_(am_is_valid_for_client)(ptr, 1, VKI_PROT_READ)) {
510       return False;
511    } else {
512       ch_no = find_chunk_for(ptr, lc_chunks, lc_n_chunks);
513       tl_assert(ch_no >= -1 && ch_no < lc_n_chunks);
514 
515       if (ch_no == -1) {
516          return False;
517       } else {
518          // Ok, we've found a pointer to a chunk.  Get the MC_Chunk and its
519          // LC_Extra.
520          ch = lc_chunks[ch_no];
521          ex = &(lc_extras[ch_no]);
522 
523          tl_assert(ptr >= ch->data);
524          tl_assert(ptr < ch->data + ch->szB + (ch->szB==0  ? 1  : 0));
525 
526          if (VG_DEBUG_LEAKCHECK)
527             VG_(printf)("ptr=%#lx -> block %d\n", ptr, ch_no);
528 
529          *pch_no = ch_no;
530          *pch    = ch;
531          *pex    = ex;
532 
533          return True;
534       }
535    }
536 }
537 
538 // Push a chunk (well, just its index) onto the mark stack.
lc_push(Int ch_no,MC_Chunk * ch)539 static void lc_push(Int ch_no, MC_Chunk* ch)
540 {
541    if (!lc_extras[ch_no].pending) {
542       if (0) {
543          VG_(printf)("pushing %#lx-%#lx\n", ch->data, ch->data + ch->szB);
544       }
545       lc_markstack_top++;
546       tl_assert(lc_markstack_top < lc_n_chunks);
547       lc_markstack[lc_markstack_top] = ch_no;
548       tl_assert(!lc_extras[ch_no].pending);
549       lc_extras[ch_no].pending = True;
550    }
551 }
552 
553 // Return the index of the chunk on the top of the mark stack, or -1 if
554 // there isn't one.
lc_pop(Int * ret)555 static Bool lc_pop(Int* ret)
556 {
557    if (-1 == lc_markstack_top) {
558       return False;
559    } else {
560       tl_assert(0 <= lc_markstack_top && lc_markstack_top < lc_n_chunks);
561       *ret = lc_markstack[lc_markstack_top];
562       lc_markstack_top--;
563       tl_assert(lc_extras[*ret].pending);
564       lc_extras[*ret].pending = False;
565       return True;
566    }
567 }
568 
569 
570 // If 'ptr' is pointing to a heap-allocated block which hasn't been seen
571 // before, push it onto the mark stack.
572 static void
lc_push_without_clique_if_a_chunk_ptr(Addr ptr,Bool is_prior_definite)573 lc_push_without_clique_if_a_chunk_ptr(Addr ptr, Bool is_prior_definite)
574 {
575    Int ch_no;
576    MC_Chunk* ch;
577    LC_Extra* ex;
578 
579    if ( ! lc_is_a_chunk_ptr(ptr, &ch_no, &ch, &ex) )
580       return;
581 
582    // Possibly upgrade the state, ie. one of:
583    // - Unreached --> Possible
584    // - Unreached --> Reachable
585    // - Possible  --> Reachable
586    if (ptr == ch->data && is_prior_definite && ex->state != Reachable) {
587       // 'ptr' points to the start of the block, and the prior node is
588       // definite, which means that this block is definitely reachable.
589       ex->state = Reachable;
590 
591       // State has changed to Reachable so (re)scan the block to make
592       // sure any blocks it points to are correctly marked.
593       lc_push(ch_no, ch);
594 
595    } else if (ex->state == Unreached) {
596       // Either 'ptr' is a interior-pointer, or the prior node isn't definite,
597       // which means that we can only mark this block as possibly reachable.
598       ex->state = Possible;
599 
600       // State has changed to Possible so (re)scan the block to make
601       // sure any blocks it points to are correctly marked.
602       lc_push(ch_no, ch);
603    }
604 }
605 
606 static void
lc_push_if_a_chunk_ptr_register(ThreadId tid,HChar * regname,Addr ptr)607 lc_push_if_a_chunk_ptr_register(ThreadId tid, HChar* regname, Addr ptr)
608 {
609    lc_push_without_clique_if_a_chunk_ptr(ptr, /*is_prior_definite*/True);
610 }
611 
612 // If ptr is pointing to a heap-allocated block which hasn't been seen
613 // before, push it onto the mark stack.  Clique is the index of the
614 // clique leader.
615 static void
lc_push_with_clique_if_a_chunk_ptr(Addr ptr,Int clique,Int cur_clique)616 lc_push_with_clique_if_a_chunk_ptr(Addr ptr, Int clique, Int cur_clique)
617 {
618    Int ch_no;
619    MC_Chunk* ch;
620    LC_Extra* ex;
621 
622    tl_assert(0 <= clique && clique < lc_n_chunks);
623 
624    if ( ! lc_is_a_chunk_ptr(ptr, &ch_no, &ch, &ex) )
625       return;
626 
627    // If it's not Unreached, it's already been handled so ignore it.
628    // If ch_no==clique, it's the clique leader, which means this is a cyclic
629    // structure;  again ignore it because it's already been handled.
630    if (ex->state == Unreached && ch_no != clique) {
631       // Note that, unlike reachable blocks, we currently don't distinguish
632       // between start-pointers and interior-pointers here.  We probably
633       // should, though.
634       lc_push(ch_no, ch);
635 
636       // Add the block to the clique, and add its size to the
637       // clique-leader's indirect size.  Also, if the new block was
638       // itself a clique leader, it isn't any more, so add its
639       // indirect_szB to the new clique leader.
640       if (VG_DEBUG_CLIQUE) {
641          if (ex->IorC.indirect_szB > 0)
642             VG_(printf)("  clique %d joining clique %d adding %lu+%lu\n",
643                         ch_no, clique, (unsigned long)ch->szB,
644 			(unsigned long)ex->IorC.indirect_szB);
645          else
646             VG_(printf)("  block %d joining clique %d adding %lu\n",
647                         ch_no, clique, (unsigned long)ch->szB);
648       }
649 
650       lc_extras[clique].IorC.indirect_szB += ch->szB;
651       lc_extras[clique].IorC.indirect_szB += ex->IorC.indirect_szB;
652       ex->state = IndirectLeak;
653       ex->IorC.clique = (SizeT) cur_clique;
654    }
655 }
656 
657 static void
lc_push_if_a_chunk_ptr(Addr ptr,Int clique,Int cur_clique,Bool is_prior_definite)658 lc_push_if_a_chunk_ptr(Addr ptr, Int clique, Int cur_clique, Bool is_prior_definite)
659 {
660    if (-1 == clique)
661       lc_push_without_clique_if_a_chunk_ptr(ptr, is_prior_definite);
662    else
663       lc_push_with_clique_if_a_chunk_ptr(ptr, clique, cur_clique);
664 }
665 
666 
667 static VG_MINIMAL_JMP_BUF(memscan_jmpbuf);
668 
669 static
scan_all_valid_memory_catcher(Int sigNo,Addr addr)670 void scan_all_valid_memory_catcher ( Int sigNo, Addr addr )
671 {
672    if (0)
673       VG_(printf)("OUCH! sig=%d addr=%#lx\n", sigNo, addr);
674    if (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS)
675       VG_MINIMAL_LONGJMP(memscan_jmpbuf);
676 }
677 
678 // lc_scan_memory has 2 modes:
679 //
680 // 1. Leak check mode (searched == 0).
681 // -----------------------------------
682 // Scan a block of memory between [start, start+len).  This range may
683 // be bogus, inaccessable, or otherwise strange; we deal with it.  For each
684 // valid aligned word we assume it's a pointer to a chunk a push the chunk
685 // onto the mark stack if so.
686 // clique is the "highest level clique" in which indirectly leaked blocks have
687 // to be collected. cur_clique is the current "lower" level clique through which
688 // the memory to be scanned has been found.
689 // Example: in the below tree if A is leaked, the top level clique will
690 //   be A, while lower level cliques will be B and C.
691 /*
692            A
693          /   \
694         B     C
695        / \   / \
696       D   E F   G
697 */
698 // Proper handling of top and lowest level clique allows block_list of a loss
699 // record to describe the hierarchy of indirectly leaked blocks.
700 //
701 // 2. Search ptr mode (searched != 0).
702 // -----------------------------------
703 // In this mode, searches for pointers to a specific address range
704 // In such a case, lc_scan_memory just scans [start..start+len[ for pointers to searched
705 // and outputs the places where searched is found. It does not recursively scans the
706 // found memory.
707 static void
lc_scan_memory(Addr start,SizeT len,Bool is_prior_definite,Int clique,Int cur_clique,Addr searched,SizeT szB)708 lc_scan_memory(Addr start, SizeT len, Bool is_prior_definite, Int clique, Int cur_clique,
709                Addr searched, SizeT szB)
710 {
711    /* memory scan is based on the assumption that valid pointers are aligned
712       on a multiple of sizeof(Addr). So, we can (and must) skip the begin and
713       end portions of the block if they are not aligned on sizeof(Addr):
714       These cannot be a valid pointer, and calls to MC_(is_valid_aligned_word)
715       will assert for a non aligned address. */
716    Addr ptr = VG_ROUNDUP(start,     sizeof(Addr));
717    Addr end = VG_ROUNDDN(start+len, sizeof(Addr));
718    vki_sigset_t sigmask;
719 
720    if (VG_DEBUG_LEAKCHECK)
721       VG_(printf)("scan %#lx-%#lx (%lu)\n", start, end, len);
722 
723    VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &sigmask);
724    VG_(set_fault_catcher)(scan_all_valid_memory_catcher);
725 
726    /* Optimisation: the loop below will check for each begin
727       of SM chunk if the chunk is fully unaddressable. The idea is to
728       skip efficiently such fully unaddressable SM chunks.
729       So, we preferrably start the loop on a chunk boundary.
730       If the chunk is not fully unaddressable, we might be in
731       an unaddressable page. Again, the idea is to skip efficiently
732       such unaddressable page : this is the "else" part.
733       We use an "else" so that two consecutive fully unaddressable
734       SM chunks will be skipped efficiently: first one is skipped
735       by this piece of code. The next SM chunk will be skipped inside
736       the loop. */
737    if ( ! MC_(is_within_valid_secondary)(ptr) ) {
738       // Skip an invalid SM chunk till the beginning of the next SM Chunk.
739       ptr = VG_ROUNDUP(ptr+1, SM_SIZE);
740    } else if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ)) {
741       // else we are in a (at least partially) valid SM chunk.
742       // We might be in the middle of an unreadable page.
743       // Do a cheap check to see if it's valid;
744       // if not, skip onto the next page.
745       ptr = VG_PGROUNDUP(ptr+1);        // First page is bad - skip it.
746    }
747    /* This optimisation and below loop is based on some relationships between
748       VKI_PAGE_SIZE, SM_SIZE and sizeof(Addr) which are asserted in
749       MC_(detect_memory_leaks). */
750 
751    while (ptr < end) {
752       Addr addr;
753 
754       // Skip invalid chunks.
755       if (UNLIKELY((ptr % SM_SIZE) == 0)) {
756          if (! MC_(is_within_valid_secondary)(ptr) ) {
757             ptr = VG_ROUNDUP(ptr+1, SM_SIZE);
758             continue;
759          }
760       }
761 
762       // Look to see if this page seems reasonable.
763       if (UNLIKELY((ptr % VKI_PAGE_SIZE) == 0)) {
764          if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ)) {
765             ptr += VKI_PAGE_SIZE;      // Bad page - skip it.
766             continue;
767          }
768          // aspacemgr indicates the page is readable and belongs to client.
769          // We still probe the page explicitely in case aspacemgr is
770          // desynchronised with the real page mappings.
771          // Such a desynchronisation can happen due to an aspacemgr bug.
772          // Note that if the application is using mprotect(NONE), then
773          // a page can be unreadable but have addressable and defined
774          // VA bits (see mc_main.c function mc_new_mem_mprotect).
775          if (VG_MINIMAL_SETJMP(memscan_jmpbuf) == 0) {
776             // Try a read in the beginning of the page ...
777             Addr test = *(volatile Addr *)ptr;
778             __asm__ __volatile__("": :"r"(test) : "cc","memory");
779          } else {
780             // Catch read error ...
781             // We need to restore the signal mask, because we were
782             // longjmped out of a signal handler.
783             VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);
784             ptr += VKI_PAGE_SIZE;      // Bad page - skip it.
785             continue;
786          }
787       }
788 
789       if ( MC_(is_valid_aligned_word)(ptr) ) {
790          lc_scanned_szB += sizeof(Addr);
791          addr = *(Addr *)ptr;
792          // If we get here, the scanned word is in valid memory.  Now
793          // let's see if its contents point to a chunk.
794          if (UNLIKELY(searched)) {
795             if (addr >= searched && addr < searched + szB) {
796                if (addr == searched)
797                   VG_(umsg)("*%#lx points at %#lx\n", ptr, searched);
798                else
799                   VG_(umsg)("*%#lx interior points at %lu bytes inside %#lx\n",
800                             ptr, (long unsigned) addr - searched, searched);
801                MC_(pp_describe_addr) (ptr);
802             }
803          } else {
804             lc_push_if_a_chunk_ptr(addr, clique, cur_clique, is_prior_definite);
805          }
806       } else if (0 && VG_DEBUG_LEAKCHECK) {
807          VG_(printf)("%#lx not valid\n", ptr);
808       }
809       ptr += sizeof(Addr);
810    }
811 
812    VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);
813    VG_(set_fault_catcher)(NULL);
814 }
815 
816 
817 // Process the mark stack until empty.
lc_process_markstack(Int clique)818 static void lc_process_markstack(Int clique)
819 {
820    Int  top = -1;    // shut gcc up
821    Bool is_prior_definite;
822 
823    while (lc_pop(&top)) {
824       tl_assert(top >= 0 && top < lc_n_chunks);
825 
826       // See comment about 'is_prior_definite' at the top to understand this.
827       is_prior_definite = ( Possible != lc_extras[top].state );
828 
829       lc_scan_memory(lc_chunks[top]->data, lc_chunks[top]->szB,
830                      is_prior_definite, clique, (clique == -1 ? -1 : top),
831                      /*searched*/ 0, 0);
832    }
833 }
834 
cmp_LossRecordKey_LossRecord(const void * key,const void * elem)835 static Word cmp_LossRecordKey_LossRecord(const void* key, const void* elem)
836 {
837    LossRecordKey* a = (LossRecordKey*)key;
838    LossRecordKey* b = &(((LossRecord*)elem)->key);
839 
840    // Compare on states first because that's fast.
841    if (a->state < b->state) return -1;
842    if (a->state > b->state) return  1;
843    // Ok, the states are equal.  Now compare the locations, which is slower.
844    if (VG_(eq_ExeContext)(
845             MC_(clo_leak_resolution), a->allocated_at, b->allocated_at))
846       return 0;
847    // Different locations.  Ordering is arbitrary, just use the ec pointer.
848    if (a->allocated_at < b->allocated_at) return -1;
849    if (a->allocated_at > b->allocated_at) return  1;
850    VG_(tool_panic)("bad LossRecord comparison");
851 }
852 
cmp_LossRecords(void * va,void * vb)853 static Int cmp_LossRecords(void* va, void* vb)
854 {
855    LossRecord* lr_a = *(LossRecord**)va;
856    LossRecord* lr_b = *(LossRecord**)vb;
857    SizeT total_szB_a = lr_a->szB + lr_a->indirect_szB;
858    SizeT total_szB_b = lr_b->szB + lr_b->indirect_szB;
859 
860    // First compare by sizes.
861    if (total_szB_a < total_szB_b) return -1;
862    if (total_szB_a > total_szB_b) return  1;
863    // If size are equal, compare by states.
864    if (lr_a->key.state < lr_b->key.state) return -1;
865    if (lr_a->key.state > lr_b->key.state) return  1;
866    // If they're still equal here, it doesn't matter that much, but we keep
867    // comparing other things so that regtests are as deterministic as
868    // possible.  So:  compare num_blocks.
869    if (lr_a->num_blocks < lr_b->num_blocks) return -1;
870    if (lr_a->num_blocks > lr_b->num_blocks) return  1;
871    // Finally, compare ExeContext addresses... older ones are likely to have
872    // lower addresses.
873    if (lr_a->key.allocated_at < lr_b->key.allocated_at) return -1;
874    if (lr_a->key.allocated_at > lr_b->key.allocated_at) return  1;
875    return 0;
876 }
877 
878 // allocates or reallocates lr_array, and set its elements to the loss records
879 // contains in lr_table.
get_lr_array_from_lr_table(void)880 static Int get_lr_array_from_lr_table(void) {
881    Int          i, n_lossrecords;
882    LossRecord*  lr;
883 
884    n_lossrecords = VG_(OSetGen_Size)(lr_table);
885 
886    // (re-)create the array of pointers to the loss records.
887    // lr_array is kept to allow producing the block list from gdbserver.
888    if (lr_array != NULL)
889       VG_(free)(lr_array);
890    lr_array = VG_(malloc)("mc.pr.2", n_lossrecords * sizeof(LossRecord*));
891    i = 0;
892    VG_(OSetGen_ResetIter)(lr_table);
893    while ( (lr = VG_(OSetGen_Next)(lr_table)) ) {
894       lr_array[i++] = lr;
895    }
896    tl_assert(i == n_lossrecords);
897    return n_lossrecords;
898 }
899 
900 
get_printing_rules(LeakCheckParams * lcp,LossRecord * lr,Bool * count_as_error,Bool * print_record)901 static void get_printing_rules(LeakCheckParams* lcp,
902                                LossRecord*  lr,
903                                Bool* count_as_error,
904                                Bool* print_record)
905 {
906    // Rules for printing:
907    // - We don't show suppressed loss records ever (and that's controlled
908    //   within the error manager).
909    // - We show non-suppressed loss records that are not "reachable" if
910    //   --leak-check=yes.
911    // - We show all non-suppressed loss records if --leak-check=yes and
912    //   --show-reachable=yes.
913    //
914    // Nb: here "reachable" means Reachable *or* IndirectLeak;  note that
915    // this is different to "still reachable" used elsewhere because it
916    // includes indirectly lost blocks!
917 
918    Bool delta_considered;
919 
920    switch (lcp->deltamode) {
921    case LCD_Any:
922       delta_considered = lr->num_blocks > 0;
923       break;
924    case LCD_Increased:
925       delta_considered
926          = lr->szB > lr->old_szB
927          || lr->indirect_szB > lr->old_indirect_szB
928          || lr->num_blocks > lr->old_num_blocks;
929       break;
930    case LCD_Changed:
931       delta_considered = lr->szB != lr->old_szB
932          || lr->indirect_szB != lr->old_indirect_szB
933          || lr->num_blocks != lr->old_num_blocks;
934       break;
935    default:
936       tl_assert(0);
937    }
938 
939    *print_record = lcp->mode == LC_Full && delta_considered &&
940       ( lcp->show_reachable ||
941         Unreached == lr->key.state ||
942         ( lcp->show_possibly_lost &&
943           Possible  == lr->key.state ) );
944    // We don't count a leaks as errors with lcp->mode==LC_Summary.
945    // Otherwise you can get high error counts with few or no error
946    // messages, which can be confusing.  Also, you could argue that
947    // indirect leaks should be counted as errors, but it seems better to
948    // make the counting criteria similar to the printing criteria.  So we
949    // don't count them.
950    *count_as_error = lcp->mode == LC_Full && delta_considered &&
951       ( Unreached == lr->key.state ||
952         Possible  == lr->key.state );
953 }
954 
print_results(ThreadId tid,LeakCheckParams * lcp)955 static void print_results(ThreadId tid, LeakCheckParams* lcp)
956 {
957    Int          i, n_lossrecords, start_lr_output_scan;
958    LossRecord*  lr;
959    Bool         is_suppressed;
960    SizeT        old_bytes_leaked      = MC_(bytes_leaked); /* to report delta in summary */
961    SizeT        old_bytes_indirect    = MC_(bytes_indirect);
962    SizeT        old_bytes_dubious     = MC_(bytes_dubious);
963    SizeT        old_bytes_reachable   = MC_(bytes_reachable);
964    SizeT        old_bytes_suppressed  = MC_(bytes_suppressed);
965    SizeT        old_blocks_leaked     = MC_(blocks_leaked);
966    SizeT        old_blocks_indirect   = MC_(blocks_indirect);
967    SizeT        old_blocks_dubious    = MC_(blocks_dubious);
968    SizeT        old_blocks_reachable  = MC_(blocks_reachable);
969    SizeT        old_blocks_suppressed = MC_(blocks_suppressed);
970 
971    if (lr_table == NULL)
972       // Create the lr_table, which holds the loss records.
973       // If the lr_table already exists, it means it contains
974       // loss_records from the previous leak search. The old_*
975       // values in these records are used to implement the
976       // leak check delta mode
977       lr_table =
978          VG_(OSetGen_Create)(offsetof(LossRecord, key),
979                              cmp_LossRecordKey_LossRecord,
980                              VG_(malloc), "mc.pr.1",
981                              VG_(free));
982 
983    // If we have loss records from a previous search, reset values to have
984    // proper printing of the deltas between previous search and this search.
985    n_lossrecords = get_lr_array_from_lr_table();
986    for (i = 0; i < n_lossrecords; i++) {
987       if (lr_array[i]->num_blocks == 0) {
988          // remove from lr_table the old loss_records with 0 bytes found
989          VG_(OSetGen_Remove) (lr_table, &lr_array[i]->key);
990          VG_(OSetGen_FreeNode)(lr_table, lr_array[i]);
991       } else {
992          // move the leak sizes to old_* and zero the current sizes
993          // for next leak search
994          lr_array[i]->old_szB          = lr_array[i]->szB;
995          lr_array[i]->old_indirect_szB = lr_array[i]->indirect_szB;
996          lr_array[i]->old_num_blocks   = lr_array[i]->num_blocks;
997          lr_array[i]->szB              = 0;
998          lr_array[i]->indirect_szB     = 0;
999          lr_array[i]->num_blocks       = 0;
1000       }
1001    }
1002    // lr_array now contains "invalid" loss records => free it.
1003    // lr_array will be re-created below with the kept and new loss records.
1004    VG_(free) (lr_array);
1005    lr_array = NULL;
1006 
1007    // Convert the chunks into loss records, merging them where appropriate.
1008    for (i = 0; i < lc_n_chunks; i++) {
1009       MC_Chunk*     ch = lc_chunks[i];
1010       LC_Extra*     ex = &(lc_extras)[i];
1011       LossRecord*   old_lr;
1012       LossRecordKey lrkey;
1013       lrkey.state        = ex->state;
1014       lrkey.allocated_at = ch->where;
1015 
1016       old_lr = VG_(OSetGen_Lookup)(lr_table, &lrkey);
1017       if (old_lr) {
1018          // We found an existing loss record matching this chunk.  Update the
1019          // loss record's details in-situ.  This is safe because we don't
1020          // change the elements used as the OSet key.
1021          old_lr->szB          += ch->szB;
1022          if (ex->state == Unreached)
1023             old_lr->indirect_szB += ex->IorC.indirect_szB;
1024          old_lr->num_blocks++;
1025       } else {
1026          // No existing loss record matches this chunk.  Create a new loss
1027          // record, initialise it from the chunk, and insert it into lr_table.
1028          lr = VG_(OSetGen_AllocNode)(lr_table, sizeof(LossRecord));
1029          lr->key              = lrkey;
1030          lr->szB              = ch->szB;
1031          if (ex->state == Unreached)
1032             lr->indirect_szB     = ex->IorC.indirect_szB;
1033          else
1034             lr->indirect_szB     = 0;
1035          lr->num_blocks       = 1;
1036          lr->old_szB          = 0;
1037          lr->old_indirect_szB = 0;
1038          lr->old_num_blocks   = 0;
1039          VG_(OSetGen_Insert)(lr_table, lr);
1040       }
1041    }
1042 
1043    // (re-)create the array of pointers to the (new) loss records.
1044    n_lossrecords = get_lr_array_from_lr_table ();
1045    tl_assert(VG_(OSetGen_Size)(lr_table) == n_lossrecords);
1046 
1047    // Sort the array by loss record sizes.
1048    VG_(ssort)(lr_array, n_lossrecords, sizeof(LossRecord*),
1049               cmp_LossRecords);
1050 
1051    // Zero totals.
1052    MC_(blocks_leaked)     = MC_(bytes_leaked)     = 0;
1053    MC_(blocks_indirect)   = MC_(bytes_indirect)   = 0;
1054    MC_(blocks_dubious)    = MC_(bytes_dubious)    = 0;
1055    MC_(blocks_reachable)  = MC_(bytes_reachable)  = 0;
1056    MC_(blocks_suppressed) = MC_(bytes_suppressed) = 0;
1057 
1058    // If there is a maximum nr of loss records we can output, then first
1059    // compute from where the output scan has to start.
1060    // By default, start from the first loss record. Compute a higher
1061    // value if there is a maximum to respect. We need to print the last
1062    // records, as the one with the biggest sizes are more interesting.
1063    start_lr_output_scan = 0;
1064    if (lcp->mode == LC_Full && lcp->max_loss_records_output < n_lossrecords) {
1065       Int nr_printable_records = 0;
1066       for (i = n_lossrecords - 1; i >= 0 && start_lr_output_scan == 0; i--) {
1067          Bool count_as_error, print_record;
1068          lr = lr_array[i];
1069          get_printing_rules (lcp, lr, &count_as_error, &print_record);
1070          // Do not use get_printing_rules results for is_suppressed, as we
1071          // only want to check if the record would be suppressed.
1072          is_suppressed =
1073             MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr,
1074                                      False /* print_record */,
1075                                      False /* count_as_error */);
1076          if (print_record && !is_suppressed) {
1077             nr_printable_records++;
1078             if (nr_printable_records == lcp->max_loss_records_output)
1079                start_lr_output_scan = i;
1080          }
1081       }
1082    }
1083 
1084    // Print the loss records (in size order) and collect summary stats.
1085    for (i = start_lr_output_scan; i < n_lossrecords; i++) {
1086       Bool count_as_error, print_record;
1087       lr = lr_array[i];
1088       get_printing_rules(lcp, lr, &count_as_error, &print_record);
1089       is_suppressed =
1090          MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr, print_record,
1091                                   count_as_error );
1092 
1093       if (is_suppressed) {
1094          MC_(blocks_suppressed) += lr->num_blocks;
1095          MC_(bytes_suppressed)  += lr->szB;
1096 
1097       } else if (Unreached == lr->key.state) {
1098          MC_(blocks_leaked)     += lr->num_blocks;
1099          MC_(bytes_leaked)      += lr->szB;
1100 
1101       } else if (IndirectLeak == lr->key.state) {
1102          MC_(blocks_indirect)   += lr->num_blocks;
1103          MC_(bytes_indirect)    += lr->szB;
1104 
1105       } else if (Possible == lr->key.state) {
1106          MC_(blocks_dubious)    += lr->num_blocks;
1107          MC_(bytes_dubious)     += lr->szB;
1108 
1109       } else if (Reachable == lr->key.state) {
1110          MC_(blocks_reachable)  += lr->num_blocks;
1111          MC_(bytes_reachable)   += lr->szB;
1112 
1113       } else {
1114          VG_(tool_panic)("unknown loss mode");
1115       }
1116    }
1117 
1118    if (VG_(clo_verbosity) > 0 && !VG_(clo_xml)) {
1119       char d_bytes[20];
1120       char d_blocks[20];
1121 
1122       VG_(umsg)("LEAK SUMMARY:\n");
1123       VG_(umsg)("   definitely lost: %'lu%s bytes in %'lu%s blocks\n",
1124                 MC_(bytes_leaked),
1125                 MC_(snprintf_delta) (d_bytes, 20, MC_(bytes_leaked), old_bytes_leaked, lcp->deltamode),
1126                 MC_(blocks_leaked),
1127                 MC_(snprintf_delta) (d_blocks, 20, MC_(blocks_leaked), old_blocks_leaked, lcp->deltamode));
1128       VG_(umsg)("   indirectly lost: %'lu%s bytes in %'lu%s blocks\n",
1129                 MC_(bytes_indirect),
1130                 MC_(snprintf_delta) (d_bytes, 20, MC_(bytes_indirect), old_bytes_indirect, lcp->deltamode),
1131                 MC_(blocks_indirect),
1132                 MC_(snprintf_delta) (d_blocks, 20, MC_(blocks_indirect), old_blocks_indirect, lcp->deltamode) );
1133       VG_(umsg)("     possibly lost: %'lu%s bytes in %'lu%s blocks\n",
1134                 MC_(bytes_dubious),
1135                 MC_(snprintf_delta) (d_bytes, 20, MC_(bytes_dubious), old_bytes_dubious, lcp->deltamode),
1136                 MC_(blocks_dubious),
1137                 MC_(snprintf_delta) (d_blocks, 20, MC_(blocks_dubious), old_blocks_dubious, lcp->deltamode) );
1138       VG_(umsg)("   still reachable: %'lu%s bytes in %'lu%s blocks\n",
1139                 MC_(bytes_reachable),
1140                 MC_(snprintf_delta) (d_bytes, 20, MC_(bytes_reachable), old_bytes_reachable, lcp->deltamode),
1141                 MC_(blocks_reachable),
1142                 MC_(snprintf_delta) (d_blocks, 20, MC_(blocks_reachable), old_blocks_reachable, lcp->deltamode) );
1143       VG_(umsg)("        suppressed: %'lu%s bytes in %'lu%s blocks\n",
1144                 MC_(bytes_suppressed),
1145                 MC_(snprintf_delta) (d_bytes, 20, MC_(bytes_suppressed), old_bytes_suppressed, lcp->deltamode),
1146                 MC_(blocks_suppressed),
1147                 MC_(snprintf_delta) (d_blocks, 20, MC_(blocks_suppressed), old_blocks_suppressed, lcp->deltamode) );
1148       if (lcp->mode != LC_Full &&
1149           (MC_(blocks_leaked) + MC_(blocks_indirect) +
1150            MC_(blocks_dubious) + MC_(blocks_reachable)) > 0) {
1151          if (lcp->requested_by_monitor_command)
1152             VG_(umsg)("To see details of leaked memory, give 'full' arg to leak_check\n");
1153          else
1154             VG_(umsg)("Rerun with --leak-check=full to see details "
1155                       "of leaked memory\n");
1156       }
1157       if (lcp->mode == LC_Full &&
1158           MC_(blocks_reachable) > 0 && !lcp->show_reachable)
1159       {
1160          VG_(umsg)("Reachable blocks (those to which a pointer "
1161                    "was found) are not shown.\n");
1162          if (lcp->requested_by_monitor_command)
1163             VG_(umsg)("To see them, add 'reachable any' args to leak_check\n");
1164          else
1165             VG_(umsg)("To see them, rerun with: --leak-check=full "
1166                       "--show-reachable=yes\n");
1167       }
1168       VG_(umsg)("\n");
1169    }
1170 }
1171 
1172 // print recursively all indirectly leaked blocks collected in clique.
print_clique(Int clique,UInt level)1173 static void print_clique (Int clique, UInt level)
1174 {
1175    Int ind;
1176    Int i,  n_lossrecords;;
1177 
1178    n_lossrecords = VG_(OSetGen_Size)(lr_table);
1179 
1180    for (ind = 0; ind < lc_n_chunks; ind++) {
1181       LC_Extra*     ind_ex = &(lc_extras)[ind];
1182       if (ind_ex->state == IndirectLeak && ind_ex->IorC.clique == (SizeT) clique) {
1183          MC_Chunk*    ind_ch = lc_chunks[ind];
1184          LossRecord*  ind_lr;
1185          LossRecordKey ind_lrkey;
1186          Int lr_i;
1187          ind_lrkey.state = ind_ex->state;
1188          ind_lrkey.allocated_at = ind_ch->where;
1189          ind_lr = VG_(OSetGen_Lookup)(lr_table, &ind_lrkey);
1190          for (lr_i = 0; lr_i < n_lossrecords; lr_i++)
1191             if (ind_lr == lr_array[lr_i])
1192                break;
1193          for (i = 0; i < level; i++)
1194             VG_(umsg)("  ");
1195          VG_(umsg)("%p[%lu] indirect loss record %d\n",
1196                    (void *)ind_ch->data, (unsigned long)ind_ch->szB,
1197                    lr_i+1); // lr_i+1 for user numbering.
1198          if (lr_i >= n_lossrecords)
1199             VG_(umsg)
1200                ("error: no indirect loss record found for %p[%lu]?????\n",
1201                 (void *)ind_ch->data, (unsigned long)ind_ch->szB);
1202          print_clique(ind, level+1);
1203       }
1204    }
1205  }
1206 
MC_(print_block_list)1207 Bool MC_(print_block_list) ( UInt loss_record_nr)
1208 {
1209    Int          i,  n_lossrecords;
1210    LossRecord*  lr;
1211 
1212    if (lr_table == NULL || lc_chunks == NULL || lc_extras == NULL) {
1213       VG_(umsg)("Can't print block list : no valid leak search result\n");
1214       return False;
1215    }
1216 
1217    if (lc_chunks_n_frees_marker != MC_(get_cmalloc_n_frees)()) {
1218       VG_(umsg)("Can't print obsolete block list : redo a leak search first\n");
1219       return False;
1220    }
1221 
1222    n_lossrecords = VG_(OSetGen_Size)(lr_table);
1223    if (loss_record_nr >= n_lossrecords)
1224       return False; // Invalid loss record nr.
1225 
1226    tl_assert (lr_array);
1227    lr = lr_array[loss_record_nr];
1228 
1229    // (re-)print the loss record details.
1230    // (+1 on loss_record_nr as user numbering for loss records starts at 1).
1231    MC_(pp_LossRecord)(loss_record_nr+1, n_lossrecords, lr);
1232 
1233    // Match the chunks with loss records.
1234    for (i = 0; i < lc_n_chunks; i++) {
1235       MC_Chunk*     ch = lc_chunks[i];
1236       LC_Extra*     ex = &(lc_extras)[i];
1237       LossRecord*   old_lr;
1238       LossRecordKey lrkey;
1239       lrkey.state        = ex->state;
1240       lrkey.allocated_at = ch->where;
1241 
1242       old_lr = VG_(OSetGen_Lookup)(lr_table, &lrkey);
1243       if (old_lr) {
1244          // We found an existing loss record matching this chunk.
1245          // If this is the loss record we are looking for, then output the pointer.
1246          if (old_lr == lr_array[loss_record_nr]) {
1247             VG_(umsg)("%p[%lu]\n",
1248                       (void *)ch->data, (unsigned long) ch->szB);
1249             if (ex->state != Reachable) {
1250                // We can print the clique in all states, except Reachable.
1251                // In Unreached state, lc_chunk[i] is the clique leader.
1252                // In IndirectLeak, lc_chunk[i] might have been a clique leader
1253                // which was later collected in another clique.
1254                // For Possible, lc_chunk[i] might be the top of a clique
1255                // or an intermediate clique.
1256                print_clique(i, 1);
1257             }
1258          }
1259       } else {
1260          // No existing loss record matches this chunk ???
1261          VG_(umsg)("error: no loss record found for %p[%lu]?????\n",
1262                    (void *)ch->data, (unsigned long) ch->szB);
1263       }
1264    }
1265    return True;
1266 }
1267 
1268 // If searched = 0, scan memory root set, pushing onto the mark stack the blocks
1269 // encountered.
1270 // Otherwise (searched != 0), scan the memory root set searching for ptr pointing
1271 // inside [searched, searched+szB[.
scan_memory_root_set(Addr searched,SizeT szB)1272 static void scan_memory_root_set(Addr searched, SizeT szB)
1273 {
1274    Int   i;
1275    Int   n_seg_starts;
1276    Addr* seg_starts = VG_(get_segment_starts)( &n_seg_starts );
1277 
1278    tl_assert(seg_starts && n_seg_starts > 0);
1279 
1280    lc_scanned_szB = 0;
1281 
1282    // VG_(am_show_nsegments)( 0, "leakcheck");
1283    for (i = 0; i < n_seg_starts; i++) {
1284       SizeT seg_size;
1285       NSegment const* seg = VG_(am_find_nsegment)( seg_starts[i] );
1286       tl_assert(seg);
1287 
1288       if (seg->kind != SkFileC && seg->kind != SkAnonC) continue;
1289       if (!(seg->hasR && seg->hasW))                    continue;
1290       if (seg->isCH)                                    continue;
1291 
1292       // Don't poke around in device segments as this may cause
1293       // hangs.  Exclude /dev/zero just in case someone allocated
1294       // memory by explicitly mapping /dev/zero.
1295       if (seg->kind == SkFileC
1296           && (VKI_S_ISCHR(seg->mode) || VKI_S_ISBLK(seg->mode))) {
1297          HChar* dev_name = VG_(am_get_filename)( (NSegment*)seg );
1298          if (dev_name && 0 == VG_(strcmp)(dev_name, "/dev/zero")) {
1299             // Don't skip /dev/zero.
1300          } else {
1301             // Skip this device mapping.
1302             continue;
1303          }
1304       }
1305 
1306       if (0)
1307          VG_(printf)("ACCEPT %2d  %#lx %#lx\n", i, seg->start, seg->end);
1308 
1309       // Scan the segment.  We use -1 for the clique number, because this
1310       // is a root-set.
1311       seg_size = seg->end - seg->start + 1;
1312       if (VG_(clo_verbosity) > 2) {
1313          VG_(message)(Vg_DebugMsg,
1314                       "  Scanning root segment: %#lx..%#lx (%lu)\n",
1315                       seg->start, seg->end, seg_size);
1316       }
1317       lc_scan_memory(seg->start, seg_size, /*is_prior_definite*/True,
1318                      /*clique*/-1, /*cur_clique*/-1,
1319                      searched, szB);
1320    }
1321    VG_(free)(seg_starts);
1322 }
1323 
1324 /*------------------------------------------------------------*/
1325 /*--- Top-level entry point.                               ---*/
1326 /*------------------------------------------------------------*/
1327 
MC_(detect_memory_leaks)1328 void MC_(detect_memory_leaks) ( ThreadId tid, LeakCheckParams* lcp)
1329 {
1330    Int i, j;
1331 
1332    tl_assert(lcp->mode != LC_Off);
1333 
1334    // Verify some assertions which are used in lc_scan_memory.
1335    tl_assert((VKI_PAGE_SIZE % sizeof(Addr)) == 0);
1336    tl_assert((SM_SIZE % sizeof(Addr)) == 0);
1337    // Above two assertions are critical, while below assertion
1338    // ensures that the optimisation in the loop is done in the
1339    // correct order : the loop checks for (big) SM chunk skipping
1340    // before checking for (smaller) page skipping.
1341    tl_assert((SM_SIZE % VKI_PAGE_SIZE) == 0);
1342 
1343 
1344    MC_(detect_memory_leaks_last_delta_mode) = lcp->deltamode;
1345 
1346    // Get the chunks, stop if there were none.
1347    if (lc_chunks) {
1348       VG_(free)(lc_chunks);
1349       lc_chunks = NULL;
1350    }
1351    lc_chunks = find_active_chunks(&lc_n_chunks);
1352    lc_chunks_n_frees_marker = MC_(get_cmalloc_n_frees)();
1353    if (lc_n_chunks == 0) {
1354       tl_assert(lc_chunks == NULL);
1355       if (lr_table != NULL) {
1356          // forget the previous recorded LossRecords as next leak search
1357          // can in any case just create new leaks.
1358          // Maybe it would be better to rather call print_result ?
1359          // (at least when leak decreases are requested)
1360          // This will then output all LossRecords with a size decreasing to 0
1361          VG_(OSetGen_Destroy) (lr_table);
1362          lr_table = NULL;
1363       }
1364       if (VG_(clo_verbosity) >= 1 && !VG_(clo_xml)) {
1365          VG_(umsg)("All heap blocks were freed -- no leaks are possible\n");
1366          VG_(umsg)("\n");
1367       }
1368       return;
1369    }
1370 
1371    // Sort the array so blocks are in ascending order in memory.
1372    VG_(ssort)(lc_chunks, lc_n_chunks, sizeof(VgHashNode*), compare_MC_Chunks);
1373 
1374    // Sanity check -- make sure they're in order.
1375    for (i = 0; i < lc_n_chunks-1; i++) {
1376       tl_assert( lc_chunks[i]->data <= lc_chunks[i+1]->data);
1377    }
1378 
1379    // Sanity check -- make sure they don't overlap.  The one exception is that
1380    // we allow a MALLOCLIKE block to sit entirely within a malloc() block.
1381    // This is for bug 100628.  If this occurs, we ignore the malloc() block
1382    // for leak-checking purposes.  This is a hack and probably should be done
1383    // better, but at least it's consistent with mempools (which are treated
1384    // like this in find_active_chunks).  Mempools have a separate VgHashTable
1385    // for mempool chunks, but if custom-allocated blocks are put in a separate
1386    // table from normal heap blocks it makes free-mismatch checking more
1387    // difficult.
1388    //
1389    // If this check fails, it probably means that the application
1390    // has done something stupid with VALGRIND_MALLOCLIKE_BLOCK client
1391    // requests, eg. has made overlapping requests (which are
1392    // nonsensical), or used VALGRIND_MALLOCLIKE_BLOCK for stack locations;
1393    // again nonsensical.
1394    //
1395    for (i = 0; i < lc_n_chunks-1; i++) {
1396       MC_Chunk* ch1 = lc_chunks[i];
1397       MC_Chunk* ch2 = lc_chunks[i+1];
1398 
1399       Addr start1    = ch1->data;
1400       Addr start2    = ch2->data;
1401       Addr end1      = ch1->data + ch1->szB - 1;
1402       Addr end2      = ch2->data + ch2->szB - 1;
1403       Bool isCustom1 = ch1->allockind == MC_AllocCustom;
1404       Bool isCustom2 = ch2->allockind == MC_AllocCustom;
1405 
1406       if (end1 < start2) {
1407          // Normal case - no overlap.
1408 
1409       // We used to allow exact duplicates, I'm not sure why.  --njn
1410       //} else if (start1 == start2 && end1 == end2) {
1411          // Degenerate case: exact duplicates.
1412 
1413       } else if (start1 >= start2 && end1 <= end2 && isCustom1 && !isCustom2) {
1414          // Block i is MALLOCLIKE and entirely within block i+1.
1415          // Remove block i+1.
1416          for (j = i+1; j < lc_n_chunks-1; j++) {
1417             lc_chunks[j] = lc_chunks[j+1];
1418          }
1419          lc_n_chunks--;
1420 
1421       } else if (start2 >= start1 && end2 <= end1 && isCustom2 && !isCustom1) {
1422          // Block i+1 is MALLOCLIKE and entirely within block i.
1423          // Remove block i.
1424          for (j = i; j < lc_n_chunks-1; j++) {
1425             lc_chunks[j] = lc_chunks[j+1];
1426          }
1427          lc_n_chunks--;
1428 
1429       } else {
1430          VG_(umsg)("Block 0x%lx..0x%lx overlaps with block 0x%lx..0x%lx\n",
1431                    start1, end1, start2, end2);
1432          VG_(umsg)("Blocks allocation contexts:\n"),
1433          VG_(pp_ExeContext)( ch1->where);
1434          VG_(umsg)("\n"),
1435          VG_(pp_ExeContext)( ch2->where);
1436          VG_(umsg)("This is usually caused by using VALGRIND_MALLOCLIKE_BLOCK");
1437          VG_(umsg)("in an inappropriate way.\n");
1438          tl_assert (0);
1439       }
1440    }
1441 
1442    // Initialise lc_extras.
1443    if (lc_extras) {
1444       VG_(free)(lc_extras);
1445       lc_extras = NULL;
1446    }
1447    lc_extras = VG_(malloc)( "mc.dml.2", lc_n_chunks * sizeof(LC_Extra) );
1448    for (i = 0; i < lc_n_chunks; i++) {
1449       lc_extras[i].state        = Unreached;
1450       lc_extras[i].pending      = False;
1451       lc_extras[i].IorC.indirect_szB = 0;
1452    }
1453 
1454    // Initialise lc_markstack.
1455    lc_markstack = VG_(malloc)( "mc.dml.2", lc_n_chunks * sizeof(Int) );
1456    for (i = 0; i < lc_n_chunks; i++) {
1457       lc_markstack[i] = -1;
1458    }
1459    lc_markstack_top = -1;
1460 
1461    // Verbosity.
1462    if (VG_(clo_verbosity) > 1 && !VG_(clo_xml)) {
1463       VG_(umsg)( "Searching for pointers to %'d not-freed blocks\n",
1464                  lc_n_chunks );
1465    }
1466 
1467    // Scan the memory root-set, pushing onto the mark stack any blocks
1468    // pointed to.
1469    scan_memory_root_set(/*searched*/0, 0);
1470 
1471    // Scan GP registers for chunk pointers.
1472    VG_(apply_to_GP_regs)(lc_push_if_a_chunk_ptr_register);
1473 
1474    // Process the pushed blocks.  After this, every block that is reachable
1475    // from the root-set has been traced.
1476    lc_process_markstack(/*clique*/-1);
1477 
1478    if (VG_(clo_verbosity) > 1 && !VG_(clo_xml)) {
1479       VG_(umsg)("Checked %'lu bytes\n", lc_scanned_szB);
1480       VG_(umsg)( "\n" );
1481    }
1482 
1483    // Trace all the leaked blocks to determine which are directly leaked and
1484    // which are indirectly leaked.  For each Unreached block, push it onto
1485    // the mark stack, and find all the as-yet-Unreached blocks reachable
1486    // from it.  These form a clique and are marked IndirectLeak, and their
1487    // size is added to the clique leader's indirect size.  If one of the
1488    // found blocks was itself a clique leader (from a previous clique), then
1489    // the cliques are merged.
1490    for (i = 0; i < lc_n_chunks; i++) {
1491       MC_Chunk* ch = lc_chunks[i];
1492       LC_Extra* ex = &(lc_extras[i]);
1493 
1494       if (VG_DEBUG_CLIQUE)
1495          VG_(printf)("cliques: %d at %#lx -> Loss state %d\n",
1496                      i, ch->data, ex->state);
1497 
1498       tl_assert(lc_markstack_top == -1);
1499 
1500       if (ex->state == Unreached) {
1501          if (VG_DEBUG_CLIQUE)
1502             VG_(printf)("%d: gathering clique %#lx\n", i, ch->data);
1503 
1504          // Push this Unreached block onto the stack and process it.
1505          lc_push(i, ch);
1506          lc_process_markstack(/*clique*/i);
1507 
1508          tl_assert(lc_markstack_top == -1);
1509          tl_assert(ex->state == Unreached);
1510       }
1511    }
1512 
1513    print_results( tid, lcp);
1514 
1515    VG_(free) ( lc_markstack );
1516    lc_markstack = NULL;
1517    // lc_chunks, lc_extras, lr_array and lr_table are kept (needed if user
1518    // calls MC_(print_block_list)). lr_table also used for delta leak reporting
1519    // between this leak search and the next leak search.
1520 }
1521 
1522 static Addr searched_wpa;
1523 static SizeT searched_szB;
1524 static void
search_address_in_GP_reg(ThreadId tid,HChar * regname,Addr addr_in_reg)1525 search_address_in_GP_reg(ThreadId tid, HChar* regname, Addr addr_in_reg)
1526 {
1527    if (addr_in_reg >= searched_wpa
1528        && addr_in_reg < searched_wpa + searched_szB) {
1529       if (addr_in_reg == searched_wpa)
1530          VG_(umsg)
1531             ("tid %d register %s pointing at %#lx\n",
1532              tid, regname, searched_wpa);
1533       else
1534          VG_(umsg)
1535             ("tid %d register %s interior pointing %lu bytes inside %#lx\n",
1536              tid, regname, (long unsigned) addr_in_reg - searched_wpa,
1537              searched_wpa);
1538    }
1539 }
1540 
MC_(who_points_at)1541 void MC_(who_points_at) ( Addr address, SizeT szB)
1542 {
1543    MC_Chunk** chunks;
1544    Int        n_chunks;
1545    Int        i;
1546 
1547    if (szB == 1)
1548       VG_(umsg) ("Searching for pointers to %#lx\n", address);
1549    else
1550       VG_(umsg) ("Searching for pointers pointing in %lu bytes from %#lx\n",
1551                  szB, address);
1552 
1553    // Scan memory root-set, searching for ptr pointing in address[szB]
1554    scan_memory_root_set(address, szB);
1555 
1556    // Scan active malloc-ed chunks
1557    chunks = find_active_chunks(&n_chunks);
1558    for (i = 0; i < n_chunks; i++) {
1559       lc_scan_memory(chunks[i]->data, chunks[i]->szB,
1560                      /*is_prior_definite*/True,
1561                      /*clique*/-1, /*cur_clique*/-1,
1562                      address, szB);
1563    }
1564    VG_(free) ( chunks );
1565 
1566    // Scan GP registers for pointers to address range.
1567    searched_wpa = address;
1568    searched_szB = szB;
1569    VG_(apply_to_GP_regs)(search_address_in_GP_reg);
1570 
1571 }
1572 
1573 /*--------------------------------------------------------------------*/
1574 /*--- end                                                          ---*/
1575 /*--------------------------------------------------------------------*/
1576 
1577