vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / posix / malloc_debug / malloc_debug_api.cpp
blobbf38d4c9e7473b6e6f7b1514ee3b623c43e17baf
1 /*
2 * Copyright 2015, Michael Lotz <mmlr@mlotz.ch>.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "malloc_debug_api.h"
9 #include <malloc.h>
10 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
16 static heap_implementation* sCurrentHeap = NULL;
19 // #pragma mark - Heap Debug API
22 extern "C" status_t
23 heap_debug_start_wall_checking(int msInterval)
25 if (sCurrentHeap->start_wall_checking != NULL)
26 return sCurrentHeap->start_wall_checking(msInterval);
28 return B_NOT_SUPPORTED;
32 extern "C" status_t
33 heap_debug_stop_wall_checking()
35 if (sCurrentHeap->stop_wall_checking != NULL)
36 return sCurrentHeap->stop_wall_checking();
38 return B_NOT_SUPPORTED;
42 extern "C" void
43 heap_debug_set_paranoid_validation(bool enabled)
45 if (sCurrentHeap->set_paranoid_validation != NULL)
46 sCurrentHeap->set_paranoid_validation(enabled);
50 extern "C" void
51 heap_debug_set_memory_reuse(bool enabled)
53 if (sCurrentHeap->set_memory_reuse != NULL)
54 sCurrentHeap->set_memory_reuse(enabled);
58 extern "C" void
59 heap_debug_set_debugger_calls(bool enabled)
61 if (sCurrentHeap->set_debugger_calls != NULL)
62 sCurrentHeap->set_debugger_calls(enabled);
66 extern "C" void
67 heap_debug_set_default_alignment(size_t defaultAlignment)
69 if (sCurrentHeap->set_default_alignment != NULL)
70 sCurrentHeap->set_default_alignment(defaultAlignment);
74 extern "C" void
75 heap_debug_validate_heaps()
77 if (sCurrentHeap->validate_heaps != NULL)
78 sCurrentHeap->validate_heaps();
82 extern "C" void
83 heap_debug_validate_walls()
85 if (sCurrentHeap->validate_walls != NULL)
86 sCurrentHeap->validate_walls();
90 extern "C" void
91 heap_debug_dump_allocations(bool statsOnly, thread_id thread)
93 if (sCurrentHeap->dump_allocations != NULL)
94 sCurrentHeap->dump_allocations(statsOnly, thread);
98 extern "C" void
99 heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
101 if (sCurrentHeap->dump_heaps != NULL)
102 sCurrentHeap->dump_heaps(dumpAreas, dumpBins);
106 extern "C" void *
107 heap_debug_malloc_with_guard_page(size_t size)
109 if (sCurrentHeap->malloc_with_guard_page != NULL)
110 return sCurrentHeap->malloc_with_guard_page(size);
112 return NULL;
116 extern "C" status_t
117 heap_debug_get_allocation_info(void *address, size_t *size,
118 thread_id *thread)
120 if (sCurrentHeap->get_allocation_info != NULL)
121 return sCurrentHeap->get_allocation_info(address, size, thread);
123 return B_NOT_SUPPORTED;
127 extern "C" status_t
128 heap_debug_set_dump_allocations_on_exit(bool enabled)
130 if (sCurrentHeap->set_dump_allocations_on_exit != NULL)
131 return sCurrentHeap->set_dump_allocations_on_exit(enabled);
133 return B_NOT_SUPPORTED;
137 extern "C" status_t
138 heap_debug_set_stack_trace_depth(size_t stackTraceDepth)
140 if (sCurrentHeap->set_stack_trace_depth != NULL)
141 return sCurrentHeap->set_stack_trace_depth(stackTraceDepth);
143 return B_NOT_SUPPORTED;
147 // #pragma mark - Init
150 extern "C" status_t
151 __init_heap(void)
153 const char *mode = getenv("MALLOC_DEBUG");
154 if (mode == NULL || strchr(mode, 'g') == NULL)
155 sCurrentHeap = &__mallocDebugHeap;
156 else
157 sCurrentHeap = &__mallocGuardedHeap;
159 status_t result = sCurrentHeap->init();
160 if (result != B_OK)
161 return result;
163 if (mode != NULL) {
164 if (strchr(mode, 'p') != NULL)
165 heap_debug_set_paranoid_validation(true);
166 if (strchr(mode, 'r') != NULL)
167 heap_debug_set_memory_reuse(false);
168 if (strchr(mode, 'e') != NULL)
169 heap_debug_set_dump_allocations_on_exit(true);
171 size_t defaultAlignment = 0;
172 const char *argument = strchr(mode, 'a');
173 if (argument != NULL
174 && sscanf(argument, "a%" B_SCNuSIZE, &defaultAlignment) == 1) {
175 heap_debug_set_default_alignment(defaultAlignment);
178 size_t stackTraceDepth = 0;
179 argument = strchr(mode, 's');
180 if (argument != NULL
181 && sscanf(argument, "s%" B_SCNuSIZE, &stackTraceDepth) == 1) {
182 heap_debug_set_stack_trace_depth(stackTraceDepth);
185 int wallCheckInterval = 0;
186 argument = strchr(mode, 'w');
187 if (argument != NULL
188 && sscanf(argument, "w%d", &wallCheckInterval) == 1) {
189 heap_debug_start_wall_checking(wallCheckInterval);
193 return B_OK;
197 extern "C" void
198 __heap_terminate_after()
200 if (sCurrentHeap->terminate_after != NULL)
201 sCurrentHeap->terminate_after();
205 extern "C" void
206 __heap_before_fork(void)
211 extern "C" void
212 __heap_after_fork_child(void)
217 extern "C" void
218 __heap_after_fork_parent(void)
223 // #pragma mark - Public API
226 extern "C" void*
227 memalign(size_t alignment, size_t size)
229 return sCurrentHeap->memalign(alignment, size);
233 extern "C" void*
234 malloc(size_t size)
236 return sCurrentHeap->malloc(size);
240 extern "C" void
241 free(void* address)
243 sCurrentHeap->free(address);
247 extern "C" void*
248 realloc(void* address, size_t newSize)
250 return sCurrentHeap->realloc(address, newSize);
254 extern "C" void*
255 calloc(size_t numElements, size_t size)
257 if (sCurrentHeap->calloc != NULL)
258 return sCurrentHeap->calloc(numElements, size);
260 void* address = malloc(numElements * size);
261 if (address != NULL)
262 memset(address, 0, numElements * size);
264 return address;
268 extern "C" void*
269 valloc(size_t size)
271 if (sCurrentHeap->valloc != NULL)
272 return sCurrentHeap->valloc(size);
274 return memalign(B_PAGE_SIZE, size);
278 extern "C" int
279 posix_memalign(void **pointer, size_t alignment, size_t size)
281 if (sCurrentHeap->posix_memalign != NULL)
282 return sCurrentHeap->posix_memalign(pointer, alignment, size);
284 if (!is_valid_alignment(alignment))
285 return EINVAL;
287 *pointer = memalign(alignment, size);
288 if (*pointer == NULL)
289 return ENOMEM;
291 return 0;