[haiku-commits] haiku: hrev49536 - in src/system/libroot/posix/malloc_debug: . src/system/libroot

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 13 Aug 2015 22:39:28 +0200 (CEST)

hrev49536 adds 4 changesets to branch 'master'
old head: 749241987723489674e347d8bed25730d43d29a3
new head: dfcf52c9f13cfe96b517549c57327380c82e6d4a
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=dfcf52c9f13c+%5E749241987723

----------------------------------------------------------------------------

f474606ee92a: libroot_debug: Merge guarded heap into libroot_debug.

The individual debug heap implementations are now exposed via a
structure of function pointers and a common frontend dispatches the
malloc and malloc_debug APIs through them.

The MALLOC_DEBUG environment variable can be used to select the guarded
heap by adding 'g', otherwise the debug heap is used as the default.
Consequently the separate libroot_guarded is not needed anymore and has
been removed.

To allow the use of environment variables this early, init_env_post_heap
has been added and the heap dependent atfork() moved there. This allowed
to fold the code of init_heap_post_env into init_heap so the former has
been removed.

8fa441bf5c9a: libroot_debug: Revert to a legacy default alignment of 8.

This reverts the legacy default alignment (in absence of max_align_t)
to 8, as it was before.

1748116d1c5d: libroot_debug.so: Fix missing alignment in guarded realloc.

dfcf52c9f13c: leak_analyser: Update excludes with more generic regex for ICU.

Also add initialize_before of libroot to the default excludes.

[ Michael Lotz <mmlr@xxxxxxxx> ]

----------------------------------------------------------------------------

14 files changed, 487 insertions(+), 330 deletions(-)
build/jam/packages/HaikuDevel | 1 -
headers/private/libroot/libroot_private.h | 2 +-
src/bin/leak_analyser.sh | 6 +-
src/system/libroot/Jamfile | 26 --
src/system/libroot/libroot_init.c | 4 +-
.../libroot/posix/malloc/arch-specific.cpp | 7 -
src/system/libroot/posix/malloc_debug/Jamfile | 5 +-
.../libroot/posix/malloc_debug/guarded_heap.cpp | 196 ++++---------
src/system/libroot/posix/malloc_debug/heap.cpp | 221 +++++----------
.../posix/malloc_debug/malloc_debug_api.cpp | 283 +++++++++++++++++++
.../posix/malloc_debug/malloc_debug_api.h | 57 ++++
src/system/libroot/posix/stdlib/env.cpp | 5 +
src/system/libroot/stubbed/libroot_stubs.c | 2 +-
.../libroot/stubbed/libroot_stubs_legacy.c | 2 +-

############################################################################

Commit: f474606ee92a7afddb5b3b6350a97ffd31e22c42
URL: http://cgit.haiku-os.org/haiku/commit/?id=f474606ee92a
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Wed Aug 12 18:53:59 2015 UTC

libroot_debug: Merge guarded heap into libroot_debug.

The individual debug heap implementations are now exposed via a
structure of function pointers and a common frontend dispatches the
malloc and malloc_debug APIs through them.

The MALLOC_DEBUG environment variable can be used to select the guarded
heap by adding 'g', otherwise the debug heap is used as the default.
Consequently the separate libroot_guarded is not needed anymore and has
been removed.

To allow the use of environment variables this early, init_env_post_heap
has been added and the heap dependent atfork() moved there. This allowed
to fold the code of init_heap_post_env into init_heap so the former has
been removed.

----------------------------------------------------------------------------

diff --git a/build/jam/packages/HaikuDevel b/build/jam/packages/HaikuDevel
index b18f7d8..de160cd 100644
--- a/build/jam/packages/HaikuDevel
+++ b/build/jam/packages/HaikuDevel
@@ -21,7 +21,6 @@ AddFilesToPackage develop lib : kernel.so : _KERNEL_ ;
# additional libraries
local developmentLibs =
<revisioned>libroot_debug.so
- <revisioned>libroot_guarded.so
;

AddFilesToPackage lib : $(developmentLibs) ;
diff --git a/headers/private/libroot/libroot_private.h
b/headers/private/libroot/libroot_private.h
index 1d5fad3..d0676a6 100644
--- a/headers/private/libroot/libroot_private.h
+++ b/headers/private/libroot/libroot_private.h
@@ -33,8 +33,8 @@ status_t __flatten_process_args(const char* const* args,
int32 argCount,
char*** _flatArgs, size_t* _flatSize);
void _call_atexit_hooks_for_range(addr_t start, addr_t size);
void __init_env(const struct user_space_program_args *args);
+void __init_env_post_heap(void);
status_t __init_heap(void);
-void __init_heap_post_env(void);
void __heap_terminate_after(void);

void __init_time(addr_t commPageTable);
diff --git a/src/bin/leak_analyser.sh b/src/bin/leak_analyser.sh
index 222388e..66c6880a 100755
--- a/src/bin/leak_analyser.sh
+++ b/src/bin/leak_analyser.sh
@@ -14,7 +14,7 @@ then
To generate such a file run a program with the following
environment variables prefixed and pipe the output to a file:

- LD_PRELOAD=libroot_guarded.so MALLOC_DEBUG=es50 program > file
+ LD_PRELOAD=libroot_debug.so MALLOC_DEBUG=ges50 program > file

The number after the "s" is the stack trace depth. Note that
there is an implementation defined maximum.
diff --git a/src/system/libroot/Jamfile b/src/system/libroot/Jamfile
index 1b29fb5..b9d9622 100644
--- a/src/system/libroot/Jamfile
+++ b/src/system/libroot/Jamfile
@@ -63,11 +63,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
;
librootDebugObjects = $(librootDebugObjects:G=$(architecture)) ;

