blob: f8ae72efef013bbc6b3875d518785fd77d1f6acc [file] [log] [blame]
njn43c799e2003-04-08 00:08:52 +00001
2/*--------------------------------------------------------------------*/
njn1d0825f2006-03-27 11:37:07 +00003/*--- The leak checker. mc_leakcheck.c ---*/
njn43c799e2003-04-08 00:08:52 +00004/*--------------------------------------------------------------------*/
5
6/*
nethercote137bc552003-11-14 17:47:54 +00007 This file is part of MemCheck, a heavyweight Valgrind tool for
njn1d0825f2006-03-27 11:37:07 +00008 detecting memory errors.
njn43c799e2003-04-08 00:08:52 +00009
sewardjb3a1e4b2015-08-21 11:32:26 +000010 Copyright (C) 2000-2015 Julian Seward
njn43c799e2003-04-08 00:08:52 +000011 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
njnc7561b92005-06-19 01:24:32 +000031#include "pub_tool_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_tool_vki.h"
njnac1e0332009-05-08 00:39:31 +000033#include "pub_tool_aspacehl.h"
njn4802b382005-06-11 04:58:29 +000034#include "pub_tool_aspacemgr.h"
njn1d0825f2006-03-27 11:37:07 +000035#include "pub_tool_execontext.h"
36#include "pub_tool_hashtable.h"
njn97405b22005-06-02 03:39:33 +000037#include "pub_tool_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000038#include "pub_tool_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000039#include "pub_tool_libcprint.h"
njnde62cbf2005-06-10 22:08:14 +000040#include "pub_tool_libcsignal.h"
njn6ace3ea2005-06-17 03:06:27 +000041#include "pub_tool_machine.h"
njnc7561b92005-06-19 01:24:32 +000042#include "pub_tool_mallocfree.h"
43#include "pub_tool_options.h"
njn29a5c012009-05-06 06:15:55 +000044#include "pub_tool_oset.h"
philippe6643e962012-01-17 21:16:30 +000045#include "pub_tool_poolalloc.h"
46#include "pub_tool_signals.h" // Needed for mc_include.h
sewardj6c591e12011-04-11 16:17:51 +000047#include "pub_tool_libcsetjmp.h" // setjmp facilities
njn1d0825f2006-03-27 11:37:07 +000048#include "pub_tool_tooliface.h" // Needed for mc_include.h
njn43c799e2003-04-08 00:08:52 +000049
njn1d0825f2006-03-27 11:37:07 +000050#include "mc_include.h"
njnc7561b92005-06-19 01:24:32 +000051
njn8225cc02009-03-09 22:52:24 +000052/*------------------------------------------------------------*/
53/*--- An overview of leak checking. ---*/
54/*------------------------------------------------------------*/
njnc7561b92005-06-19 01:24:32 +000055
njn8225cc02009-03-09 22:52:24 +000056// 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?
njnc2f8b1b2009-08-10 06:47:00 +0000116// [bug 197930]
njn8225cc02009-03-09 22:52:24 +0000117//
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.
philippe2193a7c2012-12-08 17:54:16 +0000123// We now have the option --show-leak-kinds=... which allows to specify =all.
njn8225cc02009-03-09 22:52:24 +0000124//
125// ----
126//
127// Also, the VALGRIND_LEAK_CHECK and VALGRIND_QUICK_LEAK_CHECK aren't great
128// names. VALGRIND_FULL_LEAK_CHECK and VALGRIND_SUMMARY_LEAK_CHECK would be
129// better.
130//
131// ----
132//
133// Also, VALGRIND_COUNT_LEAKS and VALGRIND_COUNT_LEAK_BLOCKS aren't great as
134// they combine direct leaks and indirect leaks into one. New, more precise
135// ones (they'll need new names) would be good. If more categories are
136// used, as per the --follow-interior-pointers option, they should be
137// updated accordingly. And they should use a struct to return the values.
138//
139// ----
140//
141// Also, for this case:
142//
143// (4) p4 BBB ---> AAA
144//
145// BBB is definitely directly lost. AAA is definitely indirectly lost.
146// Here's the relevant loss records printed for a full check (each block is
147// 16 bytes):
148//
149// ==20397== 16 bytes in 1 blocks are indirectly lost in loss record 9 of 15
150// ==20397== at 0x4C2694E: malloc (vg_replace_malloc.c:177)
151// ==20397== by 0x400521: mk (leak-cases.c:49)
152// ==20397== by 0x400578: main (leak-cases.c:72)
153//
154// ==20397== 32 (16 direct, 16 indirect) bytes in 1 blocks are definitely
155// lost in loss record 14 of 15
156// ==20397== at 0x4C2694E: malloc (vg_replace_malloc.c:177)
157// ==20397== by 0x400521: mk (leak-cases.c:49)
158// ==20397== by 0x400580: main (leak-cases.c:72)
159//
160// The first one is fine -- it describes AAA.
161//
162// The second one is for BBB. It's correct in that 16 bytes in 1 block are
163// directly lost. It's also correct that 16 are indirectly lost as a result,
164// but it means that AAA is being counted twice in the loss records. (It's
165// not, thankfully, counted twice in the summary counts). Argh.
166//
167// This would be less confusing for the second one:
168//
169// ==20397== 16 bytes in 1 blocks are definitely lost in loss record 14
170// of 15 (and 16 bytes in 1 block are indirectly lost as a result; they
philippe2193a7c2012-12-08 17:54:16 +0000171// are mentioned elsewhere (if --show-reachable=yes or indirect is given
172// in --show-leak-kinds=... !))
njn8225cc02009-03-09 22:52:24 +0000173// ==20397== at 0x4C2694E: malloc (vg_replace_malloc.c:177)
174// ==20397== by 0x400521: mk (leak-cases.c:49)
175// ==20397== by 0x400580: main (leak-cases.c:72)
176//
177// But ideally we'd present the loss record for the directly lost block and
178// then the resultant indirectly lost blocks and make it clear the
179// dependence. Double argh.
180
181/*------------------------------------------------------------*/
182/*--- The actual algorithm. ---*/
183/*------------------------------------------------------------*/
184
185// - Find all the blocks (a.k.a. chunks) to check. Mempool chunks require
186// some special treatment because they can be within malloc'd blocks.
187// - Scan every word in the root set (GP registers and valid
188// non-heap memory words).
189// - First, we skip if it doesn't point to valid memory.
190// - Then, we see if it points to the start or interior of a block. If
191// so, we push the block onto the mark stack and mark it as having been
192// reached.
193// - Then, we process the mark stack, repeating the scanning for each block;
194// this can push more blocks onto the mark stack. We repeat until the
195// mark stack is empty. Each block is marked as definitely or possibly
196// reachable, depending on whether interior-pointers were required to
197// reach it.
198// - At this point we know for every block if it's reachable or not.
199// - We then push each unreached block onto the mark stack, using the block
200// number as the "clique" number.
201// - We process the mark stack again, this time grouping blocks into cliques
202// in order to facilitate the directly/indirectly lost categorisation.
203// - We group blocks by their ExeContexts and categorisation, and print them
204// if --leak-check=full. We also print summary numbers.
205//
206// A note on "cliques":
207// - A directly lost block is one with no pointers to it. An indirectly
208// lost block is one that is pointed to by a directly or indirectly lost
209// block.
210// - Each directly lost block has zero or more indirectly lost blocks
211// hanging off it. All these blocks together form a "clique". The
212// directly lost block is called the "clique leader". The clique number
213// is the number (in lc_chunks[]) of the clique leader.
214// - Actually, a directly lost block may be pointed to if it's part of a
215// cycle. In that case, there may be more than one choice for the clique
216// leader, and the choice is arbitrary. Eg. if you have A-->B and B-->A
217// either A or B could be the clique leader.
218// - Cliques cannot overlap, and will be truncated to avoid this. Eg. if we
219// have A-->C and B-->C, the two cliques will be {A,C} and {B}, or {A} and
220// {B,C} (again the choice is arbitrary). This is because we don't want
221// to count a block as indirectly lost more than once.
222//
223// A note on 'is_prior_definite':
224// - This is a boolean used in various places that indicates if the chain
225// up to the prior node (prior to the one being considered) is definite.
226// - In the clique == -1 case:
227// - if True it means that the prior node is a root-set node, or that the
228// prior node is a block which is reachable from the root-set via
229// start-pointers.
230// - if False it means that the prior node is a block that is only
231// reachable from the root-set via a path including at least one
232// interior-pointer.
233// - In the clique != -1 case, currently it's always True because we treat
234// start-pointers and interior-pointers the same for direct/indirect leak
235// checking. If we added a PossibleIndirectLeak state then this would
236// change.
237
238
239// Define to debug the memory-leak-detector.
Elliott Hughesa0664b92017-04-18 17:46:52 -0700240#define VG_DEBUG_FIND_CHUNK 0
sewardjb5f6f512005-03-10 23:59:00 +0000241#define VG_DEBUG_LEAKCHECK 0
njn8225cc02009-03-09 22:52:24 +0000242#define VG_DEBUG_CLIQUE 0
243
sewardjb5f6f512005-03-10 23:59:00 +0000244
njn43c799e2003-04-08 00:08:52 +0000245/*------------------------------------------------------------*/
njn8225cc02009-03-09 22:52:24 +0000246/*--- Getting the initial chunks, and searching them. ---*/
njn43c799e2003-04-08 00:08:52 +0000247/*------------------------------------------------------------*/
248
njn8225cc02009-03-09 22:52:24 +0000249// Compare the MC_Chunks by 'data' (i.e. the address of the block).
florian6bd9dc12012-11-23 16:17:43 +0000250static Int compare_MC_Chunks(const void* n1, const void* n2)
njn43c799e2003-04-08 00:08:52 +0000251{
florian3e798632012-11-24 19:41:54 +0000252 const MC_Chunk* mc1 = *(const MC_Chunk *const *)n1;
253 const MC_Chunk* mc2 = *(const MC_Chunk *const *)n2;
njn8225cc02009-03-09 22:52:24 +0000254 if (mc1->data < mc2->data) return -1;
255 if (mc1->data > mc2->data) return 1;
256 return 0;
njn43c799e2003-04-08 00:08:52 +0000257}
258
Elliott Hughesa0664b92017-04-18 17:46:52 -0700259#if VG_DEBUG_FIND_CHUNK
njn8225cc02009-03-09 22:52:24 +0000260// Used to sanity-check the fast binary-search mechanism.
261static
262Int find_chunk_for_OLD ( Addr ptr,
263 MC_Chunk** chunks,
264 Int n_chunks )
265
266{
267 Int i;
268 Addr a_lo, a_hi;
florian60042192015-08-04 15:58:41 +0000269 PROF_EVENT(MCPE_FIND_CHUNK_FOR_OLD);
njn8225cc02009-03-09 22:52:24 +0000270 for (i = 0; i < n_chunks; i++) {
florian60042192015-08-04 15:58:41 +0000271 PROF_EVENT(MCPE_FIND_CHUNK_FOR_OLD_LOOP);
njn8225cc02009-03-09 22:52:24 +0000272 a_lo = chunks[i]->data;
273 a_hi = ((Addr)chunks[i]->data) + chunks[i]->szB;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700274 if (a_lo == a_hi)
275 a_hi++; // Special case for szB 0. See find_chunk_for.
njn8225cc02009-03-09 22:52:24 +0000276 if (a_lo <= ptr && ptr < a_hi)
277 return i;
278 }
279 return -1;
280}
281#endif
282
283// Find the i such that ptr points at or inside the block described by
284// chunks[i]. Return -1 if none found. This assumes that chunks[]
285// has been sorted on the 'data' field.
286static
287Int find_chunk_for ( Addr ptr,
288 MC_Chunk** chunks,
289 Int n_chunks )
290{
291 Addr a_mid_lo, a_mid_hi;
292 Int lo, mid, hi, retVal;
293 // VG_(printf)("find chunk for %p = ", ptr);
294 retVal = -1;
295 lo = 0;
296 hi = n_chunks-1;
297 while (True) {
298 // Invariant: current unsearched space is from lo to hi, inclusive.
299 if (lo > hi) break; // not found
300
301 mid = (lo + hi) / 2;
302 a_mid_lo = chunks[mid]->data;
303 a_mid_hi = chunks[mid]->data + chunks[mid]->szB;
304 // Extent of block 'mid' is [a_mid_lo .. a_mid_hi).
305 // Special-case zero-sized blocks - treat them as if they had
306 // size 1. Not doing so causes them to not cover any address
307 // range at all and so will never be identified as the target of
308 // any pointer, which causes them to be incorrectly reported as
309 // definitely leaked.
310 if (chunks[mid]->szB == 0)
311 a_mid_hi++;
312
313 if (ptr < a_mid_lo) {
314 hi = mid-1;
315 continue;
316 }
317 if (ptr >= a_mid_hi) {
318 lo = mid+1;
319 continue;
320 }
321 tl_assert(ptr >= a_mid_lo && ptr < a_mid_hi);
322 retVal = mid;
323 break;
324 }
325
Elliott Hughesa0664b92017-04-18 17:46:52 -0700326# if VG_DEBUG_FIND_CHUNK
njn8225cc02009-03-09 22:52:24 +0000327 tl_assert(retVal == find_chunk_for_OLD ( ptr, chunks, n_chunks ));
328# endif
329 // VG_(printf)("%d\n", retVal);
330 return retVal;
331}
332
333
334static MC_Chunk**
florian54fe2022012-10-27 23:07:42 +0000335find_active_chunks(Int* pn_chunks)
njn8225cc02009-03-09 22:52:24 +0000336{
337 // Our goal is to construct a set of chunks that includes every
338 // mempool chunk, and every malloc region that *doesn't* contain a
339 // mempool chunk.
340 MC_Mempool *mp;
341 MC_Chunk **mallocs, **chunks, *mc;
342 UInt n_mallocs, n_chunks, m, s;
343 Bool *malloc_chunk_holds_a_pool_chunk;
344
345 // First we collect all the malloc chunks into an array and sort it.
346 // We do this because we want to query the chunks by interior
347 // pointers, requiring binary search.
348 mallocs = (MC_Chunk**) VG_(HT_to_array)( MC_(malloc_list), &n_mallocs );
349 if (n_mallocs == 0) {
350 tl_assert(mallocs == NULL);
351 *pn_chunks = 0;
352 return NULL;
353 }
354 VG_(ssort)(mallocs, n_mallocs, sizeof(VgHashNode*), compare_MC_Chunks);
355
356 // Then we build an array containing a Bool for each malloc chunk,
357 // indicating whether it contains any mempools.
358 malloc_chunk_holds_a_pool_chunk = VG_(calloc)( "mc.fas.1",
359 n_mallocs, sizeof(Bool) );
360 n_chunks = n_mallocs;
361
362 // Then we loop over the mempool tables. For each chunk in each
363 // pool, we set the entry in the Bool array corresponding to the
364 // malloc chunk containing the mempool chunk.
365 VG_(HT_ResetIter)(MC_(mempool_list));
366 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
367 VG_(HT_ResetIter)(mp->chunks);
368 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
369
370 // We'll need to record this chunk.
371 n_chunks++;
372
373 // Possibly invalidate the malloc holding the beginning of this chunk.
374 m = find_chunk_for(mc->data, mallocs, n_mallocs);
375 if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
376 tl_assert(n_chunks > 0);
377 n_chunks--;
378 malloc_chunk_holds_a_pool_chunk[m] = True;
379 }
380
381 // Possibly invalidate the malloc holding the end of this chunk.
382 if (mc->szB > 1) {
383 m = find_chunk_for(mc->data + (mc->szB - 1), mallocs, n_mallocs);
384 if (m != -1 && malloc_chunk_holds_a_pool_chunk[m] == False) {
385 tl_assert(n_chunks > 0);
386 n_chunks--;
387 malloc_chunk_holds_a_pool_chunk[m] = True;
388 }
389 }
390 }
391 }
392 tl_assert(n_chunks > 0);
393
394 // Create final chunk array.
395 chunks = VG_(malloc)("mc.fas.2", sizeof(VgHashNode*) * (n_chunks));
396 s = 0;
397
398 // Copy the mempool chunks and the non-marked malloc chunks into a
399 // combined array of chunks.
400 VG_(HT_ResetIter)(MC_(mempool_list));
401 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
402 VG_(HT_ResetIter)(mp->chunks);
403 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
404 tl_assert(s < n_chunks);
405 chunks[s++] = mc;
406 }
407 }
408 for (m = 0; m < n_mallocs; ++m) {
409 if (!malloc_chunk_holds_a_pool_chunk[m]) {
410 tl_assert(s < n_chunks);
411 chunks[s++] = mallocs[m];
412 }
413 }
414 tl_assert(s == n_chunks);
415
416 // Free temporaries.
417 VG_(free)(mallocs);
418 VG_(free)(malloc_chunk_holds_a_pool_chunk);
419
420 *pn_chunks = n_chunks;
421
422 return chunks;
423}
424
425/*------------------------------------------------------------*/
426/*--- The leak detector proper. ---*/
427/*------------------------------------------------------------*/
428
429// Holds extra info about each block during leak checking.
430typedef
431 struct {
432 UInt state:2; // Reachedness.
philippeab1fce92013-09-29 13:47:32 +0000433 UInt pending:1; // Scan pending.
434 UInt heuristic: (sizeof(UInt)*8)-3;
435 // Heuristic with which this block was considered reachable.
436 // LchNone if state != Reachable or no heuristic needed to
437 // consider it reachable.
438
philippea22f59d2012-01-26 23:13:52 +0000439 union {
philippeab1fce92013-09-29 13:47:32 +0000440 SizeT indirect_szB;
441 // If Unreached, how many bytes are unreachable from here.
442 SizeT clique;
443 // if IndirectLeak, clique leader to which it belongs.
philippea22f59d2012-01-26 23:13:52 +0000444 } IorC;
njn8225cc02009-03-09 22:52:24 +0000445 }
446 LC_Extra;
447
448// An array holding pointers to every chunk we're checking. Sorted by address.
philippea22f59d2012-01-26 23:13:52 +0000449// lc_chunks is initialised during leak search. It is kept after leak search
450// to support printing the list of blocks belonging to a loss record.
451// lc_chunk array can only be used validly till the next "free" operation
452// (as a free operation potentially destroys one or more chunks).
453// To detect lc_chunk is valid, we store the nr of frees operations done
454// when lc_chunk was build : lc_chunks (and lc_extras) stays valid as
455// long as no free operations has been done since lc_chunks building.
njn8225cc02009-03-09 22:52:24 +0000456static MC_Chunk** lc_chunks;
457// How many chunks we're dealing with.
458static Int lc_n_chunks;
philippea22f59d2012-01-26 23:13:52 +0000459static SizeT lc_chunks_n_frees_marker;
460// This has the same number of entries as lc_chunks, and each entry
461// in lc_chunks corresponds with the entry here (ie. lc_chunks[i] and
462// lc_extras[i] describe the same block).
463static LC_Extra* lc_extras;
464
sewardjc8bd1df2011-06-26 12:41:33 +0000465// chunks will be converted and merged in loss record, maintained in lr_table
466// lr_table elements are kept from one leak_search to another to implement
467// the "print new/changed leaks" client request
468static OSet* lr_table;
philippea22f59d2012-01-26 23:13:52 +0000469// Array of sorted loss record (produced during last leak search).
470static LossRecord** lr_array;
471
philippeab1fce92013-09-29 13:47:32 +0000472// Value of the heuristics parameter used in the current (or last) leak check.
473static UInt detect_memory_leaks_last_heuristics;
sewardjc8bd1df2011-06-26 12:41:33 +0000474
475// DeltaMode used the last time we called detect_memory_leaks.
philippeab1fce92013-09-29 13:47:32 +0000476// The recorded leak errors are output using a logic based on this delta_mode.
sewardjc8bd1df2011-06-26 12:41:33 +0000477// The below avoids replicating the delta_mode in each LossRecord.
478LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
479
philippe4e32d672013-10-17 22:10:41 +0000480// Each leak search run increments the below generation counter.
481// A used suppression during a leak search will contain this
482// generation number.
483UInt MC_(leak_search_gen);
njn8225cc02009-03-09 22:52:24 +0000484
njn8225cc02009-03-09 22:52:24 +0000485// Records chunks that are currently being processed. Each element in the
486// stack is an index into lc_chunks and lc_extras. Its size is
487// 'lc_n_chunks' because in the worst case that's how many chunks could be
488// pushed onto it (actually I think the maximum is lc_n_chunks-1 but let's
489// be conservative).
490static Int* lc_markstack;
491// The index of the top element of the stack; -1 if the stack is empty, 0 if
492// the stack has one element, 1 if it has two, etc.
493static Int lc_markstack_top;
494
495// Keeps track of how many bytes of memory we've scanned, for printing.
496// (Nb: We don't keep track of how many register bytes we've scanned.)
497static SizeT lc_scanned_szB;
philippe7a76f4b2013-10-06 21:23:04 +0000498// Keeps track of how many bytes we have not scanned due to read errors that
499// caused a signal such as SIGSEGV.
500static SizeT lc_sig_skipped_szB;
njn8225cc02009-03-09 22:52:24 +0000501
502
503SizeT MC_(bytes_leaked) = 0;
504SizeT MC_(bytes_indirect) = 0;
505SizeT MC_(bytes_dubious) = 0;
506SizeT MC_(bytes_reachable) = 0;
507SizeT MC_(bytes_suppressed) = 0;
508
509SizeT MC_(blocks_leaked) = 0;
510SizeT MC_(blocks_indirect) = 0;
511SizeT MC_(blocks_dubious) = 0;
512SizeT MC_(blocks_reachable) = 0;
513SizeT MC_(blocks_suppressed) = 0;
514
philippeab1fce92013-09-29 13:47:32 +0000515// Subset of MC_(bytes_reachable) and MC_(blocks_reachable) which
516// are considered reachable due to the corresponding heuristic.
517static SizeT MC_(bytes_heuristically_reachable)[N_LEAK_CHECK_HEURISTICS]
518 = {0,0,0,0};
519static SizeT MC_(blocks_heuristically_reachable)[N_LEAK_CHECK_HEURISTICS]
520 = {0,0,0,0};
521
njn8225cc02009-03-09 22:52:24 +0000522// Determines if a pointer is to a chunk. Returns the chunk number et al
523// via call-by-reference.
524static Bool
525lc_is_a_chunk_ptr(Addr ptr, Int* pch_no, MC_Chunk** pch, LC_Extra** pex)
njn43c799e2003-04-08 00:08:52 +0000526{
njn8225cc02009-03-09 22:52:24 +0000527 Int ch_no;
528 MC_Chunk* ch;
529 LC_Extra* ex;
njn43c799e2003-04-08 00:08:52 +0000530
philippe57a16a22012-07-18 22:26:51 +0000531 // Quick filter. Note: implemented with am, not with get_vabits2
532 // as ptr might be random data pointing anywhere. On 64 bit
533 // platforms, getting va bits for random data can be quite costly
534 // due to the secondary map.
njn8225cc02009-03-09 22:52:24 +0000535 if (!VG_(am_is_valid_for_client)(ptr, 1, VKI_PROT_READ)) {
536 return False;
sewardjb5f6f512005-03-10 23:59:00 +0000537 } else {
njn8225cc02009-03-09 22:52:24 +0000538 ch_no = find_chunk_for(ptr, lc_chunks, lc_n_chunks);
539 tl_assert(ch_no >= -1 && ch_no < lc_n_chunks);
540
541 if (ch_no == -1) {
542 return False;
543 } else {
544 // Ok, we've found a pointer to a chunk. Get the MC_Chunk and its
545 // LC_Extra.
546 ch = lc_chunks[ch_no];
547 ex = &(lc_extras[ch_no]);
548
549 tl_assert(ptr >= ch->data);
550 tl_assert(ptr < ch->data + ch->szB + (ch->szB==0 ? 1 : 0));
551
552 if (VG_DEBUG_LEAKCHECK)
553 VG_(printf)("ptr=%#lx -> block %d\n", ptr, ch_no);
554
555 *pch_no = ch_no;
556 *pch = ch;
557 *pex = ex;
558
559 return True;
560 }
sewardjb5f6f512005-03-10 23:59:00 +0000561 }
562}
563
njn8225cc02009-03-09 22:52:24 +0000564// Push a chunk (well, just its index) onto the mark stack.
565static void lc_push(Int ch_no, MC_Chunk* ch)
sewardjb5f6f512005-03-10 23:59:00 +0000566{
tom1d0f3f62010-10-04 20:55:21 +0000567 if (!lc_extras[ch_no].pending) {
568 if (0) {
569 VG_(printf)("pushing %#lx-%#lx\n", ch->data, ch->data + ch->szB);
570 }
571 lc_markstack_top++;
572 tl_assert(lc_markstack_top < lc_n_chunks);
573 lc_markstack[lc_markstack_top] = ch_no;
574 tl_assert(!lc_extras[ch_no].pending);
575 lc_extras[ch_no].pending = True;
njn8225cc02009-03-09 22:52:24 +0000576 }
sewardjb5f6f512005-03-10 23:59:00 +0000577}
578
njn8225cc02009-03-09 22:52:24 +0000579// Return the index of the chunk on the top of the mark stack, or -1 if
580// there isn't one.
581static Bool lc_pop(Int* ret)
sewardjb5f6f512005-03-10 23:59:00 +0000582{
njn8225cc02009-03-09 22:52:24 +0000583 if (-1 == lc_markstack_top) {
584 return False;
585 } else {
586 tl_assert(0 <= lc_markstack_top && lc_markstack_top < lc_n_chunks);
587 *ret = lc_markstack[lc_markstack_top];
588 lc_markstack_top--;
tom1d0f3f62010-10-04 20:55:21 +0000589 tl_assert(lc_extras[*ret].pending);
590 lc_extras[*ret].pending = False;
njn8225cc02009-03-09 22:52:24 +0000591 return True;
592 }
593}
sewardjb5f6f512005-03-10 23:59:00 +0000594
philippeab1fce92013-09-29 13:47:32 +0000595static const HChar* pp_heuristic(LeakCheckHeuristic h)
596{
597 switch(h) {
598 case LchNone: return "none";
599 case LchStdString: return "stdstring";
philippe7c69a3e2014-07-21 19:55:11 +0000600 case LchLength64: return "length64";
philippeab1fce92013-09-29 13:47:32 +0000601 case LchNewArray: return "newarray";
602 case LchMultipleInheritance: return "multipleinheritance";
603 default: return "???invalid heuristic???";
604 }
605}
606
607// True if ptr looks like the address of a vtable, i.e. if ptr
608// points to an array of pointers to functions.
609// It is assumed the only caller of this function is heuristic_reachedness
610// which must check that ptr is aligned and above page 0.
611// Checking that ptr is above page 0 is an optimisation : it is assumed
612// that no vtable is located in the page 0. So, all small integer values
613// encountered during the scan will not incur the cost of calling this
614// function.
615static Bool aligned_ptr_above_page0_is_vtable_addr(Addr ptr)
616{
617 // ??? If performance problem:
618 // ??? maybe implement a cache (array indexed by ptr % primenr)
619 // ??? of "I am a vtable ptr" ???
620
621 // ??? Maybe the debug info could (efficiently?) be used to detect vtables ?
622
623 // We consider ptr as a vtable ptr if it points to a table
624 // where we find only NULL pointers or pointers pointing at an
625 // executable region. We must find at least 2 non NULL pointers
626 // before considering ptr as a vtable pointer.
627 // We scan a maximum of VTABLE_MAX_CHECK words for these 2 non NULL
628 // pointers.
629#define VTABLE_MAX_CHECK 20
630
631 NSegment const *seg;
632 UInt nr_fn_ptrs = 0;
633 Addr scan;
634 Addr scan_max;
635
636 // First verify ptr points inside a client mapped file section.
637 // ??? is a vtable always in a file mapped readable section ?
638 seg = VG_(am_find_nsegment) (ptr);
639 if (seg == NULL
640 || seg->kind != SkFileC
641 || !seg->hasR)
642 return False;
643
644 // Check potential function pointers, up to a maximum of VTABLE_MAX_CHECK.
645 scan_max = ptr + VTABLE_MAX_CHECK*sizeof(Addr);
646 // If ptr is near the end of seg, avoid scan_max exceeding the end of seg:
647 if (scan_max > seg->end - sizeof(Addr))
648 scan_max = seg->end - sizeof(Addr);
649 for (scan = ptr; scan <= scan_max; scan+=sizeof(Addr)) {
650 Addr pot_fn = *((Addr *)scan);
651 if (pot_fn == 0)
652 continue; // NULL fn pointer. Seems it can happen in vtable.
653 seg = VG_(am_find_nsegment) (pot_fn);
carll3ed5c702015-05-15 16:50:06 +0000654#if defined(VGA_ppc64be)
655 // ppc64BE uses a thunk table (function descriptors), so we have one
656 // more level of indirection to follow.
philippeab1fce92013-09-29 13:47:32 +0000657 if (seg == NULL
658 || seg->kind != SkFileC
659 || !seg->hasR
660 || !seg->hasW)
661 return False; // ptr to nowhere, or not a ptr to thunks.
662 pot_fn = *((Addr *)pot_fn);
663 if (pot_fn == 0)
664 continue; // NULL fn pointer. Seems it can happen in vtable.
665 seg = VG_(am_find_nsegment) (pot_fn);
666#endif
667 if (seg == NULL
668 || seg->kind != SkFileC
669 || !seg->hasT)
670 return False; // ptr to nowhere, or not a fn ptr.
671 nr_fn_ptrs++;
672 if (nr_fn_ptrs == 2)
673 return True;
674 }
675
676 return False;
677}
678
philippe7c69a3e2014-07-21 19:55:11 +0000679// true if a is properly aligned and points to 64bits of valid memory
680static Bool is_valid_aligned_ULong ( Addr a )
681{
682 if (sizeof(Word) == 8)
683 return MC_(is_valid_aligned_word)(a);
684
685 return MC_(is_valid_aligned_word)(a)
686 && MC_(is_valid_aligned_word)(a + 4);
687}
688
philippeb5a02e72015-10-22 19:14:30 +0000689/* The below leak_search_fault_catcher is used to catch memory access
690 errors happening during leak_search. During the scan, we check
691 with aspacemgr and/or VA bits that each page or dereferenced location is
692 readable and belongs to the client. However, we still protect
693 against SIGSEGV and SIGBUS e.g. in case aspacemgr is desynchronised
694 with the real page mappings. Such a desynchronisation could happen
695 due to an aspacemgr bug. Note that if the application is using
696 mprotect(NONE), then a page can be unreadable but have addressable
697 and defined VA bits (see mc_main.c function mc_new_mem_mprotect).
698 Currently, 2 functions are dereferencing client memory during leak search:
699 heuristic_reachedness and lc_scan_memory.
700 Each such function has its own fault catcher, that will call
701 leak_search_fault_catcher with the proper 'who' and jmpbuf parameters. */
702static volatile Addr bad_scanned_addr;
703static
704void leak_search_fault_catcher ( Int sigNo, Addr addr,
705 const HChar *who, VG_MINIMAL_JMP_BUF(jmpbuf) )
706{
707 vki_sigset_t sigmask;
708
709 if (0)
710 VG_(printf)("OUCH! sig=%d addr=%#lx who=%s\n", sigNo, addr, who);
711
712 /* Signal handler runs with the signal masked.
713 Unmask the handled signal before longjmp-ing or return-ing.
714 Note that during leak search, we expect only SIGSEGV or SIGBUS
715 and we do not expect another occurence until we longjmp-ed!return-ed
716 to resume the leak search. So, it is safe to unmask the signal
717 here. */
718 /* First get current mask (by passing NULL as first arg) */
719 VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &sigmask);
720 /* Then set a new sigmask, with this signal removed from the mask. */
721 VG_(sigdelset)(&sigmask, sigNo);
722 VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);
723
724 if (sigNo == VKI_SIGSEGV || sigNo == VKI_SIGBUS) {
725 bad_scanned_addr = addr;
726 VG_MINIMAL_LONGJMP(jmpbuf);
727 } else {
728 /* ??? During leak search, we are not supposed to receive any
729 other sync signal that these 2.
730 In theory, we should not call VG_(umsg) in a signal handler,
731 but better (try to) report this unexpected behaviour. */
732 VG_(umsg)("leak_search_fault_catcher:"
733 " unexpected signal %d, catcher %s ???\n",
734 sigNo, who);
735 }
736}
737
738// jmpbuf and fault_catcher used during heuristic_reachedness
739static VG_MINIMAL_JMP_BUF(heuristic_reachedness_jmpbuf);
740static
741void heuristic_reachedness_fault_catcher ( Int sigNo, Addr addr )
742{
743 leak_search_fault_catcher (sigNo, addr,
744 "heuristic_reachedness_fault_catcher",
745 heuristic_reachedness_jmpbuf);
746}
747
philippeab1fce92013-09-29 13:47:32 +0000748// If ch is heuristically reachable via an heuristic member of heur_set,
749// returns this heuristic.
750// If ch cannot be considered reachable using one of these heuristics,
751// return LchNone.
752// This should only be called when ptr is an interior ptr to ch.
753// The StdString/NewArray/MultipleInheritance heuristics are directly
754// inspired from DrMemory:
755// see http://www.burningcutlery.com/derek/docs/drmem-CGO11.pdf [section VI,C]
756// and bug 280271.
757static LeakCheckHeuristic heuristic_reachedness (Addr ptr,
758 MC_Chunk *ch, LC_Extra *ex,
759 UInt heur_set)
760{
philippeb5a02e72015-10-22 19:14:30 +0000761
762 fault_catcher_t prev_catcher;
763
764 prev_catcher = VG_(set_fault_catcher)(heuristic_reachedness_fault_catcher);
765
766 // See leak_search_fault_catcher
767 if (VG_MINIMAL_SETJMP(heuristic_reachedness_jmpbuf) != 0) {
768 VG_(set_fault_catcher) (prev_catcher);
769 return LchNone;
770 }
771
philippeab1fce92013-09-29 13:47:32 +0000772 if (HiS(LchStdString, heur_set)) {
773 // Detects inner pointers to Std::String for layout being
774 // length capacity refcount char_array[] \0
775 // where ptr points to the beginning of the char_array.
philippe078ab862013-10-13 18:38:30 +0000776 // Note: we check definedness for length and capacity but
777 // not for refcount, as refcount size might be smaller than
778 // a SizeT, giving a uninitialised hole in the first 3 SizeT.
779 if ( ptr == ch->data + 3 * sizeof(SizeT)
780 && MC_(is_valid_aligned_word)(ch->data + sizeof(SizeT))) {
781 const SizeT capacity = *((SizeT*)(ch->data + sizeof(SizeT)));
782 if (3 * sizeof(SizeT) + capacity + 1 == ch->szB
783 && MC_(is_valid_aligned_word)(ch->data)) {
784 const SizeT length = *((SizeT*)ch->data);
785 if (length <= capacity) {
786 // ??? could check there is no null byte from ptr to ptr+length-1
787 // ??? and that there is a null byte at ptr+length.
788 // ???
789 // ??? could check that ch->allockind is MC_AllocNew ???
790 // ??? probably not a good idea, as I guess stdstring
791 // ??? allocator can be done via custom allocator
792 // ??? or even a call to malloc ????
philippeb5a02e72015-10-22 19:14:30 +0000793 VG_(set_fault_catcher) (prev_catcher);
philippe078ab862013-10-13 18:38:30 +0000794 return LchStdString;
795 }
philippeab1fce92013-09-29 13:47:32 +0000796 }
797 }
798 }
799
philippe7c69a3e2014-07-21 19:55:11 +0000800 if (HiS(LchLength64, heur_set)) {
801 // Detects inner pointers that point at 64bit offset (8 bytes) into a
802 // block following the length of the remaining as 64bit number
803 // (=total block size - 8).
804 // This is used e.g. by sqlite for tracking the total size of allocated
805 // memory.
806 // Note that on 64bit platforms, a block matching LchLength64 will
807 // also be matched by LchNewArray.
808 if ( ptr == ch->data + sizeof(ULong)
809 && is_valid_aligned_ULong(ch->data)) {
810 const ULong size = *((ULong*)ch->data);
811 if (size > 0 && (ch->szB - sizeof(ULong)) == size) {
philippeb5a02e72015-10-22 19:14:30 +0000812 VG_(set_fault_catcher) (prev_catcher);
philippe7c69a3e2014-07-21 19:55:11 +0000813 return LchLength64;
814 }
815 }
816 }
817
philippeab1fce92013-09-29 13:47:32 +0000818 if (HiS(LchNewArray, heur_set)) {
819 // Detects inner pointers at second word of new[] array, following
820 // a plausible nr of elements.
821 // Such inner pointers are used for arrays of elements
822 // having a destructor, as the delete[] of the array must know
823 // how many elements to destroy.
824 //
825 // We have a strange/wrong case for 'ptr = new MyClass[0];' :
826 // For such a case, the returned ptr points just outside the
827 // allocated chunk. This chunk is then seen as a definite
828 // leak by Valgrind, as it is not considered an interior pointer.
829 // It is the c++ equivalent of bug 99923 (malloc(0) wrongly considered
830 // as definitely leaked). See the trick in find_chunk_for handling
831 // 0-sized block. This trick does not work for 'new MyClass[0]'
832 // because a chunk "word-sized" is allocated to store the (0) nr
833 // of elements.
philippe078ab862013-10-13 18:38:30 +0000834 if ( ptr == ch->data + sizeof(SizeT)
835 && MC_(is_valid_aligned_word)(ch->data)) {
philippeab1fce92013-09-29 13:47:32 +0000836 const SizeT nr_elts = *((SizeT*)ch->data);
837 if (nr_elts > 0 && (ch->szB - sizeof(SizeT)) % nr_elts == 0) {
838 // ??? could check that ch->allockind is MC_AllocNewVec ???
philippeb5a02e72015-10-22 19:14:30 +0000839 VG_(set_fault_catcher) (prev_catcher);
philippeab1fce92013-09-29 13:47:32 +0000840 return LchNewArray;
841 }
842 }
843 }
844
845 if (HiS(LchMultipleInheritance, heur_set)) {
846 // Detect inner pointer used for multiple inheritance.
847 // Assumption is that the vtable pointers are before the object.
philippe078ab862013-10-13 18:38:30 +0000848 if (VG_IS_WORD_ALIGNED(ptr)
849 && MC_(is_valid_aligned_word)(ptr)) {
philippeab1fce92013-09-29 13:47:32 +0000850 Addr first_addr;
851 Addr inner_addr;
852
853 // Avoid the call to is_vtable_addr when the addr is not
854 // aligned or points in the page0, as it is unlikely
855 // a vtable is located in this page. This last optimisation
856 // avoids to call aligned_ptr_above_page0_is_vtable_addr
857 // for all small integers.
858 // Note: we could possibly also avoid calling this function
859 // for small negative integers, as no vtable should be located
860 // in the last page.
861 inner_addr = *((Addr*)ptr);
862 if (VG_IS_WORD_ALIGNED(inner_addr)
philippe078ab862013-10-13 18:38:30 +0000863 && inner_addr >= (Addr)VKI_PAGE_SIZE
864 && MC_(is_valid_aligned_word)(ch->data)) {
philippeab1fce92013-09-29 13:47:32 +0000865 first_addr = *((Addr*)ch->data);
866 if (VG_IS_WORD_ALIGNED(first_addr)
867 && first_addr >= (Addr)VKI_PAGE_SIZE
868 && aligned_ptr_above_page0_is_vtable_addr(inner_addr)
869 && aligned_ptr_above_page0_is_vtable_addr(first_addr)) {
870 // ??? could check that ch->allockind is MC_AllocNew ???
philippeb5a02e72015-10-22 19:14:30 +0000871 VG_(set_fault_catcher) (prev_catcher);
philippeab1fce92013-09-29 13:47:32 +0000872 return LchMultipleInheritance;
873 }
874 }
875 }
876 }
877
philippeb5a02e72015-10-22 19:14:30 +0000878 VG_(set_fault_catcher) (prev_catcher);
philippeab1fce92013-09-29 13:47:32 +0000879 return LchNone;
880}
881
njn8225cc02009-03-09 22:52:24 +0000882
883// If 'ptr' is pointing to a heap-allocated block which hasn't been seen
884// before, push it onto the mark stack.
885static void
886lc_push_without_clique_if_a_chunk_ptr(Addr ptr, Bool is_prior_definite)
887{
888 Int ch_no;
889 MC_Chunk* ch;
890 LC_Extra* ex;
philippeab1fce92013-09-29 13:47:32 +0000891 Reachedness ch_via_ptr; // Is ch reachable via ptr, and how ?
njn8225cc02009-03-09 22:52:24 +0000892
893 if ( ! lc_is_a_chunk_ptr(ptr, &ch_no, &ch, &ex) )
894 return;
philippeab1fce92013-09-29 13:47:32 +0000895
896 if (ex->state == Reachable) {
philippe078ab862013-10-13 18:38:30 +0000897 if (ex->heuristic && ptr == ch->data)
898 // If block was considered reachable via an heuristic, and it is now
899 // directly reachable via ptr, clear the heuristic field.
philippeab1fce92013-09-29 13:47:32 +0000900 ex->heuristic = LchNone;
philippeab1fce92013-09-29 13:47:32 +0000901 return;
902 }
tom1d0f3f62010-10-04 20:55:21 +0000903
njn8225cc02009-03-09 22:52:24 +0000904 // Possibly upgrade the state, ie. one of:
905 // - Unreached --> Possible
906 // - Unreached --> Reachable
907 // - Possible --> Reachable
philippeab1fce92013-09-29 13:47:32 +0000908
909 if (ptr == ch->data)
910 ch_via_ptr = Reachable;
911 else if (detect_memory_leaks_last_heuristics) {
912 ex->heuristic
913 = heuristic_reachedness (ptr, ch, ex,
914 detect_memory_leaks_last_heuristics);
915 if (ex->heuristic)
916 ch_via_ptr = Reachable;
917 else
918 ch_via_ptr = Possible;
919 } else
920 ch_via_ptr = Possible;
921
922 if (ch_via_ptr == Reachable && is_prior_definite) {
923 // 'ptr' points to the start of the block or is to be considered as
924 // pointing to the start of the block, and the prior node is
njn8225cc02009-03-09 22:52:24 +0000925 // definite, which means that this block is definitely reachable.
926 ex->state = Reachable;
927
tom1d0f3f62010-10-04 20:55:21 +0000928 // State has changed to Reachable so (re)scan the block to make
929 // sure any blocks it points to are correctly marked.
930 lc_push(ch_no, ch);
931
njn8225cc02009-03-09 22:52:24 +0000932 } else if (ex->state == Unreached) {
933 // Either 'ptr' is a interior-pointer, or the prior node isn't definite,
934 // which means that we can only mark this block as possibly reachable.
935 ex->state = Possible;
tom1d0f3f62010-10-04 20:55:21 +0000936
937 // State has changed to Possible so (re)scan the block to make
938 // sure any blocks it points to are correctly marked.
939 lc_push(ch_no, ch);
njn8225cc02009-03-09 22:52:24 +0000940 }
941}
942
943static void
florian6bd9dc12012-11-23 16:17:43 +0000944lc_push_if_a_chunk_ptr_register(ThreadId tid, const HChar* regname, Addr ptr)
njn8225cc02009-03-09 22:52:24 +0000945{
946 lc_push_without_clique_if_a_chunk_ptr(ptr, /*is_prior_definite*/True);
947}
948
949// If ptr is pointing to a heap-allocated block which hasn't been seen
950// before, push it onto the mark stack. Clique is the index of the
951// clique leader.
952static void
philippea22f59d2012-01-26 23:13:52 +0000953lc_push_with_clique_if_a_chunk_ptr(Addr ptr, Int clique, Int cur_clique)
njn8225cc02009-03-09 22:52:24 +0000954{
955 Int ch_no;
956 MC_Chunk* ch;
957 LC_Extra* ex;
958
959 tl_assert(0 <= clique && clique < lc_n_chunks);
960
961 if ( ! lc_is_a_chunk_ptr(ptr, &ch_no, &ch, &ex) )
962 return;
963
964 // If it's not Unreached, it's already been handled so ignore it.
965 // If ch_no==clique, it's the clique leader, which means this is a cyclic
966 // structure; again ignore it because it's already been handled.
967 if (ex->state == Unreached && ch_no != clique) {
968 // Note that, unlike reachable blocks, we currently don't distinguish
969 // between start-pointers and interior-pointers here. We probably
970 // should, though.
njn8225cc02009-03-09 22:52:24 +0000971 lc_push(ch_no, ch);
972
973 // Add the block to the clique, and add its size to the
974 // clique-leader's indirect size. Also, if the new block was
975 // itself a clique leader, it isn't any more, so add its
976 // indirect_szB to the new clique leader.
977 if (VG_DEBUG_CLIQUE) {
philippea22f59d2012-01-26 23:13:52 +0000978 if (ex->IorC.indirect_szB > 0)
njn8225cc02009-03-09 22:52:24 +0000979 VG_(printf)(" clique %d joining clique %d adding %lu+%lu\n",
florian47755db2015-08-05 12:09:55 +0000980 ch_no, clique, (SizeT)ch->szB, ex->IorC.indirect_szB);
njn8225cc02009-03-09 22:52:24 +0000981 else
982 VG_(printf)(" block %d joining clique %d adding %lu\n",
florian47755db2015-08-05 12:09:55 +0000983 ch_no, clique, (SizeT)ch->szB);
njn8225cc02009-03-09 22:52:24 +0000984 }
985
philippea22f59d2012-01-26 23:13:52 +0000986 lc_extras[clique].IorC.indirect_szB += ch->szB;
987 lc_extras[clique].IorC.indirect_szB += ex->IorC.indirect_szB;
988 ex->state = IndirectLeak;
989 ex->IorC.clique = (SizeT) cur_clique;
njn8225cc02009-03-09 22:52:24 +0000990 }
991}
992
993static void
philippeab1fce92013-09-29 13:47:32 +0000994lc_push_if_a_chunk_ptr(Addr ptr,
995 Int clique, Int cur_clique, Bool is_prior_definite)
njn8225cc02009-03-09 22:52:24 +0000996{
997 if (-1 == clique)
998 lc_push_without_clique_if_a_chunk_ptr(ptr, is_prior_definite);
999 else
philippea22f59d2012-01-26 23:13:52 +00001000 lc_push_with_clique_if_a_chunk_ptr(ptr, clique, cur_clique);
sewardjb5f6f512005-03-10 23:59:00 +00001001}
1002
sewardj45d94cc2005-04-20 14:44:11 +00001003
philippeb5a02e72015-10-22 19:14:30 +00001004static VG_MINIMAL_JMP_BUF(lc_scan_memory_jmpbuf);
njn8225cc02009-03-09 22:52:24 +00001005static
philippeb5a02e72015-10-22 19:14:30 +00001006void lc_scan_memory_fault_catcher ( Int sigNo, Addr addr )
sewardjb5f6f512005-03-10 23:59:00 +00001007{
philippeb5a02e72015-10-22 19:14:30 +00001008 leak_search_fault_catcher (sigNo, addr,
1009 "lc_scan_memory_fault_catcher",
1010 lc_scan_memory_jmpbuf);
njn8225cc02009-03-09 22:52:24 +00001011}
1012
philippea22f59d2012-01-26 23:13:52 +00001013// lc_scan_memory has 2 modes:
1014//
1015// 1. Leak check mode (searched == 0).
1016// -----------------------------------
njn8225cc02009-03-09 22:52:24 +00001017// Scan a block of memory between [start, start+len). This range may
florianad4e9792015-07-05 21:53:33 +00001018// be bogus, inaccessible, or otherwise strange; we deal with it. For each
njn8225cc02009-03-09 22:52:24 +00001019// valid aligned word we assume it's a pointer to a chunk a push the chunk
1020// onto the mark stack if so.
philippea22f59d2012-01-26 23:13:52 +00001021// clique is the "highest level clique" in which indirectly leaked blocks have
1022// to be collected. cur_clique is the current "lower" level clique through which
1023// the memory to be scanned has been found.
1024// Example: in the below tree if A is leaked, the top level clique will
1025// be A, while lower level cliques will be B and C.
1026/*
1027 A
florianf5300ff2014-12-28 16:46:14 +00001028 / \
philippea22f59d2012-01-26 23:13:52 +00001029 B C
florianf5300ff2014-12-28 16:46:14 +00001030 / \ / \
philippea22f59d2012-01-26 23:13:52 +00001031 D E F G
1032*/
1033// Proper handling of top and lowest level clique allows block_list of a loss
1034// record to describe the hierarchy of indirectly leaked blocks.
1035//
1036// 2. Search ptr mode (searched != 0).
1037// -----------------------------------
1038// In this mode, searches for pointers to a specific address range
philippeab1fce92013-09-29 13:47:32 +00001039// In such a case, lc_scan_memory just scans [start..start+len[ for pointers
1040// to searched and outputs the places where searched is found.
1041// It does not recursively scans the found memory.
njn8225cc02009-03-09 22:52:24 +00001042static void
philippeab1fce92013-09-29 13:47:32 +00001043lc_scan_memory(Addr start, SizeT len, Bool is_prior_definite,
1044 Int clique, Int cur_clique,
philippea22f59d2012-01-26 23:13:52 +00001045 Addr searched, SizeT szB)
njn8225cc02009-03-09 22:52:24 +00001046{
philippe57a16a22012-07-18 22:26:51 +00001047 /* memory scan is based on the assumption that valid pointers are aligned
1048 on a multiple of sizeof(Addr). So, we can (and must) skip the begin and
1049 end portions of the block if they are not aligned on sizeof(Addr):
1050 These cannot be a valid pointer, and calls to MC_(is_valid_aligned_word)
1051 will assert for a non aligned address. */
philippe110c77e2013-10-15 21:04:56 +00001052#if defined(VGA_s390x)
1053 // Define ptr as volatile, as on this platform, the value of ptr
1054 // is read in code executed via a longjmp.
1055 volatile
1056#endif
philippe7a76f4b2013-10-06 21:23:04 +00001057 Addr ptr = VG_ROUNDUP(start, sizeof(Addr));
1058 const Addr end = VG_ROUNDDN(start+len, sizeof(Addr));
philippeb5a02e72015-10-22 19:14:30 +00001059 fault_catcher_t prev_catcher;
sewardjb5f6f512005-03-10 23:59:00 +00001060
1061 if (VG_DEBUG_LEAKCHECK)
njn8225cc02009-03-09 22:52:24 +00001062 VG_(printf)("scan %#lx-%#lx (%lu)\n", start, end, len);
1063
philippeb5a02e72015-10-22 19:14:30 +00001064 prev_catcher = VG_(set_fault_catcher)(lc_scan_memory_fault_catcher);
sewardjb5f6f512005-03-10 23:59:00 +00001065
philippe57a16a22012-07-18 22:26:51 +00001066 /* Optimisation: the loop below will check for each begin
1067 of SM chunk if the chunk is fully unaddressable. The idea is to
1068 skip efficiently such fully unaddressable SM chunks.
florianad4e9792015-07-05 21:53:33 +00001069 So, we preferably start the loop on a chunk boundary.
philippe57a16a22012-07-18 22:26:51 +00001070 If the chunk is not fully unaddressable, we might be in
1071 an unaddressable page. Again, the idea is to skip efficiently
1072 such unaddressable page : this is the "else" part.
1073 We use an "else" so that two consecutive fully unaddressable
1074 SM chunks will be skipped efficiently: first one is skipped
1075 by this piece of code. The next SM chunk will be skipped inside
1076 the loop. */
1077 if ( ! MC_(is_within_valid_secondary)(ptr) ) {
1078 // Skip an invalid SM chunk till the beginning of the next SM Chunk.
1079 ptr = VG_ROUNDUP(ptr+1, SM_SIZE);
1080 } else if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ)) {
1081 // else we are in a (at least partially) valid SM chunk.
1082 // We might be in the middle of an unreadable page.
1083 // Do a cheap check to see if it's valid;
1084 // if not, skip onto the next page.
njn8225cc02009-03-09 22:52:24 +00001085 ptr = VG_PGROUNDUP(ptr+1); // First page is bad - skip it.
philippe57a16a22012-07-18 22:26:51 +00001086 }
philippe7a76f4b2013-10-06 21:23:04 +00001087 /* The above optimisation and below loop is based on some relationships
1088 between VKI_PAGE_SIZE, SM_SIZE and sizeof(Addr) which are asserted in
philippe57a16a22012-07-18 22:26:51 +00001089 MC_(detect_memory_leaks). */
sewardjb5f6f512005-03-10 23:59:00 +00001090
philippeb5a02e72015-10-22 19:14:30 +00001091 // See leak_search_fault_catcher
1092 if (VG_MINIMAL_SETJMP(lc_scan_memory_jmpbuf) != 0) {
philippe7a76f4b2013-10-06 21:23:04 +00001093 // Catch read error ...
philippe110c77e2013-10-15 21:04:56 +00001094# if defined(VGA_s390x)
1095 // For a SIGSEGV, s390 delivers the page address of the bad address.
1096 // For a SIGBUS, old s390 kernels deliver a NULL address.
1097 // bad_scanned_addr can thus not be used.
1098 // So, on this platform, we always skip a full page from ptr.
1099 // The below implies to mark ptr as volatile, as we read the value
1100 // after a longjmp to here.
1101 lc_sig_skipped_szB += VKI_PAGE_SIZE;
1102 ptr = ptr + VKI_PAGE_SIZE; // Unaddressable, - skip it.
1103# else
1104 // On other platforms, just skip one Addr.
philippe7a76f4b2013-10-06 21:23:04 +00001105 lc_sig_skipped_szB += sizeof(Addr);
1106 tl_assert(bad_scanned_addr >= VG_ROUNDUP(start, sizeof(Addr)));
1107 tl_assert(bad_scanned_addr < VG_ROUNDDN(start+len, sizeof(Addr)));
1108 ptr = bad_scanned_addr + sizeof(Addr); // Unaddressable, - skip it.
philippe110c77e2013-10-15 21:04:56 +00001109#endif
philippe7a76f4b2013-10-06 21:23:04 +00001110 }
sewardj05fe85e2005-04-27 22:46:36 +00001111 while (ptr < end) {
sewardjb5f6f512005-03-10 23:59:00 +00001112 Addr addr;
1113
njn8225cc02009-03-09 22:52:24 +00001114 // Skip invalid chunks.
philippe57a16a22012-07-18 22:26:51 +00001115 if (UNLIKELY((ptr % SM_SIZE) == 0)) {
1116 if (! MC_(is_within_valid_secondary)(ptr) ) {
1117 ptr = VG_ROUNDUP(ptr+1, SM_SIZE);
1118 continue;
1119 }
sewardjb5f6f512005-03-10 23:59:00 +00001120 }
1121
njn8225cc02009-03-09 22:52:24 +00001122 // Look to see if this page seems reasonable.
philippe57a16a22012-07-18 22:26:51 +00001123 if (UNLIKELY((ptr % VKI_PAGE_SIZE) == 0)) {
njn8225cc02009-03-09 22:52:24 +00001124 if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ)) {
1125 ptr += VKI_PAGE_SIZE; // Bad page - skip it.
1126 continue;
1127 }
sewardjb5f6f512005-03-10 23:59:00 +00001128 }
1129
philippe57a16a22012-07-18 22:26:51 +00001130 if ( MC_(is_valid_aligned_word)(ptr) ) {
1131 lc_scanned_szB += sizeof(Addr);
philippe7a76f4b2013-10-06 21:23:04 +00001132 // If the below read fails, we will longjmp to the loop begin.
philippe57a16a22012-07-18 22:26:51 +00001133 addr = *(Addr *)ptr;
1134 // If we get here, the scanned word is in valid memory. Now
1135 // let's see if its contents point to a chunk.
1136 if (UNLIKELY(searched)) {
1137 if (addr >= searched && addr < searched + szB) {
philippeab1fce92013-09-29 13:47:32 +00001138 if (addr == searched) {
philippe57a16a22012-07-18 22:26:51 +00001139 VG_(umsg)("*%#lx points at %#lx\n", ptr, searched);
philippeab1fce92013-09-29 13:47:32 +00001140 MC_(pp_describe_addr) (ptr);
1141 } else {
1142 Int ch_no;
1143 MC_Chunk *ch;
1144 LC_Extra *ex;
philippe57a16a22012-07-18 22:26:51 +00001145 VG_(umsg)("*%#lx interior points at %lu bytes inside %#lx\n",
1146 ptr, (long unsigned) addr - searched, searched);
philippeab1fce92013-09-29 13:47:32 +00001147 MC_(pp_describe_addr) (ptr);
1148 if (lc_is_a_chunk_ptr(addr, &ch_no, &ch, &ex) ) {
1149 Int h;
philippe7c69a3e2014-07-21 19:55:11 +00001150 for (h = LchStdString; h < N_LEAK_CHECK_HEURISTICS; h++) {
philippeab1fce92013-09-29 13:47:32 +00001151 if (heuristic_reachedness(addr, ch, ex, H2S(h)) == h) {
1152 VG_(umsg)("block at %#lx considered reachable "
1153 "by ptr %#lx using %s heuristic\n",
1154 ch->data, addr, pp_heuristic(h));
1155 }
1156 }
philippe7a76f4b2013-10-06 21:23:04 +00001157 // Verify the loop above has properly scanned all
1158 // heuristics. If the below fails, it probably means the
1159 // LeakCheckHeuristic enum is not in sync anymore with the
1160 // above loop and/or with N_LEAK_CHECK_HEURISTICS.
philippe5bd40602013-10-02 20:59:05 +00001161 tl_assert (h == N_LEAK_CHECK_HEURISTICS);
philippeab1fce92013-09-29 13:47:32 +00001162 }
1163 }
philippea22f59d2012-01-26 23:13:52 +00001164 }
philippe57a16a22012-07-18 22:26:51 +00001165 } else {
1166 lc_push_if_a_chunk_ptr(addr, clique, cur_clique, is_prior_definite);
njn8225cc02009-03-09 22:52:24 +00001167 }
philippe57a16a22012-07-18 22:26:51 +00001168 } else if (0 && VG_DEBUG_LEAKCHECK) {
1169 VG_(printf)("%#lx not valid\n", ptr);
sewardjb5f6f512005-03-10 23:59:00 +00001170 }
philippe57a16a22012-07-18 22:26:51 +00001171 ptr += sizeof(Addr);
sewardjb5f6f512005-03-10 23:59:00 +00001172 }
1173
philippeb5a02e72015-10-22 19:14:30 +00001174 VG_(set_fault_catcher)(prev_catcher);
sewardjb5f6f512005-03-10 23:59:00 +00001175}
1176
sewardj45d94cc2005-04-20 14:44:11 +00001177
njn8225cc02009-03-09 22:52:24 +00001178// Process the mark stack until empty.
1179static void lc_process_markstack(Int clique)
sewardjb5f6f512005-03-10 23:59:00 +00001180{
njne3675d62009-05-19 02:08:25 +00001181 Int top = -1; // shut gcc up
njn8225cc02009-03-09 22:52:24 +00001182 Bool is_prior_definite;
sewardjb5f6f512005-03-10 23:59:00 +00001183
njn8225cc02009-03-09 22:52:24 +00001184 while (lc_pop(&top)) {
tom1d0f3f62010-10-04 20:55:21 +00001185 tl_assert(top >= 0 && top < lc_n_chunks);
sewardjb5f6f512005-03-10 23:59:00 +00001186
njn8225cc02009-03-09 22:52:24 +00001187 // See comment about 'is_prior_definite' at the top to understand this.
1188 is_prior_definite = ( Possible != lc_extras[top].state );
sewardjb5f6f512005-03-10 23:59:00 +00001189
njn8225cc02009-03-09 22:52:24 +00001190 lc_scan_memory(lc_chunks[top]->data, lc_chunks[top]->szB,
philippea22f59d2012-01-26 23:13:52 +00001191 is_prior_definite, clique, (clique == -1 ? -1 : top),
1192 /*searched*/ 0, 0);
sewardjb5f6f512005-03-10 23:59:00 +00001193 }
1194}
1195
njn29a5c012009-05-06 06:15:55 +00001196static Word cmp_LossRecordKey_LossRecord(const void* key, const void* elem)
1197{
florian3e798632012-11-24 19:41:54 +00001198 const LossRecordKey* a = key;
1199 const LossRecordKey* b = &(((const LossRecord*)elem)->key);
njn29a5c012009-05-06 06:15:55 +00001200
1201 // Compare on states first because that's fast.
1202 if (a->state < b->state) return -1;
1203 if (a->state > b->state) return 1;
1204 // Ok, the states are equal. Now compare the locations, which is slower.
1205 if (VG_(eq_ExeContext)(
1206 MC_(clo_leak_resolution), a->allocated_at, b->allocated_at))
1207 return 0;
1208 // Different locations. Ordering is arbitrary, just use the ec pointer.
1209 if (a->allocated_at < b->allocated_at) return -1;
1210 if (a->allocated_at > b->allocated_at) return 1;
1211 VG_(tool_panic)("bad LossRecord comparison");
1212}
1213
florian6bd9dc12012-11-23 16:17:43 +00001214static Int cmp_LossRecords(const void* va, const void* vb)
njn29a5c012009-05-06 06:15:55 +00001215{
florian3e798632012-11-24 19:41:54 +00001216 const LossRecord* lr_a = *(const LossRecord *const *)va;
1217 const LossRecord* lr_b = *(const LossRecord *const *)vb;
njn29a5c012009-05-06 06:15:55 +00001218 SizeT total_szB_a = lr_a->szB + lr_a->indirect_szB;
1219 SizeT total_szB_b = lr_b->szB + lr_b->indirect_szB;
1220
1221 // First compare by sizes.
1222 if (total_szB_a < total_szB_b) return -1;
1223 if (total_szB_a > total_szB_b) return 1;
1224 // If size are equal, compare by states.
1225 if (lr_a->key.state < lr_b->key.state) return -1;
1226 if (lr_a->key.state > lr_b->key.state) return 1;
njne10c7f82009-05-06 06:52:47 +00001227 // If they're still equal here, it doesn't matter that much, but we keep
1228 // comparing other things so that regtests are as deterministic as
1229 // possible. So: compare num_blocks.
1230 if (lr_a->num_blocks < lr_b->num_blocks) return -1;
1231 if (lr_a->num_blocks > lr_b->num_blocks) return 1;
1232 // Finally, compare ExeContext addresses... older ones are likely to have
1233 // lower addresses.
1234 if (lr_a->key.allocated_at < lr_b->key.allocated_at) return -1;
1235 if (lr_a->key.allocated_at > lr_b->key.allocated_at) return 1;
njn29a5c012009-05-06 06:15:55 +00001236 return 0;
1237}
1238
philippea22f59d2012-01-26 23:13:52 +00001239// allocates or reallocates lr_array, and set its elements to the loss records
1240// contains in lr_table.
florian47755db2015-08-05 12:09:55 +00001241static UInt get_lr_array_from_lr_table(void) {
1242 UInt i, n_lossrecords;
philippea22f59d2012-01-26 23:13:52 +00001243 LossRecord* lr;
1244
1245 n_lossrecords = VG_(OSetGen_Size)(lr_table);
1246
1247 // (re-)create the array of pointers to the loss records.
1248 // lr_array is kept to allow producing the block list from gdbserver.
1249 if (lr_array != NULL)
1250 VG_(free)(lr_array);
1251 lr_array = VG_(malloc)("mc.pr.2", n_lossrecords * sizeof(LossRecord*));
1252 i = 0;
1253 VG_(OSetGen_ResetIter)(lr_table);
1254 while ( (lr = VG_(OSetGen_Next)(lr_table)) ) {
1255 lr_array[i++] = lr;
1256 }
1257 tl_assert(i == n_lossrecords);
1258 return n_lossrecords;
1259}
1260
philippe84234902012-01-14 13:53:13 +00001261
1262static void get_printing_rules(LeakCheckParams* lcp,
1263 LossRecord* lr,
1264 Bool* count_as_error,
1265 Bool* print_record)
sewardjb5f6f512005-03-10 23:59:00 +00001266{
philippe84234902012-01-14 13:53:13 +00001267 // Rules for printing:
1268 // - We don't show suppressed loss records ever (and that's controlled
1269 // within the error manager).
philippe2193a7c2012-12-08 17:54:16 +00001270 // - We show non-suppressed loss records that are specified in
1271 // --show-leak-kinds=... if --leak-check=yes.
philippe84234902012-01-14 13:53:13 +00001272
1273 Bool delta_considered;
1274
1275 switch (lcp->deltamode) {
1276 case LCD_Any:
1277 delta_considered = lr->num_blocks > 0;
1278 break;
1279 case LCD_Increased:
1280 delta_considered
1281 = lr->szB > lr->old_szB
1282 || lr->indirect_szB > lr->old_indirect_szB
1283 || lr->num_blocks > lr->old_num_blocks;
1284 break;
1285 case LCD_Changed:
1286 delta_considered = lr->szB != lr->old_szB
1287 || lr->indirect_szB != lr->old_indirect_szB
1288 || lr->num_blocks != lr->old_num_blocks;
1289 break;
1290 default:
1291 tl_assert(0);
1292 }
1293
philippe2193a7c2012-12-08 17:54:16 +00001294 *print_record = lcp->mode == LC_Full && delta_considered
1295 && RiS(lr->key.state,lcp->show_leak_kinds);
philippe84234902012-01-14 13:53:13 +00001296 // We don't count a leaks as errors with lcp->mode==LC_Summary.
1297 // Otherwise you can get high error counts with few or no error
philippe2193a7c2012-12-08 17:54:16 +00001298 // messages, which can be confusing. Otherwise, we count as errors
1299 // the leak kinds requested by --errors-for-leak-kinds=...
1300 *count_as_error = lcp->mode == LC_Full && delta_considered
1301 && RiS(lr->key.state,lcp->errors_for_leak_kinds);
philippe84234902012-01-14 13:53:13 +00001302}
1303
1304static void print_results(ThreadId tid, LeakCheckParams* lcp)
1305{
1306 Int i, n_lossrecords, start_lr_output_scan;
njn29a5c012009-05-06 06:15:55 +00001307 LossRecord* lr;
1308 Bool is_suppressed;
philippeab1fce92013-09-29 13:47:32 +00001309 /* old_* variables are used to report delta in summary. */
1310 SizeT old_bytes_leaked = MC_(bytes_leaked);
sewardjc8bd1df2011-06-26 12:41:33 +00001311 SizeT old_bytes_indirect = MC_(bytes_indirect);
1312 SizeT old_bytes_dubious = MC_(bytes_dubious);
1313 SizeT old_bytes_reachable = MC_(bytes_reachable);
1314 SizeT old_bytes_suppressed = MC_(bytes_suppressed);
1315 SizeT old_blocks_leaked = MC_(blocks_leaked);
1316 SizeT old_blocks_indirect = MC_(blocks_indirect);
1317 SizeT old_blocks_dubious = MC_(blocks_dubious);
1318 SizeT old_blocks_reachable = MC_(blocks_reachable);
1319 SizeT old_blocks_suppressed = MC_(blocks_suppressed);
sewardjb5f6f512005-03-10 23:59:00 +00001320
philippeab1fce92013-09-29 13:47:32 +00001321 SizeT old_bytes_heuristically_reachable[N_LEAK_CHECK_HEURISTICS];
1322 SizeT old_blocks_heuristically_reachable[N_LEAK_CHECK_HEURISTICS];
1323
1324 for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) {
1325 old_bytes_heuristically_reachable[i]
1326 = MC_(bytes_heuristically_reachable)[i];
1327 MC_(bytes_heuristically_reachable)[i] = 0;
1328 old_blocks_heuristically_reachable[i]
1329 = MC_(blocks_heuristically_reachable)[i];
1330 MC_(blocks_heuristically_reachable)[i] = 0;
1331 }
1332
sewardjc8bd1df2011-06-26 12:41:33 +00001333 if (lr_table == NULL)
1334 // Create the lr_table, which holds the loss records.
1335 // If the lr_table already exists, it means it contains
1336 // loss_records from the previous leak search. The old_*
1337 // values in these records are used to implement the
1338 // leak check delta mode
1339 lr_table =
1340 VG_(OSetGen_Create)(offsetof(LossRecord, key),
1341 cmp_LossRecordKey_LossRecord,
1342 VG_(malloc), "mc.pr.1",
1343 VG_(free));
1344
philippea22f59d2012-01-26 23:13:52 +00001345 // If we have loss records from a previous search, reset values to have
1346 // proper printing of the deltas between previous search and this search.
1347 n_lossrecords = get_lr_array_from_lr_table();
1348 for (i = 0; i < n_lossrecords; i++) {
philippe4bbfc5f2012-02-27 21:52:45 +00001349 if (lr_array[i]->num_blocks == 0) {
philippea22f59d2012-01-26 23:13:52 +00001350 // remove from lr_table the old loss_records with 0 bytes found
1351 VG_(OSetGen_Remove) (lr_table, &lr_array[i]->key);
philippe4bbfc5f2012-02-27 21:52:45 +00001352 VG_(OSetGen_FreeNode)(lr_table, lr_array[i]);
1353 } else {
philippea22f59d2012-01-26 23:13:52 +00001354 // move the leak sizes to old_* and zero the current sizes
1355 // for next leak search
1356 lr_array[i]->old_szB = lr_array[i]->szB;
1357 lr_array[i]->old_indirect_szB = lr_array[i]->indirect_szB;
1358 lr_array[i]->old_num_blocks = lr_array[i]->num_blocks;
1359 lr_array[i]->szB = 0;
1360 lr_array[i]->indirect_szB = 0;
1361 lr_array[i]->num_blocks = 0;
1362 }
1363 }
1364 // lr_array now contains "invalid" loss records => free it.
1365 // lr_array will be re-created below with the kept and new loss records.
1366 VG_(free) (lr_array);
1367 lr_array = NULL;
njn29a5c012009-05-06 06:15:55 +00001368
1369 // Convert the chunks into loss records, merging them where appropriate.
njn8225cc02009-03-09 22:52:24 +00001370 for (i = 0; i < lc_n_chunks; i++) {
njn29a5c012009-05-06 06:15:55 +00001371 MC_Chunk* ch = lc_chunks[i];
1372 LC_Extra* ex = &(lc_extras)[i];
1373 LossRecord* old_lr;
1374 LossRecordKey lrkey;
1375 lrkey.state = ex->state;
philippe8617b5b2013-01-12 19:53:08 +00001376 lrkey.allocated_at = MC_(allocated_at)(ch);
sewardjb5f6f512005-03-10 23:59:00 +00001377
philippeab1fce92013-09-29 13:47:32 +00001378 if (ex->heuristic) {
1379 MC_(bytes_heuristically_reachable)[ex->heuristic] += ch->szB;
1380 MC_(blocks_heuristically_reachable)[ex->heuristic]++;
1381 if (VG_DEBUG_LEAKCHECK)
1382 VG_(printf)("heuristic %s %#lx len %lu\n",
1383 pp_heuristic(ex->heuristic),
florian47755db2015-08-05 12:09:55 +00001384 ch->data, (SizeT)ch->szB);
philippeab1fce92013-09-29 13:47:32 +00001385 }
1386
njn29a5c012009-05-06 06:15:55 +00001387 old_lr = VG_(OSetGen_Lookup)(lr_table, &lrkey);
1388 if (old_lr) {
1389 // We found an existing loss record matching this chunk. Update the
1390 // loss record's details in-situ. This is safe because we don't
1391 // change the elements used as the OSet key.
1392 old_lr->szB += ch->szB;
philippea22f59d2012-01-26 23:13:52 +00001393 if (ex->state == Unreached)
1394 old_lr->indirect_szB += ex->IorC.indirect_szB;
njn29a5c012009-05-06 06:15:55 +00001395 old_lr->num_blocks++;
sewardjb5f6f512005-03-10 23:59:00 +00001396 } else {
njn29a5c012009-05-06 06:15:55 +00001397 // No existing loss record matches this chunk. Create a new loss
1398 // record, initialise it from the chunk, and insert it into lr_table.
1399 lr = VG_(OSetGen_AllocNode)(lr_table, sizeof(LossRecord));
1400 lr->key = lrkey;
1401 lr->szB = ch->szB;
philippea22f59d2012-01-26 23:13:52 +00001402 if (ex->state == Unreached)
1403 lr->indirect_szB = ex->IorC.indirect_szB;
1404 else
1405 lr->indirect_szB = 0;
njn29a5c012009-05-06 06:15:55 +00001406 lr->num_blocks = 1;
sewardjc8bd1df2011-06-26 12:41:33 +00001407 lr->old_szB = 0;
1408 lr->old_indirect_szB = 0;
1409 lr->old_num_blocks = 0;
njn29a5c012009-05-06 06:15:55 +00001410 VG_(OSetGen_Insert)(lr_table, lr);
sewardjb5f6f512005-03-10 23:59:00 +00001411 }
1412 }
1413
philippea22f59d2012-01-26 23:13:52 +00001414 // (re-)create the array of pointers to the (new) loss records.
1415 n_lossrecords = get_lr_array_from_lr_table ();
1416 tl_assert(VG_(OSetGen_Size)(lr_table) == n_lossrecords);
njn29a5c012009-05-06 06:15:55 +00001417
1418 // Sort the array by loss record sizes.
1419 VG_(ssort)(lr_array, n_lossrecords, sizeof(LossRecord*),
1420 cmp_LossRecords);
1421
1422 // Zero totals.
njn8225cc02009-03-09 22:52:24 +00001423 MC_(blocks_leaked) = MC_(bytes_leaked) = 0;
1424 MC_(blocks_indirect) = MC_(bytes_indirect) = 0;
1425 MC_(blocks_dubious) = MC_(bytes_dubious) = 0;
1426 MC_(blocks_reachable) = MC_(bytes_reachable) = 0;
1427 MC_(blocks_suppressed) = MC_(bytes_suppressed) = 0;
1428
philippe84234902012-01-14 13:53:13 +00001429 // If there is a maximum nr of loss records we can output, then first
1430 // compute from where the output scan has to start.
1431 // By default, start from the first loss record. Compute a higher
1432 // value if there is a maximum to respect. We need to print the last
1433 // records, as the one with the biggest sizes are more interesting.
1434 start_lr_output_scan = 0;
1435 if (lcp->mode == LC_Full && lcp->max_loss_records_output < n_lossrecords) {
1436 Int nr_printable_records = 0;
1437 for (i = n_lossrecords - 1; i >= 0 && start_lr_output_scan == 0; i--) {
1438 Bool count_as_error, print_record;
1439 lr = lr_array[i];
1440 get_printing_rules (lcp, lr, &count_as_error, &print_record);
1441 // Do not use get_printing_rules results for is_suppressed, as we
1442 // only want to check if the record would be suppressed.
1443 is_suppressed =
1444 MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr,
1445 False /* print_record */,
1446 False /* count_as_error */);
1447 if (print_record && !is_suppressed) {
1448 nr_printable_records++;
1449 if (nr_printable_records == lcp->max_loss_records_output)
1450 start_lr_output_scan = i;
1451 }
sewardjc8bd1df2011-06-26 12:41:33 +00001452 }
philippe84234902012-01-14 13:53:13 +00001453 }
sewardjc8bd1df2011-06-26 12:41:33 +00001454
philippe84234902012-01-14 13:53:13 +00001455 // Print the loss records (in size order) and collect summary stats.
1456 for (i = start_lr_output_scan; i < n_lossrecords; i++) {
1457 Bool count_as_error, print_record;
1458 lr = lr_array[i];
1459 get_printing_rules(lcp, lr, &count_as_error, &print_record);
sewardjb5f6f512005-03-10 23:59:00 +00001460 is_suppressed =
njn18afe5d2009-08-10 08:25:39 +00001461 MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr, print_record,
1462 count_as_error );
sewardjb5f6f512005-03-10 23:59:00 +00001463
1464 if (is_suppressed) {
njn29a5c012009-05-06 06:15:55 +00001465 MC_(blocks_suppressed) += lr->num_blocks;
1466 MC_(bytes_suppressed) += lr->szB;
sewardjb5f6f512005-03-10 23:59:00 +00001467
njn29a5c012009-05-06 06:15:55 +00001468 } else if (Unreached == lr->key.state) {
1469 MC_(blocks_leaked) += lr->num_blocks;
1470 MC_(bytes_leaked) += lr->szB;
sewardjb5f6f512005-03-10 23:59:00 +00001471
njn29a5c012009-05-06 06:15:55 +00001472 } else if (IndirectLeak == lr->key.state) {
1473 MC_(blocks_indirect) += lr->num_blocks;
1474 MC_(bytes_indirect) += lr->szB;
sewardjb5f6f512005-03-10 23:59:00 +00001475
njn29a5c012009-05-06 06:15:55 +00001476 } else if (Possible == lr->key.state) {
1477 MC_(blocks_dubious) += lr->num_blocks;
1478 MC_(bytes_dubious) += lr->szB;
sewardjb5f6f512005-03-10 23:59:00 +00001479
njn29a5c012009-05-06 06:15:55 +00001480 } else if (Reachable == lr->key.state) {
1481 MC_(blocks_reachable) += lr->num_blocks;
1482 MC_(bytes_reachable) += lr->szB;
sewardjb5f6f512005-03-10 23:59:00 +00001483
1484 } else {
njn8225cc02009-03-09 22:52:24 +00001485 VG_(tool_panic)("unknown loss mode");
sewardjb5f6f512005-03-10 23:59:00 +00001486 }
sewardjb5f6f512005-03-10 23:59:00 +00001487 }
sewardjb5f6f512005-03-10 23:59:00 +00001488
njn8225cc02009-03-09 22:52:24 +00001489 if (VG_(clo_verbosity) > 0 && !VG_(clo_xml)) {
floriancf6e7342014-09-28 13:29:06 +00001490 HChar d_bytes[31];
1491 HChar d_blocks[31];
philippeab1fce92013-09-29 13:47:32 +00001492# define DBY(new,old) \
floriancf6e7342014-09-28 13:29:06 +00001493 MC_(snprintf_delta) (d_bytes, sizeof(d_bytes), (new), (old), \
1494 lcp->deltamode)
philippeab1fce92013-09-29 13:47:32 +00001495# define DBL(new,old) \
floriancf6e7342014-09-28 13:29:06 +00001496 MC_(snprintf_delta) (d_blocks, sizeof(d_blocks), (new), (old), \
1497 lcp->deltamode)
sewardjc8bd1df2011-06-26 12:41:33 +00001498
sewardj6b523cd2009-07-15 14:49:40 +00001499 VG_(umsg)("LEAK SUMMARY:\n");
sewardjc8bd1df2011-06-26 12:41:33 +00001500 VG_(umsg)(" definitely lost: %'lu%s bytes in %'lu%s blocks\n",
1501 MC_(bytes_leaked),
philippeab1fce92013-09-29 13:47:32 +00001502 DBY (MC_(bytes_leaked), old_bytes_leaked),
sewardjc8bd1df2011-06-26 12:41:33 +00001503 MC_(blocks_leaked),
philippeab1fce92013-09-29 13:47:32 +00001504 DBL (MC_(blocks_leaked), old_blocks_leaked));
sewardjc8bd1df2011-06-26 12:41:33 +00001505 VG_(umsg)(" indirectly lost: %'lu%s bytes in %'lu%s blocks\n",
1506 MC_(bytes_indirect),
philippeab1fce92013-09-29 13:47:32 +00001507 DBY (MC_(bytes_indirect), old_bytes_indirect),
sewardjc8bd1df2011-06-26 12:41:33 +00001508 MC_(blocks_indirect),
philippeab1fce92013-09-29 13:47:32 +00001509 DBL (MC_(blocks_indirect), old_blocks_indirect));
sewardjc8bd1df2011-06-26 12:41:33 +00001510 VG_(umsg)(" possibly lost: %'lu%s bytes in %'lu%s blocks\n",
1511 MC_(bytes_dubious),
philippeab1fce92013-09-29 13:47:32 +00001512 DBY (MC_(bytes_dubious), old_bytes_dubious),
sewardjc8bd1df2011-06-26 12:41:33 +00001513 MC_(blocks_dubious),
philippeab1fce92013-09-29 13:47:32 +00001514 DBL (MC_(blocks_dubious), old_blocks_dubious));
sewardjc8bd1df2011-06-26 12:41:33 +00001515 VG_(umsg)(" still reachable: %'lu%s bytes in %'lu%s blocks\n",
1516 MC_(bytes_reachable),
philippeab1fce92013-09-29 13:47:32 +00001517 DBY (MC_(bytes_reachable), old_bytes_reachable),
sewardjc8bd1df2011-06-26 12:41:33 +00001518 MC_(blocks_reachable),
philippeab1fce92013-09-29 13:47:32 +00001519 DBL (MC_(blocks_reachable), old_blocks_reachable));
1520 for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++)
1521 if (old_blocks_heuristically_reachable[i] > 0
1522 || MC_(blocks_heuristically_reachable)[i] > 0) {
1523 VG_(umsg)(" of which "
1524 "reachable via heuristic:\n");
1525 break;
1526 }
1527 for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++)
1528 if (old_blocks_heuristically_reachable[i] > 0
1529 || MC_(blocks_heuristically_reachable)[i] > 0)
florian866862a2014-12-13 18:35:00 +00001530 VG_(umsg)(" %-19s: "
philippeab1fce92013-09-29 13:47:32 +00001531 "%'lu%s bytes in %'lu%s blocks\n",
1532 pp_heuristic(i),
1533 MC_(bytes_heuristically_reachable)[i],
1534 DBY (MC_(bytes_heuristically_reachable)[i],
1535 old_bytes_heuristically_reachable[i]),
1536 MC_(blocks_heuristically_reachable)[i],
1537 DBL (MC_(blocks_heuristically_reachable)[i],
1538 old_blocks_heuristically_reachable[i]));
sewardjc8bd1df2011-06-26 12:41:33 +00001539 VG_(umsg)(" suppressed: %'lu%s bytes in %'lu%s blocks\n",
1540 MC_(bytes_suppressed),
philippeab1fce92013-09-29 13:47:32 +00001541 DBY (MC_(bytes_suppressed), old_bytes_suppressed),
sewardjc8bd1df2011-06-26 12:41:33 +00001542 MC_(blocks_suppressed),
philippeab1fce92013-09-29 13:47:32 +00001543 DBL (MC_(blocks_suppressed), old_blocks_suppressed));
philippe84234902012-01-14 13:53:13 +00001544 if (lcp->mode != LC_Full &&
njn8225cc02009-03-09 22:52:24 +00001545 (MC_(blocks_leaked) + MC_(blocks_indirect) +
1546 MC_(blocks_dubious) + MC_(blocks_reachable)) > 0) {
philippe84234902012-01-14 13:53:13 +00001547 if (lcp->requested_by_monitor_command)
philippeab1fce92013-09-29 13:47:32 +00001548 VG_(umsg)("To see details of leaked memory, "
1549 "give 'full' arg to leak_check\n");
sewardjc8bd1df2011-06-26 12:41:33 +00001550 else
1551 VG_(umsg)("Rerun with --leak-check=full to see details "
1552 "of leaked memory\n");
njn8225cc02009-03-09 22:52:24 +00001553 }
philippe84234902012-01-14 13:53:13 +00001554 if (lcp->mode == LC_Full &&
philippeab1fce92013-09-29 13:47:32 +00001555 MC_(blocks_reachable) > 0 && !RiS(Reachable,lcp->show_leak_kinds)) {
sewardj6b523cd2009-07-15 14:49:40 +00001556 VG_(umsg)("Reachable blocks (those to which a pointer "
1557 "was found) are not shown.\n");
philippe84234902012-01-14 13:53:13 +00001558 if (lcp->requested_by_monitor_command)
sewardj30b3eca2011-06-28 08:20:39 +00001559 VG_(umsg)("To see them, add 'reachable any' args to leak_check\n");
sewardjc8bd1df2011-06-26 12:41:33 +00001560 else
1561 VG_(umsg)("To see them, rerun with: --leak-check=full "
philippe2193a7c2012-12-08 17:54:16 +00001562 "--show-leak-kinds=all\n");
sewardjb5f6f512005-03-10 23:59:00 +00001563 }
njnb6267bd2009-08-12 00:14:16 +00001564 VG_(umsg)("\n");
philippeab1fce92013-09-29 13:47:32 +00001565 #undef DBL
1566 #undef DBY
sewardjb5f6f512005-03-10 23:59:00 +00001567 }
1568}
1569
philippea22f59d2012-01-26 23:13:52 +00001570// print recursively all indirectly leaked blocks collected in clique.
philippe6d3cb492015-08-13 22:49:32 +00001571// Printing stops when *remaining reaches 0.
1572static void print_clique (Int clique, UInt level, UInt *remaining)
philippea22f59d2012-01-26 23:13:52 +00001573{
1574 Int ind;
florian47755db2015-08-05 12:09:55 +00001575 UInt i, n_lossrecords;
philippea22f59d2012-01-26 23:13:52 +00001576
1577 n_lossrecords = VG_(OSetGen_Size)(lr_table);
1578
philippe6d3cb492015-08-13 22:49:32 +00001579 for (ind = 0; ind < lc_n_chunks && *remaining > 0; ind++) {
philippea22f59d2012-01-26 23:13:52 +00001580 LC_Extra* ind_ex = &(lc_extras)[ind];
philippeab1fce92013-09-29 13:47:32 +00001581 if (ind_ex->state == IndirectLeak
1582 && ind_ex->IorC.clique == (SizeT) clique) {
philippea22f59d2012-01-26 23:13:52 +00001583 MC_Chunk* ind_ch = lc_chunks[ind];
1584 LossRecord* ind_lr;
1585 LossRecordKey ind_lrkey;
florian47755db2015-08-05 12:09:55 +00001586 UInt lr_i;
philippea22f59d2012-01-26 23:13:52 +00001587 ind_lrkey.state = ind_ex->state;
philippe8617b5b2013-01-12 19:53:08 +00001588 ind_lrkey.allocated_at = MC_(allocated_at)(ind_ch);
philippea22f59d2012-01-26 23:13:52 +00001589 ind_lr = VG_(OSetGen_Lookup)(lr_table, &ind_lrkey);
1590 for (lr_i = 0; lr_i < n_lossrecords; lr_i++)
1591 if (ind_lr == lr_array[lr_i])
1592 break;
1593 for (i = 0; i < level; i++)
1594 VG_(umsg)(" ");
florian47755db2015-08-05 12:09:55 +00001595 VG_(umsg)("%p[%lu] indirect loss record %u\n",
1596 (void *)ind_ch->data, (SizeT)ind_ch->szB,
philippea22f59d2012-01-26 23:13:52 +00001597 lr_i+1); // lr_i+1 for user numbering.
philippe6d3cb492015-08-13 22:49:32 +00001598 (*remaining)--;
philippea22f59d2012-01-26 23:13:52 +00001599 if (lr_i >= n_lossrecords)
1600 VG_(umsg)
1601 ("error: no indirect loss record found for %p[%lu]?????\n",
florian47755db2015-08-05 12:09:55 +00001602 (void *)ind_ch->data, (SizeT)ind_ch->szB);
philippe6d3cb492015-08-13 22:49:32 +00001603 print_clique(ind, level+1, remaining);
philippea22f59d2012-01-26 23:13:52 +00001604 }
1605 }
1606 }
1607
philippece3b04c2015-09-02 21:26:34 +00001608Bool MC_(print_block_list) ( UInt loss_record_nr_from,
1609 UInt loss_record_nr_to,
1610 UInt max_blocks,
1611 UInt heuristics)
philippea22f59d2012-01-26 23:13:52 +00001612{
philippece3b04c2015-09-02 21:26:34 +00001613 UInt loss_record_nr;
florian47755db2015-08-05 12:09:55 +00001614 UInt i, n_lossrecords;
philippea22f59d2012-01-26 23:13:52 +00001615 LossRecord* lr;
philippece3b04c2015-09-02 21:26:34 +00001616 Bool lr_printed;
philippe6d3cb492015-08-13 22:49:32 +00001617 UInt remaining = max_blocks;
philippea22f59d2012-01-26 23:13:52 +00001618
1619 if (lr_table == NULL || lc_chunks == NULL || lc_extras == NULL) {
1620 VG_(umsg)("Can't print block list : no valid leak search result\n");
1621 return False;
1622 }
1623
1624 if (lc_chunks_n_frees_marker != MC_(get_cmalloc_n_frees)()) {
1625 VG_(umsg)("Can't print obsolete block list : redo a leak search first\n");
1626 return False;
1627 }
1628
1629 n_lossrecords = VG_(OSetGen_Size)(lr_table);
philippece3b04c2015-09-02 21:26:34 +00001630 if (loss_record_nr_from >= n_lossrecords)
1631 return False; // Invalid starting loss record nr.
1632
1633 if (loss_record_nr_to >= n_lossrecords)
1634 loss_record_nr_to = n_lossrecords - 1;
philippea22f59d2012-01-26 23:13:52 +00001635
1636 tl_assert (lr_array);
philippece3b04c2015-09-02 21:26:34 +00001637
1638 for (loss_record_nr = loss_record_nr_from;
1639 loss_record_nr <= loss_record_nr_to && remaining > 0;
1640 loss_record_nr++) {
1641 lr = lr_array[loss_record_nr];
1642 lr_printed = False;
1643
1644 /* If user asks to print a specific loss record, we print
1645 the block details, even if no block will be shown for this lr.
1646 If user asks to print a range of lr, we only print lr details
1647 when at least one block is shown. */
1648 if (loss_record_nr_from == loss_record_nr_to) {
1649 /* (+1 on loss_record_nr as user numbering for loss records
1650 starts at 1). */
1651 MC_(pp_LossRecord)(loss_record_nr+1, n_lossrecords, lr);
1652 lr_printed = True;
1653 }
philippea22f59d2012-01-26 23:13:52 +00001654
philippece3b04c2015-09-02 21:26:34 +00001655 // Match the chunks with loss records.
1656 for (i = 0; i < lc_n_chunks && remaining > 0; i++) {
1657 MC_Chunk* ch = lc_chunks[i];
1658 LC_Extra* ex = &(lc_extras)[i];
1659 LossRecord* old_lr;
1660 LossRecordKey lrkey;
1661 lrkey.state = ex->state;
1662 lrkey.allocated_at = MC_(allocated_at)(ch);
philippea22f59d2012-01-26 23:13:52 +00001663
philippece3b04c2015-09-02 21:26:34 +00001664 old_lr = VG_(OSetGen_Lookup)(lr_table, &lrkey);
1665 if (old_lr) {
1666 // We found an existing loss record matching this chunk.
1667 // If this is the loss record we are looking for, output the
1668 // pointer.
1669 if (old_lr == lr_array[loss_record_nr]
1670 && (heuristics == 0 || HiS(ex->heuristic, heuristics))) {
1671 if (!lr_printed) {
1672 MC_(pp_LossRecord)(loss_record_nr+1, n_lossrecords, lr);
1673 lr_printed = True;
1674 }
philippea22f59d2012-01-26 23:13:52 +00001675
philippece3b04c2015-09-02 21:26:34 +00001676 if (ex->heuristic)
1677 VG_(umsg)("%p[%lu] (found via heuristic %s)\n",
1678 (void *)ch->data, (SizeT)ch->szB,
1679 pp_heuristic (ex->heuristic));
1680 else
1681 VG_(umsg)("%p[%lu]\n",
1682 (void *)ch->data, (SizeT)ch->szB);
1683 remaining--;
1684 if (ex->state != Reachable) {
1685 // We can print the clique in all states, except Reachable.
1686 // In Unreached state, lc_chunk[i] is the clique leader.
1687 // In IndirectLeak, lc_chunk[i] might have been a clique
1688 // leader which was later collected in another clique.
1689 // For Possible, lc_chunk[i] might be the top of a clique
1690 // or an intermediate clique.
1691 print_clique(i, 1, &remaining);
1692 }
philippea22f59d2012-01-26 23:13:52 +00001693 }
philippece3b04c2015-09-02 21:26:34 +00001694 } else {
1695 // No existing loss record matches this chunk ???
1696 VG_(umsg)("error: no loss record found for %p[%lu]?????\n",
1697 (void *)ch->data, (SizeT)ch->szB);
philippea22f59d2012-01-26 23:13:52 +00001698 }
philippea22f59d2012-01-26 23:13:52 +00001699 }
1700 }
1701 return True;
1702}
1703
1704// If searched = 0, scan memory root set, pushing onto the mark stack the blocks
1705// encountered.
philippeab1fce92013-09-29 13:47:32 +00001706// Otherwise (searched != 0), scan the memory root set searching for ptr
1707// pointing inside [searched, searched+szB[.
philippea22f59d2012-01-26 23:13:52 +00001708static void scan_memory_root_set(Addr searched, SizeT szB)
1709{
1710 Int i;
1711 Int n_seg_starts;
florianea8a88c2015-02-20 14:00:23 +00001712 Addr* seg_starts = VG_(get_segment_starts)( SkFileC | SkAnonC | SkShmC,
1713 &n_seg_starts );
philippea22f59d2012-01-26 23:13:52 +00001714
1715 tl_assert(seg_starts && n_seg_starts > 0);
1716
1717 lc_scanned_szB = 0;
philippe7a76f4b2013-10-06 21:23:04 +00001718 lc_sig_skipped_szB = 0;
philippea22f59d2012-01-26 23:13:52 +00001719
1720 // VG_(am_show_nsegments)( 0, "leakcheck");
1721 for (i = 0; i < n_seg_starts; i++) {
1722 SizeT seg_size;
1723 NSegment const* seg = VG_(am_find_nsegment)( seg_starts[i] );
1724 tl_assert(seg);
florianea8a88c2015-02-20 14:00:23 +00001725 tl_assert(seg->kind == SkFileC || seg->kind == SkAnonC ||
1726 seg->kind == SkShmC);
philippea22f59d2012-01-26 23:13:52 +00001727
philippea22f59d2012-01-26 23:13:52 +00001728 if (!(seg->hasR && seg->hasW)) continue;
1729 if (seg->isCH) continue;
1730
1731 // Don't poke around in device segments as this may cause
florian5d3d43d2015-02-20 16:46:50 +00001732 // hangs. Include /dev/zero just in case someone allocated
philippea22f59d2012-01-26 23:13:52 +00001733 // memory by explicitly mapping /dev/zero.
1734 if (seg->kind == SkFileC
1735 && (VKI_S_ISCHR(seg->mode) || VKI_S_ISBLK(seg->mode))) {
floriand3166c42015-01-24 00:02:19 +00001736 const HChar* dev_name = VG_(am_get_filename)( seg );
philippea22f59d2012-01-26 23:13:52 +00001737 if (dev_name && 0 == VG_(strcmp)(dev_name, "/dev/zero")) {
1738 // Don't skip /dev/zero.
1739 } else {
1740 // Skip this device mapping.
1741 continue;
1742 }
1743 }
1744
1745 if (0)
1746 VG_(printf)("ACCEPT %2d %#lx %#lx\n", i, seg->start, seg->end);
1747
1748 // Scan the segment. We use -1 for the clique number, because this
1749 // is a root-set.
1750 seg_size = seg->end - seg->start + 1;
1751 if (VG_(clo_verbosity) > 2) {
1752 VG_(message)(Vg_DebugMsg,
1753 " Scanning root segment: %#lx..%#lx (%lu)\n",
1754 seg->start, seg->end, seg_size);
1755 }
1756 lc_scan_memory(seg->start, seg_size, /*is_prior_definite*/True,
1757 /*clique*/-1, /*cur_clique*/-1,
1758 searched, szB);
1759 }
philippe7d69fd92012-02-26 21:26:00 +00001760 VG_(free)(seg_starts);
philippea22f59d2012-01-26 23:13:52 +00001761}
1762
Elliott Hughesa0664b92017-04-18 17:46:52 -07001763static MC_Mempool *find_mp_of_chunk (MC_Chunk* mc_search)
1764{
1765 MC_Mempool* mp;
1766
1767 tl_assert( MC_(mempool_list) );
1768
1769 VG_(HT_ResetIter)( MC_(mempool_list) );
1770 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
1771 MC_Chunk* mc;
1772 VG_(HT_ResetIter)(mp->chunks);
1773 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
1774 if (mc == mc_search)
1775 return mp;
1776 }
1777 }
1778
1779 return NULL;
1780}
1781
njn8225cc02009-03-09 22:52:24 +00001782/*------------------------------------------------------------*/
1783/*--- Top-level entry point. ---*/
1784/*------------------------------------------------------------*/
sewardj3cf26a52006-07-27 23:48:53 +00001785
philippe84234902012-01-14 13:53:13 +00001786void MC_(detect_memory_leaks) ( ThreadId tid, LeakCheckParams* lcp)
njn43c799e2003-04-08 00:08:52 +00001787{
njnb965efb2009-08-10 07:36:54 +00001788 Int i, j;
njn43c799e2003-04-08 00:08:52 +00001789
philippe84234902012-01-14 13:53:13 +00001790 tl_assert(lcp->mode != LC_Off);
sewardjc8bd1df2011-06-26 12:41:33 +00001791
philippe57a16a22012-07-18 22:26:51 +00001792 // Verify some assertions which are used in lc_scan_memory.
1793 tl_assert((VKI_PAGE_SIZE % sizeof(Addr)) == 0);
1794 tl_assert((SM_SIZE % sizeof(Addr)) == 0);
1795 // Above two assertions are critical, while below assertion
1796 // ensures that the optimisation in the loop is done in the
1797 // correct order : the loop checks for (big) SM chunk skipping
1798 // before checking for (smaller) page skipping.
1799 tl_assert((SM_SIZE % VKI_PAGE_SIZE) == 0);
1800
philippe4e32d672013-10-17 22:10:41 +00001801 MC_(leak_search_gen)++;
philippe84234902012-01-14 13:53:13 +00001802 MC_(detect_memory_leaks_last_delta_mode) = lcp->deltamode;
philippeab1fce92013-09-29 13:47:32 +00001803 detect_memory_leaks_last_heuristics = lcp->heuristics;
njn43c799e2003-04-08 00:08:52 +00001804
njn8225cc02009-03-09 22:52:24 +00001805 // Get the chunks, stop if there were none.
philippea22f59d2012-01-26 23:13:52 +00001806 if (lc_chunks) {
1807 VG_(free)(lc_chunks);
1808 lc_chunks = NULL;
1809 }
njn8225cc02009-03-09 22:52:24 +00001810 lc_chunks = find_active_chunks(&lc_n_chunks);
philippea22f59d2012-01-26 23:13:52 +00001811 lc_chunks_n_frees_marker = MC_(get_cmalloc_n_frees)();
njn8225cc02009-03-09 22:52:24 +00001812 if (lc_n_chunks == 0) {
1813 tl_assert(lc_chunks == NULL);
sewardjc8bd1df2011-06-26 12:41:33 +00001814 if (lr_table != NULL) {
philippea22f59d2012-01-26 23:13:52 +00001815 // forget the previous recorded LossRecords as next leak search
1816 // can in any case just create new leaks.
sewardjc8bd1df2011-06-26 12:41:33 +00001817 // Maybe it would be better to rather call print_result ?
philippea22f59d2012-01-26 23:13:52 +00001818 // (at least when leak decreases are requested)
sewardjc8bd1df2011-06-26 12:41:33 +00001819 // This will then output all LossRecords with a size decreasing to 0
1820 VG_(OSetGen_Destroy) (lr_table);
philippea22f59d2012-01-26 23:13:52 +00001821 lr_table = NULL;
sewardjc8bd1df2011-06-26 12:41:33 +00001822 }
sewardj71bc3cb2005-05-19 00:25:45 +00001823 if (VG_(clo_verbosity) >= 1 && !VG_(clo_xml)) {
njnb6267bd2009-08-12 00:14:16 +00001824 VG_(umsg)("All heap blocks were freed -- no leaks are possible\n");
sewardj2d9e8742009-08-07 15:46:56 +00001825 VG_(umsg)("\n");
sewardj37d06f22003-09-17 21:48:26 +00001826 }
njn43c799e2003-04-08 00:08:52 +00001827 return;
1828 }
1829
njn8225cc02009-03-09 22:52:24 +00001830 // Sort the array so blocks are in ascending order in memory.
1831 VG_(ssort)(lc_chunks, lc_n_chunks, sizeof(VgHashNode*), compare_MC_Chunks);
njn43c799e2003-04-08 00:08:52 +00001832
njn8225cc02009-03-09 22:52:24 +00001833 // Sanity check -- make sure they're in order.
1834 for (i = 0; i < lc_n_chunks-1; i++) {
1835 tl_assert( lc_chunks[i]->data <= lc_chunks[i+1]->data);
1836 }
njn43c799e2003-04-08 00:08:52 +00001837
Elliott Hughesa0664b92017-04-18 17:46:52 -07001838 // Sanity check -- make sure they don't overlap. One exception is that
njnb965efb2009-08-10 07:36:54 +00001839 // we allow a MALLOCLIKE block to sit entirely within a malloc() block.
1840 // This is for bug 100628. If this occurs, we ignore the malloc() block
1841 // for leak-checking purposes. This is a hack and probably should be done
1842 // better, but at least it's consistent with mempools (which are treated
1843 // like this in find_active_chunks). Mempools have a separate VgHashTable
1844 // for mempool chunks, but if custom-allocated blocks are put in a separate
1845 // table from normal heap blocks it makes free-mismatch checking more
1846 // difficult.
Elliott Hughesa0664b92017-04-18 17:46:52 -07001847 // Another exception: Metapool memory blocks overlap by definition. The meta-
1848 // block is allocated (by a custom allocator), and chunks of that block are
1849 // allocated again for use by the application: Not an error.
njnb965efb2009-08-10 07:36:54 +00001850 //
1851 // If this check fails, it probably means that the application
njn8225cc02009-03-09 22:52:24 +00001852 // has done something stupid with VALGRIND_MALLOCLIKE_BLOCK client
njnb965efb2009-08-10 07:36:54 +00001853 // requests, eg. has made overlapping requests (which are
1854 // nonsensical), or used VALGRIND_MALLOCLIKE_BLOCK for stack locations;
1855 // again nonsensical.
1856 //
njn8225cc02009-03-09 22:52:24 +00001857 for (i = 0; i < lc_n_chunks-1; i++) {
1858 MC_Chunk* ch1 = lc_chunks[i];
1859 MC_Chunk* ch2 = lc_chunks[i+1];
njnb965efb2009-08-10 07:36:54 +00001860
1861 Addr start1 = ch1->data;
1862 Addr start2 = ch2->data;
1863 Addr end1 = ch1->data + ch1->szB - 1;
1864 Addr end2 = ch2->data + ch2->szB - 1;
1865 Bool isCustom1 = ch1->allockind == MC_AllocCustom;
1866 Bool isCustom2 = ch2->allockind == MC_AllocCustom;
1867
1868 if (end1 < start2) {
1869 // Normal case - no overlap.
1870
1871 // We used to allow exact duplicates, I'm not sure why. --njn
1872 //} else if (start1 == start2 && end1 == end2) {
1873 // Degenerate case: exact duplicates.
1874
1875 } else if (start1 >= start2 && end1 <= end2 && isCustom1 && !isCustom2) {
1876 // Block i is MALLOCLIKE and entirely within block i+1.
1877 // Remove block i+1.
1878 for (j = i+1; j < lc_n_chunks-1; j++) {
1879 lc_chunks[j] = lc_chunks[j+1];
1880 }
1881 lc_n_chunks--;
1882
1883 } else if (start2 >= start1 && end2 <= end1 && isCustom2 && !isCustom1) {
1884 // Block i+1 is MALLOCLIKE and entirely within block i.
1885 // Remove block i.
1886 for (j = i; j < lc_n_chunks-1; j++) {
1887 lc_chunks[j] = lc_chunks[j+1];
1888 }
1889 lc_n_chunks--;
1890
1891 } else {
Elliott Hughesa0664b92017-04-18 17:46:52 -07001892 // Overlap is allowed ONLY when one of the two candicates is a block
1893 // from a memory pool that has the metapool attribute set.
1894 // All other mixtures trigger the error + assert.
1895 MC_Mempool* mp;
1896 Bool ch1_is_meta = False, ch2_is_meta = False;
1897 Bool Inappropriate = False;
1898
1899 if (MC_(is_mempool_block)(ch1)) {
1900 mp = find_mp_of_chunk(ch1);
1901 if (mp && mp->metapool) {
1902 ch1_is_meta = True;
1903 }
1904 }
1905
1906 if (MC_(is_mempool_block)(ch2)) {
1907 mp = find_mp_of_chunk(ch2);
1908 if (mp && mp->metapool) {
1909 ch2_is_meta = True;
1910 }
1911 }
1912
1913 // If one of the blocks is a meta block, the other must be entirely
1914 // within that meta block, or something is really wrong with the custom
1915 // allocator.
1916 if (ch1_is_meta != ch2_is_meta) {
1917 if ( (ch1_is_meta && (start2 < start1 || end2 > end1)) ||
1918 (ch2_is_meta && (start1 < start2 || end1 > end2)) ) {
1919 Inappropriate = True;
1920 }
1921 }
1922
1923 if (ch1_is_meta == ch2_is_meta || Inappropriate) {
1924 VG_(umsg)("Block 0x%lx..0x%lx overlaps with block 0x%lx..0x%lx\n",
1925 start1, end1, start2, end2);
1926 VG_(umsg)("Blocks allocation contexts:\n"),
1927 VG_(pp_ExeContext)( MC_(allocated_at)(ch1));
1928 VG_(umsg)("\n"),
1929 VG_(pp_ExeContext)( MC_(allocated_at)(ch2));
1930 VG_(umsg)("This is usually caused by using ");
1931 VG_(umsg)("VALGRIND_MALLOCLIKE_BLOCK in an inappropriate way.\n");
1932 tl_assert (0);
1933 }
njn8225cc02009-03-09 22:52:24 +00001934 }
njn8225cc02009-03-09 22:52:24 +00001935 }
1936
1937 // Initialise lc_extras.
philippea22f59d2012-01-26 23:13:52 +00001938 if (lc_extras) {
1939 VG_(free)(lc_extras);
1940 lc_extras = NULL;
1941 }
njn8225cc02009-03-09 22:52:24 +00001942 lc_extras = VG_(malloc)( "mc.dml.2", lc_n_chunks * sizeof(LC_Extra) );
1943 for (i = 0; i < lc_n_chunks; i++) {
1944 lc_extras[i].state = Unreached;
tom1d0f3f62010-10-04 20:55:21 +00001945 lc_extras[i].pending = False;
philippeab1fce92013-09-29 13:47:32 +00001946 lc_extras[i].heuristic = LchNone;
philippea22f59d2012-01-26 23:13:52 +00001947 lc_extras[i].IorC.indirect_szB = 0;
njn8225cc02009-03-09 22:52:24 +00001948 }
1949
1950 // Initialise lc_markstack.
1951 lc_markstack = VG_(malloc)( "mc.dml.2", lc_n_chunks * sizeof(Int) );
1952 for (i = 0; i < lc_n_chunks; i++) {
1953 lc_markstack[i] = -1;
sewardjb5f6f512005-03-10 23:59:00 +00001954 }
1955 lc_markstack_top = -1;
njn43c799e2003-04-08 00:08:52 +00001956
njn8225cc02009-03-09 22:52:24 +00001957 // Verbosity.
sewardj2d9e8742009-08-07 15:46:56 +00001958 if (VG_(clo_verbosity) > 1 && !VG_(clo_xml)) {
njnb6267bd2009-08-12 00:14:16 +00001959 VG_(umsg)( "Searching for pointers to %'d not-freed blocks\n",
sewardj6b523cd2009-07-15 14:49:40 +00001960 lc_n_chunks );
sewardj2d9e8742009-08-07 15:46:56 +00001961 }
sewardjb5f6f512005-03-10 23:59:00 +00001962
njn8225cc02009-03-09 22:52:24 +00001963 // Scan the memory root-set, pushing onto the mark stack any blocks
1964 // pointed to.
philippea22f59d2012-01-26 23:13:52 +00001965 scan_memory_root_set(/*searched*/0, 0);
sewardjb5f6f512005-03-10 23:59:00 +00001966
njn8225cc02009-03-09 22:52:24 +00001967 // Scan GP registers for chunk pointers.
1968 VG_(apply_to_GP_regs)(lc_push_if_a_chunk_ptr_register);
sewardjb5f6f512005-03-10 23:59:00 +00001969
njn8225cc02009-03-09 22:52:24 +00001970 // Process the pushed blocks. After this, every block that is reachable
1971 // from the root-set has been traced.
1972 lc_process_markstack(/*clique*/-1);
njn43c799e2003-04-08 00:08:52 +00001973
njnb6267bd2009-08-12 00:14:16 +00001974 if (VG_(clo_verbosity) > 1 && !VG_(clo_xml)) {
1975 VG_(umsg)("Checked %'lu bytes\n", lc_scanned_szB);
philippe7a76f4b2013-10-06 21:23:04 +00001976 if (lc_sig_skipped_szB > 0)
1977 VG_(umsg)("Skipped %'lu bytes due to read errors\n",
1978 lc_sig_skipped_szB);
njnb6267bd2009-08-12 00:14:16 +00001979 VG_(umsg)( "\n" );
1980 }
njn43c799e2003-04-08 00:08:52 +00001981
njn8225cc02009-03-09 22:52:24 +00001982 // Trace all the leaked blocks to determine which are directly leaked and
1983 // which are indirectly leaked. For each Unreached block, push it onto
1984 // the mark stack, and find all the as-yet-Unreached blocks reachable
1985 // from it. These form a clique and are marked IndirectLeak, and their
1986 // size is added to the clique leader's indirect size. If one of the
1987 // found blocks was itself a clique leader (from a previous clique), then
1988 // the cliques are merged.
1989 for (i = 0; i < lc_n_chunks; i++) {
1990 MC_Chunk* ch = lc_chunks[i];
1991 LC_Extra* ex = &(lc_extras[i]);
njn43c799e2003-04-08 00:08:52 +00001992
njn8225cc02009-03-09 22:52:24 +00001993 if (VG_DEBUG_CLIQUE)
1994 VG_(printf)("cliques: %d at %#lx -> Loss state %d\n",
1995 i, ch->data, ex->state);
njn43c799e2003-04-08 00:08:52 +00001996
njn8225cc02009-03-09 22:52:24 +00001997 tl_assert(lc_markstack_top == -1);
1998
1999 if (ex->state == Unreached) {
2000 if (VG_DEBUG_CLIQUE)
2001 VG_(printf)("%d: gathering clique %#lx\n", i, ch->data);
2002
2003 // Push this Unreached block onto the stack and process it.
2004 lc_push(i, ch);
philippea22f59d2012-01-26 23:13:52 +00002005 lc_process_markstack(/*clique*/i);
njn8225cc02009-03-09 22:52:24 +00002006
2007 tl_assert(lc_markstack_top == -1);
2008 tl_assert(ex->state == Unreached);
nethercote0f19bce2003-12-02 10:17:44 +00002009 }
njn43c799e2003-04-08 00:08:52 +00002010 }
philippeb5a02e72015-10-22 19:14:30 +00002011
sewardjc8bd1df2011-06-26 12:41:33 +00002012 print_results( tid, lcp);
njn43c799e2003-04-08 00:08:52 +00002013
sewardjb5f6f512005-03-10 23:59:00 +00002014 VG_(free) ( lc_markstack );
philippea22f59d2012-01-26 23:13:52 +00002015 lc_markstack = NULL;
2016 // lc_chunks, lc_extras, lr_array and lr_table are kept (needed if user
2017 // calls MC_(print_block_list)). lr_table also used for delta leak reporting
2018 // between this leak search and the next leak search.
2019}
2020
2021static Addr searched_wpa;
2022static SizeT searched_szB;
2023static void
florian6bd9dc12012-11-23 16:17:43 +00002024search_address_in_GP_reg(ThreadId tid, const HChar* regname, Addr addr_in_reg)
philippea22f59d2012-01-26 23:13:52 +00002025{
2026 if (addr_in_reg >= searched_wpa
2027 && addr_in_reg < searched_wpa + searched_szB) {
2028 if (addr_in_reg == searched_wpa)
2029 VG_(umsg)
floriande3df032015-08-04 21:26:10 +00002030 ("tid %u register %s pointing at %#lx\n",
philippea22f59d2012-01-26 23:13:52 +00002031 tid, regname, searched_wpa);
2032 else
2033 VG_(umsg)
floriande3df032015-08-04 21:26:10 +00002034 ("tid %u register %s interior pointing %lu bytes inside %#lx\n",
philippea22f59d2012-01-26 23:13:52 +00002035 tid, regname, (long unsigned) addr_in_reg - searched_wpa,
2036 searched_wpa);
2037 }
2038}
2039
2040void MC_(who_points_at) ( Addr address, SizeT szB)
2041{
2042 MC_Chunk** chunks;
2043 Int n_chunks;
2044 Int i;
2045
2046 if (szB == 1)
2047 VG_(umsg) ("Searching for pointers to %#lx\n", address);
2048 else
2049 VG_(umsg) ("Searching for pointers pointing in %lu bytes from %#lx\n",
2050 szB, address);
2051
philippeab1fce92013-09-29 13:47:32 +00002052 chunks = find_active_chunks(&n_chunks);
2053
philippea22f59d2012-01-26 23:13:52 +00002054 // Scan memory root-set, searching for ptr pointing in address[szB]
2055 scan_memory_root_set(address, szB);
2056
2057 // Scan active malloc-ed chunks
philippea22f59d2012-01-26 23:13:52 +00002058 for (i = 0; i < n_chunks; i++) {
2059 lc_scan_memory(chunks[i]->data, chunks[i]->szB,
2060 /*is_prior_definite*/True,
2061 /*clique*/-1, /*cur_clique*/-1,
2062 address, szB);
2063 }
2064 VG_(free) ( chunks );
2065
2066 // Scan GP registers for pointers to address range.
2067 searched_wpa = address;
2068 searched_szB = szB;
2069 VG_(apply_to_GP_regs)(search_address_in_GP_reg);
2070
njn43c799e2003-04-08 00:08:52 +00002071}
2072
2073/*--------------------------------------------------------------------*/
njn1d0825f2006-03-27 11:37:07 +00002074/*--- end ---*/
njn43c799e2003-04-08 00:08:52 +00002075/*--------------------------------------------------------------------*/
2076