mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-08-25 02:36:07 +00:00
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.
This commit is contained in:
parent
bd52afb29f
commit
858e160f9c
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
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):
|
||||
Redid symbol lookup to work better in some cases where dladdr
|
||||
would not give us the right function.
|
||||
|
||||
* test/nautilus-leak-checker.c: (allocate_lots), (leak_mem2),
|
||||
(leak_mem), (main):
|
||||
tweaks to testing code.
|
||||
|
||||
2000-06-13 Rebecca Schulman <rebecka@eazel.com>
|
||||
Initial changes to implement search architecture.
|
||||
|
||||
|
|
|
@ -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 \
|
||||
$(NULL)
|
||||
|
||||
# we need to link libbfd and liberty statically
|
||||
# this is currently broken because of libtool dumbness
|
||||
|
||||
# LIBLEAKCHECK_STATIC_LIBS = "-Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic"
|
||||
|
||||
libleakcheck_la_LDFLAGS = -module -avoid-version $(LIBLEAKCHECK_STATIC_LIBS)
|
||||
libleakcheck_la_LIBADD = -ldl
|
||||
#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 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
|
||||
# the libtool way of building libleakcheck.so is totally broken, libtool cannot
|
||||
# build an .so with statically linked -liberty
|
||||
|
||||
libleakcheck.la: $(libleakcheck_la_OBJECTS) $(libleakcheck_la_DEPENDENCIES)
|
||||
$(LINK) -rpath $(libdir) $(libleakcheck_la_LDFLAGS) $(libleakcheck_la_OBJECTS) $(libleakcheck_la_LIBADD) $(LIBS)
|
||||
# LIBLEAKCHECK_STATIC_LIBS = "-Wl,-Bstatic -lbfd -liberty -Wl,-Bdynamic"
|
||||
#libleakcheck_la_LDFLAGS = -module -avoid-version $(LIBLEAKCHECK_STATIC_LIBS)
|
||||
#libleakcheck_la_LIBADD = -ldl
|
||||
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
install: libleakcheck.so
|
||||
cp -f libleakcheck.so $(DESTDIR)$(libdir)
|
|
@ -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 = 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 = 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 = 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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue