1
/*--------------------------------------------------------------------*/
2
/*--- The Omega tool: traces memory allocations and alerts when ---*/
3
/*--- the final reference to an allocated block dies. ---*/
5
/*--------------------------------------------------------------------*/
8
This file is part of Omega, a Valgrind tool for detecting memory
11
Copyright (C) 2006-2007 Bryan "Brain Murders" Meredith
12
(A note of personal thanks to my employers at Apertio (www.apertio.com)
13
for allowing the use of their time, equipment for 64bit testing and
14
providing moral support.)
16
Partly based upon other Valgrind tools
17
Copyright (C) 2000-2007 Julian Seward, Nicholas Nethercote et al.
21
This program is free software; you can redistribute it and/or
22
modify it under the terms of the GNU General Public License as
23
published by the Free Software Foundation; either version 2 of the
24
License, or (at your option) any later version.
26
This program is distributed in the hope that it will be useful, but
27
WITHOUT ANY WARRANTY; without even the implied warranty of
28
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29
General Public License for more details.
31
You should have received a copy of the GNU General Public License
32
along with this program; if not, write to the Free Software
33
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
36
The GNU General Public License is contained in the file COPYING.
38
The current maintainer is Rich Coe <richard.coe@med.ge.com>.
42
** Read the tool documentation for an explaination of the ideas
43
** behind this implementation.
46
#include "pub_tool_basics.h"
47
#include "pub_tool_libcassert.h"
48
#include "pub_tool_tooliface.h"
49
#include "pub_tool_hashtable.h"
50
#include "pub_tool_libcbase.h"
51
#include "pub_tool_libcprint.h"
52
#include "pub_tool_libcassert.h"
53
#include "pub_tool_mallocfree.h"
54
#include "pub_tool_replacemalloc.h"
55
#include "pub_tool_machine.h"
56
#include "pub_tool_threadstate.h"
57
#include "pub_tool_stacktrace.h"
58
#include "pub_tool_options.h"
59
#include "pub_tool_clreq.h"
61
#include "coregrind/pub_core_options.h"
62
#include "coregrind/pub_core_debugger.h"
64
#include "libvex_guest_offsets.h"
66
#include "exp-omega.h"
69
** A little sanity in a mad, mad world.
71
#if !(VG_WORDSIZE == 4) && !(VG_WORDSIZE == 8)
73
** We don't handle anything else yet.
75
#error Unsupported VG_WORDSIZE
79
** 4 lots of debug - always, general, memory and pbit.
80
** general, memory and pbit can also be turned off with a master switch.
81
** You wont want any of this on unless you are hacking the source around.
83
#define NO_DEBUG(fmt, args...)
84
#define O_DEBUG(fmt, args...) VG_(message)(Vg_DebugMsg, fmt, ## args)
86
// Set to 0 to remove almost all debug from compiled tool
89
static Bool o_traceMem = True; //False;
90
static Bool o_tracePBit = False;
91
static Bool o_traceGeneral = True; //False;
92
static Bool o_traceStop = True;
94
#define O_GDEBUG(fmt, args...) \
95
if(o_traceGeneral && !o_traceStop) \
97
VG_(message)(Vg_DebugMsg, fmt, ## args); \
100
#define O_MDEBUG(fmt, args...) \
101
if(o_traceMem && !o_traceStop) \
103
VG_(message)(Vg_DebugMsg, fmt, ## args); \
106
#define O_PDEBUG(fmt, args...) \
107
if(o_tracePBit && !o_traceStop) \
109
VG_(message)(Vg_DebugMsg, fmt, ## args); \
112
#define O_TRACE_ON() {o_traceStop = False;}
113
#define O_TRACE_OFF() {o_traceStop = True;}
114
#define O_TRACE_MEM_ON() {o_traceMem = True;}
115
#define O_TRACE_MEM_OFF() {o_traceMem = False;}
116
#define O_TRACE_PBIT_ON() {o_tracePBit = True;}
117
#define O_TRACE_PBIT_OFF() {o_tracePBit = False;}
118
#define O_TRACE_GENERAL_ON() {o_traceGeneral = True;}
119
#define O_TRACE_GENERAL_OFF() {o_traceGeneral = False;}
120
#define O_MASTER_DEBUG 1
123
** Should we instrument memory loads for debugging?
124
** Comment out to stop register loads from showing.
126
//#define O_TRACK_LOADS 1
129
** No debug included at all.
131
#define O_GDEBUG(fmt, args...)
132
#define O_MDEBUG(fmt, args...)
133
#define O_PDEBUG(fmt, args...)
135
#define O_TRACE_OFF()
136
#define O_TRACE_MEM_ON()
137
#define O_TRACE_MEM_OFF()
138
#define O_TRACE_PBIT_ON()
139
#define O_TRACE_PBIT_OFF()
140
#define O_TRACE_GENERAL_ON()
141
#define O_TRACE_GENERAL_OFF()
146
** Need somewhere to give addresses to tracked pointers in registers.
147
** We dont write to the locations, just use their addresses.
148
** To make it easy to see, use the very top 64K of memory.
149
** Note that we might have to map this somewhere else if this is in user space.
151
#if (VG_WORDSIZE == 4)
152
#define FAKE_REG_BASE 0xFFFF0000
154
#define FAKE_REG_BASE 0xFFFFFFFFFFFF0000
156
#define MAP_TO_REG(tid, offset) \
157
(FAKE_REG_BASE + (0x0100 * ((tid) - 1)) + (offset))
158
#define OFFSET_FROM_REG(regAddress) \
159
((regAddress) & 0x00ff)
160
#define IS_REG(addr) ((addr >= FAKE_REG_BASE) ? !0 : 0)
162
static UInt o_isReturnIgnoreReg(Addr reg)
165
** Indicate registers that are 'scratch' registers and should be ignored on
166
** function return for tracked pointer purposes.
168
JRS 10 Nov 2007: Seems to me this should be somehow related to
169
caller- vs callee-saved classification of registers, but not sure.
170
See docs/internal/register-uses.txt for a summary.
172
This fn really ought to be partitioned along VGP_arch_os lines
173
rather than VGA_arch lines, since register conventions are OS
174
dependant as well as CPU dependant.
177
switch(OFFSET_FROM_REG(reg))
185
#elif defined(VGA_amd64)
186
switch(OFFSET_FROM_REG(reg))
188
case OFFSET_amd64_RCX:
189
case OFFSET_amd64_RSI:
190
case OFFSET_amd64_RDI:
191
case OFFSET_amd64_R8:
192
case OFFSET_amd64_R9:
193
case OFFSET_amd64_R10:
194
case OFFSET_amd64_R11:
199
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
200
VG_(printf)("\nOmega does not currently work on PowerPC/POWER platforms."
204
# error "Unknown arch"
212
/*------------------------------------------------------------*/
213
/*--- Command Line Option Flags and Values ---*/
214
/*------------------------------------------------------------*/
216
** Should we track all memory block allocations or just blocks
217
** indicated to us with the MALLOCLIKE_BLOCK user request?
219
static Bool o_onlyMallocLike = False;
221
** Should we show memory that leaks due to a block leaking?
223
static Bool o_showIndirect = False;
225
** Should we show pointers to a block that is deallocated?
227
static Bool o_showHanging = False;
229
** Should we show blocks with only circular references?
231
static Bool o_showCircular = False;
233
** Show interal stats at the end of the run.
235
static Bool o_showInternStats = False;
237
** Should we only show the summary report.
239
static Bool o_showSummaryOnly = True;
242
** Should we clear leaked blocks to try and force an error.
244
static Bool o_poison = False;
247
** These figures are pure wet finger in the air guestimates.
248
** If the user has _lots_ of memory blocks / tracked pointers, they can
249
** increase the prime number on the command line.
252
** Number of PBit Node entries in the hash table.
254
static UInt o_pbitNodeHashSize = 1031;
256
** Number of MemBlock entries in the hash table.
258
static UInt o_memblockHashSize = 65537;
260
** Number of Tracked Pointer entries in the hash table.
262
static UInt o_trackedPointerHashSize = 65537;
264
/*------------------------------------------------------------*/
265
/*--- Statistics ---*/
266
/*------------------------------------------------------------*/
269
unsigned long liveTrackedPointers;
270
unsigned long trackedPointersAllocated;
271
unsigned long liveMemoryBlocks;
272
unsigned long memoryBlocksAllocated;
273
unsigned long shadowMemoryBlocksAllocated;
274
unsigned long memoryBlocksLeaked;
275
unsigned long memoryBlocksLostAndFound;
276
unsigned long pbitNodes;
279
static Stats o_stats;
281
/*------------------------------------------------------------*/
282
/*--- PBit Tracking ---*/
283
/*------------------------------------------------------------*/
285
** Setup constants for PBit tracking.
287
#if (VG_WORDSIZE == 4)
288
#define PBIT_MAJOR_SHIFT 7
289
#define PBIT_MINOR_SHIFT 2
290
#define PBIT_MINOR_MASK 0x1F
291
#elif (VG_WORDSIZE == 8)
292
#define PBIT_MAJOR_SHIFT 8
293
#define PBIT_MINOR_SHIFT 3
294
#define PBIT_MINOR_MASK 0x1F
298
** Work out how many bytes a UInt of pbits covers
300
#define PBIT_RANGE (sizeof(UInt) * 8 * VG_WORDSIZE)
303
** Number of UInts to store in a node so that the node covers 64K
305
#define PBIT_NODE_UINTS ((64 * 1024) / PBIT_RANGE)
308
** Memory range covered by a pbit node
310
#define PBIT_NODE_RANGE 0xFFFF
311
#define PBIT_NODE_RANGE_MASK (~PBIT_NODE_RANGE)
312
#define PBIT_NODE_SHIFT 16
314
/* Define the pbit storage node. */
316
VgHashNode hdr; // Must be first item
317
UInt set_bits; // Count of set bits
318
UInt pbits[PBIT_NODE_UINTS]; // 64K of coverage
322
** We use a hash table to track the p-bits.
323
** The node is defined just above. The key to a node is the memory
324
** address right shifted PBIT_NODE_SHIFT bits.
326
static VgHashTable o_PBits = NULL;
329
** For speed, we keep a node to track register allocations and cache the last
330
** node that was accessed.
332
static PBitNode o_registerPBits;
333
static PBitNode *o_lastPBitNode = NULL;
334
static Addr o_lastPBitNodeKey = 0;
337
** Convenience macros for working out which bit in which PBIT_NODE_UINT we
340
#define PBIT_MAJOR_INDEX( addr ) \
341
(((addr) & PBIT_NODE_RANGE) >> PBIT_MAJOR_SHIFT)
342
#define PBIT_MINOR_INDEX( addr ) \
343
(((addr) >> PBIT_MINOR_SHIFT) & PBIT_MINOR_MASK)
344
#define PBIT_KEY( addr ) ((Addr)(addr) >> PBIT_NODE_SHIFT)
353
** Helper functions for doing fast searches through an address range.
355
static Addr o_firstPBit(PBitContext *context, Addr start, SizeT length);
356
static Addr o_nextPBit(PBitContext *context);
359
** Basic PBit manipulation.
361
static PBitNode *o_getPBitNode(Addr address, Bool create)
363
Addr key = PBIT_KEY(address);
365
O_PDEBUG("o_getPBitNode(%p%s)", address,
366
create ? ", create" : "");
368
O_PDEBUG("o_getPBitNode last node %p, last key %p",
369
o_lastPBitNode, o_lastPBitNodeKey);
374
** This is a register - use the register PBit node.
376
O_PDEBUG("o_getPBitNode returning register PBit node");
377
return &o_registerPBits;
379
else if((key == o_lastPBitNodeKey) &&
380
(o_lastPBitNode || !create))
383
** This is in the same node as last time.
385
O_PDEBUG("o_getPBitNode returning last PBit node");
386
return o_lastPBitNode;
392
** Look it up then cache both the node and the node key.
394
o_lastPBitNode = VG_(HT_lookup)(o_PBits, key);
395
o_lastPBitNodeKey = key;
397
if(!o_lastPBitNode & create)
400
** We don't have a node for this address. Create one now.
402
o_lastPBitNode = VG_(malloc)( sizeof(PBitNode) );
403
tl_assert(o_lastPBitNode);
404
VG_(memset)(o_lastPBitNode, 0, sizeof(PBitNode));
405
o_lastPBitNode->hdr.key = key;
408
** Add this node into the hash table.
410
VG_(HT_add_node)(o_PBits, o_lastPBitNode);
412
O_PDEBUG("Created PBit node beginning %p for address %p",
413
(key << PBIT_NODE_SHIFT),
419
O_PDEBUG("o_getPBitNode returning lookup PBit node");
421
return o_lastPBitNode;
425
static void o_setPBit( Addr address )
428
** Retrieve the node that contains this address then set the appropriate bit.
430
PBitNode *pbn = o_getPBitNode(address, True);
432
O_PDEBUG("o_setPBit(%p)", address);
434
O_PDEBUG("o_setPBit - node = %p, MAJOR = %d, MINOR = %d",
436
PBIT_MAJOR_INDEX(address),
437
PBIT_MINOR_INDEX(address));
439
** The PBit might not be clear so only tweak things if it is.
441
if(!(pbn->pbits[PBIT_MAJOR_INDEX(address)] &
442
(1 << PBIT_MINOR_INDEX(address))))
445
** Set the pbit and increment the convenience count.
447
pbn->pbits[PBIT_MAJOR_INDEX(address)] |=
448
(1 << PBIT_MINOR_INDEX(address));
452
O_PDEBUG("o_setPBit done");
456
static void o_clearPBit( Addr address )
459
** Retrieve the node that contains this address. If the node does not exist,
460
** we assert as this really shouldnt happen.
462
PBitNode *pbn = o_getPBitNode(address, False);
464
O_PDEBUG("o_clearPBit(%p)", address);
469
** The PBit might not be set so only tweak things if it is.
471
if(pbn->pbits[PBIT_MAJOR_INDEX(address)] &
472
(1 << PBIT_MINOR_INDEX(address)))
475
** Clear the pbit and decrement the convenience count.
477
pbn->pbits[PBIT_MAJOR_INDEX(address)] &=
478
~(1 << PBIT_MINOR_INDEX(address));
485
static Bool o_isPBitSet( Addr address )
488
** Retrieve the node that contains this address. If the node does not exist,
489
** the Pbit isnt set ;-)
491
PBitNode *pbn = o_getPBitNode(address, False);
493
O_PDEBUG("o_isPBitSet(%p)", address);
499
** Return the Pbit status.
501
return ((pbn->pbits[PBIT_MAJOR_INDEX(address)] &
502
(1 << PBIT_MINOR_INDEX(address))) != 0);
506
** For ease of range checking PBits, we provide the following two functions.
507
** The idea is that you call the first one with your start address and range.
508
** It returns the first address that is marked by a PBit or 0 if the range is
509
** clear (we overlap the supplied range in order to check partial pointers at
510
** each end). By calling the second one with the same context until it returns
511
** zero, you get all of the PBits within the range. You supply the context so
512
** we should be able to nest calls if need be.
514
static Addr o_firstPBit(PBitContext *context, Addr start, SizeT length)
516
const Addr MASK = ~(VG_WORDSIZE - 1);
519
tl_assert(start > VG_WORDSIZE);
521
O_PDEBUG("o_firstPBit(%p, %p)", start, length);
523
** Optimisation for single pointer ranges and bizarre 0 length calls.
529
else if(length <= VG_WORDSIZE)
532
** Set the current address to 0.
534
context->currentAddress = 0;
535
return (o_isPBitSet(start)) ? (start & MASK) : 0;
539
** Setup the current and final addresses. Note that we set the current
540
** address to one aligned address below because of how nextPBit works.
542
context->currentAddress = ((start & MASK) - VG_WORDSIZE);
543
context->finalAddress = ((start + length - 1) & MASK);
545
context->node = o_getPBitNode(context->currentAddress, False);
547
O_PDEBUG("o_firstPBit current %p, final %p",
548
context->currentAddress, context->finalAddress);
550
return o_nextPBit(context);
553
static Addr o_nextPBit(PBitContext *context)
556
** Current address is the last address we returned.
557
** We keep going until we have checked final address.
568
** When the current address is set to 0, we just exit.
570
if(context->currentAddress == 0)
575
O_PDEBUG("o_nextPBit(%p,%p)",
576
context->currentAddress, context->finalAddress);
579
(context->currentAddress <= context->finalAddress))
582
** Check if we need another node and get it if we do.
584
startAddr = context->currentAddress + VG_WORDSIZE;
586
O_PDEBUG("o_nextPBit c %p s %p", context->currentAddress, startAddr);
588
if(PBIT_KEY(context->currentAddress) !=
591
O_PDEBUG("o_nextPBit getting next node %p",
592
startAddr & PBIT_NODE_RANGE_MASK);
594
context->node = o_getPBitNode(startAddr, False);
596
context->currentAddress = startAddr;
599
** Check if we have a node - skip to next node (final address
600
** permitting) if we dont. This is the 64k of addresses at a time
605
O_PDEBUG("o_nextPbit: no node.");
607
if(context->currentAddress > context->finalAddress)
610
** We have passed the final address - time to stop looking.
612
O_PDEBUG("o_nextPbit: current > final");
615
else if((context->currentAddress & PBIT_NODE_RANGE_MASK) !=
616
(context->finalAddress & PBIT_NODE_RANGE_MASK))
619
** Align to VG_WORDSIZE below the next node range then loop.
621
O_PDEBUG("o_nextPbit: aligning to next node. (%p, %p)",
622
context->currentAddress,
623
context->finalAddress);
625
context->currentAddress += (PBIT_NODE_RANGE + 1);
626
context->currentAddress &= PBIT_NODE_RANGE_MASK;
627
context->currentAddress -= VG_WORDSIZE;
629
O_PDEBUG("o_nextPbit: aligned to %p",
630
context->currentAddress);
637
** Node range is the same but no node == no pbits.
639
context->currentAddress = context->finalAddress + VG_WORDSIZE;
645
** The index of the PBit array item we want to check then get the pbits.
647
majorIndex = PBIT_MAJOR_INDEX(context->currentAddress);
648
minorIndex = PBIT_MINOR_INDEX(context->currentAddress);
649
pbits = context->node->pbits[majorIndex];
652
** Mask off addresses below the current address then test.
654
pbits &= ~((1 << minorIndex) - 1);
656
O_PDEBUG("o_nextPbit: major %d, minor %d, bit %p",
657
majorIndex, minorIndex, pbits);
659
** This checks up to PBIT_RANGE at a time (256 addresses on a
665
** No pbits set in this UInt. Set the current address to VG_WORDSIZE
666
** below the next UInt then loop around.
668
context->currentAddress += PBIT_RANGE;
669
context->currentAddress &= ~(PBIT_RANGE - 1);
670
context->currentAddress -= VG_WORDSIZE;
676
** Now we walk the UInt a bit at a time.
679
((minorIndex <= PBIT_MINOR_MASK) &&
680
(context->currentAddress <= context->finalAddress))
683
if(pbits & (1 << minorIndex))
688
foundAddr = context->currentAddress;
689
O_PDEBUG("o_nextPbit found %p", foundAddr);
694
context->currentAddress += VG_WORDSIZE;
700
** Final range check.
702
if(foundAddr > context->finalAddress)
708
** Store the result so that we know where to start from next time.
710
context->currentAddress = foundAddr;
712
O_PDEBUG("o_nextPbit returning %p", foundAddr);
717
/*------------------------------------------------------------*/
718
/*--- Error Report and Suppression Tracking ---*/
719
/*------------------------------------------------------------*/
721
** We hold a doubley linked list of Exe contexts for leaks and suppressions.
722
** If a block is tagged as leaked then comes back to life, we move it
723
** into the suppression list. We always check the suppression list first
724
** before adding a record to the leaked list.
725
** We keep a count of how may times a record matches as it saves space.
727
struct _BlockRecord {
728
struct _BlockRecord *next;
729
struct _BlockRecord *prev;
730
ExeContext *allocated;
736
typedef struct _BlockRecord BlockRecord;
742
static BlockRecordList o_leakRecords = {NULL, NULL};
743
static BlockRecordList o_suppressionRecords = {NULL, NULL};
745
#define DUMP_BLOCK(block) \
746
O_DEBUG("n %p, p %p, a %p, l %p, c %d b %p", \
747
block->next, block->prev, \
748
block->allocated, block->leaked, block->count, \
752
** List handling - we need to be able to add and remove a single block
753
** from anywhere in the list but the chances are, removals will come from
754
** the end, hence using a doubly linked list. We also need to walk the list
755
** to find a matching item. Again, we do this backwards as it tends to get
756
** a match faster in the case of moving newly leaked block records into
757
** the suppression list.
759
static void o_addBlockRecord(BlockRecordList *list, BlockRecord *item)
764
tl_assert(list && item);
766
NO_DEBUG("o_addBlockRecord pre()");
771
list->start = list->end = item;
772
item->prev = item->next = NULL;
777
** OK, add it onto the end.
779
item->prev = list->end;
781
list->end->next = item;
784
NO_DEBUG("o_addBlockRecord post()");
789
static void o_removeBlockRecord(BlockRecordList *list, BlockRecord *item)
792
** We don't check that the item is in the list.
793
** Ensure you check with the findBlockRecord function.
795
tl_assert(list && item);
797
NO_DEBUG("o_removeBlockRecord pre()");
804
item->prev->next = item->next;
811
list->start = item->next;
819
item->next->prev = item->prev;
826
list->end = item->prev;
829
NO_DEBUG("o_removeBlockRecord post()");
835
static BlockRecord *o_findBlockRecord(BlockRecordList *list,
836
ExeContext *allocated,
841
** Search backwards for the block record that matches the contexts.
842
** We allow leaked to be null so that we can handle the circular checking
843
** blocks as well which only have an allocated context.
845
BlockRecord *item = NULL;
847
tl_assert(list && allocated);
853
if(VG_(eq_ExeContext)(Vg_HighRes, item->allocated, allocated) &&
854
((!item->leaked && !leaked) ||
855
((item->leaked && leaked) &&
856
VG_(eq_ExeContext)(Vg_HighRes, item->leaked, leaked))))
867
static Bool o_addLeakedBlock(ExeContext *allocated,
871
BlockRecord *item = NULL;
873
tl_assert(allocated && leaked);
876
** See if we already have this block.
877
** Check the suppression record first.
879
item = o_findBlockRecord(&o_suppressionRecords, allocated, leaked);
884
** Not in the suppression record.
885
** Try the leaked block list.
887
item = o_findBlockRecord(&o_leakRecords, allocated, leaked);
893
** Just increment the count.
897
//O_DEBUG("o_addLeakedBlock - block exists");
904
** Create a new block and add it to the leaked list.
906
item = VG_(malloc)(sizeof(BlockRecord));
911
item->next = item->prev = NULL;
912
item->allocated = allocated;
913
item->leaked = leaked;
915
o_addBlockRecord(&o_leakRecords, item);
922
static Bool o_addSuppressionBlock(ExeContext *allocated,
925
BlockRecord *item = NULL;
927
tl_assert(allocated && leaked);
930
** See if we already have this block.
931
** Check the suppression record first.
933
item = o_findBlockRecord(&o_suppressionRecords, allocated, leaked);
938
** Not in the suppression record.
939
** Try the leaked block list.
941
item = o_findBlockRecord(&o_leakRecords, allocated, leaked);
945
VG_(tool_panic)("suppressing block that didnt leak :-(");
950
** Move the block to the suppression list.
952
o_removeBlockRecord(&o_leakRecords, item);
953
o_addBlockRecord(&o_suppressionRecords, item);
959
** The block is already suppressed - just increase the count.
963
//O_DEBUG("o_addSuppressionBlock - block exists");
971
/*------------------------------------------------------------*/
972
/*--- Allocated Block and Pointer Tracking ---*/
973
/*------------------------------------------------------------*/
975
** Where these structures have address references, they are the address
976
** of the item in client memory NOT the address of either of these
977
** internal tracking structures.
981
VgHashNode hdr; // Must be first item
982
Addr block; // Address of the allocated block start
983
SizeT length; // Length of the allocated block
984
struct _MemBlock *memBlock; // Pointer to the memblock
987
typedef struct _MemBlock {
988
VgHashNode hdr; // Must be first item
989
SizeT length; // Length of the allocated block
990
ExeContext *where; // Where the block was allocated
991
UInt refNum; // Number of back references
992
TrackedPointer **pointers; // Back references to TrackedPointer info
993
struct _MemBlock *shadowing; // Set to memblock of block that we shadow
994
struct _MemBlock *shadowed; // Set to memblock of our shadow
995
ExeContext *leaked; // Where we think the block leaked
996
UInt nonRegCount; // Non register tracked pointers
997
Int external; // Used in circular dependency checking
999
TrackedPointer *maybeLast; // Last live tracked pointer on function return
1000
ExeContext *funcEnd; // matching exe context for the end of the function
1001
Bool doLeak; // Set if this block should leak on instruction
1002
// end. We have to make instructions atomic or we
1003
// go bang on things like xchng as there is no way
1004
// of telling which value gets overwritten first.
1005
struct _MemBlock *next; // Linked list of blocks that might be leaking at
1007
int depth; // Depth that the potential leak occurred at.
1008
TrackedPointer *wasLast; // Pointer t
1010
UInt nonScratch; // Number of non-scratch registers.
1015
** This helps to solve the problem of where a program does its own memory
1016
** management of the kind:
1018
1 secret *foo = malloc(sizeof(bar) + sizeof(secret) + alignment_correction);
1019
2 foo->secret_stuff = magic_key;
1024
** If the pointer to foo is shadowed at some internal offset to the block
1025
** start, we create a shadow record and link it to the main block so that
1026
** we can track references to either. Without this we do a leak alert at
1027
** line 4 instead which is undesireable.
1029
** There can only be one shadow to a block unless we need more and someone
1030
** wants to code it. A side effect of the current implementation allows a
1031
** shadow of a shadow but it is explicitly blocked for now.
1035
** We use separate hash tables to track the pointers and allocated blocks.
1036
** The key of each node is the address of the corresponding item in client
1037
** memory, shifted right to remove the wasted bits caused by alignment of
1038
** pointers in memory.
1040
#if (VG_WORDSIZE == 4)
1041
#define TRACK_MINOR_SHIFT 2
1042
#define TRACK_MINOR_MASK ~0x03
1043
#elif (VG_WORDSIZE == 8)
1044
#define TRACK_MINOR_SHIFT 3
1045
#define TRACK_MINOR_MASK ~0x07
1048
#define TRACKED_KEY( a ) ((UWord)(a) >> TRACK_MINOR_SHIFT)
1049
#define FROM_TRACKED_KEY( a ) ((UWord)(a) << TRACK_MINOR_SHIFT)
1052
** Storage for the two hash tables we need.
1054
static VgHashTable o_MemBlocks = NULL;
1055
static VgHashTable o_TrackedPointers = NULL;
1058
** Start of a linked list of blocks that may be leaking during this original
1059
** processor instruction. Instructions are broken down inside VEX so a single
1060
** original instruction can become many VEX instructions. By not doing leak
1061
** reports until the end of the original instruction, everything becomes
1062
** atomic again - the stack moves and the popped value appears in the register
1063
** in one movement rather than two which cause a leak if the stack is
1064
** invalidated before the value appears in the register. xchng works both ways
1065
** around and so on.
1067
static MemBlock *doLeakList = NULL;
1068
static UInt doLeakListCount = 0;
1069
static Bool doLeakNow = False;
1072
** Set when we are removing pointers within a free()ed block.
1074
static Bool o_clearingBlock = False;
1077
** Set when we are removing pointers within a free()ed block or a
1078
** block that leaked. It shows the indirection level in cascades.
1080
static UInt o_indirectChecking = 0;
1081
static ExeContext *o_indirectStack = NULL;
1084
** Set when the stack is unwinding.
1086
static Bool o_stackUnwind = False;
1088
static void o_killRange(Addr start, SizeT length);
1091
** This is set to stop us from tracking leaks once we exit main.
1092
** (May well need a per thread flag to catch when threads exit as well.)
1094
static Bool o_inhibitLeakDetect = False;
1097
static void o_cleanupTrackedPointers( MemBlock * mb )
1101
for(pointerIndex = 0; pointerIndex < mb->refNum; pointerIndex++)
1104
VG_(HT_remove)(o_TrackedPointers,
1105
mb->pointers[pointerIndex]->hdr.key);
1108
O_GDEBUG("Removing tracked pointer at %p pointing to %p",
1109
FROM_TRACKED_KEY(p->hdr.key),
1113
** Remove the PBit for this tracked pointer.
1115
o_clearPBit(FROM_TRACKED_KEY(p->hdr.key));
1118
** Show any pointers to this block as we deallocate them.
1122
if(IS_REG(FROM_TRACKED_KEY(p->hdr.key)))
1125
** Maybe decode registers to names later?
1127
O_DEBUG("Removing hanging pointer in a register to block %p",
1132
O_DEBUG("Removing hanging pointer at %p to block %p",
1133
FROM_TRACKED_KEY(p->hdr.key),
1138
o_stats.liveTrackedPointers--;
1142
** Free off the pointers back reference.
1144
VG_(free)(mb->pointers);
1145
mb->pointers = NULL;
1151
static void o_cleanupMemBlock( MemBlock **mbpp )
1155
O_GDEBUG("o_cleanupMemBlock(%p)", mbpp);
1161
O_DEBUG("o_cleanupMemBlock passed null memory block pointer.");
1166
** Take a local copy with less indirection.
1170
O_GDEBUG("o_cleanupMemBlock mb=%p", mb->hdr.key);
1173
** If this is a shadowed block, complain then return.
1177
O_DEBUG("Trying to cleanup a shadow block at %p tracking %p",
1179
mb->shadowing->hdr.key);
1184
** If a shadow exists, clean it up.
1188
MemBlock *shadowed = mb->shadowed;
1191
** Cleanup its pointers, remove it from the hash table then
1192
** free off the block.
1194
O_GDEBUG("cleanup shadow pointers");
1195
o_cleanupTrackedPointers(shadowed);
1196
(void)VG_(HT_remove)(o_MemBlocks, shadowed->hdr.key);
1197
VG_(free)(shadowed);
1199
o_stats.liveMemoryBlocks--;
1203
** Free off the tracked pointers.
1205
O_GDEBUG("cleanup tracked pointers");
1206
o_cleanupTrackedPointers(mb);
1209
** Check for tracked pointers inside the allocated block being lost.
1211
o_indirectChecking++;
1212
o_clearingBlock = True;
1213
o_killRange(mb->hdr.key,
1215
o_clearingBlock = False;
1216
o_indirectChecking--;
1219
** Now free off the memory block.
1222
o_stats.liveMemoryBlocks--;
1225
** Clear the passed in pointer.
1232
static void o_addMemBlockReference( MemBlock *mb, TrackedPointer *tp )
1236
O_GDEBUG("o_addMemBlockReference tp=%p, mb=%p",
1237
FROM_TRACKED_KEY(tp->hdr.key),
1241
** Check if we are shadowing.
1246
** Get the mem block for the true allocated block.
1247
** Note that this leaves smb pointing to the shadow block which is
1254
** Check if the block previously leaked.
1256
if(!mb->shadowed && !mb->refNum && mb->leaked)
1259
** Seems that the block didnt leak after all.
1261
if(o_addSuppressionBlock(mb->where, mb->leaked) && !o_showSummaryOnly)
1263
O_DEBUG("Welcome back to the supposedly leaked block at %p. Illegal read?",
1266
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
1271
o_stats.memoryBlocksLeaked--;
1272
o_stats.memoryBlocksLostAndFound++;
1276
** Populate the tracked pointer then add it to the hash.
1277
** We use the shadow block so that it points to the correct place.
1278
** Add the back reference to the mem block.
1280
tp->block = smb->hdr.key;
1281
tp->length = mb->length;
1283
VG_(HT_add_node)(o_TrackedPointers, tp);
1286
** Do we need more memory for pointers?
1291
VG_(malloc)((smb->refNum + 8) * sizeof(TrackedPointer *));
1292
tl_assert(smb->pointers);
1294
else if(!((smb->refNum + 1) & 7))
1297
** Add space for another 8 back references.
1298
** Note that this will also shrink us if needed.
1301
VG_(realloc)(smb->pointers, ((smb->refNum + 8) * sizeof(Addr)));
1302
tl_assert(smb->pointers);
1305
smb->pointers[smb->refNum] = tp;
1308
** Track register and memory pointers.
1310
if(!IS_REG(FROM_TRACKED_KEY(smb->pointers[smb->refNum]->hdr.key)))
1314
else if(!o_isReturnIgnoreReg(FROM_TRACKED_KEY(smb->pointers[smb->refNum]->hdr.key)))
1320
** Clear the maybeLast and funcEnd. Adding a reference means that
1321
** the cached one wasnt the last.
1323
smb->maybeLast = NULL;
1324
smb->funcEnd = NULL;
1327
** Clear the doLeak flag - we just added a reference so the block survived
1330
smb->doLeak = False;
1333
O_MDEBUG("Added tracked pointer at %p pointing to %s%p",
1334
FROM_TRACKED_KEY(tp->hdr.key),
1335
smb->shadowing ? "(S)" : "",
1341
static void o_removePointerFromList(MemBlock *mb, TrackedPointer *tp)
1345
O_GDEBUG("removePointerFromList tp=%p mb=%p",
1346
FROM_TRACKED_KEY(tp->hdr.key),
1350
** Check that this tracked pointer belongs to this block.
1352
tl_assert(tp->memBlock == mb);
1355
** Find the tracked pointer in the memory blocks' list.
1357
for(pointerNum = 0; pointerNum < mb->refNum; pointerNum++)
1359
if(mb->pointers[pointerNum] == tp)
1363
** If this is not the last pointer in the list, copy the last
1366
if((pointerNum + 1) != mb->refNum)
1368
mb->pointers[pointerNum] = mb->pointers[(mb->refNum - 1)];
1376
** Track register and memory pointers.
1378
if(!IS_REG(FROM_TRACKED_KEY(tp->hdr.key)))
1382
else if(!o_isReturnIgnoreReg(FROM_TRACKED_KEY(tp->hdr.key)))
1392
static void o_doLeakReport(MemBlock *mb);
1393
static void o_removeMemBlockReference( MemBlock *mb, TrackedPointer *tp )
1395
MemBlock *smb = NULL;
1397
UInt nonRegCount = 0;
1398
Bool shadowed = False;
1401
** We need the tracked pointer object.
1406
** If we dont have the memory block, get it from the tracked pointer.
1414
O_GDEBUG("o_removeMemBlockReference tp=%p, mb=%p",
1415
FROM_TRACKED_KEY(tp->hdr.key),
1419
refCount = smb->refNum;
1420
nonRegCount = smb->nonRegCount;
1422
O_GDEBUG("(A)refCount %d, o_stackUnwind %c, nonRegCount %d, isReg %c",
1424
(o_stackUnwind ? 'Y' : 'N'),
1426
IS_REG(FROM_TRACKED_KEY(tp->hdr.key)) ? 'Y' : 'N');
1429
** Check if we are shadowing.
1434
** Get the mem block for the true allocated block.
1435
** Note that this leaves smb pointing to the shadow which is correct.
1438
#if defined(O_MASTER_DEBUG)
1442
for(count = 0; count < mb->refNum && count < 6; count++)
1443
O_GDEBUG(" %p", FROM_TRACKED_KEY(mb->pointers[count]->hdr.key));
1446
refCount += mb->refNum;
1448
nonRegCount += mb->nonRegCount;
1450
else if(mb->shadowed)
1453
** Get the mem block for the shadow as we need the refNum from it.
1455
MemBlock *tmb = mb->shadowed;
1456
#if defined(O_MASTER_DEBUG)
1460
for(count = 0; count < tmb->refNum && count < 6; count++)
1461
O_GDEBUG(" %p", FROM_TRACKED_KEY(tmb->pointers[count]->hdr.key));
1464
refCount += tmb->refNum;
1466
nonRegCount += tmb->nonRegCount;
1468
#if defined(O_MASTER_DEBUG)
1469
else if(!o_traceStop)
1472
for(count = 0; count < mb->refNum && count < 6; count++)
1473
O_GDEBUG(" %p", FROM_TRACKED_KEY(mb->pointers[count]->hdr.key));
1478
O_GDEBUG("(B)rCnt %d, nRCnt %d, ns %d, shad %c, free %c",
1482
(shadowed ? 'Y' : 'N'),
1483
(o_clearingBlock ? 'Y' : 'N'));
1485
** We really should have at least one tracked pointer.
1487
tl_assert(refCount);
1489
#if defined(O_MASTER_DEBUG)
1492
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 8);O_DEBUG("");
1497
** We remove the tracked pointer from the hash table but do not delete it.
1498
** This allows a slight gain where a tracked pointer can immediately be
1499
** reused rather than free()ed off and a new one malloc()ed.
1500
** We then remove the back reference from the memory block and
1501
** squeal if it is the last one. We don't clean the tracked pointer as this
1502
** is a waste if it is going to be free()ed off.
1503
** If warn indirect is set and this is an indirect check, do nothing.
1505
(void)VG_(HT_remove)(o_TrackedPointers, tp->hdr.key);
1507
O_GDEBUG("Removing tracked pointer at %p pointing to %p",
1508
FROM_TRACKED_KEY(tp->hdr.key),
1511
if((refCount <= 1) // Last pointer
1514
** Catch cascades of memory blocks when we call free().
1516
|| (o_clearingBlock && !shadowed && !mb->nonScratch &&
1517
(nonRegCount == 1) && !IS_REG(FROM_TRACKED_KEY(tp->hdr.key)))
1519
#if defined(VGA_x86)
1521
** Losing all in memory pointers within a basic block is not a good sign.
1523
|| (!o_stackUnwind && (nonRegCount == 1) &&
1524
!IS_REG(FROM_TRACKED_KEY(tp->hdr.key)))
1528
if((!o_inhibitLeakDetect)
1530
** Don't report when there are just register based pointers left and
1531
** we have already reported the block as leaked.
1533
&& !(mb->leaked && IS_REG(FROM_TRACKED_KEY(tp->hdr.key)))
1537
** Set the doLeak flag for the block and add it to the doLeakList.
1538
** We also need to stash the indirect depth value for possibly reporting
1539
** later. Finally, if maybeLast matches the pointer that is being removed
1540
** and thus causing the leak, we leave maybeLast and funcEnd otherwise, we
1543
mb->depth = o_indirectChecking;
1544
if(mb->maybeLast != tp)
1546
mb->maybeLast = NULL;
1551
** Cascades triggered by a doLeak being actioned should report
1552
** immediately, rather than being added to the doLeakList. Likewise
1553
** cascades caused by freeing a block.
1555
if(doLeakNow || o_clearingBlock)
1562
mb->next = doLeakList;
1570
** Finally, remove the pointer from the blocks' list.
1572
o_removePointerFromList(smb, tp);
1577
static void o_doLeakReport(MemBlock *mb)
1579
Bool doReport = True;
1583
// This is the suspected last pointer - use the cached stacktrace
1584
O_MDEBUG("maybe last was the last");
1585
tl_assert(mb->funcEnd);
1586
mb->leaked = mb->funcEnd;
1587
o_indirectStack = mb->funcEnd;
1589
else if(mb->depth && o_indirectStack)
1591
O_MDEBUG("indirect with indirect stack set");
1592
// We are cascading - use the cached stacktrace, if there is one
1593
mb->leaked = o_indirectStack;
1597
O_MDEBUG("creating new context maybeLast=0");
1598
// Get the current stacktrace
1599
mb->leaked = VG_(record_ExeContext)(VG_(get_running_tid)(),
1600
0/*first_ip_delta*/);
1603
doReport = o_addLeakedBlock(mb->where, mb->leaked, mb->length);
1605
** Report the probable leak.
1607
o_stats.memoryBlocksLeaked++;
1609
if(doReport && !o_showSummaryOnly)
1615
VG_(message)(Vg_UserMsg,
1616
"Probably indirectly (level %d) leaking block of %d(%p) bytes",
1624
VG_(message)(Vg_UserMsg,
1625
"Probably leaking block of %d(%p) bytes",
1630
if(!mb->depth || o_showIndirect)
1632
VG_(pp_ExeContext)(mb->leaked);
1634
VG_(message)(Vg_UserMsg,
1635
" Block at %p allocated", mb->hdr.key);
1636
VG_(pp_ExeContext)(mb->where);
1637
VG_(message)(Vg_UserMsg,"");
1641
** Only attach the debugger for the first leaking block in the chain
1642
** and only when show summary is disabled (--instant-reports).
1644
if(!mb->depth && VG_(clo_db_attach))
1646
VG_(start_debugger)(VG_(get_running_tid)());
1651
** Check for tracked pointers inside the allocated block being lost.
1653
o_indirectChecking++;
1654
o_killRange(mb->hdr.key, mb->length);
1655
o_indirectChecking--;
1658
** Poison the block if requested.
1661
VG_(memset)((Addr *)mb->hdr.key, 0, mb->length);
1666
static Bool o_setupShadow(TrackedPointer *tp, Addr address)
1668
Bool doneShadow = False;
1669
MemBlock *mb = NULL;
1670
MemBlock *smb = NULL;
1672
O_MDEBUG("setup shadow tp %p block %p address %p",
1673
FROM_TRACKED_KEY(tp->hdr.key), tp->block, address);
1675
** Get the memory block for the tracked pointer.
1682
** If this is a shadow block, get the main block as well.
1693
** If the block is already shadowed at address, bail out and let the
1694
** normal code handle it.
1698
if(mb->shadowed->hdr.key == address)
1700
O_MDEBUG("already shadowed %p", address);
1704
** Get the shadow block.
1711
** Check if address is within the block that we are tracking.
1712
** If it is then we need to work out whether to create a
1713
** new shadow or move an eixsting one.
1715
if((address > mb->hdr.key) &&
1716
(address < (mb->hdr.key + mb->length)))
1720
O_MDEBUG("About to shadow internal address %p to block %p in %p",
1723
FROM_TRACKED_KEY(tp->hdr.key));
1727
O_MDEBUG("creating new shadow");
1729
** Create a new shadow for the block.
1731
smb = VG_(malloc)( sizeof(MemBlock) );
1734
o_stats.shadowMemoryBlocksAllocated++;
1735
o_stats.liveMemoryBlocks++;
1737
VG_(memset)(smb, 0, sizeof(MemBlock));
1738
smb->hdr.key = address;
1740
smb->where = 0; // Dont need this in the shadow.
1741
smb->shadowing = mb;
1743
VG_(HT_add_node(o_MemBlocks, smb));
1746
** Move the tracked pointer from the main block to the shadow.
1748
(void)VG_(HT_remove)(o_TrackedPointers, tp->hdr.key);
1749
o_removePointerFromList(mb, tp);
1750
o_addMemBlockReference(smb, tp);
1752
else if((smb->refNum == 1) &&
1753
(smb == tp->memBlock))
1755
O_MDEBUG("moving existing shadow at %p", smb->hdr.key);
1757
** Move the existing shadow.
1759
(void)VG_(HT_remove)(o_MemBlocks, smb->hdr.key);
1760
smb->hdr.key = address;
1761
smb->where = 0; // Dont need this in the shadow.
1762
VG_(HT_add_node(o_MemBlocks, smb));
1765
** Tweak the existing tracked pointer, leaving the PBit alone.
1767
tp->block = address;
1772
** A shadow exists and has pointers assigned to it.
1773
** We do not allow more than one shadow so deregister and
1774
** free this tracked pointer and clear its PBit.
1776
O_MDEBUG("Prevented second shadow %p (first %p) for %p",
1781
o_clearPBit(FROM_TRACKED_KEY(tp->hdr.key));
1782
o_removeMemBlockReference(NULL, tp);
1785
o_stats.liveTrackedPointers--;
1788
O_MDEBUG("shadow creation / reallocation done");
1790
else if((smb != mb) &&
1791
(address == mb->hdr.key))
1795
** Looks like we are setting the tracked pointer to the block start.
1796
** If it was previously pointing at the shadow block, we need to move it
1799
if(tp->block == smb->hdr.key)
1801
O_MDEBUG("moving pointer from shadow to main");
1803
if(smb->refNum == 1)
1807
O_MDEBUG("destroying shadow of %p at %p",
1811
** Remove the shadow block and move the pointer.
1813
(void)VG_(HT_remove)(o_MemBlocks, smb->hdr.key);
1815
VG_(free)(smb->pointers);
1817
o_stats.liveMemoryBlocks--;
1819
(void)VG_(HT_remove)(o_TrackedPointers, tp->hdr.key);
1820
o_addMemBlockReference(mb, tp);
1825
** Let the normal code move the pointer.
1832
O_MDEBUG("tracked pointer out of range");
1838
static void o_killTrackedPointer(Addr addr)
1840
TrackedPointer *tp = VG_(HT_lookup)(o_TrackedPointers, TRACKED_KEY(addr));
1843
** We really should have the tracked pointer.
1848
** Remove the tracked pointer from its memory block, causing
1849
** a leak report as required then free it.
1853
O_MDEBUG("Removing tracked pointer to %p at %p",
1854
tp->block, FROM_TRACKED_KEY(tp->hdr.key));
1856
o_removeMemBlockReference(NULL, tp);
1860
o_stats.liveTrackedPointers--;
1864
static void o_killRange(Addr start, SizeT length)
1867
** We need to check the PBits for the addresses starting at start.
1868
** We use the firstPBit / nextPBit functions to get us a list of set
1869
** pbits in the specified range.
1874
O_MDEBUG("killing range %p bytes from %p", length, start);
1877
a = o_firstPBit(&pb, start, length);
1880
o_killTrackedPointer(a);
1881
a = o_nextPBit(&pb);
1883
O_MDEBUG("killing range %p bytes from %p done.", length, start);
1886
static void o_duplicateTrackedPointers(Addr dst, Addr src, SizeT length)
1889
** For each set PBit in the src block, create a new tracked pointer
1890
** in the destination block, pointing to the same memory block.
1895
O_MDEBUG("o_duplicateTrackedPointers(%p, %p %d(%p))",
1896
dst, src, length, length);
1898
address = o_firstPBit(&pb, src, length);
1903
** Create a tracked pointer at the appropriate place within the new
1906
TrackedPointer *tp = VG_(HT_lookup)(o_TrackedPointers, TRACKED_KEY(address));
1907
Int diff = dst - src;
1908
TrackedPointer *ntp = VG_(malloc)((sizeof(TrackedPointer)));
1909
MemBlock *mb = NULL;
1913
o_stats.liveTrackedPointers++;
1914
o_stats.trackedPointersAllocated++;
1917
** Get the memory block from the tracked pointer at this address.
1923
O_DEBUG("Oops! Copying pointer at %p to block that leaked(%p)",
1924
address, tp->block);
1925
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
1928
VG_(tool_panic)("we lost track of a pointer :-(");
1933
VG_(memset)(ntp, 0, sizeof(TrackedPointer));
1934
ntp->hdr.key = TRACKED_KEY(address + diff);
1935
o_addMemBlockReference(mb, ntp);
1938
** Set the PBit for this tracked pointer.
1940
o_setPBit(address + diff);
1942
address = o_nextPBit(&pb);
1947
static void o_createMemBlock(ThreadId tid, Addr start, SizeT size)
1949
MemBlock *mb = VG_(malloc)(sizeof(MemBlock));
1952
o_stats.memoryBlocksAllocated++;
1953
o_stats.liveMemoryBlocks++;
1955
VG_(memset)(mb, 0, sizeof(MemBlock));
1958
** Populate the block. Note that we have no pointers until one is written
1961
mb->hdr.key = start;
1963
mb->where = VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
1966
O_DEBUG("Creating new MemBlock (%p) key = %p, length %d",
1967
mb, (void *)start, size);
1968
VG_(pp_ExeContext)(mb->where);
1972
** Add this node into the hash table.
1974
VG_(HT_add_node)(o_MemBlocks, mb);
1977
static void o_destroyMemBlock(ThreadId tid, Addr start)
1980
** Destroy our memory block.
1982
MemBlock *mb = VG_(HT_remove)(o_MemBlocks, start);
1985
** The block really should exist, unless this is a double free attempt...
1989
O_DEBUG("Double/Invalid call to free(%p)", start);
1990
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
1998
** Seems that the block didnt leak after all.
2000
** Why do so many libs access memory in blocks they free()ed?
2002
if(o_addSuppressionBlock(mb->where, mb->leaked) && !o_showSummaryOnly)
2004
O_DEBUG("Welcome back (and goodbye) to the supposedly leaked block at %p",
2007
o_stats.memoryBlocksLeaked--;
2008
o_stats.memoryBlocksLostAndFound++;
2011
** Clean up the block - we pass a pointer pointer so that we can
2012
** set it to NULL during the cleanup process.
2014
o_cleanupMemBlock(&mb);
2021
static void o_setupMaybeLast(Addr a)
2025
** Maybe returning a value - set the maybeLast and funcEnd members
2026
** in the memory block this register points to if it is the last
2029
TrackedPointer *tp = VG_(HT_lookup)(o_TrackedPointers, TRACKED_KEY(a));
2031
** We really should have the tracked pointer.
2035
refCount = tp->memBlock->refNum;
2036
if(tp->memBlock->shadowing)
2038
refCount += tp->memBlock->shadowing->refNum;
2040
else if(tp->memBlock->shadowed)
2042
refCount += tp->memBlock->shadowed->refNum;
2047
// Hmmm, last reference. If we haven't already done so,
2048
// save the context, just in case
2049
tl_assert(!tp->memBlock->maybeLast ||
2050
(tp->memBlock->maybeLast == tp));
2051
if(!tp->memBlock->maybeLast)
2053
tp->memBlock->maybeLast = tp;
2054
tp->memBlock->funcEnd = VG_(record_ExeContext)(VG_(get_running_tid)(),
2055
0/*first_ip_delta*/);
2056
O_MDEBUG("setting maybeLast to %p in block at %p",
2057
FROM_TRACKED_KEY(tp->hdr.key), tp->block);
2059
#if defined(O_MASTER_DEBUG)
2062
O_MDEBUG("leaving maybeLast at %p in block at %p",
2063
FROM_TRACKED_KEY(tp->hdr.key), tp->block);
2067
O_MDEBUG("leaving register %p", OFFSET_FROM_REG(a));
2070
/*------------------------------------------------------------*/
2071
/*--- Helper functions called by instrumentation ---*/
2072
/*------------------------------------------------------------*/
2073
#if defined(O_TRACK_LOADS)
2074
static VG_REGPARM(1)
2075
void o_omegaLoadTracker( Addr address )
2077
O_MDEBUG("o_omegaLoadTracker(%p, %p)", address, *((Addr *)address));
2083
static VG_REGPARM(2)
2084
void o_omegaScratchRemover( Addr start, Addr length )
2086
O_MDEBUG("o_omegaScratchRemover(%p, %p)", start, length);
2087
o_killRange(start, length);
2092
static VG_REGPARM(1)
2093
void o_endOfInstruction( Addr address )
2096
** Any generated leaks should report immediately.
2100
O_MDEBUG("o_endOfInstruction %p doLeakListCount = %d",
2101
address, doLeakListCount);
2105
if(doLeakListCount > 1)
2108
** Reverse the list so the reports come out in the correct order.
2110
MemBlock *front = NULL;
2111
MemBlock *temp = NULL;
2115
temp = doLeakList->next;
2119
doLeakList->next = front;
2123
doLeakList->next = NULL;
2132
** Now do the leak reports.
2137
front = front->next;
2141
temp->doLeak = False;
2142
o_doLeakReport(temp);
2146
O_MDEBUG("block at %p survived!", temp->hdr.key);
2152
if(doLeakList->doLeak)
2155
** The block has leaked. Report it.
2157
o_doLeakReport(doLeakList);
2161
O_MDEBUG("block at %p survived!", doLeakList->hdr.key);
2164
doLeakList->doLeak = False;
2169
O_MDEBUG("o_endOfInstruction done");
2171
o_indirectStack = NULL;
2172
doLeakListCount = 0;
2177
void o_omegaFunctionReturn( void )
2183
** Zap scratch registers.
2186
#if defined(VGA_x86)
2187
a = o_firstPBit(&pb,
2188
MAP_TO_REG(VG_(get_running_tid)(), OFFSET_x86_ECX),
2189
OFFSET_x86_EDI + 4);
2190
#elif defined(VGA_amd64)
2191
a = o_firstPBit(&pb,
2192
MAP_TO_REG(VG_(get_running_tid)(), OFFSET_amd64_RCX),
2193
OFFSET_amd64_R15 + 8);
2198
if(o_isReturnIgnoreReg(OFFSET_FROM_REG(a)))
2200
O_MDEBUG("killing register %p", OFFSET_FROM_REG(a));
2201
o_killTrackedPointer(a);
2203
a = o_nextPBit(&pb);
2208
** Now work out if we might be returning a value in the accumulator.
2210
#if defined(VGA_x86)
2211
a = MAP_TO_REG(VG_(get_running_tid)(), OFFSET_x86_EAX);
2212
#elif defined(VGA_amd64)
2213
a = MAP_TO_REG(VG_(get_running_tid)(), OFFSET_amd64_RAX);
2216
o_setupMaybeLast(a);
2218
#if defined(VGA_amd64)
2219
// Also need to check for the RDX register as it is a second return reg
2220
a = MAP_TO_REG(VG_(get_running_tid)(), OFFSET_amd64_RDX);
2222
o_setupMaybeLast(a);
2227
static VG_REGPARM(2)
2228
void o_omegaDetector( Addr address, Addr value)
2230
TrackedPointer *tp = NULL;
2231
MemBlock *mb = NULL;
2234
** We need to track the registers.
2235
** To do this, if the address < 256, change it to our local shadow.
2237
** We really want to be able to track the proper shadow but I have no
2238
** idea yet how to get the address for it. Once I do, use that in
2239
** preference. Note that all we need is a unique memory location for
2240
** the register in order to generate a tracked pointer.
2244
O_MDEBUG("o_omegaDetector(%p, %p)", address, value);
2245
address = MAP_TO_REG(VG_(get_running_tid)(), address);
2250
** Check aligned - if not, align it and retrive the stored value.
2252
if(address & ~TRACK_MINOR_MASK)
2254
address &= TRACK_MINOR_MASK;
2255
value = *((Addr *)address);
2257
O_MDEBUG("o_omegaDetector(%p, %p)", address, value);
2261
** Done the alignment tweaks so do the more expensive lookups.
2263
if(o_isPBitSet(address))
2265
tp = VG_(HT_lookup)(o_TrackedPointers, TRACKED_KEY(address));
2267
if(tp && (tp->block == value))
2270
** Unlikely but it seems that we are writing the same value back into
2271
** the tracked pointer - don't process further for a small gain.
2273
//O_DEBUG("writing duplicate into tracked pointer.");
2278
** We always auto shadow.
2279
** Note that auto shadowing only works if you overwrite a tracked pointer.
2280
** Checking for the creation of a new tracked pointer at some internal
2281
** address is too much overhead as we would have to scan backwards to find
2282
** a memory block then check if the value is within it. For those cases,
2283
** we need to get something going with the client request system.
2287
if(o_setupShadow(tp, value))
2294
** Remove the tracked pointer and clear the PBit,
2299
tl_assert(tp->hdr.key == TRACKED_KEY(address));
2300
O_MDEBUG("Removing tracked pointer to %p at %p",
2301
tp->block, FROM_TRACKED_KEY(tp->hdr.key));
2302
o_clearPBit(address);
2303
o_removeMemBlockReference(NULL, tp);
2308
** Get the mem block now - it might not exist if tp was the last
2309
** reference to it. It might not exist anyway.
2313
mb = VG_(HT_lookup)(o_MemBlocks, value);
2317
** If we have a memblock, clean the tracked pointer then add it.
2318
** If not, free the tracked pointer.
2325
** No tracked pointer - create one now.
2327
tp = VG_(malloc)(sizeof(TrackedPointer));
2329
o_stats.trackedPointersAllocated++;
2330
o_stats.liveTrackedPointers++;
2332
VG_(memset)(tp, 0, sizeof(TrackedPointer));
2333
tp->hdr.key = TRACKED_KEY(address);
2334
o_addMemBlockReference(mb, tp);
2336
** Set the PBit for this tracked pointer.
2340
O_MDEBUG("Added tracked pointer to %p at %p",
2341
tp->block, FROM_TRACKED_KEY(tp->hdr.key));
2347
o_stats.liveTrackedPointers--;
2353
/*------------------------------------------------------------*/
2354
/*--- malloc() et al replacement wrappers ---*/
2355
/*------------------------------------------------------------*/
2358
void* o_newBlock ( ThreadId tid, SizeT size, SizeT align, Bool is_zeroed )
2363
#if defined(O_MASTER_DEBUG)
2366
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 8);O_DEBUG("");
2370
O_MDEBUG("newBlock(%d, %d, %d, %d)",
2377
** Allocate and zero if necessary.
2379
p = VG_(cli_malloc)( align, size );
2382
O_DEBUG("Out of memory!");
2383
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
2391
VG_(memset)(p, 0, size);
2394
if(!o_onlyMallocLike)
2397
** Create a new MemBlock.
2399
o_createMemBlock(tid, (Addr)p, size);
2402
O_MDEBUG("o_newBlock returning %p", p);
2408
void o_dieBlock ( ThreadId tid, void* p )
2411
** Free off the allocated memory block.
2413
O_MDEBUG("o_dieBlock(%d, %p)", tid, p);
2416
** Check if we have a potentially valid pointer
2424
** If we are doing malloc like block handling, only free off the memory.
2426
if(!o_onlyMallocLike)
2428
o_destroyMemBlock(tid, (Addr)p);
2432
** Actually free the heap block.
2439
static void* o_malloc ( ThreadId tid, SizeT n )
2441
return o_newBlock( tid, n, VG_(clo_alignment), /*is_zeroed*/False );
2444
static void* o__builtin_new ( ThreadId tid, SizeT n )
2446
return o_newBlock( tid, n, VG_(clo_alignment), /*is_zeroed*/False );
2449
static void* o__builtin_vec_new ( ThreadId tid, SizeT n )
2451
return o_newBlock( tid, n, VG_(clo_alignment), /*is_zeroed*/False );
2454
static void* o_calloc ( ThreadId tid, SizeT m, SizeT size )
2456
return o_newBlock( tid, m*size, VG_(clo_alignment), /*is_zeroed*/True );
2459
static void *o_memalign ( ThreadId tid, SizeT align, SizeT n )
2461
return o_newBlock( tid, n, align, False );
2464
static void o_free ( ThreadId tid, void* p )
2466
o_dieBlock( tid, p );
2469
static void o__builtin_delete ( ThreadId tid, void* p )
2471
o_dieBlock( tid, p );
2474
static void o__builtin_vec_delete ( ThreadId tid, void* p )
2476
o_dieBlock( tid, p );
2479
static void* o_realloc ( ThreadId tid, void* p_old, SizeT new_size )
2481
MemBlock *mb = NULL;
2484
O_MDEBUG("o_realloc p_old %p, new_size %d",
2490
** Pointer == NULL so let new block do the work.
2492
return o_newBlock(tid, new_size, VG_(clo_alignment), /*is_zeroed*/False);
2495
mb = VG_(HT_lookup)(o_MemBlocks, (Addr)p_old);
2498
** Check that we have this memory block.
2503
** Log the bad call but return p_old so the program can continue.
2504
** This might not be a good thing but some of the libraries are a
2505
** little weird and returning NULL as per the spec blows them up...
2507
O_DEBUG("Invalid call to realloc(%p)", p_old);
2508
VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), VG_(clo_backtrace_size));
2517
** Seems that the block didnt leak after all.
2519
if(o_addSuppressionBlock(mb->where, mb->leaked) && !o_showSummaryOnly)
2521
O_DEBUG("Welcome back to the supposedly leaked block at %p",
2525
o_stats.memoryBlocksLeaked--;
2526
o_stats.memoryBlocksLostAndFound++;
2531
if(new_size > mb->length)
2534
** Make a new block, copy the data into it then free the old block.
2535
** We lose all tracked pointers but that is to be expected as this is
2536
** a new block at a new address. However, any tracked pointers within
2537
** must be preserved.
2540
p_new = o_newBlock(tid, new_size, VG_(clo_alignment), False);
2543
VG_(memcpy)(p_new, p_old, mb->length);
2545
o_duplicateTrackedPointers((Addr)p_new, (Addr)p_old, mb->length);
2550
** Return the existing block.
2557
** This will remove all of the old tracked pointers within.
2559
o_dieBlock(tid, p_old);
2564
static void o_dieMemStack(Addr start, SizeT length)
2567
** Flag that this is a stack unwind.
2569
o_stackUnwind = True;
2570
o_killRange(start, length);
2571
o_stackUnwind = False;
2574
static void o_post_clo_init(void)
2577
** Allocate the hash tables.
2578
** Note that we can improve performance at the cost of memory by initialising
2579
** with a larger prime number so more of the key part of the address is
2580
** unique. The defaults are probably OK for many programs but we expose them
2581
** on the command line to make it easier for users to change them.
2583
o_PBits = VG_(HT_construct)( "omega pbits" );
2586
o_MemBlocks = VG_(HT_construct)( "omega memblocks" );
2587
tl_assert(o_MemBlocks);
2589
o_TrackedPointers = VG_(HT_construct)( "omega tracked ptrs" );
2590
tl_assert(o_TrackedPointers);
2593
** We need precise instructions so that we can work out the range of the
2594
** original machine instruction in terms of grouping together lumps of IR.
2595
** We lose out big time on optimisation but we have to take the hit in order
2596
** to deal with instructions like pop and xchg.
2598
VG_(clo_vex_control).iropt_precise_memory_exns = True;
2603
o_instrument(VgCallbackClosure* closure,
2605
VexGuestLayout* layout,
2606
VexGuestExtents* vge,
2607
IRType gWordTy, IRType hWordTy)
2614
IRStmt* stackReg = NULL;
2616
#if 0 //defined(O_MASTER_DEBUG)
2618
static int thisBlock = 0;
2620
if(thisBlock == 11377)
2624
else if(thisBlock == 11390)
2626
VG_(tool_panic)("hit stop block");
2630
if (gWordTy != hWordTy)
2632
/* We don't currently support this case. */
2633
VG_(tool_panic)("host/guest word size mismatch");
2640
bb->tyenv = deepCopyIRTypeEnv(bb_in->tyenv);
2641
bb->next = deepCopyIRExpr(bb_in->next);
2642
bb->jumpkind = bb_in->jumpkind;
2644
#if (VG_WORDSIZE == 4)
2647
#elif (VG_WORDSIZE == 8)
2652
for (i = 0; i < bb_in->stmts_used; i++)
2654
IRStmt* st = bb_in->stmts[i];
2655
if (!st || st->tag == Ist_NoOp)
2666
** An area just went undefined. There may be pointers in this
2667
** scratch area that we should now ignore.
2668
** Make sure that we do so.
2672
addStmtToIRSB( bb, stackReg );
2675
di = unsafeIRDirty_0_N( 2, "o_omegaScratchRemover",
2676
&o_omegaScratchRemover,
2677
mkIRExprVec_2(st->Ist.AbiHint.base,
2678
mkIRExpr_HWord(st->Ist.AbiHint.len)));
2680
** Add in the original instruction second.
2682
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2688
addStmtToIRSB( bb, stackReg );
2691
if(typeOfIRExpr(bb->tyenv, st->Ist.Store.addr) == type)
2694
** We have an address of native size.
2696
if(typeOfIRExpr(bb->tyenv, st->Ist.Store.data) == type)
2699
** We have data of native size - check if this is a pointer being
2702
di = unsafeIRDirty_0_N( 2, "o_omegaDetector", &o_omegaDetector,
2703
mkIRExprVec_2(st->Ist.Store.addr,
2704
st->Ist.Store.data));
2706
** Add in the original instruction second.
2708
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2709
addStmtToIRSB( bb, st );
2715
** There is no way that the data is a pointer but we still have to
2716
** check if a pointer will be overwritten.
2718
di = unsafeIRDirty_0_N( 2, "o_omegaDetector", &o_omegaDetector,
2719
mkIRExprVec_2(st->Ist.Store.addr,
2720
mkIRExpr_HWord(0)));
2722
** Add in the original instruction first.
2724
addStmtToIRSB( bb, st );
2725
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2731
O_GDEBUG("o_instrument address type(%p) not a pointer",
2732
typeOfIRExpr(bb->tyenv, st->Ist.Store.addr));
2739
** Call the end of instruction callback. This is to check what actually
2740
** leaked as opposed to what appeared to leak in a transient fashion
2741
** due to instructions getting broken up into more simple IR
2742
** instructions. Note that stack register updates are moved to
2743
** the end of the orginal instruction so that things like 'pop' get
2744
** the values into registers BEFORE the stack is invalidated.
2748
addStmtToIRSB( bb, stackReg );
2751
di = unsafeIRDirty_0_N( 1, "o_endOfInstruction", &o_endOfInstruction,
2752
mkIRExprVec_1(mkIRExpr_HWord(st->Ist.IMark.addr)));
2753
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2754
addStmtToIRSB( bb, st );
2755
#if defined(VGA_x86)
2757
** Make sure the EIP sim cpu register gets updated or our stack
2758
** traces go a little Pete Tong...
2759
** If this duplicates, the ir optimisation will knock one of them out.
2761
addStmtToIRSB( bb, IRStmt_Put(OFFSET_x86_EIP,
2762
mkIRExpr_HWord(st->Ist.IMark.addr)));
2769
** Track the general purpose registers.
2771
switch(st->Ist.Put.offset & mask)
2773
#if defined(VGA_x86)
2774
case OFFSET_x86_ESP:
2775
#elif defined(VGA_amd64)
2776
case OFFSET_amd64_RSP:
2779
** Save the stack register update - we will add it at the end of
2786
#if defined(VGA_x86)
2788
case OFFSET_x86_EAX:
2789
case OFFSET_x86_EBX:
2790
case OFFSET_x86_ECX:
2791
case OFFSET_x86_EDX:
2792
case OFFSET_x86_ESI:
2793
case OFFSET_x86_EDI:
2794
case OFFSET_x86_EBP:
2796
#if 0 //defined(O_MASTER_DEBUG)
2797
case OFFSET_x86_EIP:
2800
#elif defined(VGA_amd64)
2802
case OFFSET_amd64_RAX:
2803
case OFFSET_amd64_RBX:
2804
case OFFSET_amd64_RCX:
2805
case OFFSET_amd64_RDX:
2806
case OFFSET_amd64_RSI:
2807
case OFFSET_amd64_RDI:
2808
case OFFSET_amd64_RBP:
2809
case OFFSET_amd64_R8:
2810
case OFFSET_amd64_R9:
2811
case OFFSET_amd64_R10:
2812
case OFFSET_amd64_R11:
2813
case OFFSET_amd64_R12:
2814
case OFFSET_amd64_R13:
2815
case OFFSET_amd64_R14:
2816
case OFFSET_amd64_R15:
2818
#if 0 //defined(O_MASTER_DEBUG)
2819
case OFFSET_amd64_RIP:
2822
#elif defined(VGA_ppc32) || defined(VGA_ppc64)
2824
VG_(printf)("\nOmega does not currently work on PowerPC/POWER platforms."
2833
if(typeOfIRExpr(bb->tyenv, st->Ist.Put.data) == type)
2836
** This is a put to a register in the simulated processor of data
2837
** that could be a pointer.
2839
di = unsafeIRDirty_0_N( 2, "o_omegaDetector", &o_omegaDetector,
2840
mkIRExprVec_2(mkIRExpr_HWord(st->Ist.Put.offset),
2846
** There is no way that the data is a pointer but we still have
2847
** to check if a pointer in a register will be overwritten.
2849
di = unsafeIRDirty_0_N( 2, "o_omegaDetector", &o_omegaDetector,
2850
mkIRExprVec_2(mkIRExpr_HWord(st->Ist.Put.offset),
2851
mkIRExpr_HWord(0)));
2854
** Add in the original instruction first.
2856
addStmtToIRSB( bb, st );
2857
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2860
break; // Register Cases
2864
#if defined(O_TRACK_LOADS)
2867
** Debug to see how 'leaked' references survive.
2868
** (From experience, mostly through illegal reads from
2869
** free()ed blocks.)
2871
if(st->Ist.Tmp.data->tag == Iex_Load)
2873
if(typeOfIRExpr(bb->tyenv, st->Ist.Tmp.data->Iex.Load.addr) == type)
2875
di = unsafeIRDirty_0_N( 1, "o_omegaLoadTracker", &o_omegaLoadTracker,
2876
mkIRExprVec_1(st->Ist.Tmp.data->Iex.Load.addr));
2878
** Add in the original instruction first.
2880
addStmtToIRSB( bb, st );
2881
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2893
** Add in the original instruction if we havent already done so.
2897
addStmtToIRSB( bb, st );
2903
addStmtToIRSB( bb, stackReg );
2907
if(bb->jumpkind == Ijk_Ret)
2910
** The client is doing a return. This is the point to invalidate
2911
** registers that belong to the callee, possibly generating a
2912
** leak report. This is to catch things like foo(malloc(128)).
2915
di = unsafeIRDirty_0_N( 0, "o_omegaFunctionReturn",
2916
&o_omegaFunctionReturn,
2919
** Add in the new instruction.
2921
addStmtToIRSB( bb, IRStmt_Dirty(di) );
2927
/*------------------------------------------------------------*/
2928
/*--- Client Request Handling ---*/
2929
/*------------------------------------------------------------*/
2930
static Bool o_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
2932
if (!VG_IS_TOOL_USERREQ('O','M',arg[0]) &&
2933
VG_USERREQ__MALLOCLIKE_BLOCK != arg[0] &&
2934
VG_USERREQ__FREELIKE_BLOCK != arg[0])
2939
case VG_USERREQ__ENTERING_MAIN:
2942
** Allow leak reports whilst inside main().
2944
o_inhibitLeakDetect = False;
2948
case VG_USERREQ__LEAVING_MAIN:
2951
** Stop any more leak reports - they won't be helpfull.
2953
o_inhibitLeakDetect = True;
2960
case VG_USERREQ__MALLOCLIKE_BLOCK:
2962
if(o_onlyMallocLike)
2965
** Either we use malloc like block or we don't.
2966
** Trying to auto track and do malloc like block handling together
2967
** is asking for trouble.
2969
Addr p = (Addr)arg[1];
2970
SizeT size = arg[2];
2972
o_createMemBlock(tid, p, size);
2977
case VG_USERREQ__FREELIKE_BLOCK:
2979
if(o_onlyMallocLike)
2982
** Either we use malloc like block or we don't.
2983
** Trying to auto track and do malloc like block handling together
2984
** is asking for trouble.
2986
Addr p = (Addr)arg[1];
2988
o_destroyMemBlock(tid, p);
2997
/*------------------------------------------------------------*/
2998
/*--- Circular Reference Detection ---*/
2999
/*------------------------------------------------------------*/
3001
** Check for circular references. This is where a memory block holds a
3002
** reference to another memory block and vice versa but there are no
3003
** references that are external. Like this:
3014
p1 = (block *)malloc(sizeof(block));
3015
p2 = (block *)malloc(sizeof(block));
3017
p1->linkedBlock = p2;
3018
p2->linkedBlock = p1;
3020
** As you can see, the blocks wont be seen to leak because they have a live
3021
** reference but the reality is that without an external reference, these
3022
** blocks are lost to the system.
3024
** To perform this test, we go through the following stages:
3026
** 1) Generate a binary tree of the memory covered by the allocated blocks
3027
** 2) Check every tracked pointer of every allocated block and mark the
3028
** block if any of them fall outside of an allocated block.
3029
** 3) For each block with an external pointer, recursivly walk through the
3030
** internal pointers to other blocks, marking the blocks as also having
3031
** an external pointer.
3032
** 4) Report any blocks without external references.
3036
typedef struct _TreeNode{
3040
struct _TreeNode *left;
3041
struct _TreeNode *right;
3044
static TreeNode *o_treeRoot = NULL;
3045
static MemBlock **o_memblockList = NULL;
3046
static UInt o_memblockListCount = 0;
3047
static BlockRecordList o_circularRecords = {NULL, NULL};
3050
TreeNode *o_findTreeNode(Addr addr, TreeNode *start, TreeNode ***parent)
3053
** Find the treenode that this address falls within and return it.
3054
** Return NULL if no matching node is found and return the parent if it is
3059
** If the treeRoot is NULL, we won't be finding anything.
3065
*parent = &o_treeRoot;
3072
** The start should be a valid node.
3076
if((addr >= start->start) &&
3077
(addr <= start->end))
3085
if(addr < start->start)
3088
** Less than - go left if we can, return NULL if we can't.
3092
return o_findTreeNode(addr, start->left, parent);
3098
*parent = &start->left;
3107
** Greater than - go right if we can, return NULL if we can't.
3111
return o_findTreeNode(addr, start->right, parent);
3117
*parent = &start->right;
3124
VG_(tool_panic)("fell out of the binary tree");
3127
static UInt o_buildMemblockTree(void)
3130
** Build a binary tree of the addresses covered by the memory blocks.
3131
** We dont do anything to balance things so this could decompose to a
3132
** linear structure. Thankfully, we are not in a time critical section.
3136
o_memblockList = (MemBlock **)VG_(HT_to_array)(o_MemBlocks,
3137
&o_memblockListCount);
3139
for(indx = 0; indx < o_memblockListCount; indx++)
3141
TreeNode **parent = NULL;
3142
TreeNode *tn = NULL;
3143
MemBlock *mb = o_memblockList[indx];
3146
** Only process main blocks that havent leaked.
3148
if(!mb->shadowing && !mb->leaked)
3150
if(o_findTreeNode(mb->hdr.key, o_treeRoot, &parent))
3152
VG_(tool_panic)("Failed to grow the binary tree.");
3156
** We should have a pointer to the parent
3161
** Create and populate the new node
3163
tn = VG_(malloc)(sizeof(TreeNode));
3164
VG_(memset)(tn, 0, sizeof(TreeNode));
3166
tn->start = mb->hdr.key;
3167
tn->end = tn->start + mb->length;
3171
** Add this node into the parent node
3177
return o_memblockListCount;
3180
static void o_checkExternalPointers(void)
3184
for(indx = 0; indx < o_memblockListCount; indx++)
3186
MemBlock *mb = o_memblockList[indx];
3189
** Only check blocks that haven't leaked.
3190
** We process through shadow blocks because we want the back references
3191
** as they still point within the shadowed block.
3197
for(pointerIndex = 0; pointerIndex < mb->refNum; pointerIndex++)
3199
if(!o_findTreeNode(FROM_TRACKED_KEY(mb->pointers[pointerIndex]->hdr.key),
3203
** External reference. Mark the block and stop checking.
3213
static void o_rippleExternelPointers(MemBlock *mb)
3220
** Iterate through the memory block list marking external blocks
3221
** so that we dont process the same blocks twice.
3223
for(indx = 0; indx < o_memblockListCount; indx++)
3225
if(o_memblockList[indx]->external > 0)
3227
o_memblockList[indx]->external = -1;
3228
o_rippleExternelPointers(o_memblockList[indx]);
3235
** We are recursing.
3236
** Follow any tracked pointers within our block, marking the target
3237
** blocks as external and recursing on those blocks.
3241
TreeNode *tn = NULL;
3243
a = o_firstPBit(&pb, mb->hdr.key, mb->length);
3246
tn = o_findTreeNode(a, o_treeRoot, NULL);
3249
** We really should have a node
3254
** If we havent already done so, mark the block as external and
3255
** processed then recurse on it.
3257
if(tn->block->external >= 0)
3259
tn->block->external = -1;
3260
o_rippleExternelPointers(tn->block);
3264
** Get the next tracked pointer within this block.
3266
a = o_nextPBit(&pb);
3271
static int o_reportCircularBlocks(void)
3274
BlockRecord *block = NULL;
3278
** Iterate through the memory block list reporting any blocks not marked
3280
** We aggregate the list of blocks as many could come from the same context.
3282
for(indx = 0; indx < o_memblockListCount; indx++)
3284
MemBlock * mb = o_memblockList[indx];
3285
if(!mb->shadowing && !mb->leaked && mb->external == 0)
3287
block = o_findBlockRecord(&o_circularRecords, mb->where, NULL);
3292
** Just increment the counts.
3294
block->bytes += mb->length;
3300
** Create a new block and add it to the circular records list.
3302
BlockRecord *item = VG_(malloc)(sizeof(BlockRecord));
3306
item->bytes = mb->length;
3307
item->next = item->prev = NULL;
3308
item->allocated = mb->where;
3309
item->leaked = NULL;
3311
o_addBlockRecord(&o_circularRecords, item);
3317
** Now report the blocks.
3319
block = o_circularRecords.start;
3324
VG_(message)(Vg_UserMsg, "The following blocks only have circular references from other blocks");
3328
VG_(message)(Vg_UserMsg, " Circular loss record %d", count);
3329
VG_(message)(Vg_UserMsg, " Leaked %d (%p) bytes in %d block%sallocated",
3333
(block->count == 1) ? " " : "s ");
3334
VG_(pp_ExeContext)(block->allocated);
3335
VG_(message)(Vg_UserMsg,"");
3338
** Get the next block, if any.
3340
block = block->next;
3346
static int o_checkCircular(void)
3351
** If there is nothing in the tree, there is nothing to check.
3353
if(o_buildMemblockTree())
3355
o_checkExternalPointers();
3356
o_rippleExternelPointers(NULL);
3357
count = o_reportCircularBlocks();
3363
static void o_fini(Int exitcode)
3366
** Iterate through the leaked block record list,
3367
** printing out the stats as we go.
3370
BlockRecord *record = o_leakRecords.start;
3372
VG_(message)(Vg_UserMsg,"");
3373
VG_(message)(Vg_UserMsg,"");
3374
VG_(message)(Vg_UserMsg,"Omega Leak Summary");
3375
VG_(message)(Vg_UserMsg,"==================");
3379
VG_(message)(Vg_UserMsg,
3380
"Loss Record %d: Leaked %d (%p) bytes in %d block%s",
3381
count, record->bytes, record->bytes, record->count,
3382
(record->count > 1) ? "s" : "");
3383
VG_(pp_ExeContext)(record->leaked);
3384
VG_(message)(Vg_UserMsg, " Block%s allocated",
3385
(record->count > 1) ? "s" : "");
3386
VG_(pp_ExeContext)(record->allocated);
3387
VG_(message)(Vg_UserMsg,"");
3390
record = record->next;
3396
** Now check for circular references.
3398
count += o_checkCircular();
3404
** Nothing leaked - assure the user.
3406
VG_(message)(Vg_UserMsg,"No leaks to report.");
3407
VG_(message)(Vg_UserMsg,"");
3411
** Remove the leaked blocks from the live blocks count - they wont be
3412
** coming back now...
3414
o_stats.liveMemoryBlocks -= o_stats.memoryBlocksLeaked;
3416
if(o_showInternStats)
3418
VG_(printf)("\n\n\n"
3419
"Omega internal statistics summary:\n"
3420
" Tracked Pointers still live: %ld\n"
3421
" Tracked Pointers Allocated: %ld\n"
3422
" Memory Blocks still live: %ld\n"
3423
" Memory Blocks Allocated: %ld\n"
3424
" Shadow Memory Blocks Allocated: %ld\n"
3425
" Memory Blocks Leaked: %ld\n"
3426
" Memory Blocks Lost and Found: %ld\n"
3427
" pbitNodes: %ld\n\n",
3428
o_stats.liveTrackedPointers,
3429
o_stats.trackedPointersAllocated,
3430
o_stats.liveMemoryBlocks,
3431
o_stats.memoryBlocksAllocated,
3432
o_stats.shadowMemoryBlocksAllocated,
3433
o_stats.memoryBlocksLeaked,
3434
o_stats.memoryBlocksLostAndFound,
3439
static Bool o_process_cmd_line_option(Char *arg)
3442
** Setup our processing state based upon what the user would like us to do.
3449
** Expose the hash sizes for simple performance tweaking.
3451
VG_NUM_CLO(arg, "--pbithashsize", pbithash);
3452
VG_NUM_CLO(arg, "--mbhashsize", mbhash);
3453
VG_NUM_CLO(arg, "--tphashsize", tphash);
3456
** Only tweak upwards for now.
3458
if(pbithash > o_pbitNodeHashSize)
3459
o_pbitNodeHashSize = pbithash;
3461
if(mbhash > o_memblockHashSize)
3462
o_memblockHashSize = mbhash;
3464
if(tphash > o_trackedPointerHashSize)
3465
o_trackedPointerHashSize = tphash;
3470
if(VG_CLO_STREQ(arg, "--only-malloclike"))
3471
o_onlyMallocLike = True;
3472
else if(VG_CLO_STREQ(arg, "--show-indirect"))
3473
o_showIndirect = True;
3474
else if(VG_CLO_STREQ(arg, "--show-circular"))
3475
o_showCircular = True;
3476
else if(VG_CLO_STREQ(arg, "--show-hanging"))
3477
o_showHanging = True;
3478
else if(VG_CLO_STREQ(arg, "--show-intern-stats"))
3479
o_showInternStats = True;
3480
else if(VG_CLO_STREQ(arg, "--instant-reports"))
3481
o_showSummaryOnly = False;
3482
else if(VG_CLO_STREQ(arg, "--poison"))
3485
return VG_(replacement_malloc_process_cmd_line_option)(arg);
3490
static void o_print_usage(void)
3493
** Tell the average user what we support.
3497
" --only-malloclike only track blocks passed through the\n"
3498
" MALLOCLIKE_BLOCK user request.\n"
3499
" --show-indirect show indirect leaks from leaked blocks.\n"
3500
" --show-circular show blocks that just have circular references.\n"
3501
" --instant-reports show leaks as they happen, not just a summary.\n"
3502
" --show-hanging show hanging pointers to the block being\n"
3508
static void o_print_debug_usage(void)
3511
** Tell the inquisitive user what else we support.
3515
" --show-intern-stats show some internal statistics from the run.\n"
3517
" IMPORTANT! These next settings must be PRIME NUMBERS\n"
3519
" --pbithashsize=<number> number of pbit nodes to allocate [%d]\n"
3520
" --mbhashsize=<number> number of mem block nodes to allocate [%d]\n"
3521
" --tphashsize=<number> number of tracked pointer nodes to allocate [%d]\n",
3524
o_trackedPointerHashSize
3528
static void o_memRemapSupport(Addr src, Addr dst, SizeT length)
3531
** The track_copy_mem_remap callback has the src and dst the opposite
3532
** way around to our duplicate tracked pointers function so this tiny
3533
** wrapper twizzles them around.
3535
o_duplicateTrackedPointers(dst, src, length);
3538
static void o_pre_clo_init(void)
3541
VG_(details_name) ("exp-omega");
3542
VG_(details_version) ("RC1");
3543
VG_(details_description) ("an instant memory leak detector");
3544
VG_(details_copyright_author)("Copyright (C) 2006-2007, and GNU GPL'd, "
3545
"by Bryan Meredith.");
3546
VG_(details_bug_reports_to) ("richard.coe@med.ge.com");
3549
VG_(basic_tool_funcs) (o_post_clo_init,
3553
VG_(needs_malloc_replacement) (o_malloc,
3560
o__builtin_vec_delete,
3563
// Want stack unwinds
3564
VG_(track_die_mem_stack) (o_dieMemStack);
3565
// Need command line input
3566
VG_(needs_command_line_options) (o_process_cmd_line_option,
3568
o_print_debug_usage);
3569
// Support MALLOCLIKE and FREELIKE
3570
VG_(needs_client_requests) (o_handle_client_request);
3572
// Wholesale destruction of memory ranges
3573
VG_(track_copy_mem_remap) (o_memRemapSupport );
3574
VG_(track_die_mem_stack_signal)(o_killRange);
3575
VG_(track_die_mem_brk) (o_killRange);
3576
VG_(track_die_mem_munmap) (o_killRange);
3580
VG_DETERMINE_INTERFACE_VERSION(o_pre_clo_init);
3582
/*--------------------------------------------------------------------*/
3584
/*--------------------------------------------------------------------*/