From 3b6a53efaf935b8c73a7b313ba1ceae25c92f866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Wed, 17 Nov 2004 23:37:44 +0000 Subject: [PATCH] *** empty log message *** --- Makefile | 2 +- TODO | 7 +- profile.c | 2 + sfile.c | 239 +++++++++++++++++++++++++++-------------------- sfile.h | 8 +- sysprof-module.c | 10 +- 6 files changed, 157 insertions(+), 111 deletions(-) diff --git a/Makefile b/Makefile index 44005ea9..bf974689 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ else CFLAGS := $(shell pkg-config --cflags gtk+-2.0 libglade-2.0) -Wall -g LIBS := $(shell pkg-config --libs gtk+-2.0 libglade-2.0) -lbfd -liberty -C_FILES := sysprof.c binfile.c stackstash.c watch.c process.c profile.c treeviewutils.c +C_FILES := sysprof.c binfile.c stackstash.c watch.c process.c profile.c treeviewutils.c sfile.c OBJS := $(addsuffix .o, $(basename $(C_FILES))) BINARY := sysprof MODULE := sysprof-module diff --git a/TODO b/TODO index 12044018..1f08f808 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,15 @@ - consider caching [filename => bin_file] - Have kernel modulereport the file the symbol was found in - Should avoid a lot of potential brokenness with dlopen etc. + Should avoid a lot of potential broken/raciness with dlopen etc. - grep FIXME - hide internal stuff in ProfileDescendant - loading and saving - Non-GUI version that can save in a format the GUI can understand. - Could be used for profiling startup etc. Should be able to dump the - data to a network socket. + Could be used for profiling startup etc. Would preferably be able to + dump the data to a network socket. Should be able to react to eg. + SIGUSR1 by dumping the data. - Port to GtkAction diff --git a/profile.c b/profile.c index eb33db6b..03bc0248 100644 --- a/profile.c +++ b/profile.c @@ -190,6 +190,7 @@ get_number (const char *input_name, return -1; } +#if 0 static Node * create_node (const char **names, const char **values, @@ -345,6 +346,7 @@ profile_load (const char *filename, return result; } +#endif static void profile_object_free (ProfileObject *obj) diff --git a/sfile.c b/sfile.c index 022f8525..66701333 100644 --- a/sfile.c +++ b/sfile.c @@ -72,6 +72,40 @@ struct Fragment struct Action { + TransitionType type; + char *name; + + union + { + struct + { + } begin_record; + + struct + { + int n_items; + } begin_list; + + struct + { + int id; + } end; + + struct + { + gpointer *location; + } pointer; + + struct + { + int value; + } integer; + + struct + { + char *value; + } string; + } u; }; static State * @@ -426,9 +460,9 @@ typedef struct ParseNode ParseNode; struct BuildContext { - ParseNode *root; - ParseNode *current_node; - GHashTable *nodes_by_id; + State *state; + Action *actions; + int n_actions; }; struct ParseNode @@ -442,42 +476,6 @@ struct ParseNode SFormat *format; }; -void -sfile_begin_get_record (SFileInput *file) -{ -} - -int -sfile_begin_get_list (SFileInput *file) -{ - return -1; /* FIXME */ -} - -void -sfile_get_pointer (SFileInput *file, - gpointer *pointer) -{ - -} - -void -sfile_get_integer (SFileInput *file, - int *integer) -{ -} - -void -sfile_get_string (SFileInput *file, - char **string) -{ -} - -void -sfile_end_get (SFileInput *file, - gpointer object) -{ -} - static gboolean get_number (const char *text, int *number) { @@ -498,6 +496,98 @@ get_number (const char *text, int *number) return TRUE; } +struct SFileInput +{ + int n_actions; + Action *actions; + Action *current_action; + GHashTable *actions_by_location; + GHashTable *objects_by_id; +}; + +void +sfile_begin_get_record (SFileInput *file, const char *name) +{ + Action *action = file->current_action++; + + g_return_if_fail (action->type == BEGIN_RECORD && + strcmp (action->name, name) == 0); +} + +int +sfile_begin_get_list (SFileInput *file, + const char *name) +{ + Action *action = file->current_action++; + + g_return_val_if_fail (action->type == BEGIN_LIST && + strcmp (action->name, name) == 0, 0); + + return action->u.begin_list.n_items; +} + +void +sfile_get_pointer (SFileInput *file, + const char *name, + gpointer *location) +{ + Action *action = file->current_action++; + g_return_if_fail (action->type == POINTER && + strcmp (action->name, name) == 0); + + action->u.pointer.location = location; + + if (location) + { + if (g_hash_table_lookup (file->actions_by_location, location)) + g_warning ("Reading into the same location twice\n"); + + g_hash_table_insert (file->actions_by_location, location, action); + } +} + +void +sfile_get_integer (SFileInput *file, + const char *name, + int *integer) +{ + Action *action = file->current_action++; + g_return_if_fail (action->type == INTEGER && + strcmp (action->name, name) == 0); + + if (integer) + *integer = action->u.integer.value; +} + +void +sfile_get_string (SFileInput *file, + const char *name, + char **string) +{ + Action *action = file->current_action++; + g_return_if_fail (action->type == STRING && + strcmp (action->name, name) == 0); + + if (string) + *string = g_strdup (action->u.string.value); +} + +void +sfile_end_get (SFileInput *file, + const char *name, + gpointer object) +{ + Action *action = file->current_action++; + + g_return_if_fail ((action->type == END_LIST || + action->type == END_RECORD) && + strcmp (action->name, name) == 0); + + if (action->u.end.id) + g_hash_table_insert (file->objects_by_id, + GINT_TO_POINTER (action->u.end.id), object); +} + static ParseNode * parse_node_new (ParseNode *parent, const char *name) @@ -526,7 +616,7 @@ handle_begin_element (GMarkupParseContext *parse_context, { BuildContext *build = user_data; const char *id_string; - ParseNode *node; + Action action; int id; int i; @@ -559,24 +649,10 @@ handle_begin_element (GMarkupParseContext *parse_context, } } - if (build->current_node->text->len > 0) - { - /* FIXME: mixing children and text */ - return; - } - - node = parse_node_new (build->current_node, element_name); + /* */ - if (id_string) - { - node->id = GINT_TO_POINTER (id); - g_hash_table_insert (build->nodes_by_id, node->id, node); - } - - build->current_node = node; - - if (!build->root) - build->root = node; + if (!state_transition_begin (build->state, element_name, &action.type, err)) { + }; } static void @@ -586,8 +662,6 @@ handle_end_element (GMarkupParseContext *context, GError **err) { BuildContext *build = user_data; - - build->current_node = build->current_node->parent; } static void @@ -598,20 +672,10 @@ handle_text (GMarkupParseContext *context, GError **err) { BuildContext *build = user_data; - - if (build->current_node->children->len > 0) - { - /* FIXME: set error: mixing children and text */ - return; - } - - g_string_append (build->current_node->text, text); } -static ParseNode * -build_tree (const char *text, - GHashTable *nodes_by_id, - GError **err) +static Action * +build_actions (const char *contents, int *n_actions, GError **err) { BuildContext build; GMarkupParseContext *parse_context; @@ -624,41 +688,15 @@ build_tree (const char *text, NULL, /* error */ }; - build.root = NULL; - build.current_node = NULL; - build.nodes_by_id = nodes_by_id; - parse_context = g_markup_parse_context_new (&parser, 0, &build, NULL); - if (!g_markup_parse_context_parse (parse_context, text, -1, err)) + if (!g_markup_parse_context_parse (parse_context, contents, -1, err)) { /* FIXME: free stuff */ return NULL; } - if (!build.root) - { - /* FIXME: empty document not allowed */ - /* FIXME: free stuff */ - return NULL; - } - - return build.root; -} - -static gboolean check_structure (ParseNode *node, SFormat *format, GHashTable *nodes_by_id, GError **err); - - -struct SFileInput -{ - int n_actions; - Action *actions; -}; - -static Action * -build_actions (const char *contents, int *n_actions, GError **err) -{ - return NULL; /* FIXME */ + return build.actions; } SFileInput * @@ -668,9 +706,6 @@ sfile_load (const char *filename, { gchar *contents; gsize length; - ParseNode *tree; - GHashTable *nodes_by_id; - GArray *read_list; SFileInput *input; if (!g_file_get_contents (filename, &contents, &length, err)) diff --git a/sfile.h b/sfile.h index 7d1bdc1c..53eb371a 100644 --- a/sfile.h +++ b/sfile.h @@ -17,15 +17,19 @@ gpointer sformat_new_string (const char *name); SFileInput * sfile_load (const char *filename, SFormat *format, GError **err); -void sfile_begin_get_record (SFileInput *file); -int sfile_begin_get_list (SFileInput *file); +void sfile_begin_get_record (SFileInput *file, const char *name); +int sfile_begin_get_list (SFileInput *file, const char *name); void sfile_get_pointer (SFileInput *file, + const char *name, gpointer *pointer); void sfile_get_integer (SFileInput *file, + const char *name, int *integer); void sfile_get_string (SFileInput *file, + const char *name, char **string); void sfile_end_get (SFileInput *file, + const char *name, gpointer object); #if 0 diff --git a/sysprof-module.c b/sysprof-module.c index d244cdc3..4a893e9d 100644 --- a/sysprof-module.c +++ b/sysprof-module.c @@ -78,13 +78,16 @@ init_userspace_reader (userspace_reader *reader, reader->page = NULL; } +/* This is mostly cutted and pasted from ptrace.c + * I removed some locking and other stuff though. I hope it + * wasn't important. + */ + /* Access another process' address space. * Source/target buffer must be kernel space, * Do not walk the page table directly, use get_user_pages */ - - - + static int x_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) { struct mm_struct *mm; @@ -244,6 +247,7 @@ generate_stack_trace(struct task_struct *task, init_userspace_reader (&reader, task); while (i < SYSPROF_MAX_ADDRESSES && read_frame (&reader, addr, &frame) && addr < START_OF_STACK && addr >= regs->esp) { + trace->addresses[i++] = (void *)frame.return_address; addr = frame.next; }