*** empty log message ***

This commit is contained in:
Søren Sandmann Pedersen
2004-11-04 22:10:01 +00:00
parent 1fa465fb26
commit 7d54b85e92
3 changed files with 303 additions and 183 deletions

6
README
View File

@ -6,17 +6,17 @@ program "sysprof".
- There is no auto* stuff. Just type "make" and hope for the best. - 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 - 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 - The programs you want to profile should have debugging symbols, or
you won't get much useful information. you won't get much useful information.
- To get symbols from the X server, run sysprof as root (go figure). - To get symbols from the X server, run sysprof as root (go figure).
- It may be broken on SMP kernels.
S<EFBFBD>ren S<EFBFBD>ren

235
sysprof.c
View File

@ -17,28 +17,41 @@
typedef struct Application Application; typedef struct Application Application;
typedef enum
{
INITIAL,
DISPLAYING,
PROFILING
} State;
struct Application struct Application
{ {
int input_fd; int input_fd;
State state;
StackStash * stash; StackStash * stash;
GList * page_faults;
GtkTreeView * object_view; GtkTreeView * object_view;
GtkTreeView * callers_view; GtkTreeView * callers_view;
GtkTreeView * descendants_view; GtkTreeView * descendants_view;
GtkStatusbar * statusbar; GtkStatusbar * statusbar;
GtkToolItem * profile_button; GtkWidget * start_button;
GtkToolItem * reset_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; Profile * profile;
ProfileDescendant * descendants; ProfileDescendant * descendants;
ProfileCaller * callers; ProfileCaller * callers;
int n_samples; int n_samples;
gboolean profiling;
int timeout_id; int timeout_id;
int generating_profile; int generating_profile;
}; };
@ -52,14 +65,46 @@ disaster (const char *what)
static void static void
update_sensitivity (Application *app) 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), gtk_widget_set_sensitive (GTK_WIDGET (app->profile_button),
sensitive_profile_button); sensitive_profile_button);
#if 0
gtk_widget_set_sensitive (GTK_WIDGET (app->reset_button), gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (app->profile_button),
sensitive_profile_button); active_profile_button);
#endif
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 #if 0
@ -106,10 +151,12 @@ on_read (gpointer data)
Application *app = data; Application *app = data;
SysprofStackTrace trace; SysprofStackTrace trace;
int rd; int rd;
int i;
rd = read (app->input_fd, &trace, sizeof (trace)); rd = read (app->input_fd, &trace, sizeof (trace));
if (app->state != PROFILING)
return;
#if 0 #if 0
g_print ("pid: %d\n", trace.pid); g_print ("pid: %d\n", trace.pid);
for (i=0; i < trace.n_addresses; ++i) for (i=0; i < trace.n_addresses; ++i)
@ -117,7 +164,7 @@ on_read (gpointer data)
g_print ("-=-\n"); g_print ("-=-\n");
#endif #endif
if (rd > 0 && app->profiling && !app->generating_profile) if (rd > 0 && !app->generating_profile)
{ {
Process *process = process_get_from_pid (trace.pid); Process *process = process_get_from_pid (trace.pid);
int i; int i;
@ -143,7 +190,7 @@ on_read (gpointer data)
} }
static void static void
on_reset (GtkWidget *widget, gpointer data) on_start_clicked (GtkToggleToolButton *tool_button, gpointer data)
{ {
Application *app = data; Application *app = data;
@ -163,6 +210,8 @@ on_reset (GtkWidget *widget, gpointer data)
process_flush_caches (); process_flush_caches ();
app->n_samples = 0; app->n_samples = 0;
show_samples (app); show_samples (app);
app->state = PROFILING;
update_sensitivity (app); update_sensitivity (app);
} }
@ -243,11 +292,11 @@ fill_main_list (Application *app)
} }
static void static void
on_profile (gpointer widget, gpointer data) on_profile_toggled (gpointer widget, gpointer data)
{ {
Application *app = data; Application *app = data;
if (app->generating_profile) if (app->generating_profile || !gtk_toggle_tool_button_get_active (widget))
return; return;
if (app->profile) if (app->profile)
@ -261,6 +310,31 @@ on_profile (gpointer widget, gpointer data)
app->generating_profile = FALSE; app->generating_profile = FALSE;
fill_main_list (app); 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 static void
@ -269,16 +343,6 @@ on_delete (GtkWidget *window)
gtk_main_quit (); 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 static void
add_node (GtkTreeStore *store, add_node (GtkTreeStore *store,
int size, int size,
@ -548,27 +612,13 @@ on_callers_row_activated (GtkTreeView *tree_view,
} }
static void static void
add_stock (const char *stock_id, get_default_size (int *w, int *h)
const char *label, guint size, const guint8 *data)
{ {
GdkPixbuf *pixbuf; /* FIXME, this should really be some percentage of the screen,
GtkIconSet *icon_set; * and the window size should be stored in gconf etc.
GtkIconFactory *icon_factory; */
GtkStockItem stock_item; *w = 700;
*h = 480;
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);
} }
static void static void
@ -576,10 +626,8 @@ build_gui (Application *app)
{ {
GladeXML *xml; GladeXML *xml;
GtkWidget *main_window; GtkWidget *main_window;
GtkWidget *main_vbox;
GtkWidget *toolbar;
GtkToolItem *item;
GtkTreeSelection *selection; GtkTreeSelection *selection;
int w, h;
xml = glade_xml_new ("./sysprof.glade", NULL, NULL); xml = glade_xml_new ("./sysprof.glade", NULL, NULL);
@ -588,66 +636,64 @@ build_gui (Application *app)
g_signal_connect (G_OBJECT (main_window), "delete_event", g_signal_connect (G_OBJECT (main_window), "delete_event",
G_CALLBACK (on_delete), NULL); G_CALLBACK (on_delete), NULL);
gtk_window_set_default_size (GTK_WINDOW (main_window), 640, 400);
gtk_widget_show_all (main_window); gtk_widget_show_all (main_window);
/* Toolbar */ /* Menu items */
main_vbox = glade_xml_get_widget (xml, "main_vbox"); app->start_item = glade_xml_get_widget (xml, "start_item");
toolbar = gtk_toolbar_new (); 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");
/* Stock Items */ g_assert (app->start_item);
#include "pixbufs.c" g_assert (app->profile_item);
add_stock ("sysprof-start-profiling", "Star_t", g_assert (app->save_as_item);
sizeof (start_profiling), start_profiling); g_assert (app->open_item);
add_stock ("sysprof-stop-profiling", "Sto_p",
sizeof (stop_profiling), stop_profiling);
/* Stop */ g_signal_connect (G_OBJECT (app->start_item), "activate",
item = gtk_radio_tool_button_new_from_stock ( G_CALLBACK (on_start_clicked), app);
NULL, "sysprof-stop-profiling");
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -11);
/* Start */ g_signal_connect (G_OBJECT (app->profile_item), "activate",
item = gtk_radio_tool_button_new_with_stock_from_widget ( G_CALLBACK (on_profile_toggled), app);
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 */ g_signal_connect (G_OBJECT (app->open_item), "activate",
item = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR); G_CALLBACK (on_open_clicked), app);
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; g_signal_connect (G_OBJECT (app->save_as_item), "activate",
G_CALLBACK (on_save_as_clicked), app);
/* Separator */ /* quit */
item = gtk_separator_tool_item_new (); g_signal_connect (G_OBJECT (glade_xml_get_widget (xml, "quit_item")), "activate",
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); G_CALLBACK (on_delete), NULL);
/* Profile */ /* Tool items */
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);
app->profile_button = item; 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");
/* Show toolbar */ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (
gtk_widget_show_all (GTK_WIDGET (toolbar)); app->profile_button), FALSE);
/* Add toolbar to vbox */ g_signal_connect (G_OBJECT (app->start_button), "clicked",
gtk_container_add (GTK_CONTAINER (main_vbox), toolbar); G_CALLBACK (on_start_clicked), app);
gtk_box_reorder_child (GTK_BOX (main_vbox), toolbar, 1);
gtk_box_set_child_packing (GTK_BOX (main_vbox), toolbar, g_signal_connect (G_OBJECT (app->profile_button), "toggled",
FALSE, TRUE, 0, GTK_PACK_START); 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 */ /* TreeViews */
/* object view */ /* object view */
app->object_view = (GtkTreeView *)glade_xml_get_widget (xml, "object_view"); app->object_view = (GtkTreeView *)glade_xml_get_widget (xml, "object_view");
add_plain_text_column (app->object_view, _("Name"), OBJECT_NAME); add_plain_text_column (app->object_view, _("Name"), OBJECT_NAME);
@ -684,6 +730,7 @@ application_new (void)
app->stash = stack_stash_new (); app->stash = stack_stash_new ();
app->input_fd = -1; app->input_fd = -1;
app->state = INITIAL;
return app; return app;
} }

