diff options
author | glider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-16 09:15:05 +0000 |
---|---|---|
committer | glider@chromium.org <glider@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-16 09:15:05 +0000 |
commit | 9beaf2987dfc53dc150ac8c22336ea5046da005c (patch) | |
tree | 691df5aca5967b5827c7040fc579230a4d674500 /third_party/tcmalloc/chromium/src/windows | |
parent | 59e2c39984b9a34bbb72db1f3a02be171dc9726d (diff) | |
download | chromium_src-9beaf2987dfc53dc150ac8c22336ea5046da005c.zip chromium_src-9beaf2987dfc53dc150ac8c22336ea5046da005c.tar.gz chromium_src-9beaf2987dfc53dc150ac8c22336ea5046da005c.tar.bz2 |
Revert 38882 - Land http://codereview.chromium.org/576001 again temporarily.
TBR=jar,antonm
Review URL: http://codereview.chromium.org/596083
TBR=glider@chromium.org
Review URL: http://codereview.chromium.org/604063
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39083 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/tcmalloc/chromium/src/windows')
4 files changed, 106 insertions, 218 deletions
diff --git a/third_party/tcmalloc/chromium/src/windows/config.h b/third_party/tcmalloc/chromium/src/windows/config.h index 99de82c..b3a6852 100644 --- a/third_party/tcmalloc/chromium/src/windows/config.h +++ b/third_party/tcmalloc/chromium/src/windows/config.h @@ -175,9 +175,6 @@ /* define if your compiler has __attribute__ */ #undef HAVE___ATTRIBUTE__ -/* Define to 1 if compiler supports __environ */ -#undef HAVE___ENVIRON - /* Define to 1 if the system has the type `__int64'. */ #define HAVE___INT64 1 diff --git a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h index 4b97b15..15a2e19 100644 --- a/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h +++ b/third_party/tcmalloc/chromium/src/windows/google/tcmalloc.h @@ -90,7 +90,6 @@ extern "C" { #endif #ifdef __cplusplus - PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW; PERFTOOLS_DLL_DECL void* tc_new(size_t size); PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW; PERFTOOLS_DLL_DECL void* tc_newarray(size_t size); diff --git a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc b/third_party/tcmalloc/chromium/src/windows/patch_functions.cc index c1ed37f..d0e54ff 100644 --- a/third_party/tcmalloc/chromium/src/windows/patch_functions.cc +++ b/third_party/tcmalloc/chromium/src/windows/patch_functions.cc @@ -72,21 +72,9 @@ #error This file is intended for patching allocators - use override_functions.cc instead. #endif -// We use psapi. Non-MSVC systems will have to link this in themselves. -#ifdef _MSC_VER -#pragma comment(lib, "Psapi.lib") -#endif - -// Make sure we always use the 'old' names of the psapi functions. -#ifndef PSAPI_VERSION -#define PSAPI_VERSION 1 -#endif - #include <windows.h> #include <malloc.h> // for _msize and _expand -#include <Psapi.h> // for EnumProcessModules, GetModuleInformation, etc. -#include <set> -#include <map> +#include <tlhelp32.h> // for CreateToolhelp32Snapshot() #include <vector> #include <base/logging.h> #include "base/spinlock.h" @@ -94,10 +82,10 @@ #include "malloc_hook-inl.h" #include "preamble_patcher.h" -// The maximum number of modules we allow to be in one executable -const int kMaxModules = 8182; -// The maximum size of a module's basename -const int kMaxModuleNameSize = 256; +// MinGW doesn't seem to define this, perhaps some windowsen don't either. +#ifndef TH32CS_SNAPMODULE32 +#define TH32CS_SNAPMODULE32 0 +#endif // These are hard-coded, unfortunately. :-( They are also probably // compiler specific. See get_mangled_names.cc, in this directory, @@ -129,8 +117,6 @@ typedef void (*GenericFnPtr)(); using sidestep::PreamblePatcher; -struct ModuleEntryCopy; // defined below - // These functions are how we override the memory allocation // functions, just like tcmalloc.cc and malloc_hook.cc do. @@ -145,19 +131,33 @@ class LibcInfo { LibcInfo() { memset(this, 0, sizeof(*this)); // easiest way to initialize the array } - bool SameAs(const LibcInfo& that) const; - bool SameAsModuleEntry(const ModuleEntryCopy& module_entry) const; - + bool SameAs(const LibcInfo& that) const { + return (is_valid() && + module_base_address_ == that.module_base_address_ && + module_base_size_ == that.module_base_size_); + } + bool SameAsME32(const MODULEENTRY32& me32) const { + return (is_valid() && + module_base_address_ == me32.modBaseAddr && + module_base_size_ == me32.modBaseSize); + } bool patched() const { return is_valid() && module_name_[0] != '\0'; } const char* module_name() const { return is_valid() ? module_name_ : ""; } void set_is_valid(bool b) { is_valid_ = b; } + // These shouldn't have to be public, since only subclasses of + // LibcInfo need it, but they do. Maybe something to do with + // templates. Shrug. + bool is_valid() const { return is_valid_; } + GenericFnPtr windows_fn(int ifunction) const { + return windows_fn_[ifunction]; + } + // Populates all the windows_fn_[] vars based on our module info. // Returns false if windows_fn_ is all NULL's, because there's - // nothing to patch. Also populates the rest of the module_entry - // info, such as the module's name. - bool PopulateWindowsFn(const ModuleEntryCopy& module_entry); + // nothing to patch. Also populates the me32 info. + bool PopulateWindowsFn(const MODULEENTRY32& me32); protected: void CopyFrom(const LibcInfo& that) { @@ -207,25 +207,7 @@ class LibcInfo { const void *module_base_address_; size_t module_base_size_; - char module_name_[kMaxModuleNameSize]; - - public: - // These shouldn't have to be public, since only subclasses of - // LibcInfo need it, but they do. Maybe something to do with - // templates. Shrug. I hide them down here so users won't see - // them. :-) (OK, I also need to define ctrgProcAddress late.) - bool is_valid() const { return is_valid_; } - GenericFnPtr windows_fn(int ifunction) const { - return windows_fn_[ifunction]; - } - // These three are needed by ModuleEntryCopy. - static const int ctrgProcAddress = kNumFunctions; - static GenericFnPtr static_fn(int ifunction) { - return static_fn_[ifunction]; - } - static const char* const function_name(int ifunction) { - return function_name_[ifunction]; - } + char module_name_[MAX_MODULE_NAME32 + 1]; }; // Template trickiness: logically, a LibcInfo would include @@ -283,43 +265,6 @@ template<int> class LibcInfoWithPatchFunctions : public LibcInfo { // But they seem pretty obscure, and I'm fine not overriding them for now. }; -// This is a subset of MODDULEENTRY32, that we need for patching. -struct ModuleEntryCopy { - LPVOID modBaseAddr; - DWORD modBaseSize; - HMODULE hModule; - TCHAR szModule[kMaxModuleNameSize]; - // This is not part of MODDULEENTRY32, but is needed to avoid making - // windows syscalls while we're holding patch_all_modules_lock (see - // lock-inversion comments at patch_all_modules_lock definition, below). - GenericFnPtr rgProcAddresses[LibcInfo::ctrgProcAddress]; - - ModuleEntryCopy() { - modBaseAddr = NULL; - modBaseSize = 0; - hModule = NULL; - strcpy(szModule, "<executable>"); - for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) - rgProcAddresses[i] = LibcInfo::static_fn(i); - } - ModuleEntryCopy(HANDLE hprocess, HMODULE hmodule, const MODULEINFO& mi) { - this->modBaseAddr = mi.lpBaseOfDll; - this->modBaseSize = mi.SizeOfImage; - this->hModule = hmodule; - // TODO(csilvers): we could make more efficient by calling these - // lazily (not until the vars are needed, which is often never). - // However, there's tricky business with calling windows functions - // inside the patch_all_modules_lock (see the lock inversion - // comments with the patch_all_modules_lock definition, below), so - // it's safest to do it all here, where no lock is needed. - ::GetModuleBaseNameA(hprocess, hmodule, - this->szModule, sizeof(this->szModule)); - for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) - rgProcAddresses[i] = - (GenericFnPtr)::GetProcAddress(hModule, LibcInfo::function_name(i)); - } -}; - // This class is easier because there's only one of them. class WindowsInfo { public: @@ -373,11 +318,6 @@ class WindowsInfo { // If you run out, just add a few more to the array. You'll also need // to update the switch statement in PatchOneModule(), and the list in // UnpatchWindowsFunctions(). -// main_executable and main_executable_windows are two windows into -// the same executable. One is responsible for patching the libc -// routines that live in the main executable (if any) to use tcmalloc; -// the other is responsible for patching the windows routines like -// HeapAlloc/etc to use tcmalloc. static LibcInfoWithPatchFunctions<0> main_executable; static LibcInfoWithPatchFunctions<1> libc1; static LibcInfoWithPatchFunctions<2> libc2; @@ -387,7 +327,7 @@ static LibcInfoWithPatchFunctions<5> libc5; static LibcInfoWithPatchFunctions<6> libc6; static LibcInfoWithPatchFunctions<7> libc7; static LibcInfoWithPatchFunctions<8> libc8; -static LibcInfo* g_module_libcs[] = { +static LibcInfo* module_libcs[] = { &libc1, &libc2, &libc3, &libc4, &libc5, &libc6, &libc7, &libc8 }; static WindowsInfo main_executable_windows; @@ -479,28 +419,24 @@ const GenericFnPtr LibcInfoWithPatchFunctions<T>::perftools_fn_[] = { { "FreeLibrary", NULL, NULL, (GenericFnPtr)&Perftools_FreeLibrary }, }; -bool LibcInfo::SameAs(const LibcInfo& that) const { - return (is_valid() && - module_base_address_ == that.module_base_address_ && - module_base_size_ == that.module_base_size_); -} - -bool LibcInfo::SameAsModuleEntry(const ModuleEntryCopy& module_entry) const { - return (is_valid() && - module_base_address_ == module_entry.modBaseAddr && - module_base_size_ == module_entry.modBaseSize); -} +bool LibcInfo::PopulateWindowsFn(const MODULEENTRY32& me32) { + module_base_address_ = me32.modBaseAddr; + module_base_size_ = me32.modBaseSize; + strcpy(module_name_, me32.szModule); -bool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) { // First, store the location of the function to patch before // patching it. If none of these functions are found in the module, // then this module has no libc in it, and we just return false. for (int i = 0; i < kNumFunctions; i++) { if (!function_name_[i]) // we can turn off patching by unsetting name continue; - // The ::GetProcAddress calls were done in the ModuleEntryCopy - // constructor, so we don't have to make any windows calls here. - const GenericFnPtr fn = module_entry.rgProcAddresses[i]; + GenericFnPtr fn = NULL; + if (me32.hModule == NULL) { // used for the main executable + // This is used only for a statically-linked-in libc. + fn = static_fn_[i]; + } else { + fn = (GenericFnPtr)::GetProcAddress(me32.hModule, function_name_[i]); + } if (fn) { windows_fn_[i] = PreamblePatcher::ResolveTarget(fn); } @@ -526,9 +462,9 @@ bool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) { // need to set our windows_fn to NULL, to avoid double-patching. for (int ifn = 0; ifn < kNumFunctions; ifn++) { for (int imod = 0; - imod < sizeof(g_module_libcs)/sizeof(*g_module_libcs); imod++) { - if (g_module_libcs[imod]->is_valid() && - this->windows_fn(ifn) == g_module_libcs[imod]->windows_fn(ifn)) { + imod < sizeof(module_libcs)/sizeof(*module_libcs); imod++) { + if (module_libcs[imod]->is_valid() && + this->windows_fn(ifn) == module_libcs[imod]->windows_fn(ifn)) { windows_fn_[ifn] = NULL; } } @@ -551,33 +487,17 @@ bool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) { // haven't needed to yet. CHECK(windows_fn_[kFree]); CHECK(windows_fn_[kRealloc]); - - // OK, we successfully patched. Let's store our member information. - module_base_address_ = module_entry.modBaseAddr; - module_base_size_ = module_entry.modBaseSize; - strcpy(module_name_, module_entry.szModule); return true; } template<int T> bool LibcInfoWithPatchFunctions<T>::Patch(const LibcInfo& me_info) { - CopyFrom(me_info); // copies the module_entry and the windows_fn_ array + CopyFrom(me_info); // copies the me32 and the windows_fn_ array for (int i = 0; i < kNumFunctions; i++) { - if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) { - // if origstub_fn_ is not NULL, it's left around from a previous - // patch. We need to set it to NULL for the new Patch call. - // Since we've patched Unpatch() not to delete origstub_fn_ (it - // causes problems in some contexts, though obviously not this - // one), we should delete it now, before setting it to NULL. - // NOTE: casting from a function to a pointer is contra the C++ - // spec. It's not safe on IA64, but is on i386. We use - // a C-style cast here to emphasize this is not legal C++. - delete[] (char*)(origstub_fn_[i]); - origstub_fn_[i] = NULL; // Patch() will fill this in + if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) CHECK_EQ(sidestep::SIDESTEP_SUCCESS, PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i], &origstub_fn_[i])); - } } set_is_valid(true); return true; @@ -606,16 +526,6 @@ void WindowsInfo::Patch() { for (int i = 0; i < kNumFunctions; i++) { function_info_[i].windows_fn = (GenericFnPtr) ::GetProcAddress(hkernel32, function_info_[i].name); - // If origstub_fn is not NULL, it's left around from a previous - // patch. We need to set it to NULL for the new Patch call. - // Since we've patched Unpatch() not to delete origstub_fn_ (it - // causes problems in some contexts, though obviously not this - // one), we should delete it now, before setting it to NULL. - // NOTE: casting from a function to a pointer is contra the C++ - // spec. It's not safe on IA64, but is on i386. We use - // a C-style cast here to emphasize this is not legal C++. - delete[] (char*)(function_info_[i].origstub_fn); - function_info_[i].origstub_fn = NULL; // Patch() will fill this in CHECK_EQ(sidestep::SIDESTEP_SUCCESS, PreamblePatcher::Patch(function_info_[i].windows_fn, function_info_[i].perftools_fn, @@ -637,10 +547,10 @@ void WindowsInfo::Unpatch() { // You should hold the patch_all_modules_lock when calling this. void PatchOneModuleLocked(const LibcInfo& me_info) { // Double-check we haven't seen this module before. - for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) { - if (g_module_libcs[i]->SameAs(me_info)) { - fprintf(stderr, "%s:%d: FATAL PERFTOOLS ERROR: %s double-patched somehow.\n", - __FILE__, __LINE__, g_module_libcs[i]->module_name()); + for (int i = 0; i < sizeof(module_libcs)/sizeof(*module_libcs); i++) { + if (module_libcs[i]->SameAs(me_info)) { + fprintf(stderr, "%s:%d: FATAL ERROR: %s double-patched somehow.\n", + __FILE__, __LINE__, module_libcs[i]->module_name()); CHECK(false); } } @@ -648,8 +558,8 @@ void PatchOneModuleLocked(const LibcInfo& me_info) { // is where we're sad that each libcX has a different type, so we // can't use an array; instead, we have to use a switch statement. // Patch() returns false if there were no libc functions in the module. - for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) { - if (!g_module_libcs[i]->is_valid()) { // found an empty spot to add! + for (int i = 0; i < sizeof(module_libcs)/sizeof(*module_libcs); i++) { + if (!module_libcs[i]->is_valid()) { // found an empty spot to add! switch (i) { case 0: libc1.Patch(me_info); return; case 1: libc2.Patch(me_info); return; @@ -662,104 +572,88 @@ void PatchOneModuleLocked(const LibcInfo& me_info) { } } } - printf("PERFTOOLS ERROR: Too many modules containing libc in this executable\n"); + printf("ERROR: Too many modules containing libc in this executable\n"); } void PatchMainExecutableLocked() { if (main_executable.patched()) return; // main executable has already been patched - ModuleEntryCopy fake_module_entry; // make a fake one to pass into Patch() - // No need to call PopulateModuleEntryProcAddresses on the main executable. - main_executable.PopulateWindowsFn(fake_module_entry); + MODULEENTRY32 fake_me32; // we make a fake one to pass into Patch() + fake_me32.modBaseAddr = NULL; + fake_me32.modBaseSize = 0; + strcpy(fake_me32.szModule, "<executable>"); + fake_me32.hModule = NULL; + main_executable.PopulateWindowsFn(fake_me32); main_executable.Patch(main_executable); } -// This lock is subject to a subtle and annoying lock inversion -// problem: it may interact badly with unknown internal windows locks. -// In particular, windows may be holding a lock when it calls -// LoadLibraryExW and FreeLibrary, which we've patched. We have those -// routines call PatchAllModules, which acquires this lock. If we -// make windows system calls while holding this lock, those system -// calls may need the internal windows locks that are being held in -// the call to LoadLibraryExW, resulting in deadlock. The solution is -// to be very careful not to call *any* windows routines while holding -// patch_all_modules_lock, inside PatchAllModules(). static SpinLock patch_all_modules_lock(SpinLock::LINKER_INITIALIZED); // Iterates over all the modules currently loaded by the executable, // and makes sure they're all patched. For ones that aren't, we patch // them in. We also check that every module we had patched in the // past is still loaded, and update internal data structures if so. -// We return true if this PatchAllModules did any work, false else. -bool PatchAllModules() { - std::vector<ModuleEntryCopy> modules; - bool made_changes = false; - - const HANDLE hCurrentProcess = GetCurrentProcess(); - MODULEINFO mi; - DWORD cbNeeded = 0; - HMODULE hModules[kMaxModules]; // max # of modules we support in one process - if (::EnumProcessModules(hCurrentProcess, hModules, sizeof(hModules), - &cbNeeded)) { - for (int i = 0; i < cbNeeded / sizeof(*hModules); ++i) { - if (i >= kMaxModules) { - printf("PERFTOOLS ERROR: Too many modules in this executable to try" - " to patch them all (if you need to, raise kMaxModules in" - " patch_functions.cc).\n"); - break; - } - if (::GetModuleInformation(hCurrentProcess, hModules[i], &mi, sizeof(mi))) - modules.push_back(ModuleEntryCopy(hCurrentProcess, hModules[i], mi)); +void PatchAllModules() { + std::vector<LibcInfo*> modules; + bool still_loaded[sizeof(module_libcs)/sizeof(*module_libcs)] = {}; + + HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | + TH32CS_SNAPMODULE32, + GetCurrentProcessId()); + if (hModuleSnap != INVALID_HANDLE_VALUE) { + MODULEENTRY32 me32; + me32.dwSize = sizeof(me32); + if (Module32First(hModuleSnap, &me32)) { + do { + bool module_already_loaded = false; + for (int i = 0; i < sizeof(module_libcs)/sizeof(*module_libcs); i++) { + if (module_libcs[i]->SameAsME32(me32)) { + still_loaded[i] = true; + module_already_loaded = true; + break; + } + } + if (!module_already_loaded) { + LibcInfo* libc_info = new LibcInfo; + if (libc_info->PopulateWindowsFn(me32)) + modules.push_back(libc_info); + else // means module has no libc routines + delete libc_info; + } + } while (Module32Next(hModuleSnap, &me32)); } + CloseHandle(hModuleSnap); } - // Now do the actual patching and unpatching. + // Now do the actual patching. { SpinLockHolder h(&patch_all_modules_lock); - for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) { - if (!g_module_libcs[i]->is_valid()) - continue; - bool still_loaded = false; - for (std::vector<ModuleEntryCopy>::iterator it = modules.begin(); - it != modules.end(); ++it) { - if (g_module_libcs[i]->SameAsModuleEntry(*it)) { - // Both g_module_libcs[i] and it are still valid. Mark it by - // removing it from the vector; mark g_module_libcs[i] by - // setting a bool. - modules.erase(it); - still_loaded = true; - break; - } - } - if (!still_loaded) { - // Means g_module_libcs[i] is no longer loaded (no me32 matched). + // First, delete the modules that are no longer loaded. (We go first + // so we can try to open up space for the new modules we need to load.) + for (int i = 0; i < sizeof(module_libcs)/sizeof(*module_libcs); i++) { + if (!still_loaded[i]) { // We could call Unpatch() here, but why bother? The module // has gone away, so nobody is going to call into it anyway. - g_module_libcs[i]->set_is_valid(false); - made_changes = true; + module_libcs[i]->set_is_valid(false); } } - // We've handled all the g_module_libcs. Now let's handle the rest - // of the module-entries: those that haven't already been loaded. - for (std::vector<ModuleEntryCopy>::const_iterator it = modules.begin(); - it != modules.end(); ++it) { - LibcInfo libc_info; - if (libc_info.PopulateWindowsFn(*it)) { // true==module has libc routines - PatchOneModuleLocked(libc_info); // updates num_patched_modules - made_changes = true; - } + // Now, add in new modules that we need to load. + for (std::vector<LibcInfo*>::iterator it = modules.begin(); + it != modules.end(); ++it) { + PatchOneModuleLocked(**it); // updates num_patched_modules } // Now that we've dealt with the modules (dlls), update the main // executable. We do this last because PatchMainExecutableLocked // wants to look at how other modules were patched. - if (!main_executable.patched()) { - PatchMainExecutableLocked(); - made_changes = true; - } + PatchMainExecutableLocked(); + } + + for (std::vector<LibcInfo*>::iterator it = modules.begin(); + it != modules.end(); ++it) { + delete *it; } - return made_changes; } @@ -768,8 +662,6 @@ bool PatchAllModules() { // --------------------------------------------------------------------- // PatchWindowsFunctions() // This is the function that is exposed to the outside world. -// It should be called before the program becomes multi-threaded, -// since main_executable_windows.Patch() is not thread-safe. // --------------------------------------------------------------------- void PatchWindowsFunctions() { @@ -834,7 +726,7 @@ void UnpatchWindowsFunctions() { template<int T> void* LibcInfoWithPatchFunctions<T>::Perftools_malloc(size_t size) __THROW { - void* result = do_malloc_or_cpp_alloc(size); + void* result = do_malloc(size); MallocHook::InvokeNewHook(result, size); return result; } @@ -853,7 +745,7 @@ template<int T> void* LibcInfoWithPatchFunctions<T>::Perftools_realloc( void* old_ptr, size_t new_size) __THROW { if (old_ptr == NULL) { - void* result = do_malloc_or_cpp_alloc(new_size); + void* result = do_malloc(new_size); MallocHook::InvokeNewHook(result, new_size); return result; } @@ -960,7 +852,7 @@ template<int T> void* LibcInfoWithPatchFunctions<T>::Perftools__aligned_malloc(size_t size, size_t alignment) __THROW { - void* result = do_memalign_or_cpp_memalign(alignment, size); + void* result = do_memalign(alignment, size); MallocHook::InvokeNewHook(result, size); return result; } @@ -1035,7 +927,7 @@ HMODULE WINAPI WindowsInfo::Perftools_LoadLibraryExW(LPCWSTR lpFileName, HMODULE rv = ((HMODULE (WINAPI *)(LPCWSTR, HANDLE, DWORD)) function_info_[kLoadLibraryExW].origstub_fn)( lpFileName, hFile, dwFlags); - PatchAllModules(); + PatchAllModules(); // this will patch any newly loaded libraries return rv; } diff --git a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc b/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc index 78a4763..62b6e7f 100644 --- a/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc +++ b/third_party/tcmalloc/chromium/src/windows/preamble_patcher.cc @@ -316,7 +316,7 @@ SideStepError PreamblePatcher::Unpatch(void* target_function, // Stub is now useless so delete it. // [csilvers: Commented out for perftools because it causes big problems // when we're unpatching malloc. We just let this live on as a leak.] - //delete [] reinterpret_cast<unsigned char*>(original_function_stub); + //delete original_function_stub; // Restore the protection of the first MAX_PREAMBLE_STUB_SIZE bytes of // target to what they were before we started goofing around. |