Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: tools/memory_watcher/memory_hook.cc

Issue 366031: Support running memory watch under vista, plus other tweaks... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/memory_watcher/memory_hook.h ('k') | tools/memory_watcher/memory_watcher.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Static class for hooking Win32 API routines. 5 // Static class for hooking Win32 API routines.
6 6
7 // Some notes about how to hook Memory Allocation Routines in Windows. 7 // Some notes about how to hook Memory Allocation Routines in Windows.
8 // 8 //
9 // For our purposes we do not hook the libc routines. There are two 9 // For our purposes we do not hook the libc routines. There are two
10 // reasons for this. First, the libc routines all go through HeapAlloc 10 // reasons for this. First, the libc routines all go through HeapAlloc
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 210 }
211 211
212 static LPVOID WINAPI Perftools_HeapReAlloc(HANDLE hHeap, DWORD dwFlags, 212 static LPVOID WINAPI Perftools_HeapReAlloc(HANDLE hHeap, DWORD dwFlags,
213 LPVOID lpMem, SIZE_T dwBytes) { 213 LPVOID lpMem, SIZE_T dwBytes) {
214 // Don't call realloc, but instead do a free/malloc. The problem is that 214 // Don't call realloc, but instead do a free/malloc. The problem is that
215 // the builtin realloc may either expand a buffer, or it may simply 215 // the builtin realloc may either expand a buffer, or it may simply
216 // just call free/malloc. If so, we will already have tracked the new 216 // just call free/malloc. If so, we will already have tracked the new
217 // block via Perftools_HeapAlloc. 217 // block via Perftools_HeapAlloc.
218 218
219 LPVOID rv = Perftools_HeapAlloc(hHeap, dwFlags, dwBytes); 219 LPVOID rv = Perftools_HeapAlloc(hHeap, dwFlags, dwBytes);
220 DCHECK_EQ((HEAP_REALLOC_IN_PLACE_ONLY & dwFlags), 0);
220 221
221 // If there was an old buffer, now copy the data to the new buffer. 222 // If there was an old buffer, now copy the data to the new buffer.
222 if (lpMem != 0) { 223 if (lpMem != 0) {
223 size_t size = HeapSize(hHeap, 0, lpMem); 224 size_t size = HeapSize(hHeap, 0, lpMem);
224 if (size > dwBytes) 225 if (size > dwBytes)
225 size = dwBytes; 226 size = dwBytes;
226 // Note: size could be 0; HeapAlloc does allocate 0 length buffers. 227 // Note: size could be 0; HeapAlloc does allocate 0 length buffers.
227 memcpy(rv, lpMem, size); 228 memcpy(rv, lpMem, size);
228 Perftools_HeapFree(hHeap, dwFlags, lpMem); 229 Perftools_HeapFree(hHeap, dwFlags, lpMem);
229 } 230 }
230 return rv; 231 return rv;
231 } 232 }
232 233
233 static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address, 234 static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address,
234 SIZE_T size, DWORD type, 235 SIZE_T size, DWORD type,
235 DWORD protect) { 236 DWORD protect) {
236 bool already_committed = false; 237 bool already_committed = false;
237 if (address != NULL) { 238 if (address != NULL) {
238 MEMORY_BASIC_INFORMATION info; 239 MEMORY_BASIC_INFORMATION info;
239 CHECK(VirtualQuery(address, &info, sizeof(info))); 240 CHECK(VirtualQuery(address, &info, sizeof(info)));
240 if (info.State & MEM_COMMIT) 241 if (info.State & MEM_COMMIT) {
241 already_committed = true; 242 already_committed = true;
243 CHECK(size >= info.RegionSize);
244 }
242 } 245 }
243 bool reserving = (address == NULL) || (type & MEM_RESERVE); 246 bool reserving = (address == NULL) || (type & MEM_RESERVE);
244 bool committing = !already_committed && (type & MEM_COMMIT); 247 bool committing = !already_committed && (type & MEM_COMMIT);
245 248
246 249
247 LPVOID result = patch_VirtualAllocEx()(process, address, size, type, 250 LPVOID result = patch_VirtualAllocEx()(process, address, size, type,
248 protect); 251 protect);
249 MEMORY_BASIC_INFORMATION info; 252 MEMORY_BASIC_INFORMATION info;
250 CHECK(VirtualQuery(result, &info, sizeof(info))); 253 CHECK(VirtualQuery(result, &info, sizeof(info)));
251 size = info.RegionSize; 254 size = info.RegionSize;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 HGLOBAL rv = patch_GlobalAlloc()(uFlags, dwBytes); 351 HGLOBAL rv = patch_GlobalAlloc()(uFlags, dwBytes);
349 return rv; 352 return rv;
350 } 353 }
351 354
352 static HGLOBAL WINAPI Perftools_GlobalFree(HGLOBAL hMem) { 355 static HGLOBAL WINAPI Perftools_GlobalFree(HGLOBAL hMem) {
353 return patch_GlobalFree()(hMem); 356 return patch_GlobalFree()(hMem);
354 } 357 }
355 358
356 static HGLOBAL WINAPI Perftools_GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes, 359 static HGLOBAL WINAPI Perftools_GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes,
357 UINT uFlags) { 360 UINT uFlags) {
361 // TODO(jar): [The following looks like a copy/paste typo from LocalRealloc.]
358 // GlobalDiscard is a macro which calls LocalReAlloc with size 0. 362 // GlobalDiscard is a macro which calls LocalReAlloc with size 0.
359 if (dwBytes == 0) { 363 if (dwBytes == 0) {
360 return patch_GlobalReAlloc()(hMem, dwBytes, uFlags); 364 return patch_GlobalReAlloc()(hMem, dwBytes, uFlags);
361 } 365 }
362 366
363 HGLOBAL rv = Perftools_GlobalAlloc(uFlags, dwBytes); 367 HGLOBAL rv = Perftools_GlobalAlloc(uFlags, dwBytes);
364 if (hMem != 0) { 368 if (hMem != 0) {
365 size_t size = GlobalSize(hMem); 369 size_t size = GlobalSize(hMem);
366 if (size > dwBytes) 370 if (size > dwBytes)
367 size = dwBytes; 371 size = dwBytes;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 Hook(); 512 Hook();
509 513
510 DCHECK(global_hook_); 514 DCHECK(global_hook_);
511 global_hook_->watcher_ = watcher; 515 global_hook_->watcher_ = watcher;
512 return true; 516 return true;
513 } 517 }
514 518
515 bool MemoryHook::UnregisterWatcher(MemoryObserver* watcher) { 519 bool MemoryHook::UnregisterWatcher(MemoryObserver* watcher) {
516 DCHECK(hooked_); 520 DCHECK(hooked_);
517 DCHECK(global_hook_->watcher_ == watcher); 521 DCHECK(global_hook_->watcher_ == watcher);
522 // TODO(jar): changing watcher_ here is very racy. Other threads may (without
523 // a lock) testing, and then calling through this value. We probably can't
524 // remove this until we are single threaded.
518 global_hook_->watcher_ = NULL; 525 global_hook_->watcher_ = NULL;
519 526
520 // For now, since there are no more watchers, unhook memory. 527 // For now, since there are no more watchers, unhook memory.
521 return Unhook(); 528 return Unhook();
522 } 529 }
523 530
524 bool MemoryHook::CreateHeap() { 531 bool MemoryHook::CreateHeap() {
525 // Create a heap for our own memory. 532 // Create a heap for our own memory.
526 DCHECK(heap_ == NULL); 533 DCHECK(heap_ == NULL);
527 heap_ = HeapCreate(0, 0, 0); 534 heap_ = HeapCreate(0, 0, 0);
(...skipping 18 matching lines...) Expand all
546 } 553 }
547 554
548 void MemoryHook::OnUntrack(HANDLE heap, int32 id, int32 size) { 555 void MemoryHook::OnUntrack(HANDLE heap, int32 id, int32 size) {
549 // Don't notify about allocations to our internal heap. 556 // Don't notify about allocations to our internal heap.
550 if (heap == heap_) 557 if (heap == heap_)
551 return; 558 return;
552 559
553 if (watcher_) 560 if (watcher_)
554 watcher_->OnUntrack(heap, id, size); 561 watcher_->OnUntrack(heap, id, size);
555 } 562 }
OLDNEW
« no previous file with comments | « tools/memory_watcher/memory_hook.h ('k') | tools/memory_watcher/memory_watcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698