diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2007-12-05 19:43:07 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2007-12-05 19:43:07 +0000 |
commit | 0c523f03ab4967cdc8e0a62f4c337ebaa036b4b3 (patch) | |
tree | fb350af2ff7d9ba754454f3b9ad59b05942abb19 /src | |
parent | 62eebdabc278dfd3440ba6032c10b2c2c1f95081 (diff) |
Batch symbol lookups and release parsers.
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 3 | ||||
-rw-r--r-- | src/frames.c | 30 | ||||
-rw-r--r-- | src/shared-objects.c | 96 | ||||
-rw-r--r-- | src/shared-objects.h | 23 |
4 files changed, 104 insertions, 48 deletions
@@ -1550,8 +1550,9 @@ lwp_read (GIOChannel *io, App *app) so = shared_object_get (&app->client.objects, key); g_return_val_if_fail (so != NULL, FALSE); - frames_add_and_describe (&app->client.frames, eip, so, offset); + shared_object_queue_lookup_symbol (so, eip, offset); } + shared_objects_lookup_symbols (&app->client.objects); /* new allocators */ if (! readn (fd, &count, sizeof (count))) diff --git a/src/frames.c b/src/frames.c index 30247a3..aac8847 100644 --- a/src/frames.c +++ b/src/frames.c @@ -180,36 +180,6 @@ frames_add (Frames *frames, g_assert (frames_get (frames, ip) == f); } -void -frames_add_and_describe (Frames *frames, - gulong eip, - SharedObject *so, - gulong offset) -{ - const gchar *object, *function, *path, *filename; - guint lineno; - - g_assert (frames_get (frames, eip) == NULL); - - filename = NULL; - if (shared_object_describe_offset (so, offset, - &object, - &function, - &path, - &lineno)) - { - if (path != NULL && *path != '\0') { - const char *slash = strrchr (path, '/'); - if (slash) - filename = slash + 1; - else - filename = path; - } - } - - frames_add (frames, eip, object, function, filename, path, lineno); -} - gboolean frames_has_ip (Frames *frames, gulong ip) { diff --git a/src/shared-objects.c b/src/shared-objects.c index 9ec738d..90b550c 100644 --- a/src/shared-objects.c +++ b/src/shared-objects.c @@ -30,27 +30,34 @@ #include "minibfd/binfile.h" +struct _symbol_offset { + SymbolOffset *next; + gulong eip; + gulong offset; +}; + struct _shared_object { SharedObjects *objects; SharedObject *ht_next; + SharedObject *pending_next; + guint key; const char *name; BinFile *bin_file; + SymbolOffset *pending_lookups; }; extern char *minibfd_demangle (const char *mangled, int options); -gboolean -shared_object_describe_offset (SharedObject *so, - gulong offset, - const char **object, - const char **function, - const char **path, - guint *line) +static void +_shared_object_lookup_symbol (SharedObject *so, + gulong offset, + const char **function, + const char **path, + guint *line) { - *object = so->name; *function = NULL; *path = NULL; *line = 0; @@ -68,8 +75,73 @@ shared_object_describe_offset (SharedObject *so, g_free (demangled); } } +} + +void +shared_object_queue_lookup_symbol (SharedObject *so, gulong eip, gulong offset) +{ + SymbolOffset *symbol; + + if (so->pending_lookups == NULL) { + so->pending_next = so->objects->pending_lookups; + so->objects->pending_lookups = so; + } + + symbol = so->objects->symbol_offset_free_list; + if (symbol != NULL) + so->objects->symbol_offset_free_list = symbol->next; + else + symbol = client_perm_alloc (so->objects->client, sizeof (SymbolOffset)); + + symbol->eip = eip; + symbol->offset = offset; + symbol->next = so->pending_lookups; + so->pending_lookups = symbol; - return TRUE; +} + +void +shared_objects_lookup_symbols (SharedObjects *objects) +{ + Frames *frames = &objects->client->frames; + SharedObject *so; + + for (so = objects->pending_lookups; so != NULL; so = so->pending_next) { + SymbolOffset *symbol = so->pending_lookups, *next; + do { + const gchar *function, *path, *filename; + guint lineno; + + g_assert (frames_get (frames, symbol->eip) == NULL); + + _shared_object_lookup_symbol (so, symbol->offset, + &function, + &path, + &lineno); + if (path != NULL && *path != '\0') { + const char *slash = strrchr (path, '/'); + if (slash) + filename = slash + 1; + else + filename = path; + } else + filename = NULL; + + frames_add (frames, symbol->eip, so->name, + function, filename, path, lineno); + + next = symbol->next; + symbol->next = objects->symbol_offset_free_list; + objects->symbol_offset_free_list = symbol; + } while ((symbol = next)); + + so->pending_lookups = NULL; + if (so->bin_file != NULL) { + bin_file_free (so->bin_file); + so->bin_file = NULL; + } + } + objects->pending_lookups = NULL; } SharedObject * @@ -105,9 +177,11 @@ shared_object_add (SharedObjects *objects, guint key, const char *name) so = client_perm_alloc (objects->client, sizeof (SharedObject)); so->objects = objects; + so->pending_next = NULL; so->key = key; so->name = client_add_string (objects->client, name); so->bin_file = NULL; + so->pending_lookups = NULL; index = key % objects->ht.size; so->ht_next = objects->ht.nodes[index]; @@ -141,6 +215,10 @@ shared_objects_init (SharedObjects *objects, Client *client) objects->ht.size = 673; objects->ht.nnodes = 0; objects->ht.nodes = g_new0 (SharedObject *, objects->ht.size); + + objects->pending_lookups = NULL; + + objects->symbol_offset_free_list = NULL; } void diff --git a/src/shared-objects.h b/src/shared-objects.h index a63d75a..197b680 100644 --- a/src/shared-objects.h +++ b/src/shared-objects.h @@ -26,29 +26,36 @@ G_BEGIN_DECLS +typedef struct _symbol_offset SymbolOffset; + struct _shared_objects { Client *client; + struct { guint size; guint nnodes; SharedObject **nodes; } ht; + + SharedObject *pending_lookups; + SymbolOffset *symbol_offset_free_list; }; +void +shared_object_queue_lookup_symbol (SharedObject *so, gulong eip, gulong offset); + +void +shared_objects_lookup_symbols (SharedObjects *objects); + +void +shared_objects_release (SharedObjects *objects); + SharedObject * shared_object_add (SharedObjects *objects, guint key, const char *name); SharedObject * shared_object_get (SharedObjects *objects, guint key); -gboolean -shared_object_describe_offset (SharedObject *so, - gulong offset, - const char **object, - const char **function, - const char **path, - guint *lineno); - void shared_objects_init (SharedObjects *objects, Client *client); |