From 7d54b85e92647f240055088381ea453701b38f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Thu, 4 Nov 2004 22:10:01 +0000 Subject: [PATCH] *** empty log message *** --- README | 6 +- sysprof.c | 251 ++++++++++++++++++++++++++++++-------------------- sysprof.glade | 229 +++++++++++++++++++++++++++++---------------- 3 files changed, 303 insertions(+), 183 deletions(-) diff --git a/README b/README index 05a57fa9..ef54b3a0 100644 --- a/README +++ b/README @@ -6,17 +6,17 @@ program "sysprof". - There is no auto* stuff. Just type "make" and hope for the best. -- You need gtk+ 2.4.0 or better, and you need libglade +- You need gtk+ 2.4.0 or better, and you need libglade from CVS. - You need a 2.6 non-SMP kernel -- It is known to be broken on SMP kernels. Patches gladly accepted. - - The programs you want to profile should have debugging symbols, or you won't get much useful information. - To get symbols from the X server, run sysprof as root (go figure). +- It may be broken on SMP kernels. + Søren diff --git a/sysprof.c b/sysprof.c index b25206ad..dff0d927 100644 --- a/sysprof.c +++ b/sysprof.c @@ -17,28 +17,41 @@ typedef struct Application Application; +typedef enum +{ + INITIAL, + DISPLAYING, + PROFILING +} State; + struct Application { int input_fd; + State state; StackStash * stash; - GList * page_faults; + GtkTreeView * object_view; GtkTreeView * callers_view; GtkTreeView * descendants_view; GtkStatusbar * statusbar; - GtkToolItem * profile_button; - GtkToolItem * reset_button; + GtkWidget * start_button; + GtkWidget * profile_button; + GtkWidget * open_button; + GtkWidget * save_as_button; + + GtkWidget * start_item; + GtkWidget * profile_item; + GtkWidget * open_item; + GtkWidget * save_as_item; Profile * profile; ProfileDescendant * descendants; ProfileCaller * callers; int n_samples; - gboolean profiling; int timeout_id; - int generating_profile; }; @@ -52,14 +65,46 @@ disaster (const char *what) static void update_sensitivity (Application *app) { - gboolean sensitive_profile_button = (app->n_samples != 0); + gboolean sensitive_profile_button; + gboolean sensitive_save_as_button; + gboolean sensitive_start_button; + gboolean active_profile_button; + + switch (app->state) + { + case INITIAL: + sensitive_profile_button = FALSE; + sensitive_save_as_button = FALSE; + sensitive_start_button = TRUE; + active_profile_button = FALSE; + break; + + case PROFILING: + sensitive_profile_button = (app->n_samples > 0); + sensitive_save_as_button = (app->n_samples > 0); + sensitive_start_button = TRUE; + active_profile_button = FALSE; + break; + + case DISPLAYING: + sensitive_profile_button = FALSE; + sensitive_save_as_button = TRUE; + sensitive_start_button = TRUE; + active_profile_button = TRUE; + break; + } gtk_widget_set_sensitive (GTK_WIDGET (app->profile_button), sensitive_profile_button); -#if 0 - gtk_widget_set_sensitive (GTK_WIDGET (app->reset_button), - sensitive_profile_button); -#endif + + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (app->profile_button), + active_profile_button); + + gtk_widget_set_sensitive (GTK_WIDGET (app->save_as_button), + sensitive_save_as_button); + + gtk_widget_set_sensitive (GTK_WIDGET (app->start_button), + sensitive_start_button); } #if 0 @@ -106,10 +151,12 @@ on_read (gpointer data) Application *app = data; SysprofStackTrace trace; int rd; - int i; rd = read (app->input_fd, &trace, sizeof (trace)); + if (app->state != PROFILING) + return; + #if 0 g_print ("pid: %d\n", trace.pid); for (i=0; i < trace.n_addresses; ++i) @@ -117,7 +164,7 @@ on_read (gpointer data) g_print ("-=-\n"); #endif - if (rd > 0 && app->profiling && !app->generating_profile) + if (rd > 0 && !app->generating_profile) { Process *process = process_get_from_pid (trace.pid); int i; @@ -143,7 +190,7 @@ on_read (gpointer data) } static void -on_reset (GtkWidget *widget, gpointer data) +on_start_clicked (GtkToggleToolButton *tool_button, gpointer data) { Application *app = data; @@ -163,6 +210,8 @@ on_reset (GtkWidget *widget, gpointer data) process_flush_caches (); app->n_samples = 0; show_samples (app); + + app->state = PROFILING; update_sensitivity (app); } @@ -243,13 +292,13 @@ fill_main_list (Application *app) } static void -on_profile (gpointer widget, gpointer data) +on_profile_toggled (gpointer widget, gpointer data) { Application *app = data; - if (app->generating_profile) + if (app->generating_profile || !gtk_toggle_tool_button_get_active (widget)) return; - + if (app->profile) profile_free (app->profile); @@ -261,6 +310,31 @@ on_profile (gpointer widget, gpointer data) app->generating_profile = FALSE; fill_main_list (app); + + app->state = DISPLAYING; + + update_sensitivity (app); +} + +static void +on_open_clicked (gpointer widget, gpointer data) +{ + Application *app = data; + + if (app) + ; + /* FIXME */ +} + +static void +on_save_as_clicked (gpointer widget, gpointer data) +{ + Application *app = data; + + + if (app) + ; + /* FIXME */ } static void @@ -269,16 +343,6 @@ on_delete (GtkWidget *window) gtk_main_quit (); } -static void -on_start_toggled (GtkToggleToolButton *tool_button, gpointer data) -{ - Application *app = data; - - app->profiling = gtk_toggle_tool_button_get_active (tool_button); - - update_sensitivity (app); -} - static void add_node (GtkTreeStore *store, int size, @@ -548,27 +612,13 @@ on_callers_row_activated (GtkTreeView *tree_view, } static void -add_stock (const char *stock_id, - const char *label, guint size, const guint8 *data) +get_default_size (int *w, int *h) { - GdkPixbuf *pixbuf; - GtkIconSet *icon_set; - GtkIconFactory *icon_factory; - GtkStockItem stock_item; - - pixbuf = gdk_pixbuf_new_from_inline (size, data, FALSE, NULL); - icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); - icon_factory = gtk_icon_factory_new (); - gtk_icon_factory_add (icon_factory, stock_id, icon_set); - gtk_icon_factory_add_default (icon_factory); - g_object_unref (G_OBJECT (icon_factory)); - gtk_icon_set_unref (icon_set); - stock_item.stock_id = (char *)stock_id; - stock_item.label = (char *)label; - stock_item.modifier = 0; - stock_item.keyval = 0; - stock_item.translation_domain = NULL; - gtk_stock_add (&stock_item, 1); + /* FIXME, this should really be some percentage of the screen, + * and the window size should be stored in gconf etc. + */ + *w = 700; + *h = 480; } static void @@ -576,78 +626,74 @@ build_gui (Application *app) { GladeXML *xml; GtkWidget *main_window; - GtkWidget *main_vbox; - GtkWidget *toolbar; - GtkToolItem *item; GtkTreeSelection *selection; + int w, h; xml = glade_xml_new ("./sysprof.glade", NULL, NULL); - + /* Main Window */ main_window = glade_xml_get_widget (xml, "main_window"); g_signal_connect (G_OBJECT (main_window), "delete_event", G_CALLBACK (on_delete), NULL); - gtk_window_set_default_size (GTK_WINDOW (main_window), 640, 400); + gtk_widget_show_all (main_window); + + /* Menu items */ + app->start_item = glade_xml_get_widget (xml, "start_item"); + app->profile_item = glade_xml_get_widget (xml, "profile_item"); + app->open_item = glade_xml_get_widget (xml, "open_item"); + app->save_as_item = glade_xml_get_widget (xml, "save_as_item"); + + g_assert (app->start_item); + g_assert (app->profile_item); + g_assert (app->save_as_item); + g_assert (app->open_item); - /* Toolbar */ - main_vbox = glade_xml_get_widget (xml, "main_vbox"); - toolbar = gtk_toolbar_new (); + g_signal_connect (G_OBJECT (app->start_item), "activate", + G_CALLBACK (on_start_clicked), app); - /* Stock Items */ -#include "pixbufs.c" - add_stock ("sysprof-start-profiling", "Star_t", - sizeof (start_profiling), start_profiling); - add_stock ("sysprof-stop-profiling", "Sto_p", - sizeof (stop_profiling), stop_profiling); - - /* Stop */ - item = gtk_radio_tool_button_new_from_stock ( - NULL, "sysprof-stop-profiling"); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -11); + g_signal_connect (G_OBJECT (app->profile_item), "activate", + G_CALLBACK (on_profile_toggled), app); - /* Start */ - item = gtk_radio_tool_button_new_with_stock_from_widget ( - GTK_RADIO_TOOL_BUTTON (item), "sysprof-start-profiling"); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0); - g_signal_connect (G_OBJECT (item), "toggled", - G_CALLBACK (on_start_toggled), app); - - /* Reset */ - item = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), "_Reset"); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); - g_signal_connect (G_OBJECT (item), "clicked", - G_CALLBACK (on_reset), app); - - app->reset_button = item; - - /* Separator */ - item = gtk_separator_tool_item_new (); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); + g_signal_connect (G_OBJECT (app->open_item), "activate", + G_CALLBACK (on_open_clicked), app); - /* Profile */ - item = gtk_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_LEFT); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), "_Profile"); - gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (item), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); - g_signal_connect (G_OBJECT (item), "clicked", - G_CALLBACK (on_profile), app); + g_signal_connect (G_OBJECT (app->save_as_item), "activate", + G_CALLBACK (on_save_as_clicked), app); - app->profile_button = item; - - /* Show toolbar */ - gtk_widget_show_all (GTK_WIDGET (toolbar)); + /* quit */ + g_signal_connect (G_OBJECT (glade_xml_get_widget (xml, "quit_item")), "activate", + G_CALLBACK (on_delete), NULL); - /* Add toolbar to vbox */ - gtk_container_add (GTK_CONTAINER (main_vbox), toolbar); - gtk_box_reorder_child (GTK_BOX (main_vbox), toolbar, 1); - gtk_box_set_child_packing (GTK_BOX (main_vbox), toolbar, - FALSE, TRUE, 0, GTK_PACK_START); + /* Tool items */ + + app->start_button = glade_xml_get_widget (xml, "start_button"); + app->profile_button = glade_xml_get_widget (xml, "profile_button"); + app->open_button = glade_xml_get_widget (xml, "open_button"); + app->save_as_button = glade_xml_get_widget (xml, "save_as_button"); + + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( + app->profile_button), FALSE); + + g_signal_connect (G_OBJECT (app->start_button), "clicked", + G_CALLBACK (on_start_clicked), app); + + g_signal_connect (G_OBJECT (app->profile_button), "toggled", + G_CALLBACK (on_profile_toggled), app); + + g_signal_connect (G_OBJECT (app->open_button), "clicked", + G_CALLBACK (on_open_clicked), app); + + g_signal_connect (G_OBJECT (app->save_as_button), "clicked", + G_CALLBACK (on_save_as_clicked), app); + + get_default_size (&w, &h); + + gtk_window_set_default_size (GTK_WINDOW (main_window), w, h); /* TreeViews */ + /* object view */ app->object_view = (GtkTreeView *)glade_xml_get_widget (xml, "object_view"); add_plain_text_column (app->object_view, _("Name"), OBJECT_NAME); @@ -684,6 +730,7 @@ application_new (void) app->stash = stack_stash_new (); app->input_fd = -1; + app->state = INITIAL; return app; } @@ -710,7 +757,7 @@ main (int argc, char **argv) " insmod sysprof-module.ko\n" "\n"); } - + fd_add_watch (app->input_fd, app); fd_set_read_callback (app->input_fd, on_read); diff --git a/sysprof.glade b/sysprof.glade index a26968f2..c78f1881 100644 --- a/sysprof.glade +++ b/sysprof.glade @@ -8,6 +8,8 @@ GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False + 700 + 500 True False True @@ -33,37 +35,19 @@ True - + - - True - gtk-new - True - - - - - - + True gtk-open True - + - - True - gtk-save - True - - - - - - + True gtk-save-as True @@ -78,7 +62,7 @@ - + True gtk-quit True @@ -90,55 +74,6 @@ - - - True - _Edit - True - - - - - - - True - gtk-cut - True - - - - - - - True - gtk-copy - True - - - - - - - True - gtk-paste - True - - - - - - - True - gtk-delete - True - - - - - - - - True @@ -146,7 +81,49 @@ True - + + + + + True + S_tart + True + + + + + True + gtk-media-play + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _Profile + True + + + + + True + gtk-justify-left + 1 + 0.5 + 0.5 + 0 + 0 + + + + @@ -159,13 +136,13 @@ True - + - + True - _About - True + gtk-about + True @@ -182,7 +159,101 @@ - + + True + GTK_ORIENTATION_HORIZONTAL + GTK_TOOLBAR_BOTH_HORIZ + True + True + + + + True + S_tart + True + gtk-media-play + True + True + True + + + False + True + + + + + + True + _Profile + True + gtk-justify-left + True + True + True + False + + + False + True + + + + + + True + True + True + False + + + + True + True + True + True + + + + + False + False + + + + + + True + gtk-open + True + True + False + + + False + True + + + + + + True + gtk-save-as + True + True + True + + + False + True + + + + + 0 + False + False + @@ -196,11 +267,13 @@ 3 True True + 773 True True + 0