- local librootGuardedObjects =
- posix_malloc_guarded.o
- ;
- librootGuardedObjects =
$(librootGuardedObjects:G=$(architecture)) ;
-
local librootNoDebugObjects =
posix_malloc.o
;
@@ -75,15 +70,12 @@ for architectureObject in [ MultiArchSubDirSetup ] {

local libroot = [ MultiArchDefaultGristFiles libroot.so ] ;
local librootDebug = $(libroot:B=libroot_debug) ;
- local librootGuarded = $(libroot:B=libroot_guarded) ;

DONT_LINK_AGAINST_LIBROOT on $(libroot) = true ;
DONT_LINK_AGAINST_LIBROOT on $(librootDebug) = true ;
- DONT_LINK_AGAINST_LIBROOT on $(librootGuarded) = true ;

SetVersionScript $(libroot) : libroot_versions ;
SetVersionScript $(librootDebug) : libroot_versions ;
- SetVersionScript $(librootGuarded) : libroot_versions ;

SharedLibrary $(libroot)
:
@@ -109,18 +101,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
[ TargetLibgcc ]
;

- HAIKU_SONAME on $(librootGuarded) = libroot.so ;
-
- SharedLibrary $(librootGuarded)
- :
- libroot_init.c
- :
- $(librootObjects)
- $(librootGuardedObjects)
- [ TargetStaticLibsupc++ ]
- [ TargetLibgcc ]
- ;
-
# Copy libroot.so and update the copy's revision section. We
link
# everything against the original, but the copy will end up on
the disk
# image (this way we avoid unnecessary dependencies). The copy
will be
@@ -132,18 +112,12 @@ for architectureObject in [ MultiArchSubDirSetup ] {
libroot.so : revisioned ] ;
local revisionedLibrootDebug
= $(librootDebug:G=$(revisionedLibroot:G)) ;
- local revisionedLibrootGuarded
- = $(librootGuarded:G=$(revisionedLibroot:G)) ;

MakeLocate $(revisionedLibroot) : $(targetDir) ;
CopySetHaikuRevision $(revisionedLibroot) : $(libroot) ;

MakeLocate $(revisionedLibrootDebug) : $(targetDir) ;
CopySetHaikuRevision $(revisionedLibrootDebug) :
$(librootDebug) ;
-
- MakeLocate $(revisionedLibrootGuarded) : $(targetDir) ;
- CopySetHaikuRevision $(revisionedLibrootGuarded)
- : $(librootGuarded) ;
}
}
}
diff --git a/src/system/libroot/libroot_init.c
b/src/system/libroot/libroot_init.c
index 03cb17f..893833e 100644
--- a/src/system/libroot/libroot_init.c
+++ b/src/system/libroot/libroot_init.c
@@ -77,9 +77,9 @@ initialize_before(image_id imageID)
__gCPUCount = info.cpu_count;

__init_time((addr_t)__gCommPageAddress);
- __init_heap();
__init_env(__gRuntimeLoader->program_args);
- __init_heap_post_env();
+ __init_heap();
+ __init_env_post_heap();
__init_pwd_backend();
__set_stack_protection();
}
diff --git a/src/system/libroot/posix/malloc/arch-specific.cpp
b/src/system/libroot/posix/malloc/arch-specific.cpp
index d2c25b8..872867c 100644
--- a/src/system/libroot/posix/malloc/arch-specific.cpp
+++ b/src/system/libroot/posix/malloc/arch-specific.cpp
@@ -125,13 +125,6 @@ __init_heap(void)


extern "C" void
-__init_heap_post_env(void)
-{
- // no heap options available
-}
-
-
-extern "C" void
__heap_terminate_after()
{
// nothing to do
diff --git a/src/system/libroot/posix/malloc_debug/Jamfile
b/src/system/libroot/posix/malloc_debug/Jamfile
index 98d3b0b..0a2213d 100644
--- a/src/system/libroot/posix/malloc_debug/Jamfile
+++ b/src/system/libroot/posix/malloc_debug/Jamfile
@@ -15,10 +15,9 @@ for architectureObject in [ MultiArchSubDirSetup ] {

MergeObject <$(architecture)>posix_malloc_debug.o :
heap.cpp
- ;
-
- MergeObject <$(architecture)>posix_malloc_guarded.o :
guarded_heap.cpp
+
+ malloc_debug_api.cpp
;
}
}
diff --git a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
index bc5e17a..f8d2c7c 100644
--- a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
+++ b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
@@ -3,6 +3,8 @@
* Distributed under the terms of the MIT License.
*/

+#include "malloc_debug_api.h"
+

#include <malloc.h>
#include <stdio.h>
@@ -985,68 +987,36 @@ dump_allocations_full()
// #pragma mark - Heap Debug API


-extern "C" status_t
-heap_debug_start_wall_checking(int msInterval)
-{
- return B_NOT_SUPPORTED;
-}
-
-
-extern "C" status_t
-heap_debug_stop_wall_checking()
-{
- return B_NOT_SUPPORTED;
-}
-
-
-extern "C" void
-heap_debug_set_paranoid_validation(bool enabled)
-{
-}
-
-
-extern "C" void
-heap_debug_set_memory_reuse(bool enabled)
+static void
+guarded_heap_set_memory_reuse(bool enabled)
{
sGuardedHeap.reuse_memory = enabled;
}


