diff options
author | Pavel Cisler <pavel@eazel.com> | 2000-06-14 05:20:04 +0000 |
---|---|---|
committer | Pavel Cisler <pce@src.gnome.org> | 2000-06-14 05:20:04 +0000 |
commit | 858e160f9c4e238508389c6e3c55be7087370966 (patch) | |
tree | aa0e54e1e9f26cd51bd2084e464484c119122cf8 /test | |
parent | bd52afb29f404257477d3ff1bd2e1e9d8a994db4 (diff) | |
download | nautilus-858e160f9c4e238508389c6e3c55be7087370966.tar.gz |
Couldn't figure out how to build the leakchecker shared library with
2000-06-13 Pavel Cisler <pavel@eazel.com>
* test/Makefile.am:
Couldn't figure out how to build the leakchecker shared library
with libtool, added a simple link rule instead.
* test/nautilus-leak-symbol-lookup.c:
(nautilus_leak_find_symbol_in_map),
(nautilus_leak_symbol_map_get_offsets),
(nautilus_leak_symbol_map_load),
(nautilus_leak_symbol_map_load_if_needed),
(nautilus_leak_find_symbol_address),
(nautilus_leak_print_symbol_address):
Redo symbol lookup to work better in some cases.
* test/nautilus-leak-checker.c: (allocate_lots), (leak_mem2),
(leak_mem), (main):
tweaks to testing code.
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 49 | ||||
-rw-r--r-- | test/nautilus-leak-checker.c | 87 | ||||
-rw-r--r-- | test/nautilus-leak-symbol-lookup.c | 79 |
3 files changed, 135 insertions, 80 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index 2f84aa833..877a7e307 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,6 @@ NULL= -lib_LTLIBRARIES = libleakcheck.la +#lib_LTLIBRARIES = libleakcheck.la INCLUDES =\ -I$(top_srcdir) \ @@ -40,32 +40,37 @@ test_nautilus_mime_actions_SOURCES = test-nautilus-mime-actions.c test_nautilus_mime_actions_set_SOURCES = test-nautilus-mime-actions-set.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 \ +#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) -# we need to link libbfd and liberty statically -# this is currently broken because of libtool dumbness +# 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_LDFLAGS = -module -avoid-version $(LIBLEAKCHECK_STATIC_LIBS) +#libleakcheck_la_LIBADD = -ldl -libleakcheck_la_LDFLAGS = -module -avoid-version $(LIBLEAKCHECK_STATIC_LIBS) -libleakcheck_la_LIBADD = -ldl -EXTRA_DIST = \ - test-nautilus-mime-actions.c \ - $(NULL) -# the link rule is here so we can remove -rpath $(libdir) -# however - -# if we leave -rpath $(libdir) here, libtool refuses to link with -liberty -# if we dont, .libs/libleakcheck.lai doesn't get generated and make install fails +# libleakcheck.la: $(libleakcheck_la_OBJECTS) $(libleakcheck_la_DEPENDENCIES) +# $(LINK) -rpath $(libdir) $(libleakcheck_la_LDFLAGS) $(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 +libleakcheck.so: nautilus-leak-checker.c nautilus-leak-hash-table.c nautilus-leak-symbol-lookup.c + gcc nautilus-leak-checker.c nautilus-leak-hash-table.c nautilus-leak-symbol-lookup.c -Wall -o $@ -shared -I/gnome/include -I/gnome/lib/glib/include -L/gnome/lib -lglib -lpthread -ldl -Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic -libleakcheck.la: $(libleakcheck_la_OBJECTS) $(libleakcheck_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libleakcheck_la_LDFLAGS) $(libleakcheck_la_OBJECTS) $(libleakcheck_la_LIBADD) $(LIBS) +install: libleakcheck.so + cp -f libleakcheck.so $(DESTDIR)$(libdir)
\ No newline at end of file diff --git a/test/nautilus-leak-checker.c b/test/nautilus-leak-checker.c index ffc105607..96f577942 100644 --- a/test/nautilus-leak-checker.c +++ b/test/nautilus-leak-checker.c @@ -599,91 +599,94 @@ nautilus_leak_checker_init (const char *path) /* normally disabled */ static void -allocate_lots(int count) +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, g_malloc (rand() % 256)); + list = g_list_prepend (list, NULL); } for (p = list; p != NULL; p = p->next) { - g_free (p->data); +// g_free (p->data); + p->data = NULL; } g_list_free (list); } static void -leak_mem2(void) +leak_mem2 (void) { int i; for (i = 0; i < 40; i++) { - g_strdup("bla"); +// g_strdup("bla"); } - allocate_lots (128); +// allocate_lots (1280); } static void -leak_mem(void) +leak_mem (void) { int i; for (i = 0; i < 1010; i++) { - malloc(13); +// malloc(13); } leak_mem2(); - allocate_lots (200); +// allocate_lots (200); } int main (int argc, char **argv) { - void *non_leak; - void *leak; +// 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); +// 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 = malloc(13); } leak_mem(); leak_mem2(); - for (i = 0; i < 100; i++) { - allocate_lots(rand() % 40); - } + allocate_lots (1); +// for (i = 0; i < 100; i++) { +// allocate_lots(rand() % 40); +// } printf("done\n"); nautilus_leak_print_leaks (6, 12, 20, TRUE); diff --git a/test/nautilus-leak-symbol-lookup.c b/test/nautilus-leak-symbol-lookup.c index 41f00d888..d7f8b8640 100644 --- a/test/nautilus-leak-symbol-lookup.c +++ b/test/nautilus-leak-symbol-lookup.c @@ -22,7 +22,7 @@ based on MemProf by Owen Taylor, <otaylor@redhat.com> */ -#define _GNU_SOURCE +#define _GNU_SOURCE /* need this for dladdr */ #include "nautilus-leak-symbol-lookup.h" @@ -43,17 +43,19 @@ typedef struct { 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, unsigned long offset, const char *known_function_name) + unsigned int *line) { const char *file; const char *function; - address -= offset; + address -= map->start; address -= map->text_section->vma; if (address < 0 || address > map->text_section->_cooked_size) { @@ -68,18 +70,61 @@ nautilus_leak_find_symbol_in_map (const NautilusLeakSymbolLookupMap *map, return FALSE; } - if (known_function_name != NULL && - strcmp (function, known_function_name) != 0) { - 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]; + guint64 start, end; + guint major, minor; + guint64 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)) { + + count = sscanf (buffer, "%Lx-%Lx %15s %*x %u:%u %Lu %255s", + &start, &end, perms, &major, &minor, &inode, file); + + 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 = (unsigned long)start; + map->end = (unsigned long)end; + + break; + } + } + } + fclose (in); +} + static NautilusLeakSymbolLookupMap * -nautilus_leak_symbol_map_load (const char *binary_path) +nautilus_leak_symbol_map_load (const char *binary_path, gboolean executable) { NautilusLeakSymbolLookupMap *map; char *target = NULL; @@ -120,14 +165,17 @@ nautilus_leak_symbol_map_load (const char *binary_path) } 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) +nautilus_leak_symbol_map_load_if_needed (const char *binary_path, gboolean executable) { GList *p; NautilusLeakSymbolLookupMap *map; @@ -138,7 +186,7 @@ nautilus_leak_symbol_map_load_if_needed (const char *binary_path) /* no need to load the symbols, already got the map */ return map; } - return nautilus_leak_symbol_map_load (binary_path); + return nautilus_leak_symbol_map_load (binary_path, executable); } void @@ -173,11 +221,10 @@ nautilus_leak_find_symbol_address (void *address, char **function_name, char **s /* 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); + 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, - (unsigned long)info.dli_fbase, info.dli_sname)) { + function_name, source_file_name, line)) { return TRUE; } /* just return the function name and the library binary path */ @@ -192,7 +239,7 @@ nautilus_leak_find_symbol_address (void *address, char **function_name, char **s 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, 0, NULL)) + source_file_name, (unsigned int *)line)) return TRUE; } } @@ -207,7 +254,7 @@ nautilus_leak_print_symbol_address (const char *app_path, void *address) char *source_file_name; int line; - nautilus_leak_symbol_map_load_if_needed (app_path); + 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) { |