OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 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. | |
4 | |
5 #include "base/process/memory.h" | |
6 | |
7 #include <new.h> | |
8 #include <psapi.h> | |
9 | |
10 #include "base/logging.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 | |
13 namespace base { | |
14 | |
15 namespace { | |
16 | |
17 #pragma warning(push) | |
18 #pragma warning(disable: 4702) | |
19 | |
20 int OnNoMemory(size_t) { | |
21 // Kill the process. This is important for security since most of code | |
22 // does not check the result of memory allocation. | |
23 __debugbreak(); | |
24 _exit(1); | |
25 return 0; | |
26 } | |
27 | |
28 #pragma warning(pop) | |
29 | |
30 // HeapSetInformation function pointer. | |
31 typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); | |
32 | |
33 } // namespace | |
34 | |
35 bool EnableLowFragmentationHeap() { | |
36 HMODULE kernel32 = GetModuleHandle(L"kernel32.dll"); | |
37 HeapSetFn heap_set = reinterpret_cast<HeapSetFn>(GetProcAddress( | |
38 kernel32, | |
39 "HeapSetInformation")); | |
40 | |
41 // On Windows 2000, the function is not exported. This is not a reason to | |
42 // fail. | |
43 if (!heap_set) | |
44 return true; | |
45 | |
46 unsigned number_heaps = GetProcessHeaps(0, NULL); | |
47 if (!number_heaps) | |
48 return false; | |
49 | |
50 // Gives us some extra space in the array in case a thread is creating heaps | |
51 // at the same time we're querying them. | |
52 static const int MARGIN = 8; | |
53 scoped_ptr<HANDLE[]> heaps(new HANDLE[number_heaps + MARGIN]); | |
54 number_heaps = GetProcessHeaps(number_heaps + MARGIN, heaps.get()); | |
55 if (!number_heaps) | |
56 return false; | |
57 | |
58 for (unsigned i = 0; i < number_heaps; ++i) { | |
59 ULONG lfh_flag = 2; | |
60 // Don't bother with the result code. It may fails on heaps that have the | |
61 // HEAP_NO_SERIALIZE flag. This is expected and not a problem at all. | |
62 heap_set(heaps[i], | |
63 HeapCompatibilityInformation, | |
64 &lfh_flag, | |
65 sizeof(lfh_flag)); | |
66 } | |
67 return true; | |
68 } | |
69 | |
70 void EnableTerminationOnHeapCorruption() { | |
71 // Ignore the result code. Supported on XP SP3 and Vista. | |
72 HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); | |
73 } | |
74 | |
75 void EnableTerminationOnOutOfMemory() { | |
76 _set_new_handler(&OnNoMemory); | |
77 _set_new_mode(1); | |
78 } | |
79 | |
80 HMODULE GetModuleFromAddress(void* address) { | |
81 HMODULE instance = NULL; | |
82 if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | | |
83 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | |
84 static_cast<char*>(address), | |
85 &instance)) { | |
86 NOTREACHED(); | |
87 } | |
88 return instance; | |
89 } | |
90 | |
91 // TODO(b.kelemen): implement it with the required semantics. On Linux this is | |
92 // implemented with a weak symbol that is overridden by tcmalloc. This is | |
93 // neccessary because base cannot have a direct dependency on tcmalloc. Since | |
94 // weak symbols are not supported on Windows this will involve some build time | |
95 // magic, much like what is done for libcrt in order to override the allocation | |
96 // functions. | |
97 bool UncheckedMalloc(size_t size, void** result) { | |
98 *result = malloc(size); | |
99 return *result != NULL; | |
100 } | |
101 | |
102 } // namespace base | |
OLD | NEW |