-extern "C" void
-heap_debug_set_debugger_calls(bool enabled)
+static void
+guarded_heap_set_debugger_calls(bool enabled)
{
sDebuggerCalls = enabled;
}


-extern "C" void
-heap_debug_set_default_alignment(size_t defaultAlignment)
+static void
+guarded_heap_set_default_alignment(size_t defaultAlignment)
{
sDefaultAlignment = defaultAlignment;
}


-extern "C" void
-heap_debug_validate_heaps()
-{
-}
-
-
-extern "C" void
-heap_debug_validate_walls()
-{
-}
-
-
-extern "C" void
-heap_debug_dump_allocations(bool statsOnly, thread_id thread)
+static void
+guarded_heap_dump_allocations(bool statsOnly, thread_id thread)
{
dump_allocations(sGuardedHeap, statsOnly, thread);
}


-extern "C" void
-heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
+static void
+guarded_heap_dump_heaps(bool dumpAreas, bool dumpBins)
{
WriteLocker heapLocker(sGuardedHeap.lock);
dump_guarded_heap(sGuardedHeap);
@@ -1070,31 +1040,16 @@ heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
}


-extern "C" void *
-heap_debug_malloc_with_guard_page(size_t size)
-{
- return malloc(size);
-}
-
-
-extern "C" status_t
-heap_debug_get_allocation_info(void *address, size_t *size,
- thread_id *thread)
-{
- return B_NOT_SUPPORTED;
-}
-
-
-extern "C" status_t
-heap_debug_dump_allocations_on_exit(bool enabled)
+static status_t
+guarded_heap_set_dump_allocations_on_exit(bool enabled)
{
sDumpAllocationsOnExit = enabled;
return B_OK;
}


