Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #include <stdio.h> |
michael@0 | 8 | #include <stdlib.h> |
michael@0 | 9 | |
michael@0 | 10 | #include "prinrval.h" |
michael@0 | 11 | #include "prlock.h" |
michael@0 | 12 | #include "nscore.h" |
michael@0 | 13 | |
michael@0 | 14 | #include "nsDebugHelpWin32.h" |
michael@0 | 15 | #include "nsTraceMallocCallbacks.h" |
michael@0 | 16 | |
michael@0 | 17 | /***************************************************************************/ |
michael@0 | 18 | // shows how to use the dhw stuff to hook imported functions |
michael@0 | 19 | |
michael@0 | 20 | #if _MSC_VER < 1300 |
michael@0 | 21 | #define NS_DEBUG_CRT "MSVCRTD.dll" |
michael@0 | 22 | #elif _MSC_VER == 1300 |
michael@0 | 23 | #define NS_DEBUG_CRT "msvcr70d.dll" |
michael@0 | 24 | #elif _MSC_VER == 1310 |
michael@0 | 25 | #define NS_DEBUG_CRT "msvcr71d.dll" |
michael@0 | 26 | #elif _MSC_VER == 1400 |
michael@0 | 27 | #define NS_DEBUG_CRT "msvcr80d.dll" |
michael@0 | 28 | #elif _MSC_VER == 1500 |
michael@0 | 29 | #define NS_DEBUG_CRT "msvcr90d.dll" |
michael@0 | 30 | #elif _MSC_VER == 1600 |
michael@0 | 31 | #define NS_DEBUG_CRT "msvcr100d.dll" |
michael@0 | 32 | #elif _MSC_VER == 1700 |
michael@0 | 33 | #define NS_DEBUG_CRT "msvcr110d.dll" |
michael@0 | 34 | #elif _MSC_VER == 1800 |
michael@0 | 35 | #define NS_DEBUG_CRT "msvcr120d.dll" |
michael@0 | 36 | #else |
michael@0 | 37 | #error "Don't know filename of MSVC debug library." |
michael@0 | 38 | #endif |
michael@0 | 39 | |
michael@0 | 40 | decltype(malloc) dhw_malloc; |
michael@0 | 41 | |
michael@0 | 42 | DHWImportHooker &getMallocHooker() |
michael@0 | 43 | { |
michael@0 | 44 | static DHWImportHooker gMallocHooker(NS_DEBUG_CRT, "malloc", (PROC) dhw_malloc); |
michael@0 | 45 | return gMallocHooker; |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | void * __cdecl dhw_malloc( size_t size ) |
michael@0 | 49 | { |
michael@0 | 50 | tm_thread *t = tm_get_thread(); |
michael@0 | 51 | ++t->suppress_tracing; |
michael@0 | 52 | uint32_t start = PR_IntervalNow(); |
michael@0 | 53 | void* result = DHW_ORIGINAL(malloc, getMallocHooker())(size); |
michael@0 | 54 | uint32_t end = PR_IntervalNow(); |
michael@0 | 55 | --t->suppress_tracing; |
michael@0 | 56 | MallocCallback(result, size, start, end, t); |
michael@0 | 57 | return result; |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | decltype(calloc) dhw_calloc; |
michael@0 | 61 | |
michael@0 | 62 | DHWImportHooker &getCallocHooker() |
michael@0 | 63 | { |
michael@0 | 64 | static DHWImportHooker gCallocHooker(NS_DEBUG_CRT, "calloc", (PROC) dhw_calloc); |
michael@0 | 65 | return gCallocHooker; |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | void * __cdecl dhw_calloc( size_t count, size_t size ) |
michael@0 | 69 | { |
michael@0 | 70 | tm_thread *t = tm_get_thread(); |
michael@0 | 71 | ++t->suppress_tracing; |
michael@0 | 72 | uint32_t start = PR_IntervalNow(); |
michael@0 | 73 | void* result = DHW_ORIGINAL(calloc, getCallocHooker())(count,size); |
michael@0 | 74 | uint32_t end = PR_IntervalNow(); |
michael@0 | 75 | --t->suppress_tracing; |
michael@0 | 76 | CallocCallback(result, count, size, start, end, t); |
michael@0 | 77 | return result; |
michael@0 | 78 | } |
michael@0 | 79 | |
michael@0 | 80 | decltype(free) dhw_free; |
michael@0 | 81 | DHWImportHooker &getFreeHooker() |
michael@0 | 82 | { |
michael@0 | 83 | static DHWImportHooker gFreeHooker(NS_DEBUG_CRT, "free", (PROC) dhw_free); |
michael@0 | 84 | return gFreeHooker; |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | void __cdecl dhw_free( void* p ) |
michael@0 | 88 | { |
michael@0 | 89 | tm_thread *t = tm_get_thread(); |
michael@0 | 90 | ++t->suppress_tracing; |
michael@0 | 91 | uint32_t start = PR_IntervalNow(); |
michael@0 | 92 | DHW_ORIGINAL(free, getFreeHooker())(p); |
michael@0 | 93 | uint32_t end = PR_IntervalNow(); |
michael@0 | 94 | --t->suppress_tracing; |
michael@0 | 95 | /* FIXME bug 392008: We could race with reallocation of p. */ |
michael@0 | 96 | FreeCallback(p, start, end, t); |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | |
michael@0 | 100 | decltype(realloc) dhw_realloc; |
michael@0 | 101 | DHWImportHooker &getReallocHooker() |
michael@0 | 102 | { |
michael@0 | 103 | static DHWImportHooker gReallocHooker(NS_DEBUG_CRT, "realloc", (PROC) dhw_realloc); |
michael@0 | 104 | return gReallocHooker; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | void * __cdecl dhw_realloc(void * pin, size_t size) |
michael@0 | 108 | { |
michael@0 | 109 | tm_thread *t = tm_get_thread(); |
michael@0 | 110 | ++t->suppress_tracing; |
michael@0 | 111 | uint32_t start = PR_IntervalNow(); |
michael@0 | 112 | void* pout = DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); |
michael@0 | 113 | uint32_t end = PR_IntervalNow(); |
michael@0 | 114 | --t->suppress_tracing; |
michael@0 | 115 | /* FIXME bug 392008: We could race with reallocation of pin. */ |
michael@0 | 116 | ReallocCallback(pin, pout, size, start, end, t); |
michael@0 | 117 | return pout; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | // Note the mangled name! |
michael@0 | 121 | void * __cdecl dhw_new(size_t size); |
michael@0 | 122 | DHWImportHooker &getNewHooker() |
michael@0 | 123 | { |
michael@0 | 124 | static DHWImportHooker gNewHooker(NS_DEBUG_CRT, "??2@YAPAXI@Z", (PROC) dhw_new); |
michael@0 | 125 | return gNewHooker; |
michael@0 | 126 | } |
michael@0 | 127 | |
michael@0 | 128 | void * __cdecl dhw_new(size_t size) |
michael@0 | 129 | { |
michael@0 | 130 | tm_thread *t = tm_get_thread(); |
michael@0 | 131 | ++t->suppress_tracing; |
michael@0 | 132 | uint32_t start = PR_IntervalNow(); |
michael@0 | 133 | void* result = DHW_ORIGINAL(dhw_new, getNewHooker())(size); |
michael@0 | 134 | uint32_t end = PR_IntervalNow(); |
michael@0 | 135 | --t->suppress_tracing; |
michael@0 | 136 | MallocCallback(result, size, start, end, t);//do we need a different one for new? |
michael@0 | 137 | return result; |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | // Note the mangled name! |
michael@0 | 141 | void __cdecl dhw_delete(void* p); |
michael@0 | 142 | DHWImportHooker &getDeleteHooker() |
michael@0 | 143 | { |
michael@0 | 144 | static DHWImportHooker gDeleteHooker(NS_DEBUG_CRT, "??3@YAXPAX@Z", (PROC) dhw_delete); |
michael@0 | 145 | return gDeleteHooker; |
michael@0 | 146 | } |
michael@0 | 147 | |
michael@0 | 148 | void __cdecl dhw_delete(void* p) |
michael@0 | 149 | { |
michael@0 | 150 | tm_thread *t = tm_get_thread(); |
michael@0 | 151 | ++t->suppress_tracing; |
michael@0 | 152 | uint32_t start = PR_IntervalNow(); |
michael@0 | 153 | DHW_ORIGINAL(dhw_delete, getDeleteHooker())(p); |
michael@0 | 154 | uint32_t end = PR_IntervalNow(); |
michael@0 | 155 | --t->suppress_tracing; |
michael@0 | 156 | FreeCallback(p, start, end, t); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | // Note the mangled name! |
michael@0 | 160 | void * __cdecl dhw_vec_new(size_t size); |
michael@0 | 161 | DHWImportHooker &getVecNewHooker() |
michael@0 | 162 | { |
michael@0 | 163 | static DHWImportHooker gVecNewHooker(NS_DEBUG_CRT, "??_U@YAPAXI@Z", (PROC) dhw_vec_new); |
michael@0 | 164 | return gVecNewHooker; |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | void * __cdecl dhw_vec_new(size_t size) |
michael@0 | 168 | { |
michael@0 | 169 | tm_thread *t = tm_get_thread(); |
michael@0 | 170 | ++t->suppress_tracing; // need to suppress since new[] calls new |
michael@0 | 171 | uint32_t start = PR_IntervalNow(); |
michael@0 | 172 | void* result = DHW_ORIGINAL(dhw_vec_new, getVecNewHooker())(size); |
michael@0 | 173 | uint32_t end = PR_IntervalNow(); |
michael@0 | 174 | --t->suppress_tracing; |
michael@0 | 175 | MallocCallback(result, size, start, end, t);//do we need a different one for new[]? |
michael@0 | 176 | return result; |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | // Note the mangled name! |
michael@0 | 180 | void __cdecl dhw_vec_delete(void* p); |
michael@0 | 181 | DHWImportHooker &getVecDeleteHooker() |
michael@0 | 182 | { |
michael@0 | 183 | static DHWImportHooker gVecDeleteHooker(NS_DEBUG_CRT, "??_V@YAXPAX@Z", (PROC) dhw_vec_delete); |
michael@0 | 184 | return gVecDeleteHooker; |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | void __cdecl dhw_vec_delete(void* p) |
michael@0 | 188 | { |
michael@0 | 189 | tm_thread *t = tm_get_thread(); |
michael@0 | 190 | ++t->suppress_tracing; |
michael@0 | 191 | uint32_t start = PR_IntervalNow(); |
michael@0 | 192 | DHW_ORIGINAL(dhw_vec_delete, getVecDeleteHooker())(p); |
michael@0 | 193 | uint32_t end = PR_IntervalNow(); |
michael@0 | 194 | --t->suppress_tracing; |
michael@0 | 195 | FreeCallback(p, start, end, t); |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | /*C Callbacks*/ |
michael@0 | 199 | PR_IMPLEMENT(void) |
michael@0 | 200 | StartupHooker() |
michael@0 | 201 | { |
michael@0 | 202 | //run through get all hookers |
michael@0 | 203 | DHWImportHooker &loadlibraryW = DHWImportHooker::getLoadLibraryWHooker(); |
michael@0 | 204 | DHWImportHooker &loadlibraryExW = DHWImportHooker::getLoadLibraryExWHooker(); |
michael@0 | 205 | DHWImportHooker &loadlibraryA = DHWImportHooker::getLoadLibraryAHooker(); |
michael@0 | 206 | DHWImportHooker &loadlibraryExA = DHWImportHooker::getLoadLibraryExAHooker(); |
michael@0 | 207 | DHWImportHooker &mallochooker = getMallocHooker(); |
michael@0 | 208 | DHWImportHooker &reallochooker = getReallocHooker(); |
michael@0 | 209 | DHWImportHooker &callochooker = getCallocHooker(); |
michael@0 | 210 | DHWImportHooker &freehooker = getFreeHooker(); |
michael@0 | 211 | DHWImportHooker &newhooker = getNewHooker(); |
michael@0 | 212 | DHWImportHooker &deletehooker = getDeleteHooker(); |
michael@0 | 213 | DHWImportHooker &vecnewhooker = getVecNewHooker(); |
michael@0 | 214 | DHWImportHooker &vecdeletehooker = getVecDeleteHooker(); |
michael@0 | 215 | printf("Startup Hooker\n"); |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | PR_IMPLEMENT(void) |
michael@0 | 219 | ShutdownHooker() |
michael@0 | 220 | { |
michael@0 | 221 | } |
michael@0 | 222 | |
michael@0 | 223 | extern "C" { |
michael@0 | 224 | void* dhw_orig_malloc(size_t); |
michael@0 | 225 | void* dhw_orig_calloc(size_t, size_t); |
michael@0 | 226 | void* dhw_orig_realloc(void*, size_t); |
michael@0 | 227 | void dhw_orig_free(void*); |
michael@0 | 228 | } |
michael@0 | 229 | |
michael@0 | 230 | void* |
michael@0 | 231 | dhw_orig_malloc(size_t size) |
michael@0 | 232 | { |
michael@0 | 233 | return DHW_ORIGINAL(malloc, getMallocHooker())(size); |
michael@0 | 234 | } |
michael@0 | 235 | |
michael@0 | 236 | void* |
michael@0 | 237 | dhw_orig_calloc(size_t count, size_t size) |
michael@0 | 238 | { |
michael@0 | 239 | return DHW_ORIGINAL(calloc, getCallocHooker())(count,size); |
michael@0 | 240 | } |
michael@0 | 241 | |
michael@0 | 242 | void* |
michael@0 | 243 | dhw_orig_realloc(void* pin, size_t size) |
michael@0 | 244 | { |
michael@0 | 245 | return DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | void |
michael@0 | 249 | dhw_orig_free(void* p) |
michael@0 | 250 | { |
michael@0 | 251 | DHW_ORIGINAL(free, getFreeHooker())(p); |
michael@0 | 252 | } |