1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Static class for hooking Win32 API routines. For now,
6 // we only add one watcher at a time.
8 // TODO(mbelshe): Support multiple watchers.
10 #ifndef MEMORY_WATCHER_MEMORY_HOOK_
11 #define MEMORY_WATCHER_MEMORY_HOOK_
13 #include "base/logging.h"
15 // When allocating memory for internal use with the MemoryHook,
16 // we must always use the MemoryHook's heap; otherwise, the memory
17 // gets tracked, and it becomes an infinite loop (allocation() calls
18 // MemoryHook() which calls allocation(), etc).
20 // PrivateHookAllocator is an STL-friendly Allocator so that STL lists,
21 // maps, etc can be used on the global MemoryHook's heap.
23 class PrivateHookAllocator
{
25 // These type definitions are needed for stl allocators.
26 typedef size_t size_type
;
27 typedef ptrdiff_t difference_type
;
29 typedef const T
* const_pointer
;
31 typedef const T
& const_reference
;
34 PrivateHookAllocator() {}
36 // Allocate memory for STL.
37 pointer
allocate(size_type n
, const void * = 0) {
38 return reinterpret_cast<T
*>(MemoryHook::Alloc(n
* sizeof(T
)));
41 // Deallocate memory for STL.
42 void deallocate(void* p
, size_type
) {
47 // Construct the object
48 void construct(pointer p
, const T
& val
) {
49 new (reinterpret_cast<T
*>(p
))T(val
);
53 void destroy(pointer p
) { p
->~T(); }
55 size_type
max_size() const { return size_t(-1); }
58 struct rebind
{ typedef PrivateHookAllocator
<U
> other
; };
61 PrivateHookAllocator(const PrivateHookAllocator
<U
>&) {}
64 template<class T
, class U
> inline
65 bool operator==(const PrivateHookAllocator
<T
>&,
66 const PrivateHookAllocator
<U
>&) {
70 template<class T
, class U
> inline
71 bool operator!=(const PrivateHookAllocator
<T
>& left
,
72 const PrivateHookAllocator
<U
>& right
) {
73 return (!(left
== right
));
77 // Classes which monitor memory from these hooks implement
78 // the MemoryObserver interface.
79 class MemoryObserver
{
81 virtual ~MemoryObserver() {}
83 // Track a pointer. Will capture the current StackTrace.
84 virtual void OnTrack(HANDLE heap
, int32 id
, int32 size
) = 0;
86 // Untrack a pointer, removing it from our list.
87 virtual void OnUntrack(HANDLE heap
, int32 id
, int32 size
) = 0;
90 class MemoryHook
: MemoryObserver
{
92 // Initialize the MemoryHook. Must be called before
93 // registering watchers. This can be called repeatedly,
94 // but is not thread safe.
95 static bool Initialize();
97 // Returns true is memory allocations and deallocations
99 static bool hooked() { return hooked_
!= NULL
; }
101 // Register a class to receive memory allocation & deallocation
102 // callbacks. If we haven't hooked memory yet, this call will
103 // force memory hooking to start.
104 static bool RegisterWatcher(MemoryObserver
* watcher
);
106 // Register a class to stop receiving callbacks. If there are
107 // no more watchers, this call will unhook memory.
108 static bool UnregisterWatcher(MemoryObserver
* watcher
);
110 // MemoryHook provides a private heap for allocating
112 static void* Alloc(size_t size
) {
113 DCHECK(global_hook_
&& global_hook_
->heap_
);
114 return HeapAlloc(global_hook_
->heap_
, 0, size
);
116 static void Free(void* ptr
) {
117 DCHECK(global_hook_
&& global_hook_
->heap_
);
118 HeapFree(global_hook_
->heap_
, 0, ptr
);
121 // Access the global hook. For internal use only from static "C"
123 static MemoryHook
* hook() { return global_hook_
; }
125 // MemoryObserver interface.
126 virtual void OnTrack(HANDLE hHeap
, int32 id
, int32 size
);
127 virtual void OnUntrack(HANDLE hHeap
, int32 id
, int32 size
);
133 // Enable memory tracing. When memory is 'hooked',
134 // MemoryWatchers which have registered will be called
135 // as memory is allocated and deallocated.
138 // Disables memory tracing.
139 static bool Unhook();
141 // Create our private heap
144 // Close our private heap.
147 MemoryObserver
* watcher_
;
148 HANDLE heap_
; // An internal accounting heap.
150 static MemoryHook
* global_hook_
;
153 #endif // MEMORY_WATCHER_MEMORY_HOOK_