summaryrefslogtreecommitdiff
path: root/tools/profiler/nautilus-leak-symbol-lookup.C
diff options
context:
space:
mode:
Diffstat (limited to 'tools/profiler/nautilus-leak-symbol-lookup.C')
-rw-r--r--tools/profiler/nautilus-leak-symbol-lookup.C301
1 files changed, 0 insertions, 301 deletions
diff --git a/tools/profiler/nautilus-leak-symbol-lookup.C b/tools/profiler/nautilus-leak-symbol-lookup.C
deleted file mode 100644
index 02120bae9..000000000
--- a/tools/profiler/nautilus-leak-symbol-lookup.C
+++ /dev/null
@@ -1,301 +0,0 @@
-/* nautilus-leak-symbol-lookup.C - symbol lookup for a leak checking and profiling
- 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>
-*/
-
-/* Copied from the leakchecker with a few minor tweaks.
- * FIXME: need to consolidate this with the leakchecker version and
- * only have one copy for both
- */
-#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 > 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;
- }
- if (file == NULL || function == NULL) {
- 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 = (NautilusLeakSymbolLookupMap *)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 = (NautilusLeakSymbolLookupMap *)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);
-
- /* temporarily force a dladdr-only lookup.
- * should make the bfd symbol lookup work.
- */
- if (map != NULL
- && nautilus_leak_find_symbol_in_map (map, (long)address,
- function_name, source_file_name, (unsigned int *)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 = (NautilusLeakSymbolLookupMap *)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
-get_function_at_address (const char *app_path, void *address, string &result)
-{
- 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)) {
- result = function_name;
-
- g_free (function_name);
- g_free (source_file_name);
- } else {
- result = "unknown function";
- }
-}
-
-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);
- }
-}