1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/trace-malloc/lib/nsWinTraceMalloc.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,252 @@ 1.4 +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include <stdio.h> 1.11 +#include <stdlib.h> 1.12 + 1.13 +#include "prinrval.h" 1.14 +#include "prlock.h" 1.15 +#include "nscore.h" 1.16 + 1.17 +#include "nsDebugHelpWin32.h" 1.18 +#include "nsTraceMallocCallbacks.h" 1.19 + 1.20 +/***************************************************************************/ 1.21 +// shows how to use the dhw stuff to hook imported functions 1.22 + 1.23 +#if _MSC_VER < 1300 1.24 +#define NS_DEBUG_CRT "MSVCRTD.dll" 1.25 +#elif _MSC_VER == 1300 1.26 +#define NS_DEBUG_CRT "msvcr70d.dll" 1.27 +#elif _MSC_VER == 1310 1.28 +#define NS_DEBUG_CRT "msvcr71d.dll" 1.29 +#elif _MSC_VER == 1400 1.30 +#define NS_DEBUG_CRT "msvcr80d.dll" 1.31 +#elif _MSC_VER == 1500 1.32 +#define NS_DEBUG_CRT "msvcr90d.dll" 1.33 +#elif _MSC_VER == 1600 1.34 +#define NS_DEBUG_CRT "msvcr100d.dll" 1.35 +#elif _MSC_VER == 1700 1.36 +#define NS_DEBUG_CRT "msvcr110d.dll" 1.37 +#elif _MSC_VER == 1800 1.38 +#define NS_DEBUG_CRT "msvcr120d.dll" 1.39 +#else 1.40 +#error "Don't know filename of MSVC debug library." 1.41 +#endif 1.42 + 1.43 +decltype(malloc) dhw_malloc; 1.44 + 1.45 +DHWImportHooker &getMallocHooker() 1.46 +{ 1.47 + static DHWImportHooker gMallocHooker(NS_DEBUG_CRT, "malloc", (PROC) dhw_malloc); 1.48 + return gMallocHooker; 1.49 +} 1.50 + 1.51 +void * __cdecl dhw_malloc( size_t size ) 1.52 +{ 1.53 + tm_thread *t = tm_get_thread(); 1.54 + ++t->suppress_tracing; 1.55 + uint32_t start = PR_IntervalNow(); 1.56 + void* result = DHW_ORIGINAL(malloc, getMallocHooker())(size); 1.57 + uint32_t end = PR_IntervalNow(); 1.58 + --t->suppress_tracing; 1.59 + MallocCallback(result, size, start, end, t); 1.60 + return result; 1.61 +} 1.62 + 1.63 +decltype(calloc) dhw_calloc; 1.64 + 1.65 +DHWImportHooker &getCallocHooker() 1.66 +{ 1.67 + static DHWImportHooker gCallocHooker(NS_DEBUG_CRT, "calloc", (PROC) dhw_calloc); 1.68 + return gCallocHooker; 1.69 +} 1.70 + 1.71 +void * __cdecl dhw_calloc( size_t count, size_t size ) 1.72 +{ 1.73 + tm_thread *t = tm_get_thread(); 1.74 + ++t->suppress_tracing; 1.75 + uint32_t start = PR_IntervalNow(); 1.76 + void* result = DHW_ORIGINAL(calloc, getCallocHooker())(count,size); 1.77 + uint32_t end = PR_IntervalNow(); 1.78 + --t->suppress_tracing; 1.79 + CallocCallback(result, count, size, start, end, t); 1.80 + return result; 1.81 +} 1.82 + 1.83 +decltype(free) dhw_free; 1.84 +DHWImportHooker &getFreeHooker() 1.85 +{ 1.86 + static DHWImportHooker gFreeHooker(NS_DEBUG_CRT, "free", (PROC) dhw_free); 1.87 + return gFreeHooker; 1.88 +} 1.89 + 1.90 +void __cdecl dhw_free( void* p ) 1.91 +{ 1.92 + tm_thread *t = tm_get_thread(); 1.93 + ++t->suppress_tracing; 1.94 + uint32_t start = PR_IntervalNow(); 1.95 + DHW_ORIGINAL(free, getFreeHooker())(p); 1.96 + uint32_t end = PR_IntervalNow(); 1.97 + --t->suppress_tracing; 1.98 + /* FIXME bug 392008: We could race with reallocation of p. */ 1.99 + FreeCallback(p, start, end, t); 1.100 +} 1.101 + 1.102 + 1.103 +decltype(realloc) dhw_realloc; 1.104 +DHWImportHooker &getReallocHooker() 1.105 +{ 1.106 + static DHWImportHooker gReallocHooker(NS_DEBUG_CRT, "realloc", (PROC) dhw_realloc); 1.107 + return gReallocHooker; 1.108 +} 1.109 + 1.110 +void * __cdecl dhw_realloc(void * pin, size_t size) 1.111 +{ 1.112 + tm_thread *t = tm_get_thread(); 1.113 + ++t->suppress_tracing; 1.114 + uint32_t start = PR_IntervalNow(); 1.115 + void* pout = DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); 1.116 + uint32_t end = PR_IntervalNow(); 1.117 + --t->suppress_tracing; 1.118 + /* FIXME bug 392008: We could race with reallocation of pin. */ 1.119 + ReallocCallback(pin, pout, size, start, end, t); 1.120 + return pout; 1.121 +} 1.122 + 1.123 +// Note the mangled name! 1.124 +void * __cdecl dhw_new(size_t size); 1.125 +DHWImportHooker &getNewHooker() 1.126 +{ 1.127 + static DHWImportHooker gNewHooker(NS_DEBUG_CRT, "??2@YAPAXI@Z", (PROC) dhw_new); 1.128 + return gNewHooker; 1.129 +} 1.130 + 1.131 +void * __cdecl dhw_new(size_t size) 1.132 +{ 1.133 + tm_thread *t = tm_get_thread(); 1.134 + ++t->suppress_tracing; 1.135 + uint32_t start = PR_IntervalNow(); 1.136 + void* result = DHW_ORIGINAL(dhw_new, getNewHooker())(size); 1.137 + uint32_t end = PR_IntervalNow(); 1.138 + --t->suppress_tracing; 1.139 + MallocCallback(result, size, start, end, t);//do we need a different one for new? 1.140 + return result; 1.141 +} 1.142 + 1.143 +// Note the mangled name! 1.144 +void __cdecl dhw_delete(void* p); 1.145 +DHWImportHooker &getDeleteHooker() 1.146 +{ 1.147 + static DHWImportHooker gDeleteHooker(NS_DEBUG_CRT, "??3@YAXPAX@Z", (PROC) dhw_delete); 1.148 + return gDeleteHooker; 1.149 +} 1.150 + 1.151 +void __cdecl dhw_delete(void* p) 1.152 +{ 1.153 + tm_thread *t = tm_get_thread(); 1.154 + ++t->suppress_tracing; 1.155 + uint32_t start = PR_IntervalNow(); 1.156 + DHW_ORIGINAL(dhw_delete, getDeleteHooker())(p); 1.157 + uint32_t end = PR_IntervalNow(); 1.158 + --t->suppress_tracing; 1.159 + FreeCallback(p, start, end, t); 1.160 +} 1.161 + 1.162 +// Note the mangled name! 1.163 +void * __cdecl dhw_vec_new(size_t size); 1.164 +DHWImportHooker &getVecNewHooker() 1.165 +{ 1.166 + static DHWImportHooker gVecNewHooker(NS_DEBUG_CRT, "??_U@YAPAXI@Z", (PROC) dhw_vec_new); 1.167 + return gVecNewHooker; 1.168 +} 1.169 + 1.170 +void * __cdecl dhw_vec_new(size_t size) 1.171 +{ 1.172 + tm_thread *t = tm_get_thread(); 1.173 + ++t->suppress_tracing; // need to suppress since new[] calls new 1.174 + uint32_t start = PR_IntervalNow(); 1.175 + void* result = DHW_ORIGINAL(dhw_vec_new, getVecNewHooker())(size); 1.176 + uint32_t end = PR_IntervalNow(); 1.177 + --t->suppress_tracing; 1.178 + MallocCallback(result, size, start, end, t);//do we need a different one for new[]? 1.179 + return result; 1.180 +} 1.181 + 1.182 +// Note the mangled name! 1.183 +void __cdecl dhw_vec_delete(void* p); 1.184 +DHWImportHooker &getVecDeleteHooker() 1.185 +{ 1.186 + static DHWImportHooker gVecDeleteHooker(NS_DEBUG_CRT, "??_V@YAXPAX@Z", (PROC) dhw_vec_delete); 1.187 + return gVecDeleteHooker; 1.188 +} 1.189 + 1.190 +void __cdecl dhw_vec_delete(void* p) 1.191 +{ 1.192 + tm_thread *t = tm_get_thread(); 1.193 + ++t->suppress_tracing; 1.194 + uint32_t start = PR_IntervalNow(); 1.195 + DHW_ORIGINAL(dhw_vec_delete, getVecDeleteHooker())(p); 1.196 + uint32_t end = PR_IntervalNow(); 1.197 + --t->suppress_tracing; 1.198 + FreeCallback(p, start, end, t); 1.199 +} 1.200 + 1.201 +/*C Callbacks*/ 1.202 +PR_IMPLEMENT(void) 1.203 +StartupHooker() 1.204 +{ 1.205 + //run through get all hookers 1.206 + DHWImportHooker &loadlibraryW = DHWImportHooker::getLoadLibraryWHooker(); 1.207 + DHWImportHooker &loadlibraryExW = DHWImportHooker::getLoadLibraryExWHooker(); 1.208 + DHWImportHooker &loadlibraryA = DHWImportHooker::getLoadLibraryAHooker(); 1.209 + DHWImportHooker &loadlibraryExA = DHWImportHooker::getLoadLibraryExAHooker(); 1.210 + DHWImportHooker &mallochooker = getMallocHooker(); 1.211 + DHWImportHooker &reallochooker = getReallocHooker(); 1.212 + DHWImportHooker &callochooker = getCallocHooker(); 1.213 + DHWImportHooker &freehooker = getFreeHooker(); 1.214 + DHWImportHooker &newhooker = getNewHooker(); 1.215 + DHWImportHooker &deletehooker = getDeleteHooker(); 1.216 + DHWImportHooker &vecnewhooker = getVecNewHooker(); 1.217 + DHWImportHooker &vecdeletehooker = getVecDeleteHooker(); 1.218 + printf("Startup Hooker\n"); 1.219 +} 1.220 + 1.221 +PR_IMPLEMENT(void) 1.222 +ShutdownHooker() 1.223 +{ 1.224 +} 1.225 + 1.226 +extern "C" { 1.227 + void* dhw_orig_malloc(size_t); 1.228 + void* dhw_orig_calloc(size_t, size_t); 1.229 + void* dhw_orig_realloc(void*, size_t); 1.230 + void dhw_orig_free(void*); 1.231 +} 1.232 + 1.233 +void* 1.234 +dhw_orig_malloc(size_t size) 1.235 +{ 1.236 + return DHW_ORIGINAL(malloc, getMallocHooker())(size); 1.237 +} 1.238 + 1.239 +void* 1.240 +dhw_orig_calloc(size_t count, size_t size) 1.241 +{ 1.242 + return DHW_ORIGINAL(calloc, getCallocHooker())(count,size); 1.243 +} 1.244 + 1.245 +void* 1.246 +dhw_orig_realloc(void* pin, size_t size) 1.247 +{ 1.248 + return DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); 1.249 +} 1.250 + 1.251 +void 1.252 +dhw_orig_free(void* p) 1.253 +{ 1.254 + DHW_ORIGINAL(free, getFreeHooker())(p); 1.255 +}