summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorRamiro Estrugo <ramiro@src.gnome.org>2000-07-14 18:53:54 +0000
committerRamiro Estrugo <ramiro@src.gnome.org>2000-07-14 18:53:54 +0000
commit27c8b5ab89c44e2ba3d6bde1a024715f4abe5a72 (patch)
tree721ae49389f24a5db6e4d5f2c65e98e674382f9a /test
parentf7263fbde7303e78b3c8f7e14e1c1ee5e32d8691 (diff)
downloadnautilus-27c8b5ab89c44e2ba3d6bde1a024715f4abe5a72.tar.gz
Move the leakchecker library to its own place.
* configure.in: * test/Makefile.am: * test/nautilus-leak-checker-stubs.h: * test/nautilus-leak-checker.c: * test/nautilus-leak-checker.h: * test/nautilus-leak-hash-table.c: * test/nautilus-leak-hash-table.h: * test/nautilus-leak-symbol-lookup.c: * test/nautilus-leak-symbol-lookup.h: * tools/leak-checker: Move the leakchecker library to its own place.
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am48
-rw-r--r--test/nautilus-leak-checker-stubs.h78
-rw-r--r--test/nautilus-leak-checker.c760
-rw-r--r--test/nautilus-leak-checker.h54
-rw-r--r--test/nautilus-leak-hash-table.c511
-rw-r--r--test/nautilus-leak-hash-table.h57
-rw-r--r--test/nautilus-leak-symbol-lookup.c272
-rw-r--r--test/nautilus-leak-symbol-lookup.h31
8 files changed, 0 insertions, 1811 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 943dc8778..ef6180f39 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,5 @@
NULL=
-#lib_LTLIBRARIES = libleakcheck.la
-
INCLUDES =\
-I$(top_srcdir) \
-I$(top_builddir) \
@@ -50,52 +48,6 @@ test_nautilus_image_SOURCES = test-nautilus-image.c
test_nautilus_password_dialog_SOURCES = test-nautilus-password-dialog.c
-#libleakcheck_la_SOURCES = \
-# nautilus-leak-checker.c \
-# nautilus-leak-checker.h \
-# nautilus-leak-checker-stubs.h \
-# nautilus-leak-hash-table.c \
-# nautilus-leak-hash-table.h \
-# nautilus-leak-symbol-lookup.c \
-# nautilus-leak-symbol-lookup.h \
-# $(NULL)
-
EXTRA_DIST = \
test-nautilus-mime-actions.c \
$(NULL)
-
-# the libtool way of building libleakcheck.so is totally broken, libtool cannot
-# build an .so with statically linked -liberty
-
-# LIBLEAKCHECK_STATIC_LIBS = "-Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic"
-#libleakcheck_la_LDADD = -module -avoid-version $(LIBLEAKCHECK_STATIC_LIBS)
-#libleakcheck_la_LIBADD = -ldl
-
-
-
-# libleakcheck.la: $(libleakcheck_la_OBJECTS) $(libleakcheck_la_DEPENDENCIES)
-# $(LINK) -rpath $(libdir) $(libleakcheck_la_LDADD) $(libleakcheck_la_OBJECTS) $(libleakcheck_la_LIBADD) $(LIBS)
-
-
-# for now just hardcode a plain old link line, someday someone can
-#figure out what the magic password is to make libtool do this cleanly
-
-all: libleakcheck.so
-CLEANFILES += libleakcheck.so
-
-libleakcheck.so: nautilus-leak-checker.c nautilus-leak-hash-table.c nautilus-leak-symbol-lookup.c
- gcc $(srcdir)/nautilus-leak-checker.c $(srcdir)/nautilus-leak-hash-table.c \
- $(srcdir)/nautilus-leak-symbol-lookup.c \
- -Wall -o $@ -shared $(GLIB_CFLAGS) $(GLIB_LIBS) -lpthread -ldl -Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic
-
-# to include them in "make dist"
-EXTRA_DIST = nautilus-leak-checker.c nautilus-leak-hash-table.c nautilus-leak-symbol-lookup.c \
- nautilus-leak-checker-stubs.h nautilus-leak-hash-table.h nautilus-leak-checker.h nautilus-leak-symbol-lookup.h
-
-leakcheck_DATA = libleakcheck.so
-leakcheckdir= $(DESTDIR)$(libdir)
-
-leakchecktest: nautilus-leak-checker.c nautilus-leak-hash-table.c nautilus-leak-symbol-lookup.c
- gcc $(srcdir)/nautilus-leak-checker.c $(srcdir)/nautilus-leak-hash-table.c \
- $(srcdir)/nautilus-leak-symbol-lookup.c \
- -Wall -o $@ -DLEAK_CHECK_TESTING $(GLIB_CFLAGS) $(GLIB_LIBS) -lpthread -ldl -Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic
diff --git a/test/nautilus-leak-checker-stubs.h b/test/nautilus-leak-checker-stubs.h
deleted file mode 100644
index 8f175dfda..000000000
--- a/test/nautilus-leak-checker-stubs.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* nautilus-leak-checker-stubs.h - simple leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
- based on MemProf by Owen Taylor, <otaylor@redhat.com>
-*/
-
-#ifndef LEAK_CHECKER_STUBS_H
-#define LEAK_CHECKER_STUBS_H
-
-
-extern void *(* real_malloc) (size_t size);
-extern void *(* real_memalign) (size_t boundary, size_t size);
-extern void *(* real_realloc) (void *ptr, size_t size);
-extern void *(* real_calloc) (void *ptr, size_t size);
-extern void (*real_free) (void *ptr);
-
-
-void *__libc_malloc (size_t size);
-void *__libc_memalign (size_t boundary, size_t size);
-void *__libc_calloc (size_t count, size_t size);
-void *__libc_realloc (void *ptr, size_t size);
-void __libc_free (void *ptr);
-
-/* Records the context of an allocation.
- * We could add pid, allocation time, etc. if needed.
- */
-typedef struct {
- /* pointer returned by malloc/realloc */
- void *block;
-
- /* allocated size */
- size_t size;
-
- /* NULL-terminated array of return addresses */
- void **stack_crawl;
-} NautilusLeakAllocationRecord;
-
-void nautilus_leak_allocation_record_finalize
- (NautilusLeakAllocationRecord *record);
-void nautilus_leak_allocation_record_free (NautilusLeakAllocationRecord *record);
-void nautilus_leak_allocation_record_init (NautilusLeakAllocationRecord *record,
- void *block,
- size_t initial_size,
- void **stack_crawl,
- int max_depth);
-NautilusLeakAllocationRecord *nautilus_leak_allocation_record_copy
- (const NautilusLeakAllocationRecord *record);
-
-int nautilus_leak_stack_crawl_compare (void **stack_crawl1,
- void **stack_crawl2,
- int levels);
-
-/* Hash table entry. */
-struct NautilusHashEntry {
- int next;
- NautilusLeakAllocationRecord data;
-};
-
-
-#endif \ No newline at end of file
diff --git a/test/nautilus-leak-checker.c b/test/nautilus-leak-checker.c
deleted file mode 100644
index 00dfee618..000000000
--- a/test/nautilus-leak-checker.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/* nautilus-leak-checker.c - simple leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
- based on MemProf by Owen Taylor, <otaylor@redhat.com>
-*/
-
-#include "nautilus-leak-checker.h"
-/* included first, defines following switch*/
-#if LEAK_CHECKER
-
-#include <malloc.h>
-#include <dlfcn.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nautilus-leak-checker-stubs.h"
-#include "nautilus-leak-hash-table.h"
-#include "nautilus-leak-symbol-lookup.h"
-
-/* this is the maximum number of stack crawl levels we can capture */
-enum {
- TRACE_ARRAY_MAX = 512
-};
-
-static volatile gboolean nautilus_leak_hooks_initialized;
-static volatile gboolean nautilus_leak_initializing_hooks;
-static volatile gboolean nautilus_leak_check_leaks;
-
-void *(* real_malloc) (size_t size);
-void *(* real_memalign) (size_t boundary, size_t size);
-void *(* real_realloc) (void *ptr, size_t size);
-void *(* real_calloc) (void *ptr, size_t size);
-void (* real_free) (void *ptr);
-int (* real_start_main) (int (*main) (int, char **, char **), int argc,
- char **argv, void (*init) (void), void (*fini) (void),
- void (*rtld_fini) (void), void *stack_end);
-
-
-
-static const char *app_path;
-
-void
-nautilus_leak_allocation_record_init (NautilusLeakAllocationRecord *record,
- void *block, size_t initial_size, void **stack_crawl, int max_depth)
-{
- int stack_depth, index;
-
- record->block = block;
- record->size = initial_size;
-
- for (index = 0; index < max_depth; index++) {
- if (stack_crawl[index] == NULL)
- break;
- }
-
- stack_depth = index;
-
- /* call real_malloc to avoid recursion and messing up results */
- record->stack_crawl = real_malloc ((stack_depth + 1) * sizeof(void *));
- memcpy (record->stack_crawl, stack_crawl, stack_depth * sizeof(void *));
- record->stack_crawl[stack_depth] = NULL;
-}
-
-NautilusLeakAllocationRecord *
-nautilus_leak_allocation_record_copy (const NautilusLeakAllocationRecord *record)
-{
- int stack_depth, index;
- NautilusLeakAllocationRecord *result;
-
- result = real_malloc (sizeof(*result));
-
- result->block = record->block;
- result->size = record->size;
-
- for (index = 0; ; index++) {
- if (record->stack_crawl[index] == NULL)
- break;
- }
- stack_depth = index;
- result->stack_crawl = real_malloc ((stack_depth + 1) * sizeof(void *));
- memcpy (result->stack_crawl, record->stack_crawl, (stack_depth + 1) * sizeof(void *));
-
- return result;
-}
-
-void
-nautilus_leak_allocation_record_finalize (NautilusLeakAllocationRecord *record)
-{
- /* call real_free to avoid recursion and messing up results */
- real_free (record->stack_crawl);
-}
-
-void
-nautilus_leak_allocation_record_free (NautilusLeakAllocationRecord *record)
-{
- /* call real_free to avoid recursion and messing up results */
- real_free (record->stack_crawl);
- real_free (record);
-}
-
-/* return a strcmp-like result to be used in sort funcitons */
-int
-nautilus_leak_stack_crawl_compare (void **stack_crawl1, void **stack_crawl2, int levels)
-{
- int index;
- for (index = 0; index < levels; index++) {
- if (stack_crawl1 [index] == NULL && stack_crawl2 [index] == NULL) {
- return 0;
- }
-
- if (stack_crawl1 [index] < stack_crawl2 [index]) {
- return -1;
- } else if (stack_crawl1 [index] > stack_crawl2 [index]) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static void
-nautilus_leak_initialize (void)
-{
- /* Locate the original malloc calls. The dlsym calls
- * will allocate memory when doing lookups. We use a special
- * trick to deal with the fact that real_malloc is not set up
- * yet while we are doing the first dlsym -- see malloc.
- */
- real_malloc = dlsym (RTLD_NEXT, "__libc_malloc");
- real_realloc = dlsym (RTLD_NEXT, "__libc_realloc");
- real_free = dlsym (RTLD_NEXT, "__libc_free");
- real_memalign = dlsym (RTLD_NEXT, "__libc_memalign");
- real_calloc = dlsym (RTLD_NEXT, "__libc_calloc");
- real_start_main = dlsym (RTLD_NEXT, "__libc_start_main");
-
- nautilus_leak_hooks_initialized = TRUE;
- nautilus_leak_check_leaks = TRUE;
-}
-
-typedef struct StackFrame StackFrame;
-
-struct StackFrame {
- StackFrame *next_frame;
- void *return_address;
- /* first argument is here */
-};
-
-static void
-get_stack_trace (void **trace_array, int trace_array_max)
-{
- int index;
- const StackFrame *stack_frame;
-
- /* point to the stack frame pointer, two words before the
- * address of the first argument
- */
- stack_frame = (const StackFrame *)((void **)&trace_array - 2);
-
-
- /* Record stack frames; skip first two in the malloc calls. */
- for (index = -2; index < trace_array_max; index++) {
- if (index >= 0) {
- /* Return address is the next pointer after
- * stack frame.
- */
- trace_array [index] = stack_frame->return_address;
- }
- stack_frame = stack_frame->next_frame;
- if (stack_frame == NULL) {
- break;
- }
- }
- if (index < trace_array_max) {
- trace_array [index] = NULL;
- }
-}
-
-/* Figure out if one of the malloc calls is reentering itself.
- * There seems no cleaner way to handle this -- we want to override
- * malloc calls at the __libc_* level.
- * The malloc hooks recurse when initializing themselves.
- * When this happens we need a reliable way to tell that a recursion is
- * underway so as to not record the corresponding malloc call twice
- */
-static gboolean
-detect_reentry (void *parent_caller)
-{
- int count;
- const StackFrame *stack_frame;
-
- stack_frame = (const StackFrame *)((void **)&parent_caller - 2);
- stack_frame = stack_frame->next_frame;
-
- for (count = 0; count < 7; count++) {
- /* See if we return address on the stack
- * that is near the parent_caller -- the start address
- * of the calling function.
- * We are using two arbitrary numbers here - 5 should be a "deep enough"
- * check to detect the recursion, 0x40 bytes should be a large enough distance
- * from the start of the malloc call to the point where the old malloc call is
- * being called.
- * FIXME: this the value 0x40 works well only with certain function sizes, optimization levels,
- * etc. need a more robust way of doing this. One way might be adding stuffing into the
- * __libc_* calls that is never executed but makes the funcitons longer. We could
- * then up the value without the danger of hitting the next function
- */
- if (stack_frame->return_address >= parent_caller
- && stack_frame->return_address < (void *)((char *)parent_caller + 0x40)) {
- /* printf("detected reentry at level %d\n", count); */
- return TRUE;
- }
- stack_frame = stack_frame->next_frame;
- if (stack_frame == NULL) {
- break;
- }
- }
- return FALSE;
-}
-
-static pthread_mutex_t nautilus_leak_hash_table_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-static NautilusLeakHashTable *hash_table;
-
-static int nautilus_leak_malloc_count;
-static size_t nautilus_leak_malloc_outstanding_size;
-
-static void
-nautilus_leak_record_malloc (void *ptr, size_t size)
-{
- void *trace_array [TRACE_ARRAY_MAX];
- NautilusHashEntry *element;
-
- /* printf("new block %p, %d\n", ptr, size); */
-
- if (!nautilus_leak_check_leaks)
- return;
-
- ++nautilus_leak_malloc_count;
- nautilus_leak_malloc_outstanding_size += size;
-
- get_stack_trace (trace_array, TRACE_ARRAY_MAX);
-
- pthread_mutex_lock (&nautilus_leak_hash_table_mutex);
-
- if (hash_table == NULL) {
- hash_table = nautilus_leak_hash_table_new (10 * 1024);
- }
- if (nautilus_leak_hash_table_find (hash_table, (gulong)ptr) != NULL) {
- printf("*** block %p appears to already be allocated "
- "- someone must have sneaked a free past us\n", ptr);
- nautilus_leak_hash_table_remove (hash_table, (gulong)ptr);
- }
- /* insert a new item into the hash table, using the block address as the key */
- element = nautilus_leak_hash_table_add (hash_table, (gulong)ptr);
-
- /* fill out the new allocated element */
- nautilus_leak_allocation_record_init (&element->data, ptr, size, trace_array, TRACE_ARRAY_MAX);
-
- pthread_mutex_unlock (&nautilus_leak_hash_table_mutex);
-}
-
-static void
-nautilus_leak_record_realloc (void *old_ptr, void *new_ptr, size_t size)
-{
- void *trace_array [TRACE_ARRAY_MAX];
- NautilusHashEntry *element;
-
- /* printf("reallocing block %p, %d was %p\n", new_ptr, size, old_ptr); */
-
- if (!nautilus_leak_check_leaks)
- return;
-
- get_stack_trace (trace_array, TRACE_ARRAY_MAX);
-
- pthread_mutex_lock (&nautilus_leak_hash_table_mutex);
-
- /* must have hash table by now */
- g_assert (hash_table != NULL);
- /* must have seen the block already */
- element = nautilus_leak_hash_table_find (hash_table, (gulong)old_ptr);
- if (element == NULL) {
- printf("*** we haven't seen block %p yet "
- "- someone must have sneaked a malloc past us\n", old_ptr);
- } else {
- nautilus_leak_malloc_outstanding_size -= element->data.size;
- nautilus_leak_hash_table_remove (hash_table, (gulong)old_ptr);
- }
-
- /* shouldn't have this block yet */
- if (nautilus_leak_hash_table_find (hash_table, (gulong)new_ptr) != NULL) {
- printf("*** block %p appears to already be allocated "
- "- someone must have sneaked a free past us\n", new_ptr);
- nautilus_leak_hash_table_remove (hash_table, (gulong)new_ptr);
- }
-
- /* insert a new item into the hash table, using the block address as the key */
- element = nautilus_leak_hash_table_add (hash_table, (gulong)new_ptr);
- nautilus_leak_malloc_outstanding_size += size;
-
- /* Fill out the new allocated element.
- * This way the last call to relloc will be the stack crawl that shows up in the
- * final balance.
- */
- nautilus_leak_allocation_record_init (&element->data, new_ptr, size, trace_array,
- TRACE_ARRAY_MAX);
-
- pthread_mutex_unlock (&nautilus_leak_hash_table_mutex);
-}
-
-static void
-nautilus_leak_record_free (void *ptr)
-{
- NautilusHashEntry *element;
- /* printf("freeing block %p\n", ptr); */
- if (!nautilus_leak_check_leaks)
- return;
-
- --nautilus_leak_malloc_count;
-
- pthread_mutex_lock (&nautilus_leak_hash_table_mutex);
-
- /* must have hash table by now */
- g_assert (hash_table != NULL);
- /* must have seen the block already */
- element = nautilus_leak_hash_table_find (hash_table, (gulong)ptr);
- if (element == NULL) {
- printf("*** we haven't seen block %p yet "
- "- someone must have sneaked a malloc past us\n", ptr);
- } else {
- nautilus_leak_malloc_outstanding_size -= element->data.size;
- nautilus_leak_hash_table_remove (hash_table, (gulong)ptr);
- }
- pthread_mutex_unlock (&nautilus_leak_hash_table_mutex);
-
-}
-
-static void
-nautilus_leak_initialize_if_needed (void)
-{
- if (nautilus_leak_hooks_initialized)
- return;
-
- if (nautilus_leak_initializing_hooks)
- /* guard against reentrancy */
- return;
-
- nautilus_leak_initializing_hooks = TRUE;
- nautilus_leak_initialize ();
- nautilus_leak_initializing_hooks = FALSE;
-}
-
-/* we are overlaying the original __libc_malloc */
-enum {
- STARTUP_FALLBACK_MEMORY_SIZE = 1024
-};
-
-static int startup_fallback_memory_index = 0;
-static char startup_fallback_memory [STARTUP_FALLBACK_MEMORY_SIZE];
-
-/* If our malloc hook is not installed yet - for instance when we are being
- * called from the initialize_if_needed routine. We have to fall back on
- * returning a chunk of static memory to carry us through the initialization.
- */
-static void *
-allocate_temporary_fallback_memory (ssize_t size)
-{
- void *result;
-
- /* align to natural word boundary */
- size = (size + sizeof(void *) - 1 ) & ~(sizeof(void *) - 1);
- if (size + startup_fallback_memory_index
- > STARTUP_FALLBACK_MEMORY_SIZE) {
- g_warning ("trying to allocate to much space during startup");
- return NULL;
- }
- result = &startup_fallback_memory [startup_fallback_memory_index];
- startup_fallback_memory_index += size;
-
- return result;
-}
-
-void *
-__libc_malloc (size_t size)
-{
- void *result;
-
- nautilus_leak_initialize_if_needed ();
-
- if (real_malloc == NULL) {
- return allocate_temporary_fallback_memory (size);
- }
-
- result = (*real_malloc) (size);
-
- if (result != NULL) {
- if (detect_reentry(&__libc_malloc)
- || detect_reentry(&__libc_realloc)
- || detect_reentry(&__libc_memalign)) {
- /* printf("avoiding reentry in __libc_malloc, block %p\n", result); */
- } else {
- nautilus_leak_record_malloc (result, size);
- }
- }
-
- return result;
-}
-
-void *
-__libc_memalign (size_t boundary, size_t size)
-{
- void *result;
-
- nautilus_leak_initialize_if_needed ();
- result = (*real_memalign) (boundary, size);
-
- if (result != NULL) {
- if (detect_reentry(&__libc_memalign)) {
- /* printf("avoiding reentry in __libc_memalign, block %p\n", result); */
- } else {
- nautilus_leak_record_malloc (result, size);
- }
- }
-
- return result;
-}
-
-/* We are implementing __libc_calloc by calling __libc_malloc and memset
- * instead of calling real_calloc for a reason. dlsym calls
- * calloc and this way we prevent recursion during initialization.
- * If we didn't do this, we would have to teach __libc_calloc to use
- * fallback startup memory like __libc_malloc does.
- */
-void *
-__libc_calloc (size_t count, size_t size)
-{
- size_t total;
- void *result;
-
- total = count * size;
- nautilus_leak_initialize_if_needed ();
- result = __libc_malloc (total);
-
- if (result != NULL) {
- memset (result, 0, total);
- }
-
- return result;
-}
-
-void *
-__libc_realloc (void *ptr, size_t size)
-{
- void *result;
- nautilus_leak_initialize_if_needed ();
- result = (*real_realloc) (ptr, size);
-
- if (detect_reentry(&__libc_realloc)) {
- /* printf("avoiding reentry in __libc_realloc, block %p, old block %p\n",
- result, ptr); */
- } else {
- if (result != NULL && ptr == NULL) {
- /* we are allocating a new block */
- nautilus_leak_record_malloc (result, size);
- } else {
- nautilus_leak_record_realloc (ptr, result, size);
- }
- }
- return result;
-}
-
-void
-__libc_free (void *ptr)
-{
- nautilus_leak_initialize_if_needed ();
-
- if (ptr > (void *)&startup_fallback_memory[0]
- && ptr < (void *)&startup_fallback_memory[STARTUP_FALLBACK_MEMORY_SIZE]) {
- /* this is a temporary startup fallback block, don't do anything
- * with it
- */
- return;
- }
- if (ptr != NULL) {
- if (detect_reentry(&__libc_realloc)) {
- /* printf("avoiding reentry in __libc_free, block %p\n", ptr); */
- } else {
- nautilus_leak_record_free (ptr);
- }
- }
-
- (real_free) (ptr);
-}
-
-static void
-print_leaks_at_exit (void)
-{
- /* If leak checking, dump all the outstanding allocations just before exiting. */
- nautilus_leak_print_leaks (8, 15, 100, TRUE);
-}
-
-int
-__libc_start_main (int (*main) (int, char **, char **), int argc,
- char **argv, void (*init) (void), void (*fini) (void),
- void (*rtld_fini) (void), void *stack_end)
-{
- nautilus_leak_initialize_if_needed ();
-
- nautilus_leak_checker_init (argv[0]);
-
- g_atexit (print_leaks_at_exit);
-
- return real_start_main (main, argc, argv, init, fini, rtld_fini, stack_end);
-}
-
-/* We try to keep a lot of code in between __libc_free and malloc to make
- * the reentry detection that depends on call address proximity work.
- */
-typedef struct {
- int max_count;
- int counter;
- int stack_print_depth;
- int stack_match_depth;
-} PrintOneLeakParams;
-
-/* we don't care if printf, etc. allocates (as long as it doesn't leak)
- * because by now we have a snapshot of the leaks at the time of
- * calling nautilus_leak_print_leaks
- */
-static gboolean
-print_one_leak (NautilusLeakTableEntry *entry, void *context)
-{
- int index;
- PrintOneLeakParams *params = (PrintOneLeakParams *)context;
-
- printf("----------------- total_size %ld count %d -------------------\n",
- (long)entry->total_size, entry->count);
-
- for (index = 0; index < params->stack_print_depth; index++) {
- /* only print stack_grouping worth of stack crawl -
- * beyond that different blocks may have different addresses
- * and we would be printing a lie
- */
- if (entry->sample_allocation->stack_crawl[index] == NULL)
- break;
- printf(" %c ", index >= params->stack_match_depth ? '?' : ' ');
-
- nautilus_leak_print_symbol_address (app_path,
- entry->sample_allocation->stack_crawl[index]);
- }
-
- /* only print max_counter groups */
- return params->counter++ < params->max_count;
-}
-
-void
-nautilus_leak_print_leaks (int stack_grouping_depth, int stack_print_depth,
- int max_count, gboolean sort_by_count)
-{
- NautilusLeakTable *temp_leak_table;
- PrintOneLeakParams each_context;
-
- pthread_mutex_lock (&nautilus_leak_hash_table_mutex);
- /* must have hash table by now */
- g_assert (hash_table != NULL);
-
- /* Build a leak table by grouping blocks with the same
- * stackcrawls (stack_grouping_depth levels considered)
- * from the allocated block hash table.
- */
- temp_leak_table = nautilus_leak_table_new (hash_table, stack_grouping_depth);
- pthread_mutex_unlock (&nautilus_leak_hash_table_mutex);
-
- printf("%d outstanding allocations %d bytes total ============ \n",
- nautilus_leak_malloc_count, nautilus_leak_malloc_outstanding_size);
- printf("stack trace match depth %d\n", stack_grouping_depth);
-
- /* sort the leak table */
- if (sort_by_count) {
- nautilus_leak_table_sort_by_count (temp_leak_table);
- } else {
- nautilus_leak_table_sort_by_size (temp_leak_table);
- }
-
- /* we have a sorted table of all the leakers, we can print it out. */
- each_context.counter = 0;
- each_context.max_count = max_count;
- each_context.stack_print_depth = stack_print_depth;
- each_context.stack_match_depth = stack_grouping_depth;
- nautilus_leak_table_each_item (temp_leak_table, print_one_leak, &each_context);
-
- /* we are done with it, free the leak table */
- nautilus_leak_table_free (temp_leak_table);
-
- /* we are done with it, clean up cached up data used by the symbol lookup */
- nautilus_leak_print_symbol_cleanup ();
-}
-
-void
-nautilus_leak_checker_init (const char *path)
-{
- /* we should get rid of this and find another way to find our
- * binary's name
- */
- printf("setting up the leakchecker for %s\n", path);
- app_path = path;
-
- g_atexit (print_leaks_at_exit);
-}
-
-void *
-malloc (size_t size)
-{
- return __libc_malloc (size);
-}
-
-void *
-realloc (void *ptr, size_t size)
-{
- return __libc_realloc (ptr, size);
-}
-
-void *
-memalign (size_t boundary, size_t size)
-{
- return __libc_memalign (boundary, size);
-}
-
-void *
-calloc (size_t nmemb, size_t size)
-{
- return __libc_calloc (nmemb, size);
-}
-
-void
-free (void *ptr)
-{
- __libc_free (ptr);
-}
-
-#endif
-
-#ifdef LEAK_CHECK_TESTING
-/* normally disabled */
-
-static void
-allocate_lots (int count)
-{
- GList *list;
- GList *p;
-
- list = NULL;
- for (; count > 0; count--) {
- list = g_list_prepend (list, g_malloc (rand() % 256));
- list = g_list_prepend (list, NULL);
- }
- for (p = list; p != NULL; p = p->next) {
- g_free (p->data);
- p->data = NULL;
- }
- g_list_free (list);
-}
-
-
-static void
-leak_mem2 (void)
-{
- int i;
- for (i = 0; i < 40; i++) {
- g_strdup("bla");
- }
- allocate_lots (1280);
-}
-
-static void
-leak_mem (void)
-{
- int i;
- for (i = 0; i < 1010; i++) {
- malloc(13);
- }
- leak_mem2();
- allocate_lots (200);
-}
-
-
-int
-main (int argc, char **argv)
-{
- void *non_leak;
- void *leak;
- int i;
-
- nautilus_leak_checker_init (*argv);
-
- non_leak = g_malloc(100);
- leak = g_malloc(200);
- g_assert(non_leak != NULL);
- non_leak = g_realloc(non_leak, 1000);
- g_assert(non_leak != NULL);
- non_leak = g_realloc(non_leak, 10000);
- leak = g_malloc(200);
- non_leak = g_realloc(non_leak, 100000);
- leak = g_malloc(200);
- g_assert(non_leak != NULL);
- g_free(non_leak);
-
- non_leak = calloc(1, 100);
- g_assert(non_leak != NULL);
- g_free(non_leak);
- leak = g_malloc(200);
-
- non_leak = memalign(16, 100);
- g_assert(non_leak != NULL);
- g_free(non_leak);
- leak = g_malloc(200);
- leak = memalign(16, 100);
- leak = memalign(16, 100);
- leak = memalign(16, 100);
- leak = memalign(16, 100);
- leak = memalign(16, 100);
- leak = memalign(16, 100);
-
- for (i = 0; i < 13; i++) {
- leak = malloc(13);
- }
-
- leak_mem();
- leak_mem2();
-
- allocate_lots (1);
- for (i = 0; i < 100; i++) {
- allocate_lots(rand() % 40);
- }
- printf("done\n");
- nautilus_leak_print_leaks (6, 12, 100, TRUE);
-
- return 0;
-}
-
-
-#endif
diff --git a/test/nautilus-leak-checker.h b/test/nautilus-leak-checker.h
deleted file mode 100644
index b58a633dd..000000000
--- a/test/nautilus-leak-checker.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* nautilus-leak-checker.h - simple leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
- based on MemProf by Owen Taylor, <otaylor@redhat.com>
-*/
-
-#ifndef LEAK_CHECKER_H
-#define LEAK_CHECKER_H
-
-#define LEAK_CHECKER 1
-
-#if LEAK_CHECKER
-
-#define __USE_GNU
-#define _GNU_SOURCE
-/* need this for dlsym */
-#include <pthread.h>
-#include <glib.h>
-
-/* This is a leakchecker simpler than MemProf - it tracks all the outstanding
- * allocations and allows you print a total when your app quits. It doesn't actually
- * try to identify leaks like MemProf does. The entire leakchecker machinery runs
- * in the same process as the target app and shares the same heap for it's data
- * structures.
- */
-
-extern void nautilus_leak_checker_init (const char *app_path);
-
-extern void nautilus_leak_print_leaks (int stack_grouping_depth,
- int stack_print_depth,
- int max_count,
- gboolean sort_by_count);
-
-#endif
-
-#endif
diff --git a/test/nautilus-leak-hash-table.c b/test/nautilus-leak-hash-table.c
deleted file mode 100644
index 5f5b5b5a9..000000000
--- a/test/nautilus-leak-hash-table.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* nautilus-leak-hash-table.c - hash table for a leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
-*/
-
-#include "nautilus-leak-checker.h"
-/* included first, defines following switch*/
-#if LEAK_CHECKER
-
-#include <glib.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "nautilus-leak-checker-stubs.h"
-#include "nautilus-leak-hash-table.h"
-
-/* We have our own hash table here mainly to allow avoiding calls to
- * malloc and realloc that would cause reentry
- */
-
-static void
-nautilus_leak_hash_element_finalize (NautilusHashEntry *element)
-{
- nautilus_leak_allocation_record_finalize (&element->data);
- memset (element, 0, sizeof(NautilusHashEntry));
-}
-
-static unsigned long
-nautilus_leak_hash_element_hash (NautilusHashEntry *element)
-{
- return (unsigned long)element->data.block;
-}
-
-static gboolean
-nautilus_leak_hash_element_match (NautilusHashEntry *element, unsigned long key)
-{
- return (unsigned long)element->data.block == key;
-}
-
-/* NautilusHashEntries are allocated inside a NautilusHashEntryVector.
- * NautilusHashEntryVector keeps a linked list of deleted entries.
- */
-typedef struct {
- NautilusHashEntry *data;
- size_t size;
- int next_free;
- int next_deleted;
-} NautilusHashEntryVector;
-
-static void
-nautilus_leak_hash_element_vector_inititalize (NautilusHashEntryVector *vector, size_t initial_size)
-{
- int index;
-
- vector->data = (NautilusHashEntry *)real_malloc(initial_size * sizeof(NautilusHashEntry));
- if (vector->data == NULL) {
- g_warning ("leak checker out of memory");
- abort();
- }
- memset (vector->data, 0, initial_size * sizeof(NautilusHashEntry));
- for (index = initial_size - 1; index >= 0; index --) {
- vector->data[index].next = -1;
- }
-
- vector->size = initial_size;
- vector->next_free = 0;
- vector->next_deleted = -1;
-}
-
-static void
-nautilus_leak_hash_element_vector_finalize (NautilusHashEntryVector *vector)
-{
- int index;
- for (index = 0; index < vector->size; index++) {
- nautilus_leak_hash_element_finalize (&vector->data[index]);
- }
- real_free (vector->data);
-}
-
-static NautilusHashEntry *
-nautilus_leak_hash_element_vector_at (NautilusHashEntryVector *vector, int index)
-{
- return &vector->data[index];
-}
-
-enum {
- HASH_ELEMENT_VECTOR_GROW_CHUNK = 1024
-};
-
-static int
-nautilus_leak_hash_element_vector_add (NautilusHashEntryVector *vector)
-{
- int index;
- NautilusHashEntry *new_element;
- size_t new_size;
- NautilusHashEntry *new_data;
-
- if (vector->next_deleted >= 0) {
- /* Reuse a previously deleted item. */
- index = vector->next_deleted;
- vector->next_deleted = nautilus_leak_hash_element_vector_at (vector, index)->next;
- } else if (vector->next_free >= vector->size - 1) {
- /* We need grow the vector because it cannot fit more entries. */
- new_size = vector->size + HASH_ELEMENT_VECTOR_GROW_CHUNK;
- new_data = (NautilusHashEntry *)real_malloc(new_size * sizeof(NautilusHashEntry));
- if (new_data == NULL) {
- g_warning ("leak checker out of memory");
- abort();
- }
- /* FIXME: only clean the unused part */
- memset (new_data, 0, new_size * sizeof(NautilusHashEntry));
-
- /* copy all the existing items over*/
- memcpy (new_data, vector->data, vector->size * sizeof(NautilusHashEntry));
- /* delete the old array */
- real_free (vector->data);
- vector->data = new_data;
- vector->size = new_size;
- index = vector->next_free;
- ++vector->next_free;
- } else {
- /* Just take the next free item. */
- index = vector->next_free;
- ++vector->next_free;
- }
-
- /* Initialize the new element to an empty state. */
- new_element = nautilus_leak_hash_element_vector_at (vector, index);
- memset (new_element, 0, sizeof(NautilusHashEntry));
- new_element->next = -1;
-
- return index;
-}
-
-static void
-nautilus_leak_hash_element_vector_remove (NautilusHashEntryVector *vector, int index)
-{
- /* free the data */
- nautilus_leak_hash_element_finalize (&vector->data[index]);
-
- /* insert item as first into deleted item list */
- nautilus_leak_hash_element_vector_at (vector, index)->next = vector->next_deleted;
- vector->next_deleted = index;
-}
-
-struct NautilusLeakHashTable {
- size_t array_size;
- int *hash_array;
- NautilusHashEntryVector element_vector;
-};
-
-/* These primes are close to 2^n numbers for optimal hashing performance
- * and near-2^n size.
- */
-long nautilus_leak_hash_table_primes [] = {
- 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
- 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859,
- 134217689, 268435399, 536870909, 1073741789, 2147483647, 0
-};
-
-
-static size_t
-nautilus_leak_hash_table_optimal_size (size_t size)
-{
- int index;
- for (index = 0; ; index++) {
- if (!nautilus_leak_hash_table_primes [index] || nautilus_leak_hash_table_primes [index] >= size) {
- return nautilus_leak_hash_table_primes [index];
- }
- }
-
- return 0;
-}
-
-static void
-nautilus_leak_hash_table_initialize (NautilusLeakHashTable *table, size_t initial_size)
-{
- /* calculate the size of the bucket array */
- table->array_size = nautilus_leak_hash_table_optimal_size (initial_size);
-
- /* allocate the element array */
- nautilus_leak_hash_element_vector_inititalize (&table->element_vector, table->array_size * 5);
-
- /* allocate the bucket array */
- table->hash_array = (int *)real_malloc (table->array_size * sizeof(int));
-
- /* initialize the to empty state */
- memset (table->hash_array, -1, table->array_size * sizeof(int));
-}
-
-static void
-nautilus_leak_hash_table_finalize (NautilusLeakHashTable *table)
-{
- nautilus_leak_hash_element_vector_finalize (&table->element_vector);
- real_free (table->hash_array);
-}
-
-NautilusLeakHashTable *
-nautilus_leak_hash_table_new (size_t initial_size)
-{
- NautilusLeakHashTable *new_table;
- new_table = real_malloc (sizeof(NautilusLeakHashTable));
- nautilus_leak_hash_table_initialize (new_table, initial_size);
-
- return new_table;
-}
-
-void
-nautilus_leak_hash_table_free (NautilusLeakHashTable *hash_table)
-{
- nautilus_leak_hash_table_finalize (hash_table);
- real_free (hash_table);
-}
-
-static unsigned long
-nautilus_leak_hash_table_hash (NautilusLeakHashTable *table, unsigned long seed)
-{
- return (seed >> 2) % table->array_size;
-}
-
-NautilusHashEntry *
-nautilus_leak_hash_table_find (NautilusLeakHashTable *table, unsigned long key)
-{
- int index;
- NautilusHashEntry *result;
-
- for (index = table->hash_array [nautilus_leak_hash_table_hash (table, key)]; index >= 0;) {
- result = nautilus_leak_hash_element_vector_at (&table->element_vector, index);
- if (nautilus_leak_hash_element_match (result, key)) {
- return result;
- }
- index = result->next;
- }
-
- return NULL;
-}
-
-NautilusHashEntry *
-nautilus_leak_hash_table_add (NautilusLeakHashTable *table, unsigned long key)
-{
- int new_index;
- NautilusHashEntry *result;
- unsigned long hash;
-
- /* calculate the index of the bucket */
- hash = nautilus_leak_hash_table_hash (table, key);
-
- /* allocate space for new item in element vector */
- new_index = nautilus_leak_hash_element_vector_add (&table->element_vector);
- result = nautilus_leak_hash_element_vector_at (&table->element_vector, new_index);
-
- /* insert new item first in the list for bucket <hash> */
- result->next = table->hash_array[hash];
- table->hash_array[hash] = new_index;
-
- return result;
-}
-
-static void
-nautilus_leak_hash_table_remove_element (NautilusLeakHashTable *table, NautilusHashEntry *element)
-{
- unsigned long hash;
- int next;
- int index;
- NautilusHashEntry *tmp_element;
-
- /* find the bucket */
- hash = nautilus_leak_hash_table_hash (table, nautilus_leak_hash_element_hash (element));
- next = table->hash_array[hash];
-
- g_assert (next >= 0);
-
- /* try to match bucket list head */
- if (nautilus_leak_hash_element_vector_at (&table->element_vector, next) == element) {
- table->hash_array[hash] = element->next;
- nautilus_leak_hash_element_vector_remove (&table->element_vector, next);
- return;
- }
-
- for (index = next; index >= 0; ) {
- /* look for an existing match in table */
- next = nautilus_leak_hash_element_vector_at (&table->element_vector, index)->next;
- if (next < 0) {
- g_assert (!"should not be here");
- return;
- }
-
- tmp_element = nautilus_leak_hash_element_vector_at (&table->element_vector, index);
- if (nautilus_leak_hash_element_vector_at (&table->element_vector, next) == element) {
- nautilus_leak_hash_element_vector_at (&table->element_vector, index)->next = element->next;
- nautilus_leak_hash_element_vector_remove (&table->element_vector, next);
- return;
- }
- index = next;
- }
-}
-
-gboolean
-nautilus_leak_hash_table_remove (NautilusLeakHashTable *table, unsigned long key)
-{
- NautilusHashEntry *element;
-
- element = nautilus_leak_hash_table_find (table, key);
- if (element != NULL) {
- /* FIXME: this could be faster if we just found the element
- * here and deleted it.
- */
- nautilus_leak_hash_table_remove_element (table, element);
-
- return TRUE;
- }
- return FALSE;
-}
-
-struct NautilusLeakTable {
- size_t size;
- NautilusLeakTableEntry *data;
-};
-
-static NautilusLeakTableEntry *
-nautilus_leak_table_new_entry_at (NautilusLeakTable *table, int index)
-{
- /* Allocate a new slot. Avoid using real_realloc here because
- * it ends up calling our version of __libc_malloc and messes up
- * the leak table
- */
- NautilusLeakTableEntry *new_table = (NautilusLeakTableEntry *) real_malloc
- ((table->size + 1) * sizeof (NautilusLeakTableEntry));
-
- if (new_table == NULL) {
- g_warning ("Ran out of memory while allocating leak checker structures");
- abort ();
- }
-
- /* finish what realloc would have done if we could call it */
- memcpy (new_table, table->data, (table->size) * sizeof (NautilusLeakTableEntry));
- real_free (table->data);
- table->data = new_table;
-
- /* move the items over by one to make room for new item */
- if (index < table->size) {
- memmove (&table->data[index + 1],
- &table->data[index],
- (table->size - index) * sizeof (NautilusLeakTableEntry));
- }
-
- table->size++;
-
- return &table->data[index];
-}
-
-static void
-nautilus_leak_table_add_entry (NautilusLeakTable *table, NautilusHashEntry *entry, int stack_grouping_depth)
-{
- int r, l;
- int resulting_index;
- int compare_result;
-
- /* do a binary lookup of the item */
- r = table->size - 1;
- resulting_index = 0;
- compare_result = 0;
-
- for (l = 0; l <= r; ) {
- resulting_index = (l + r) / 2;
-
- compare_result = nautilus_leak_stack_crawl_compare (
- table->data[resulting_index].sample_allocation->stack_crawl,
- entry->data.stack_crawl,
- stack_grouping_depth);
-
- if (compare_result > 0) {
- r = resulting_index - 1;
- } else if (compare_result < 0) {
- l = resulting_index + 1;
- } else {
- break;
- }
- }
-
- if (compare_result < 0) {
- resulting_index++;
- }
-
- if (compare_result == 0 && resulting_index < table->size) {
- /* we already have a match, just bump up the count and size */
- table->data[resulting_index].count++;
- table->data[resulting_index].total_size += entry->data.size;
- return;
- }
-
- nautilus_leak_table_new_entry_at (table, resulting_index);
- table->data[resulting_index].count = 1;
- table->data[resulting_index].total_size = entry->data.size;
- table->data[resulting_index].sample_allocation = nautilus_leak_allocation_record_copy (&entry->data);
-}
-
-NautilusLeakTable *
-nautilus_leak_table_new (NautilusLeakHashTable *hash_table, int stack_grouping_depth)
-{
- NautilusLeakTable *result;
- NautilusHashEntry *nautilus_leak_hash_table_entry;
- int index;
-
- result = real_malloc (sizeof(NautilusLeakTable));
- result->size = 0;
- result->data = NULL;
-
- for (index = 0; index < hash_table->element_vector.size; index++) {
- /* traverse the hash table element vector */
- nautilus_leak_hash_table_entry = nautilus_leak_hash_element_vector_at (&hash_table->element_vector, index);
- if (nautilus_leak_hash_table_entry->data.stack_crawl != NULL) {
- nautilus_leak_table_add_entry (result, nautilus_leak_hash_table_entry, stack_grouping_depth);
- }
- }
-
- return result;
-}
-
-void
-nautilus_leak_table_free (NautilusLeakTable *leak_table)
-{
- int index;
- if (leak_table != NULL) {
- for (index = 0; index < leak_table->size; index++) {
- nautilus_leak_allocation_record_free(leak_table->data[index].sample_allocation);
- }
- real_free (leak_table->data);
- }
-
- real_free (leak_table);
-}
-
-static int
-sort_by_count (const void *entry1, const void *entry2)
-{
- int result;
-
- result = ((NautilusLeakTableEntry *)entry2)->count
- - ((NautilusLeakTableEntry *)entry1)->count;
-
- if (result == 0) {
- /* match, secondary sort order by size */
- return ((NautilusLeakTableEntry *)entry2)->total_size
- - ((NautilusLeakTableEntry *)entry1)->total_size;
- }
- return result;
-}
-
-void
-nautilus_leak_table_sort_by_count (NautilusLeakTable *leak_table)
-{
- qsort (leak_table->data, leak_table->size,
- sizeof(NautilusLeakTableEntry), sort_by_count);
-}
-
-static int
-sort_by_size (const void *entry1, const void *entry2)
-{
- int result;
-
- result = ((NautilusLeakTableEntry *)entry2)->total_size
- - ((NautilusLeakTableEntry *)entry1)->total_size;
-
- if (result == 0) {
- /* match, secondary sort order by count */
- return ((NautilusLeakTableEntry *)entry2)->count
- - ((NautilusLeakTableEntry *)entry1)->count;
- }
- return result;
-}
-
-void
-nautilus_leak_table_sort_by_size (NautilusLeakTable *leak_table)
-{
- qsort (leak_table->data, leak_table->size,
- sizeof (NautilusLeakTableEntry), sort_by_size);
-}
-
-void
-nautilus_leak_table_each_item (NautilusLeakTable *leak_table, NautilusEachLeakTableFunction function,
- void *context)
-{
- int index;
- for (index = 0; index < leak_table->size; index++) {
- if (!function (&leak_table->data[index], context)) {
- /* break early */
- return;
- }
- }
-}
-
-#endif \ No newline at end of file
diff --git a/test/nautilus-leak-hash-table.h b/test/nautilus-leak-hash-table.h
deleted file mode 100644
index 08e295417..000000000
--- a/test/nautilus-leak-hash-table.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* nautilus-leak-hash-table.h - hash table for a leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
-*/
-
-#ifndef LEAK_HASH_TABLE__
-#define LEAK_HASH_TABLE__
-
-typedef struct NautilusLeakHashTable NautilusLeakHashTable;
-typedef struct NautilusHashEntry NautilusHashEntry;
-
-NautilusLeakHashTable *nautilus_leak_hash_table_new (size_t initial_size);
-void nautilus_leak_hash_table_free (NautilusLeakHashTable *hash_table);
-gboolean nautilus_leak_hash_table_remove (NautilusLeakHashTable *table,
- unsigned long key);
-NautilusHashEntry *nautilus_leak_hash_table_add (NautilusLeakHashTable *table,
- unsigned long key);
-NautilusHashEntry *nautilus_leak_hash_table_find (NautilusLeakHashTable *table,
- unsigned long key);
-
-
-typedef struct {
- int count;
- size_t total_size;
- NautilusLeakAllocationRecord *sample_allocation;
-} NautilusLeakTableEntry;
-
-typedef struct NautilusLeakTable NautilusLeakTable;
-typedef gboolean (* NautilusEachLeakTableFunction) (NautilusLeakTableEntry *entry, void *context);
-
-NautilusLeakTable *nautilus_leak_table_new (NautilusLeakHashTable *hash_table,
- int stack_grouping_depth);
-void nautilus_leak_table_free (NautilusLeakTable *leak_table);
-void nautilus_leak_table_sort_by_count (NautilusLeakTable *leak_table);
-void nautilus_leak_table_sort_by_size (NautilusLeakTable *leak_table);
-void nautilus_leak_table_each_item (NautilusLeakTable *leak_table,
- NautilusEachLeakTableFunction function,
- void *context);
-#endif \ No newline at end of file
diff --git a/test/nautilus-leak-symbol-lookup.c b/test/nautilus-leak-symbol-lookup.c
deleted file mode 100644
index f52c75040..000000000
--- a/test/nautilus-leak-symbol-lookup.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/* nautilus-leak-symbol-lookup.c - symbol lookup for a leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
- based on MemProf by Owen Taylor, <otaylor@redhat.com>
-*/
-
-#define _GNU_SOURCE
- /* need this for dladdr */
-
-#include "nautilus-leak-symbol-lookup.h"
-
-#include <bfd.h>
-#include <dlfcn.h>
-#include <glib.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-
-static GList *symbol_table_list;
-
-typedef struct {
- char *path;
- bfd *abfd;
- asymbol **symbol_table;
- asection *text_section;
- unsigned long start;
- unsigned long end;
-} NautilusLeakSymbolLookupMap;
-
-static gboolean
-nautilus_leak_find_symbol_in_map (const NautilusLeakSymbolLookupMap *map,
- unsigned long address, char **function_name, char **source_file_name,
- unsigned int *line)
-{
- const char *file;
- const char *function;
-
- address -= map->start;
- address -= map->text_section->vma;
-
- if (address < 0 || address > map->text_section->_cooked_size) {
- /* not a valid address range for this binary */
- return FALSE;
- }
-
- if (!bfd_find_nearest_line (map->abfd, map->text_section, map->symbol_table,
- address,
- &file, &function, line)) {
- printf ("error looking up address in binary %s\n", map->path);
- return FALSE;
- }
-
- *function_name = g_strdup (function);
- *source_file_name = g_strdup (file);
-
- return TRUE;
-}
-
-static void
-nautilus_leak_symbol_map_get_offsets (NautilusLeakSymbolLookupMap *map)
-{
- gchar buffer[1024];
- FILE *in;
- gchar perms[26];
- gchar file[256];
- unsigned long start, end;
- guint major, minor;
- ino_t inode;
- struct stat library_stat;
- struct stat entry_stat;
- int count;
-
- /* find the library we are looking for in the proc directories
- * to find out at which addresses it is mapped
- */
- snprintf (buffer, 1023, "/proc/%d/maps", getpid());
- in = fopen (buffer, "r");
-
- if (stat (map->path, &library_stat) != 0) {
- /* we will use st_ino and st_dev to do a file match */
- return;
- }
-
- while (fgets(buffer, 1023, in)) {
- gulong tmp;
-
- count = sscanf (buffer, "%lx-%lx %15s %*x %u:%u %lu %255s",
- &start, &end, perms, &major, &minor, &tmp, file);
- inode = tmp;
-
- if (count >= 6 && strcmp (perms, "r-xp") == 0) {
- if (stat (file, &entry_stat) != 0) {
- break;
- }
- /* check if this is the library we are loading */
- if (library_stat.st_ino == entry_stat.st_ino
- && library_stat.st_dev == entry_stat.st_dev) {
- map->start = start;
- map->end = end;
-
- break;
- }
- }
- }
- fclose (in);
-}
-
-static NautilusLeakSymbolLookupMap *
-nautilus_leak_symbol_map_load (const char *binary_path, gboolean executable)
-{
- NautilusLeakSymbolLookupMap *map;
- char *target = NULL;
- size_t storage_needed;
- int number_of_symbols;
-
- map = g_new0 (NautilusLeakSymbolLookupMap, 1);
-
- map->abfd = bfd_openr (binary_path, target);
-
- if (map->abfd == NULL) {
- fprintf (stderr, "%s: ", binary_path);
- bfd_perror (binary_path);
- return NULL;
- }
-
- if (!bfd_check_format (map->abfd, bfd_object)) {
- fprintf (stderr, "%s is not an object file\n", binary_path);
- bfd_close (map->abfd);
- return NULL;
- }
-
- /* Use the ".text" section. */
- map->text_section = bfd_get_section_by_name (map->abfd, ".text");
-
- /* Read the symbol table. */
- storage_needed = bfd_get_symtab_upper_bound (map->abfd);
- if (storage_needed == 0) {
- fprintf (stderr, "no symbols\n");
- bfd_close (map->abfd);
- return NULL;
- }
- map->symbol_table = (asymbol **)g_malloc (storage_needed);
- if (map->symbol_table == NULL) {
- fprintf (stderr, "no memory allocating symbol table\n");
- bfd_close (map->abfd);
- return NULL;
- }
- number_of_symbols = bfd_canonicalize_symtab (map->abfd, map->symbol_table);
- map->path = g_strdup (binary_path);
-
- if (!executable) {
- nautilus_leak_symbol_map_get_offsets (map);
- }
- symbol_table_list = g_list_append (symbol_table_list, map);
-
- return map;
-}
-
-static NautilusLeakSymbolLookupMap *
-nautilus_leak_symbol_map_load_if_needed (const char *binary_path, gboolean executable)
-{
- GList *p;
- NautilusLeakSymbolLookupMap *map;
-
- for (p = symbol_table_list; p != NULL; p = p->next) {
- map = p->data;
- if (strcmp (map->path, binary_path) == 0)
- /* no need to load the symbols, already got the map */
- return map;
- }
- return nautilus_leak_symbol_map_load (binary_path, executable);
-}
-
-void
-nautilus_leak_print_symbol_cleanup (void)
-{
- /* free the cached symbol tables */
- GList *p;
- NautilusLeakSymbolLookupMap *map;
-
- for (p = symbol_table_list; p != NULL; p = p->next) {
- map = p->data;
- bfd_close (map->abfd);
- g_free (map->symbol_table);
- g_free (map->path);
-
- g_free (map);
- }
-
- g_list_free (symbol_table_list);
- symbol_table_list = NULL;
-}
-
-static gboolean
-nautilus_leak_find_symbol_address (void *address, char **function_name, char **source_file_name,
- int *line)
-{
- GList *p;
- NautilusLeakSymbolLookupMap *map;
- Dl_info info;
-
- if (dladdr (address, &info) != 0) {
- /* We know the function name and the binary it lives in, now try to find
- * the function and the offset.
- */
- map = nautilus_leak_symbol_map_load_if_needed (info.dli_fname, false);
- if (map != NULL
- && nautilus_leak_find_symbol_in_map (map, (long)address,
- function_name, source_file_name, line)) {
- return TRUE;
- }
- /* just return the function name and the library binary path */
- *function_name = g_strdup (info.dli_sname);
- *source_file_name = g_strdup (info.dli_fname);
- *line = -1;
- return TRUE;
- } else {
- /* Usually dladdr will succeed, it seems to only fail for
- * address lookups for functions in the main binary.
- */
- for (p = symbol_table_list; p != NULL; p = p->next) {
- map = p->data;
- if (nautilus_leak_find_symbol_in_map (map, (long)address, function_name,
- source_file_name, (unsigned int *)line))
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void
-nautilus_leak_print_symbol_address (const char *app_path, void *address)
-{
- char *function_name;
- char *source_file_name;
- int line;
-
- nautilus_leak_symbol_map_load_if_needed (app_path, true);
-
- if (nautilus_leak_find_symbol_address (address, &function_name, &source_file_name, &line)) {
- if (line >= 0) {
- printf("%10p %-30s %s:%d\n", address, function_name, source_file_name, line);
- } else {
- printf("%10p %-30s in library %s\n", address, function_name, source_file_name);
- }
- g_free (function_name);
- g_free (source_file_name);
- } else {
- printf("%p (unknown function)\n", address);
- }
-}
diff --git a/test/nautilus-leak-symbol-lookup.h b/test/nautilus-leak-symbol-lookup.h
deleted file mode 100644
index c56f00a1c..000000000
--- a/test/nautilus-leak-symbol-lookup.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* nautilus-leak-symbol-lookup.h - symbol lookup for a leak checking library
- Virtual File System Library
-
- Copyright (C) 2000 Eazel
-
- The Gnome Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Pavel Cisler <pavel@eazel.com>
- based on MemProf by Owen Taylor, <otaylor@redhat.com>
-*/
-
-#ifndef SYMBOL_LOOKUP_H
-#define SYMBOL_LOOKUP_
-
-void nautilus_leak_print_symbol_address (const char *app_path, void *address);
-void nautilus_leak_print_symbol_cleanup (void);
-
-#endif