Make this function return a list of immediate callers again.

2006-10-09  Soren Sandmann <sandmann@daimi.au.dk>

	* profile.c (profile_list_callers): Make this function return a
	list of immediate callers again.

	* sysprof.c (build_gui): Change label back to "Callers"

	* process.c (get_kernel_symbols): Only attempt to read the kernel
	symbols once.
This commit is contained in:
Soren Sandmann
2006-10-11 05:37:24 +00:00
committed by Søren Sandmann Pedersen
parent 6475029375
commit df07f71539
5 changed files with 104 additions and 4 deletions

View File

@ -1,3 +1,13 @@
2006-10-09 Soren Sandmann <sandmann@daimi.au.dk>
* profile.c (profile_list_callers): Make this function return a
list of immediate callers again.
* sysprof.c (build_gui): Change label back to "Callers"
* process.c (get_kernel_symbols): Only attempt to read the kernel
symbols once.
2006-10-09 Soren Sandmann <sandmann@redhat.com>
* binfile.c (bin_file_get_inode): Remove this function

3
TODO
View File

@ -34,6 +34,8 @@ Before 1.0.4:
Before 1.2:
* Make sure that labels look decent in case of "No Map" etc.
* Elf bugs:
- error handling for bin_parser is necessary.
@ -422,6 +424,7 @@ http://www.linuxbase.org/spec/booksets/LSB-Embedded/LSB-Embedded/ehframe.html
should do a globale s/callers/ancestors on the code.
- not sure it's an improvement. Often it is more interesting to
find the immediate callers.
- Now it's back to just listing the immediate callers.
- Have kernel module report the file the address was found in
Should avoid a lot of potential broken/raciness with dlopen etc.

View File

@ -555,9 +555,10 @@ parse_kallsyms (const char *kallsyms,
static GHashTable *
get_kernel_symbols (void)
{
static gboolean read_symbols = FALSE;
static GHashTable *kernel_syms;
if (!kernel_syms)
if (!read_symbols)
{
char *kallsyms;
g_file_get_contents ("/proc/kallsyms", &kallsyms, NULL, NULL);
@ -572,6 +573,8 @@ get_kernel_symbols (void)
g_free (kallsyms);
g_hash_table_destroy (kernel_syms);
}
read_symbols = TRUE;
}
return NULL;

View File

@ -359,6 +359,89 @@ profile_caller_new (void)
return caller;
}
ProfileCaller *
profile_list_callers (Profile *profile,
char *callee_name)
{
StackNode *node;
StackNode *callees;
GHashTable *callers_by_name;
GHashTable *processed_callers;
ProfileCaller *result = NULL;
callers_by_name = g_hash_table_new (g_direct_hash, g_direct_equal);
processed_callers = g_hash_table_new (g_direct_hash, g_direct_equal);
callees = stack_stash_find_node (profile->stash, callee_name);
for (node = callees; node != NULL; node = node->next)
{
gpointer name;
if (node->parent)
name = node->parent->address;
else
name = NULL;
if (!g_hash_table_lookup (callers_by_name, name))
{
ProfileCaller *caller = profile_caller_new ();
caller->name = name;
caller->next = result;
caller->total = 0;
caller->self = 0;
g_hash_table_insert (callers_by_name, name, caller);
result = caller;
}
}
for (node = callees; node != NULL; node = node->next)
{
StackNode *top_caller = node->parent;
StackNode *top_callee = node;
StackNode *n;
ProfileCaller *caller;
for (n = node; n && n->parent; n = n->parent)
{
if (n->address == node->address &&
n->parent->address == node->parent->address)
{
top_caller = n->parent;
top_callee = n;
}
}
if (node->parent)
caller = g_hash_table_lookup (callers_by_name, node->parent->address);
else
caller = g_hash_table_lookup (callers_by_name, NULL);
if (!g_hash_table_lookup (processed_callers, top_caller))
{
caller->total += top_callee->total;
g_hash_table_insert (processed_callers, top_caller, top_caller);
}
caller->self += node->size;
}
g_hash_table_destroy (processed_callers);
g_hash_table_destroy (callers_by_name);
return result;
}
#if 0
/* This code generates a list of all ancestors, rather than
* all callers. It turned out to not work well in practice,
* but on the other hand the single list of callers is not
* all that great either, so we'll keep it around commented
* out for now
*/
static void
add_to_list (gpointer key,
gpointer value,
@ -380,8 +463,8 @@ listify_hash_table (GHashTable *hash_table)
}
ProfileCaller *
profile_list_callers (Profile *profile,
char *callee_name)
profile_list_ancestors (Profile *profile,
char *callee_name)
{
StackNode *callees;
StackNode *node;
@ -459,6 +542,7 @@ profile_list_callers (Profile *profile,
return result;
}
#endif
void
profile_free (Profile *profile)

View File

@ -1447,7 +1447,7 @@ build_gui (Application *app)
/* callers view */
app->callers_view = (GtkTreeView *)glade_xml_get_widget (xml, "callers_view");
gtk_tree_view_set_enable_search (app->callers_view, FALSE);
col = add_plain_text_column (app->callers_view, _("Ancestors"), CALLERS_NAME);
col = add_plain_text_column (app->callers_view, _("Callers"), CALLERS_NAME);
add_double_format_column (app->callers_view, _("Self"), CALLERS_SELF, "%.2f ");
add_double_format_column (app->callers_view, _("Total"), CALLERS_TOTAL, "%.2f ");
g_signal_connect (app->callers_view, "row-activated",