-extern "C" status_t
-heap_debug_set_stack_trace_depth(size_t stackTraceDepth)
+static status_t
+guarded_heap_set_stack_trace_depth(size_t stackTraceDepth)
{
if (stackTraceDepth == 0) {
sStackTraceDepth = 0;
@@ -1139,8 +1094,8 @@ init_after_fork()
}


-extern "C" status_t
-__init_heap(void)
+static status_t
+guarded_heap_init(void)
{
if (!guarded_heap_area_create(sGuardedHeap, GUARDED_HEAP_INITIAL_SIZE))
return B_ERROR;
@@ -1164,35 +1119,8 @@ __init_heap(void)
}


-extern "C" void
-__init_heap_post_env(void)
-{
- const char *mode = getenv("MALLOC_DEBUG");
- if (mode != NULL) {
- if (strchr(mode, 'r'))
- heap_debug_set_memory_reuse(false);
- if (strchr(mode, 'e'))
- heap_debug_dump_allocations_on_exit(true);
-
- size_t defaultAlignment = 0;
- const char *argument = strchr(mode, 'a');
- if (argument != NULL
- && sscanf(argument, "a%" B_SCNuSIZE, &defaultAlignment)
== 1) {
- heap_debug_set_default_alignment(defaultAlignment);
- }
-
- size_t stackTraceDepth = 0;
- argument = strchr(mode, 's');
- if (argument != NULL
- && sscanf(argument, "s%" B_SCNuSIZE, &stackTraceDepth)
== 1) {
- heap_debug_set_stack_trace_depth(stackTraceDepth);
- }
- }
-}
-
-
-extern "C" void
-__heap_terminate_after()
+static void
+guarded_heap_terminate_after()
{
if (sDumpAllocationsOnExit)
dump_allocations_full();
@@ -1202,17 +1130,8 @@ __heap_terminate_after()
// #pragma mark - Public API


-extern "C" void*
-sbrk_hook(long)
-{
- debug_printf("sbrk not supported on malloc debug\n");
- panic("sbrk not supported on malloc debug\n");
- return NULL;
-}
-
-
-extern "C" void*
-memalign(size_t alignment, size_t size)
+static void*
+heap_memalign(size_t alignment, size_t size)
{
if (size == 0)
size = 1;
@@ -1221,23 +1140,23 @@ memalign(size_t alignment, size_t size)
}


-extern "C" void*
-malloc(size_t size)
+static void*
+heap_malloc(size_t size)
{
- return memalign(sDefaultAlignment, size);
+ return heap_memalign(sDefaultAlignment, size);
}


-extern "C" void
-free(void* address)
+static void
+heap_free(void* address)
{
if (!guarded_heap_free(address))
panic("free failed for address %p", address);
}


-extern "C" void*
-realloc(void* address, size_t newSize)
+static void*
+heap_realloc(void* address, size_t newSize)
{
if (newSize == 0) {
free(address);
@@ -1245,40 +1164,42 @@ realloc(void* address, size_t newSize)
}

if (address == NULL)
- return memalign(sDefaultAlignment, newSize);
+ return heap_memalign(sDefaultAlignment, newSize);

return guarded_heap_realloc(address, newSize);
}


-extern "C" void*
-calloc(size_t numElements, size_t size)
-{
- void* address = malloc(numElements * size);
- if (address != NULL)
- memset(address, 0, numElements * size);
+heap_implementation __mallocGuardedHeap = {
+ guarded_heap_init,
+ guarded_heap_terminate_after,

- return address;
-}
+ heap_memalign,
+ heap_malloc,
+ heap_free,
+ heap_realloc,

+ NULL, // calloc
+ NULL, // valloc
+ NULL, // posix_memalign

-extern "C" void*
-valloc(size_t size)
-{
- return memalign(B_PAGE_SIZE, size);
-}
+ NULL, // start_wall_checking
+ NULL, // stop_wall_checking
+ NULL, // set_paranoid_validation

+ guarded_heap_set_memory_reuse,
+ guarded_heap_set_debugger_calls,
+ guarded_heap_set_default_alignment,

-extern "C" int
-posix_memalign(void **pointer, size_t alignment, size_t size)
-{
- // this cryptic line accepts zero and all powers of two
- if (((~alignment + 1) | ((alignment << 1) - 1)) != ~0UL)
- return EINVAL;
+ NULL, // validate_heaps
+ NULL, // validate_walls

- *pointer = memalign(alignment, size);
- if (*pointer == NULL)
- return ENOMEM;
+ guarded_heap_dump_allocations,
+ guarded_heap_dump_heaps,
+ heap_malloc,

- return 0;
-}
+ NULL, // get_allocation_info
+
+ guarded_heap_set_dump_allocations_on_exit,
+ guarded_heap_set_stack_trace_depth
+};
diff --git a/src/system/libroot/posix/malloc_debug/heap.cpp
b/src/system/libroot/posix/malloc_debug/heap.cpp
index 10745f3..096fd69 100644
--- a/src/system/libroot/posix/malloc_debug/heap.cpp
+++ b/src/system/libroot/posix/malloc_debug/heap.cpp
@@ -10,8 +10,9 @@
*/


+#include "malloc_debug_api.h"
+
#include <malloc.h>
-#include <malloc_debug.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -38,6 +39,9 @@
#define ASSERT(x) if (!(x)) panic("assert failed: %s", #x);


+static void *debug_heap_memalign(size_t alignment, size_t size);
+
+
static bool sDebuggerCalls = true;
static bool sReuseMemory = true;
static bool sParanoidValidation = false;
@@ -773,7 +777,7 @@ heap_remove_area(heap_allocator *heap, heap_area *area)
}


-heap_allocator *
+static heap_allocator *
heap_create_allocator(const char *name, addr_t base, size_t size,
const heap_class *heapClass)
{
@@ -1103,15 +1107,7 @@ heap_allocate_from_bin(heap_allocator *heap, uint32
binIndex, size_t size)
}


-static bool
-is_valid_alignment(size_t number)
-{
- // this cryptic line accepts zero and all powers of two
- return ((~number + 1) | ((number << 1) - 1)) == ~0UL;
-}
-
-
-void *
+static void *
heap_memalign(heap_allocator *heap, size_t alignment, size_t size)
{
INFO(("memalign(alignment = %lu, size = %lu)\n", alignment, size));
@@ -1172,7 +1168,7 @@ heap_memalign(heap_allocator *heap, size_t alignment,
size_t size)
}


-status_t
+static status_t
heap_free(heap_allocator *heap, void *address)
{
if (address == NULL)
@@ -1473,7 +1469,7 @@ heap_realloc(heap_allocator *heap, void *address, void
**newAddress,
newSize -= sizeof(addr_t) + sizeof(heap_leak_check_info);

// if not, allocate a new chunk of memory
- *newAddress = memalign(sDefaultAlignment, newSize);
+ *newAddress = debug_heap_memalign(sDefaultAlignment, newSize);
if (*newAddress == NULL) {
// we tried but it didn't work out, but still the operation is
done
return B_OK;
@@ -1643,8 +1639,8 @@ heap_wall_checker(void *data)
// #pragma mark - Heap Debug API


-extern "C" status_t
-heap_debug_start_wall_checking(int msInterval)
+static status_t
+debug_heap_start_wall_checking(int msInterval)
{
if (sWallCheckThread < 0) {
sWallCheckThread = spawn_thread(heap_wall_checker, "heap wall
checker",
@@ -1659,8 +1655,8 @@ heap_debug_start_wall_checking(int msInterval)
}


-extern "C" status_t
-heap_debug_stop_wall_checking()
+static status_t
+debug_heap_stop_wall_checking()
{
int32 result;
sStopWallChecking = true;
@@ -1668,66 +1664,52 @@ heap_debug_stop_wall_checking()
}


-extern "C" void
-heap_debug_set_paranoid_validation(bool enabled)
+static void
+debug_heap_set_paranoid_validation(bool enabled)
{
sParanoidValidation = enabled;
}


-extern "C" void
-heap_debug_set_memory_reuse(bool enabled)
+static void
+debug_heap_set_memory_reuse(bool enabled)
{
sReuseMemory = enabled;
}


-extern "C" void
-heap_debug_set_debugger_calls(bool enabled)
+static void
+debug_heap_set_debugger_calls(bool enabled)
{
sDebuggerCalls = enabled;
}


-extern "C" void
-heap_debug_set_default_alignment(size_t defaultAlignment)
+static void
+debug_heap_set_default_alignment(size_t defaultAlignment)
{
sDefaultAlignment = defaultAlignment;
}


-extern "C" void
-heap_debug_validate_heaps()
+static void
+debug_heap_validate_heaps()
{
for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++)
heap_validate_heap(sHeaps[i]);
}


-extern "C" void
-heap_debug_validate_walls()
-{
- heap_validate_walls();
-}
-
-
-extern "C" void
-heap_debug_dump_allocations(bool statsOnly, thread_id thread)
-{
- dump_allocations(statsOnly, thread);
-}
-
-
-extern "C" void
-heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
+static void
+debug_heap_dump_heaps(bool dumpAreas, bool dumpBins)
{
for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++)
dump_allocator(sHeaps[i], dumpAreas, dumpBins);
}


-extern "C" void *
-heap_debug_malloc_with_guard_page(size_t size)
+static void *
+debug_heap_malloc_with_guard_page(size_t size)
{
size_t areaSize = ROUNDUP(size + sizeof(area_allocation_info) +
B_PAGE_SIZE,
B_PAGE_SIZE);
@@ -1775,8 +1757,8 @@ heap_debug_malloc_with_guard_page(size_t size)
}


-extern "C" status_t
-heap_debug_get_allocation_info(void *address, size_t *size,
+static status_t
+debug_heap_get_allocation_info(void *address, size_t *size,
thread_id *thread)
{
for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++) {
@@ -1807,25 +1789,11 @@ heap_debug_get_allocation_info(void *address, size_t
*size,
}


-extern "C" status_t
-heap_debug_dump_allocations_on_exit(bool enabled)
-{
- return B_NOT_SUPPORTED;
-}
-
-
-extern "C" status_t
-heap_debug_set_stack_trace_depth(size_t stackTraceDepth)
-{
- return B_NOT_SUPPORTED;
-}
-
-
// #pragma mark - Init


-extern "C" status_t
-__init_heap(void)
+static status_t
+debug_heap_init(void)
{
// This will locate the heap base at 384 MB and reserve the next 1152 MB
// for it. They may get reclaimed by other areas, though, but the
maximum
@@ -1853,53 +1821,11 @@ __init_heap(void)
}


-extern "C" void
-__init_heap_post_env(void)
-{
- const char *mode = getenv("MALLOC_DEBUG");
- if (mode != NULL) {
- if (strchr(mode, 'p'))
- heap_debug_set_paranoid_validation(true);
- if (strchr(mode, 'w'))
- heap_debug_start_wall_checking(500);
- else if (strchr(mode, 'W'))
- heap_debug_start_wall_checking(100);
- if (strchr(mode, 'g'))
- sUseGuardPage = true;
- if (strchr(mode, 'r'))
- heap_debug_set_memory_reuse(false);
-
- size_t defaultAlignment = 0;
- const char *argument = strchr(mode, 'a');
- if (argument != NULL
- && sscanf(argument, "a%" B_SCNuSIZE, &defaultAlignment)
== 1) {
- heap_debug_set_default_alignment(defaultAlignment);
- }
- }
-}
-
-
-extern "C" void
-__heap_terminate_after()
-{
- // nothing to do
-}
-
-
// #pragma mark - Public API


-extern "C" void *
-sbrk_hook(long)
-{
- debug_printf("sbrk not supported on malloc debug\n");
- panic("sbrk not supported on malloc debug\n");
- return NULL;
-}
-
-
-void *
-memalign(size_t alignment, size_t size)
+static void *
+debug_heap_memalign(size_t alignment, size_t size)
{
size_t alignedSize = size + sizeof(addr_t) +
sizeof(heap_leak_check_info);
if (alignment != 0 && alignment < B_PAGE_SIZE)
@@ -1974,18 +1900,18 @@ memalign(size_t alignment, size_t size)
}


-void *
-malloc(size_t size)
+static void *
+debug_heap_malloc(size_t size)
{
if (sUseGuardPage)
- return heap_debug_malloc_with_guard_page(size);
+ return debug_heap_malloc_with_guard_page(size);

- return memalign(sDefaultAlignment, size);
+ return debug_heap_memalign(sDefaultAlignment, size);
}


-void
-free(void *address)
+static void
+debug_heap_free(void *address)
{
for (uint32 i = 0; i < HEAP_CLASS_COUNT; i++) {
heap_allocator *heap = sHeaps[i];
@@ -2017,11 +1943,11 @@ free(void *address)
}


-void *
-realloc(void *address, size_t newSize)
+static void *
+debug_heap_realloc(void *address, size_t newSize)
{
if (address == NULL)
- return memalign(sDefaultAlignment, newSize);
+ return debug_heap_memalign(sDefaultAlignment, newSize);

if (newSize == 0) {
free(address);
@@ -2079,7 +2005,7 @@ realloc(void *address, size_t newSize)
}

// have to allocate/copy/free - TODO maybe resize the
area instead?
- newAddress = malloc(newSize);
+ newAddress = debug_heap_memalign(sDefaultAlignment,
newSize);
if (newAddress == NULL) {
panic("realloc(): failed to allocate new block
of %ld"
" bytes\n", newSize);
@@ -2100,33 +2026,32 @@ realloc(void *address, size_t newSize)
}


-void *
-calloc(size_t numElements, size_t size)
-{
- void *address = malloc(numElements * size);
- if (address != NULL)
- memset(address, 0, numElements * size);
-
- return address;
-}
-
-
-extern "C" void *
-valloc(size_t size)
-{
- return memalign(B_PAGE_SIZE, size);
-}
-
-
-extern "C" int
-posix_memalign(void **pointer, size_t alignment, size_t size)
-{
- if (!is_valid_alignment(alignment))
- return EINVAL;
-
- *pointer = memalign(alignment, size);
- if (*pointer == NULL)
- return ENOMEM;
-
- return 0;
-}
+heap_implementation __mallocDebugHeap = {
+ debug_heap_init,
+ NULL, // terminate_after
+
+ debug_heap_memalign,
+ debug_heap_malloc,
+ debug_heap_free,
+ debug_heap_realloc,
+
+ NULL, // calloc
+ NULL, // valloc
+ NULL, // posix_memalign
+
+ debug_heap_start_wall_checking,
+ debug_heap_stop_wall_checking,
+ debug_heap_set_paranoid_validation,
+ debug_heap_set_memory_reuse,
+ debug_heap_set_debugger_calls,
+ debug_heap_set_default_alignment,
+ debug_heap_validate_heaps,
+ heap_validate_walls,
+ dump_allocations,
+ debug_heap_dump_heaps,
+ debug_heap_malloc_with_guard_page,
+ debug_heap_get_allocation_info,
+
+ NULL, // set_dump_allocations_on_exit
+ NULL // set_stack_trace_depth
+};
diff --git a/src/system/libroot/posix/malloc_debug/malloc_debug_api.cpp
b/src/system/libroot/posix/malloc_debug/malloc_debug_api.cpp
new file mode 100644
index 0000000..45d3c1c
--- /dev/null
+++ b/src/system/libroot/posix/malloc_debug/malloc_debug_api.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2015, Michael Lotz <mmlr@xxxxxxxx>.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "malloc_debug_api.h"
+
+#include <malloc.h>
+#include <string.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static heap_implementation* sCurrentHeap = NULL;
+
+
+// #pragma mark - Heap Debug API
+
+
+extern "C" status_t
+heap_debug_start_wall_checking(int msInterval)
+{
+ if (sCurrentHeap->start_wall_checking != NULL)
+ return sCurrentHeap->start_wall_checking(msInterval);
+
+ return B_NOT_SUPPORTED;
+}
+
+
+extern "C" status_t
+heap_debug_stop_wall_checking()
+{
+ if (sCurrentHeap->stop_wall_checking != NULL)
+ return sCurrentHeap->stop_wall_checking();
+
+ return B_NOT_SUPPORTED;
+}
+
+
+extern "C" void
+heap_debug_set_paranoid_validation(bool enabled)
+{
+ if (sCurrentHeap->set_paranoid_validation != NULL)
+ sCurrentHeap->set_paranoid_validation(enabled);
+}
+
+
+extern "C" void
+heap_debug_set_memory_reuse(bool enabled)
+{
+ if (sCurrentHeap->set_memory_reuse != NULL)
+ sCurrentHeap->set_memory_reuse(enabled);
+}
+
+
+extern "C" void
+heap_debug_set_debugger_calls(bool enabled)
+{
+ if (sCurrentHeap->set_debugger_calls != NULL)
+ sCurrentHeap->set_debugger_calls(enabled);
+}
+
+
+extern "C" void
+heap_debug_set_default_alignment(size_t defaultAlignment)
+{
+ if (sCurrentHeap->set_default_alignment != NULL)
+ sCurrentHeap->set_default_alignment(defaultAlignment);
+}
+
+
+extern "C" void
+heap_debug_validate_heaps()
+{
+ if (sCurrentHeap->validate_heaps != NULL)
+ sCurrentHeap->validate_heaps();
+}
+
+
+extern "C" void
+heap_debug_validate_walls()
+{
+ if (sCurrentHeap->validate_walls != NULL)
+ sCurrentHeap->validate_walls();
+}
+
+
+extern "C" void
+heap_debug_dump_allocations(bool statsOnly, thread_id thread)
+{
+ if (sCurrentHeap->dump_allocations != NULL)
+ sCurrentHeap->dump_allocations(statsOnly, thread);
+}
+
+
+extern "C" void
+heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
+{
+ if (sCurrentHeap->dump_heaps != NULL)
+ sCurrentHeap->dump_heaps(dumpAreas, dumpBins);
+}
+
+
+extern "C" void *
+heap_debug_malloc_with_guard_page(size_t size)
+{
+ if (sCurrentHeap->malloc_with_guard_page != NULL)
+ return sCurrentHeap->malloc_with_guard_page(size);
+
+ return NULL;
+}
+
+
+extern "C" status_t
+heap_debug_get_allocation_info(void *address, size_t *size,
+ thread_id *thread)
+{
+ if (sCurrentHeap->get_allocation_info != NULL)
+ return sCurrentHeap->get_allocation_info(address, size, thread);
+
+ return B_NOT_SUPPORTED;
+}
+
+
+extern "C" status_t
+heap_debug_set_dump_allocations_on_exit(bool enabled)
+{
+ if (sCurrentHeap->set_dump_allocations_on_exit != NULL)
+ return sCurrentHeap->set_dump_allocations_on_exit(enabled);
+
+ return B_NOT_SUPPORTED;
+}
+
+
+extern "C" status_t
+heap_debug_set_stack_trace_depth(size_t stackTraceDepth)
+{
+ if (sCurrentHeap->set_stack_trace_depth != NULL)
+ return sCurrentHeap->set_stack_trace_depth(stackTraceDepth);
+
+ return B_NOT_SUPPORTED;
+}
+
+
+// #pragma mark - Init
+
+
+extern "C" status_t
+__init_heap(void)
+{
+ const char *mode = getenv("MALLOC_DEBUG");
+ if (mode == NULL || strchr(mode, 'g') == NULL)
+ sCurrentHeap = &__mallocDebugHeap;
+ else
+ sCurrentHeap = &__mallocGuardedHeap;
+
+ status_t result = sCurrentHeap->init();
+ if (result != B_OK)
+ return result;
+
+ if (mode != NULL) {
+ if (strchr(mode, 'p') != NULL)
+ heap_debug_set_paranoid_validation(true);
+ if (strchr(mode, 'r') != NULL)
+ heap_debug_set_memory_reuse(false);
+ if (strchr(mode, 'e') != NULL)
+ heap_debug_set_dump_allocations_on_exit(true);
+
+ size_t defaultAlignment = 0;
+ const char *argument = strchr(mode, 'a');
+ if (argument != NULL
+ && sscanf(argument, "a%" B_SCNuSIZE, &defaultAlignment)
== 1) {
+ heap_debug_set_default_alignment(defaultAlignment);
+ }
+
+ size_t stackTraceDepth = 0;
+ argument = strchr(mode, 's');
+ if (argument != NULL
+ && sscanf(argument, "s%" B_SCNuSIZE, &stackTraceDepth)
== 1) {
+ heap_debug_set_stack_trace_depth(stackTraceDepth);
+ }
+
+ int wallCheckInterval = 0;
+ argument = strchr(mode, 'w');
+ if (argument != NULL
+ && sscanf(argument, "w%d", &wallCheckInterval) == 1) {
+ heap_debug_start_wall_checking(wallCheckInterval);
+ }
+ }
+
+ return B_OK;
+}
+
+
+extern "C" void
+__heap_terminate_after()
+{
+ if (sCurrentHeap->terminate_after != NULL)
+ sCurrentHeap->terminate_after();
+}
+
+
+// #pragma mark - Public API
+
+
+extern "C" void*
+sbrk_hook(long)
+{
+ debug_printf("sbrk not supported on malloc debug\n");
+ debugger("sbrk not supported on malloc debug");
+ return NULL;
+}
+
+
+extern "C" void*
+memalign(size_t alignment, size_t size)
+{
+ return sCurrentHeap->memalign(alignment, size);
+}
+
+
+extern "C" void*
+malloc(size_t size)
+{
+ return sCurrentHeap->malloc(size);
+}
+
+
+extern "C" void
+free(void* address)
+{
+ sCurrentHeap->free(address);
+}
+
+
+extern "C" void*
+realloc(void* address, size_t newSize)
+{
+ return sCurrentHeap->realloc(address, newSize);
+}
+
+
+extern "C" void*
+calloc(size_t numElements, size_t size)
+{
+ if (sCurrentHeap->calloc != NULL)
+ return sCurrentHeap->calloc(numElements, size);
+
+ void* address = malloc(numElements * size);
+ if (address != NULL)
+ memset(address, 0, numElements * size);
+
+ return address;
+}
+
+
+extern "C" void*
+valloc(size_t size)
+{
+ if (sCurrentHeap->valloc != NULL)
+ return sCurrentHeap->valloc(size);
+
+ return memalign(B_PAGE_SIZE, size);
+}
+
+
+extern "C" int
+posix_memalign(void **pointer, size_t alignment, size_t size)
+{
+ if (sCurrentHeap->posix_memalign != NULL)
+ return sCurrentHeap->posix_memalign(pointer, alignment, size);
+
+ if (!is_valid_alignment(alignment))
+ return EINVAL;
+
+ *pointer = memalign(alignment, size);
+ if (*pointer == NULL)
+ return ENOMEM;
+
+ return 0;
+}
diff --git a/src/system/libroot/posix/malloc_debug/malloc_debug_api.h
b/src/system/libroot/posix/malloc_debug/malloc_debug_api.h
new file mode 100644
index 0000000..dc949a9
--- /dev/null
+++ b/src/system/libroot/posix/malloc_debug/malloc_debug_api.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015, Michael Lotz <mmlr@xxxxxxxx>.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef MALLOC_DEBUG_API_H
+#define MALLOC_DEBUG_API_H
+
+#include <OS.h>
+
+
+struct heap_implementation {
+ status_t (*init)();
+ void (*terminate_after)();
+
+ // Mandatory hooks
+ void* (*memalign)(size_t alignment, size_t size);
+ void* (*malloc)(size_t size);
+ void (*free)(void* address);
+ void* (*realloc)(void* address, size_t newSize);
+
+ // Hooks with default implementations
+ void* (*calloc)(size_t numElements, size_t size);
+ void* (*valloc)(size_t size);
+ int (*posix_memalign)(void** pointer, size_t
alignment,
+ size_t size);
+
+ // Heap Debug API
+ status_t (*start_wall_checking)(int msInterval);
+ status_t (*stop_wall_checking)();
+ void (*set_paranoid_validation)(bool enabled);
+ void (*set_memory_reuse)(bool enabled);
+ void (*set_debugger_calls)(bool enabled);
+ void (*set_default_alignment)(size_t defaultAlignment);
+ void (*validate_heaps)();
+ void (*validate_walls)();
+ void (*dump_allocations)(bool statsOnly, thread_id thread);
+ void (*dump_heaps)(bool dumpAreas, bool dumpBins);
+ void* (*malloc_with_guard_page)(size_t size);
+ status_t (*get_allocation_info)(void* address, size_t *size,
+ thread_id *thread);
+ status_t (*set_dump_allocations_on_exit)(bool enabled);
+ status_t (*set_stack_trace_depth)(size_t stackTraceDepth);
+};
+
+
+extern heap_implementation __mallocDebugHeap;
+extern heap_implementation __mallocGuardedHeap;
+
+
+static inline bool
+is_valid_alignment(size_t number)
+{
+ // this cryptic line accepts zero and all powers of two
+ return ((~number + 1) | ((number << 1) - 1)) == ~0UL;
+}
+
+#endif // MALLOC_DEBUG_API_H
diff --git a/src/system/libroot/posix/stdlib/env.cpp
b/src/system/libroot/posix/stdlib/env.cpp
index 578a255..e811eeb 100644
--- a/src/system/libroot/posix/stdlib/env.cpp
+++ b/src/system/libroot/posix/stdlib/env.cpp
@@ -205,7 +205,12 @@ __init_env(const struct user_space_program_args *args)
// protect our implementation
environ = args->env;
sManagedEnviron = NULL;
+}
+

+void
+__init_env_post_heap()
+{
atfork(environ_fork_hook);
}

diff --git a/src/system/libroot/stubbed/libroot_stubs.c
b/src/system/libroot/stubbed/libroot_stubs.c
index 9611855..cd8ff77 100644
--- a/src/system/libroot/stubbed/libroot_stubs.c
+++ b/src/system/libroot/stubbed/libroot_stubs.c
@@ -892,8 +892,8 @@ void __ilogb() {}
void __ilogbf() {}
void __ilogbl() {}
void __init_env() {}
+void __init_env_post_heap() {}
void __init_heap() {}
-void __init_heap_post_env() {}
void __init_once() {}
void __init_pthread() {}
void __init_pwd_backend() {}
diff --git a/src/system/libroot/stubbed/libroot_stubs_legacy.c
b/src/system/libroot/stubbed/libroot_stubs_legacy.c
index 2d72b86..855c3bb 100644
--- a/src/system/libroot/stubbed/libroot_stubs_legacy.c
+++ b/src/system/libroot/stubbed/libroot_stubs_legacy.c
@@ -726,8 +726,8 @@ void __ilogb() {}
void __ilogbf() {}
void __ilogbl() {}
void __init_env() {}
+void __init_env_post_heap() {}
void __init_heap() {}
-void __init_heap_post_env() {}
void __init_once() {}
void __init_pthread() {}
void __init_pwd_backend() {}

############################################################################

Commit: 8fa441bf5c9a995d3a66da8eb55d244f4b6c7bbd
URL: http://cgit.haiku-os.org/haiku/commit/?id=8fa441bf5c9a
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Thu Aug 13 19:02:09 2015 UTC

libroot_debug: Revert to a legacy default alignment of 8.

This reverts the legacy default alignment (in absence of max_align_t)
to 8, as it was before.

----------------------------------------------------------------------------

diff --git a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
index f8d2c7c..728ae23 100644
--- a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
+++ b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
@@ -38,7 +38,7 @@ static int32 sStackEndTLSIndex = -1;
using namespace std;
static size_t sDefaultAlignment = alignof(max_align_t);
#else
-static size_t sDefaultAlignment = 0;
+static size_t sDefaultAlignment = 8;
#endif


diff --git a/src/system/libroot/posix/malloc_debug/heap.cpp
b/src/system/libroot/posix/malloc_debug/heap.cpp
index 096fd69..3c9ed49 100644
--- a/src/system/libroot/posix/malloc_debug/heap.cpp
+++ b/src/system/libroot/posix/malloc_debug/heap.cpp
@@ -54,7 +54,7 @@ static bool sUseGuardPage = false;
using namespace std;
static size_t sDefaultAlignment = alignof(max_align_t);
#else
-static size_t sDefaultAlignment = 0;
+static size_t sDefaultAlignment = 8;
#endif



############################################################################

Commit: 1748116d1c5dbfd50da5c8d8e4c53b92b1021029
URL: http://cgit.haiku-os.org/haiku/commit/?id=1748116d1c5d
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Thu Aug 13 20:33:55 2015 UTC

libroot_debug.so: Fix missing alignment in guarded realloc.

----------------------------------------------------------------------------

diff --git a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
index 728ae23..f527ff5 100644
--- a/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
+++ b/src/system/libroot/posix/malloc_debug/guarded_heap.cpp
@@ -747,7 +747,8 @@ guarded_heap_realloc(void* address, size_t newSize)
if (oldSize == newSize)
return address;

- void* newBlock = guarded_heap_allocate(sGuardedHeap, newSize, 0);
+ void* newBlock = guarded_heap_allocate(sGuardedHeap, newSize,
+ sDefaultAlignment);
if (newBlock == NULL)
return NULL;


############################################################################

Revision: hrev49536
Commit: dfcf52c9f13cfe96b517549c57327380c82e6d4a
URL: http://cgit.haiku-os.org/haiku/commit/?id=dfcf52c9f13c
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Thu Aug 13 20:34:51 2015 UTC

leak_analyser: Update excludes with more generic regex for ICU.

Also add initialize_before of libroot to the default excludes.

----------------------------------------------------------------------------

diff --git a/src/bin/leak_analyser.sh b/src/bin/leak_analyser.sh
index 66c6880a..2532e2a 100755
--- a/src/bin/leak_analyser.sh
+++ b/src/bin/leak_analyser.sh
@@ -94,6 +94,7 @@ EXCLUDE_PATTERN=""
if [ -z "$NO_DEFAULTS" ]
then
declare -a DEFAULT_EXCLUDE_LIST=( \
+ "<libroot.so> initialize_before " \
"<libroot.so> __cxa_atexit " \
"<libroot.so> BPrivate::Libroot::LocaleBackend::LoadBackend" \
"<libbe.so> initialize_before " \
@@ -108,8 +109,7 @@ then
"<libtracker.so> _init " \
"<libtranslation.so> BTranslatorRoster::Default" \
"Translator> " \
- "<libicui18n.so.54> icu::" \
- "<libicuuc.so.54> icu::" \
+ "<libicu[^.]+.so.[0-9]+> icu(_[0-9]+)?::" \
)

for EXCLUDE in "${DEFAULT_EXCLUDE_LIST[@]}"


Other related posts:

  • » [haiku-commits] haiku: hrev49536 - in src/system/libroot/posix/malloc_debug: . src/system/libroot - mmlr