blob: 83d3ada4451cc9ccaf194109c85a4da12a26824e [file] [log] [blame]
njn43c799e2003-04-08 00:08:52 +00001
2/*--------------------------------------------------------------------*/
3/*--- The leak checker, shared between Memcheck and Addrcheck. ---*/
4/*--- mac_leakcheck.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of MemCheck, a heavyweight Valgrind skin for
9 detecting memory errors, and AddrCheck, a lightweight Valgrind skin
10 for detecting memory errors.
11
12 Copyright (C) 2000-2002 Julian Seward
13 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
32
33#include "mac_shared.h"
34
35/* Define to debug the memory-leak-detector. */
36/* #define VG_DEBUG_LEAKCHECK */
37
38/*------------------------------------------------------------*/
39/*--- Low-level address-space scanning, for the leak ---*/
40/*--- detector. ---*/
41/*------------------------------------------------------------*/
42
43static
44jmp_buf memscan_jmpbuf;
45
46
47static
48void vg_scan_all_valid_memory_sighandler ( Int sigNo )
49{
50 __builtin_longjmp(memscan_jmpbuf, 1);
51}
52
53
54/* Safely (avoiding SIGSEGV / SIGBUS) scan the entire valid address
55 space and pass the addresses and values of all addressible,
56 defined, aligned words to notify_word. This is the basis for the
57 leak detector. Returns the number of calls made to notify_word.
58
59 Addresses are validated 3 ways. First we enquire whether (addr >>
60 16) denotes a 64k chunk in use, by asking is_valid_64k_chunk(). If
61 so, we decide for ourselves whether each x86-level (4 K) page in
62 the chunk is safe to inspect. If yes, we enquire with
63 is_valid_address() whether or not each of the 1024 word-locations
64 on the page is valid. Only if so are that address and its contents
65 passed to notify_word.
66
67 This is all to avoid duplication of this machinery between the
68 memcheck and addrcheck skins.
69*/
70static
71UInt vg_scan_all_valid_memory ( Bool is_valid_64k_chunk ( UInt ),
72 Bool is_valid_address ( Addr ),
73 void (*notify_word)( Addr, UInt ) )
74{
75 /* All volatile, because some gccs seem paranoid about longjmp(). */
76 volatile Bool anyValid;
77 volatile Addr pageBase, addr;
78 volatile UInt res, numPages, page, primaryMapNo;
79 volatile UInt page_first_word, nWordsNotified;
80
81 vki_ksigaction sigbus_saved;
82 vki_ksigaction sigbus_new;
83 vki_ksigaction sigsegv_saved;
84 vki_ksigaction sigsegv_new;
85 vki_ksigset_t blockmask_saved;
86 vki_ksigset_t unblockmask_new;
87
88 /* Temporarily install a new sigsegv and sigbus handler, and make
89 sure SIGBUS, SIGSEGV and SIGTERM are unblocked. (Perhaps the
90 first two can never be blocked anyway?) */
91
92 sigbus_new.ksa_handler = vg_scan_all_valid_memory_sighandler;
93 sigbus_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
94 sigbus_new.ksa_restorer = NULL;
95 res = VG_(ksigemptyset)( &sigbus_new.ksa_mask );
96 sk_assert(res == 0);
97
98 sigsegv_new.ksa_handler = vg_scan_all_valid_memory_sighandler;
99 sigsegv_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
100 sigsegv_new.ksa_restorer = NULL;
101 res = VG_(ksigemptyset)( &sigsegv_new.ksa_mask );
102 sk_assert(res == 0+0);
103
104 res = VG_(ksigemptyset)( &unblockmask_new );
105 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGBUS );
106 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGSEGV );
107 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGTERM );
108 sk_assert(res == 0+0+0);
109
110 res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_new, &sigbus_saved );
111 sk_assert(res == 0+0+0+0);
112
113 res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_new, &sigsegv_saved );
114 sk_assert(res == 0+0+0+0+0);
115
116 res = VG_(ksigprocmask)( VKI_SIG_UNBLOCK, &unblockmask_new, &blockmask_saved );
117 sk_assert(res == 0+0+0+0+0+0);
118
119 /* The signal handlers are installed. Actually do the memory scan. */
120 numPages = 1 << (32-VKI_BYTES_PER_PAGE_BITS);
121 sk_assert(numPages == 1048576);
122 sk_assert(4096 == (1 << VKI_BYTES_PER_PAGE_BITS));
123
124 nWordsNotified = 0;
125
126 for (page = 0; page < numPages; page++) {
127
128 /* Base address of this 4k page. */
129 pageBase = page << VKI_BYTES_PER_PAGE_BITS;
130
131 /* Skip if this page is in an unused 64k chunk. */
132 primaryMapNo = pageBase >> 16;
133 if (!is_valid_64k_chunk(primaryMapNo))
134 continue;
135
136 /* Next, establish whether or not we want to consider any
137 locations on this page. We need to do so before actually
138 prodding it, because prodding it when in fact it is not
139 needed can cause a page fault which under some rare
140 circumstances can cause the kernel to extend the stack
141 segment all the way down to here, which is seriously bad.
142 Hence: */
143 anyValid = False;
144 for (addr = pageBase; addr < pageBase+VKI_BYTES_PER_PAGE; addr += 4) {
145 if (is_valid_address(addr)) {
146 anyValid = True;
147 break;
148 }
149 }
150
151 if (!anyValid)
152 continue; /* nothing interesting here .. move to the next page */
153
154 /* Ok, we have to prod cautiously at the page and see if it
155 explodes or not. */
156 if (__builtin_setjmp(memscan_jmpbuf) == 0) {
157 /* try this ... */
158 page_first_word = * (volatile UInt*)pageBase;
159 /* we get here if we didn't get a fault */
160 /* Scan the page */
161 for (addr = pageBase; addr < pageBase+VKI_BYTES_PER_PAGE; addr += 4) {
162 if (is_valid_address(addr)) {
163 nWordsNotified++;
164 notify_word ( addr, *(UInt*)addr );
165 }
166 }
167 } else {
168 /* We get here if reading the first word of the page caused a
169 fault, which in turn caused the signal handler to longjmp.
170 Ignore this page. */
171 if (0)
172 VG_(printf)(
173 "vg_scan_all_valid_memory_sighandler: ignoring page at %p\n",
174 (void*)pageBase
175 );
176 }
177 }
178
179 /* Restore signal state to whatever it was before. */
180 res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_saved, NULL );
181 sk_assert(res == 0 +0);
182
183 res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_saved, NULL );
184 sk_assert(res == 0 +0 +0);
185
186 res = VG_(ksigprocmask)( VKI_SIG_SETMASK, &blockmask_saved, NULL );
187 sk_assert(res == 0 +0 +0 +0);
188
189 return nWordsNotified;
190}
191
192/*------------------------------------------------------------*/
193/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
194/*------------------------------------------------------------*/
195
196/* A block is either
197 -- Proper-ly reached; a pointer to its start has been found
198 -- Interior-ly reached; only an interior pointer to it has been found
199 -- Unreached; so far, no pointers to any part of it have been found.
200*/
201typedef
202 enum { Unreached, Interior, Proper }
203 Reachedness;
204
205/* A block record, used for generating err msgs. */
206typedef
207 struct _LossRecord {
208 struct _LossRecord* next;
209 /* Where these lost blocks were allocated. */
210 ExeContext* allocated_at;
211 /* Their reachability. */
212 Reachedness loss_mode;
213 /* Number of blocks and total # bytes involved. */
214 UInt total_bytes;
215 UInt num_blocks;
216 }
217 LossRecord;
218
219
220/* Find the i such that ptr points at or inside the block described by
221 shadows[i]. Return -1 if none found. This assumes that shadows[]
222 has been sorted on the ->data field. */
223
224#ifdef VG_DEBUG_LEAKCHECK
225/* Used to sanity-check the fast binary-search mechanism. */
226static
227Int find_shadow_for_OLD ( Addr ptr,
228 ShadowChunk** shadows,
229 Int n_shadows )
230
231{
232 Int i;
233 Addr a_lo, a_hi;
234 PROF_EVENT(70);
235 for (i = 0; i < n_shadows; i++) {
236 PROF_EVENT(71);
237 a_lo = shadows[i]->data;
238 a_hi = ((Addr)shadows[i]->data) + shadows[i]->size - 1;
239 if (a_lo <= ptr && ptr <= a_hi)
240 return i;
241 }
242 return -1;
243}
244#endif
245
246
247static
248Int find_shadow_for ( Addr ptr,
249 ShadowChunk** shadows,
250 Int n_shadows )
251{
252 Addr a_mid_lo, a_mid_hi;
253 Int lo, mid, hi, retVal;
254 /* VG_(printf)("find shadow for %p = ", ptr); */
255 retVal = -1;
256 lo = 0;
257 hi = n_shadows-1;
258 while (True) {
259 /* invariant: current unsearched space is from lo to hi,
260 inclusive. */
261 if (lo > hi) break; /* not found */
262
263 mid = (lo + hi) / 2;
264 a_mid_lo = VG_(get_sc_data)(shadows[mid]);
265 a_mid_hi = VG_(get_sc_data)(shadows[mid]) +
266 VG_(get_sc_size)(shadows[mid]) - 1;
267
268 if (ptr < a_mid_lo) {
269 hi = mid-1;
270 continue;
271 }
272 if (ptr > a_mid_hi) {
273 lo = mid+1;
274 continue;
275 }
276 sk_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
277 retVal = mid;
278 break;
279 }
280
281# ifdef VG_DEBUG_LEAKCHECK
282 sk_assert(retVal == find_shadow_for_OLD ( ptr, shadows, n_shadows ));
283# endif
284 /* VG_(printf)("%d\n", retVal); */
285 return retVal;
286}
287
288/* Globals, for the following callback used by VG_(detect_memory_leaks). */
289static ShadowChunk** vglc_shadows;
290static Int vglc_n_shadows;
291static Reachedness* vglc_reachedness;
292static Addr vglc_min_mallocd_addr;
293static Addr vglc_max_mallocd_addr;
294
295static
296void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
297{
298 Int sh_no;
299 Addr ptr;
300
301 /* Rule out some known causes of bogus pointers. Mostly these do
302 not cause much trouble because only a few false pointers can
303 ever lurk in these places. This mainly stops it reporting that
304 blocks are still reachable in stupid test programs like this
305
306 int main (void) { char* a = malloc(100); return 0; }
307
308 which people seem inordinately fond of writing, for some reason.
309
310 Note that this is a complete kludge. It would be better to
311 ignore any addresses corresponding to valgrind.so's .bss and
312 .data segments, but I cannot think of a reliable way to identify
313 where the .bss segment has been put. If you can, drop me a
314 line.
315 */
316 if (VG_(within_stack)(a)) return;
317 if (VG_(within_m_state_static)(a)) return;
318 if (a == (Addr)(&vglc_min_mallocd_addr)) return;
319 if (a == (Addr)(&vglc_max_mallocd_addr)) return;
320
321 /* OK, let's get on and do something Useful for a change. */
322
323 ptr = (Addr)word_at_a;
324 if (ptr >= vglc_min_mallocd_addr && ptr <= vglc_max_mallocd_addr) {
325 /* Might be legitimate; we'll have to investigate further. */
326 sh_no = find_shadow_for ( ptr, vglc_shadows, vglc_n_shadows );
327 if (sh_no != -1) {
328 /* Found a block at/into which ptr points. */
329 sk_assert(sh_no >= 0 && sh_no < vglc_n_shadows);
330 sk_assert(ptr < VG_(get_sc_data)(vglc_shadows[sh_no])
331 + VG_(get_sc_size)(vglc_shadows[sh_no]));
332 /* Decide whether Proper-ly or Interior-ly reached. */
333 if (ptr == VG_(get_sc_data)(vglc_shadows[sh_no])) {
334 if (0) VG_(printf)("pointer at %p to %p\n", a, word_at_a );
335 vglc_reachedness[sh_no] = Proper;
336 } else {
337 if (vglc_reachedness[sh_no] == Unreached)
338 vglc_reachedness[sh_no] = Interior;
339 }
340 }
341 }
342}
343
344/* Used for printing leak errors, avoids exposing the LossRecord type (which
345 comes in as void*, requiring a cast. */
346void MAC_(pp_LeakError)(void* vl, UInt n_this_record, UInt n_total_records)
347{
348 LossRecord* l = (LossRecord*)vl;
349
350 VG_(message)(Vg_UserMsg, "");
351 VG_(message)(Vg_UserMsg,
352 "%d bytes in %d blocks are %s in loss record %d of %d",
353 l->total_bytes, l->num_blocks,
354 l->loss_mode==Unreached ? "definitely lost"
355 : (l->loss_mode==Interior ? "possibly lost"
356 : "still reachable"),
357 n_this_record, n_total_records
358 );
359 VG_(pp_ExeContext)(l->allocated_at);
360}
361
362/* Top level entry point to leak detector. Call here, passing in
363 suitable address-validating functions (see comment at top of
364 vg_scan_all_valid_memory above). All this is to avoid duplication
365 of the leak-detection code for the Memcheck and Addrcheck skins.
366 Also pass in a skin-specific function to extract the .where field
367 for allocated blocks, an indication of the resolution wanted for
368 distinguishing different allocation points, and whether or not
369 reachable blocks should be shown.
370*/
371void MAC_(do_detect_memory_leaks) (
372 Bool is_valid_64k_chunk ( UInt ),
373 Bool is_valid_address ( Addr )
374)
375{
376 Int i;
377 Int blocks_leaked, bytes_leaked;
378 Int blocks_dubious, bytes_dubious;
379 Int blocks_reachable, bytes_reachable;
380 Int blocks_suppressed, bytes_suppressed;
381 Int n_lossrecords;
382 UInt bytes_notified;
383 Bool is_suppressed;
384
385 LossRecord* errlist;
386 LossRecord* p;
387
388 /* VG_(get_malloc_shadows) allocates storage for shadows */
389 vglc_shadows = VG_(get_malloc_shadows)( &vglc_n_shadows );
390 if (vglc_n_shadows == 0) {
391 sk_assert(vglc_shadows == NULL);
392 VG_(message)(Vg_UserMsg,
393 "No malloc'd blocks -- no leaks are possible.");
394 return;
395 }
396
397 VG_(message)(Vg_UserMsg, "searching for pointers to %d not-freed blocks.",
398 vglc_n_shadows );
399
400 vglc_min_mallocd_addr = VG_(get_sc_data)(vglc_shadows[0]);
401 vglc_max_mallocd_addr = VG_(get_sc_data)(vglc_shadows[vglc_n_shadows-1])
402 + VG_(get_sc_size)(vglc_shadows[vglc_n_shadows-1]) - 1;
403
404 vglc_reachedness = VG_(malloc)( vglc_n_shadows * sizeof(Reachedness) );
405 for (i = 0; i < vglc_n_shadows; i++)
406 vglc_reachedness[i] = Unreached;
407
408 /* Do the scan of memory. */
409 bytes_notified
410 = VKI_BYTES_PER_WORD
411 * vg_scan_all_valid_memory (
412 is_valid_64k_chunk,
413 is_valid_address,
414 &vg_detect_memory_leaks_notify_addr
415 );
416
417 VG_(message)(Vg_UserMsg, "checked %d bytes.", bytes_notified);
418
419 /* Common up the lost blocks so we can print sensible error messages. */
420 n_lossrecords = 0;
421 errlist = NULL;
422 for (i = 0; i < vglc_n_shadows; i++) {
423
424 ExeContext* where = MAC_(get_where) ( vglc_shadows[i] );
425
426 for (p = errlist; p != NULL; p = p->next) {
427 if (p->loss_mode == vglc_reachedness[i]
428 && VG_(eq_ExeContext) ( MAC_(clo_leak_resolution),
429 p->allocated_at,
430 where) ) {
431 break;
432 }
433 }
434 if (p != NULL) {
435 p->num_blocks ++;
436 p->total_bytes += VG_(get_sc_size)(vglc_shadows[i]);
437 } else {
438 n_lossrecords ++;
439 p = VG_(malloc)(sizeof(LossRecord));
440 p->loss_mode = vglc_reachedness[i];
441 p->allocated_at = where;
442 p->total_bytes = VG_(get_sc_size)(vglc_shadows[i]);
443 p->num_blocks = 1;
444 p->next = errlist;
445 errlist = p;
446 }
447 }
448
449 /* Print out the commoned-up blocks and collect summary stats. */
450 blocks_leaked = bytes_leaked = 0;
451 blocks_dubious = bytes_dubious = 0;
452 blocks_reachable = bytes_reachable = 0;
453 blocks_suppressed = bytes_suppressed = 0;
454
455 for (i = 0; i < n_lossrecords; i++) {
456 Bool print_record;
457 LossRecord* p_min = NULL;
458 UInt n_min = 0xFFFFFFFF;
459 for (p = errlist; p != NULL; p = p->next) {
460 if (p->num_blocks > 0 && p->total_bytes < n_min) {
461 n_min = p->total_bytes;
462 p_min = p;
463 }
464 }
465 sk_assert(p_min != NULL);
466
467 /* Ok to have tst==NULL; it's only used if --gdb-attach=yes, and
468 we disallow that when --leak-check=yes.
469
470 Prints the error if not suppressed, unless it's reachable (Proper)
471 and --show-reachable=no */
472
473 print_record = ( MAC_(clo_show_reachable) || Proper != p_min->loss_mode );
474 is_suppressed =
475 VG_(unique_error) ( /*tst*/NULL, LeakErr, (UInt)i+1,
476 (Char*)n_lossrecords, (void*) p_min,
477 p_min->allocated_at, print_record );
478
479 if (is_suppressed) {
480 blocks_suppressed += p_min->num_blocks;
481 bytes_suppressed += p_min->total_bytes;
482
483 } else if (Unreached == p_min->loss_mode) {
484 blocks_leaked += p_min->num_blocks;
485 bytes_leaked += p_min->total_bytes;
486
487 } else if (Interior == p_min->loss_mode) {
488 blocks_dubious += p_min->num_blocks;
489 bytes_dubious += p_min->total_bytes;
490
491 } else if (Proper == p_min->loss_mode) {
492 blocks_reachable += p_min->num_blocks;
493 bytes_reachable += p_min->total_bytes;
494
495 } else {
496 VG_(skin_panic)("generic_detect_memory_leaks: unknown loss mode");
497 }
498 p_min->num_blocks = 0;
499 }
500
501 VG_(message)(Vg_UserMsg, "");
502 VG_(message)(Vg_UserMsg, "LEAK SUMMARY:");
503 VG_(message)(Vg_UserMsg, " definitely lost: %d bytes in %d blocks.",
504 bytes_leaked, blocks_leaked );
505 VG_(message)(Vg_UserMsg, " possibly lost: %d bytes in %d blocks.",
506 bytes_dubious, blocks_dubious );
507 VG_(message)(Vg_UserMsg, " still reachable: %d bytes in %d blocks.",
508 bytes_reachable, blocks_reachable );
509 VG_(message)(Vg_UserMsg, " suppressed: %d bytes in %d blocks.",
510 bytes_suppressed, blocks_suppressed );
511 if (!MAC_(clo_show_reachable)) {
512 VG_(message)(Vg_UserMsg,
513 "Reachable blocks (those to which a pointer was found) are not shown.");
514 VG_(message)(Vg_UserMsg,
515 "To see them, rerun with: --show-reachable=yes");
516 }
517 VG_(message)(Vg_UserMsg, "");
518
519 VG_(free) ( vglc_shadows );
520 VG_(free) ( vglc_reachedness );
521}
522
523/*--------------------------------------------------------------------*/
524/*--- end mac_leakcheck.c ---*/
525/*--------------------------------------------------------------------*/
526