View File

@ -8,6 +8,8 @@
<property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property> <property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property> <property name="modal">False</property>
<property name="default_width">700</property>
<property name="default_height">500</property>
<property name="resizable">True</property> <property name="resizable">True</property>
<property name="destroy_with_parent">False</property> <property name="destroy_with_parent">False</property>
<property name="decorated">True</property> <property name="decorated">True</property>
@ -33,37 +35,19 @@
<property name="use_underline">True</property> <property name="use_underline">True</property>
<child> <child>
<widget class="GtkMenu" id="menu1"> <widget class="GtkMenu" id="menuitem1_menu">
<child> <child>
<widget class="GtkImageMenuItem" id="new1"> <widget class="GtkImageMenuItem" id="open_item">
<property name="visible">True</property>
<property name="label">gtk-new</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_new1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="open1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label">gtk-open</property> <property name="label">gtk-open</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="on_open1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/> <signal name="activate" handler="on_open_activate" last_modification_time="Thu, 04 Nov 2004 21:01:03 GMT"/>
</widget> </widget>
</child> </child>
<child> <child>
<widget class="GtkImageMenuItem" id="save1"> <widget class="GtkImageMenuItem" id="save_as_item">
<property name="visible">True</property>
<property name="label">gtk-save</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_save1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="save_as1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label">gtk-save-as</property> <property name="label">gtk-save-as</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
@ -78,7 +62,7 @@
</child> </child>
<child> <child>
<widget class="GtkImageMenuItem" id="quit1"> <widget class="GtkImageMenuItem" id="quit_item">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label">gtk-quit</property> <property name="label">gtk-quit</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
@ -90,55 +74,6 @@
</widget> </widget>
</child> </child>
<child>
<widget class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="menu2">
<child>
<widget class="GtkImageMenuItem" id="cut1">
<property name="visible">True</property>
<property name="label">gtk-cut</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_cut1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="copy1">
<property name="visible">True</property>
<property name="label">gtk-copy</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_copy1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="paste1">
<property name="visible">True</property>
<property name="label">gtk-paste</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_paste1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="delete1">
<property name="visible">True</property>
<property name="label">gtk-delete</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_delete1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child> <child>
<widget class="GtkMenuItem" id="menuitem3"> <widget class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property> <property name="visible">True</property>
@ -146,7 +81,49 @@
<property name="use_underline">True</property> <property name="use_underline">True</property>
<child> <child>
<widget class="GtkMenu" id="menu3"> <widget class="GtkMenu" id="menuitem3_menu">
<child>
<widget class="GtkImageMenuItem" id="start_item">
<property name="visible">True</property>
<property name="label" translatable="yes">S_tart</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_start1_activate" last_modification_time="Thu, 04 Nov 2004 18:51:54 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image8">
<property name="visible">True</property>
<property name="stock">gtk-media-play</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="profile_item">
<property name="visible">True</property>
<property name="label" translatable="yes">_Profile</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_profile1_activate" last_modification_time="Thu, 04 Nov 2004 18:51:54 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image9">
<property name="visible">True</property>
<property name="stock">gtk-justify-left</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>
@ -159,13 +136,13 @@
<property name="use_underline">True</property> <property name="use_underline">True</property>
<child> <child>
<widget class="GtkMenu" id="menu4"> <widget class="GtkMenu" id="menuitem4_menu">
<child> <child>
<widget class="GtkMenuItem" id="about1"> <widget class="GtkImageMenuItem" id="about_item">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">_About</property> <property name="label">gtk-about</property>
<property name="use_underline">True</property> <property name="use_stock">True</property>
<signal name="activate" handler="on_about1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/> <signal name="activate" handler="on_about1_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
</widget> </widget>
</child> </child>
@ -182,7 +159,101 @@
</child> </child>
<child> <child>
<placeholder/> <widget class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
<property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
<property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
<property name="tooltips">True</property>
<property name="show_arrow">True</property>
<child>
<widget class="GtkToolButton" id="start_button">
<property name="visible">True</property>
<property name="label" translatable="yes">S_tart</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-play</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToggleToolButton" id="profile_button">
<property name="visible">True</property>
<property name="label" translatable="yes">_Profile</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-justify-left</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
<property name="active">False</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolItem" id="toolitem1">
<property name="visible">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<child>
<widget class="GtkSeparatorToolItem" id="separatortoolitem1">
<property name="visible">True</property>
<property name="draw">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">False</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="open_button">
<property name="visible">True</property>
<property name="stock_id">gtk-open</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="save_as_button">
<property name="visible">True</property>
<property name="stock_id">gtk-save-as</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child> </child>
<child> <child>
@ -196,11 +267,13 @@
<property name="border_width">3</property> <property name="border_width">3</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="position">773</property>
<child> <child>
<widget class="GtkVPaned" id="vpaned1"> <widget class="GtkVPaned" id="vpaned1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="position">0</property>
<child> <child>
<widget class="GtkScrolledWindow" id="scrolledwindow1"> <widget class="GtkScrolledWindow" id="scrolledwindow1">