mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
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:
committed by
Søren Sandmann Pedersen
parent
6475029375
commit
df07f71539
10
ChangeLog
10
ChangeLog
@ -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>
|
2006-10-09 Soren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
* binfile.c (bin_file_get_inode): Remove this function
|
* binfile.c (bin_file_get_inode): Remove this function
|
||||||
|
|||||||
3
TODO
3
TODO
@ -34,6 +34,8 @@ Before 1.0.4:
|
|||||||
|
|
||||||
Before 1.2:
|
Before 1.2:
|
||||||
|
|
||||||
|
* Make sure that labels look decent in case of "No Map" etc.
|
||||||
|
|
||||||
* Elf bugs:
|
* Elf bugs:
|
||||||
- error handling for bin_parser is necessary.
|
- 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.
|
should do a globale s/callers/ancestors on the code.
|
||||||
- not sure it's an improvement. Often it is more interesting to
|
- not sure it's an improvement. Often it is more interesting to
|
||||||
find the immediate callers.
|
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
|
- Have kernel module report the file the address was found in
|
||||||
Should avoid a lot of potential broken/raciness with dlopen etc.
|
Should avoid a lot of potential broken/raciness with dlopen etc.
|
||||||
|
|||||||
@ -555,9 +555,10 @@ parse_kallsyms (const char *kallsyms,
|
|||||||
static GHashTable *
|
static GHashTable *
|
||||||
get_kernel_symbols (void)
|
get_kernel_symbols (void)
|
||||||
{
|
{
|
||||||
|
static gboolean read_symbols = FALSE;
|
||||||
static GHashTable *kernel_syms;
|
static GHashTable *kernel_syms;
|
||||||
|
|
||||||
if (!kernel_syms)
|
if (!read_symbols)
|
||||||
{
|
{
|
||||||
char *kallsyms;
|
char *kallsyms;
|
||||||
g_file_get_contents ("/proc/kallsyms", &kallsyms, NULL, NULL);
|
g_file_get_contents ("/proc/kallsyms", &kallsyms, NULL, NULL);
|
||||||
@ -572,6 +573,8 @@ get_kernel_symbols (void)
|
|||||||
g_free (kallsyms);
|
g_free (kallsyms);
|
||||||
g_hash_table_destroy (kernel_syms);
|
g_hash_table_destroy (kernel_syms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_symbols = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
88
profile.c
88
profile.c
@ -359,6 +359,89 @@ profile_caller_new (void)
|
|||||||
return caller;
|
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
|
static void
|
||||||
add_to_list (gpointer key,
|
add_to_list (gpointer key,
|
||||||
gpointer value,
|
gpointer value,
|
||||||
@ -380,8 +463,8 @@ listify_hash_table (GHashTable *hash_table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProfileCaller *
|
ProfileCaller *
|
||||||
profile_list_callers (Profile *profile,
|
profile_list_ancestors (Profile *profile,
|
||||||
char *callee_name)
|
char *callee_name)
|
||||||
{
|
{
|
||||||
StackNode *callees;
|
StackNode *callees;
|
||||||
StackNode *node;
|
StackNode *node;
|
||||||
@ -459,6 +542,7 @@ profile_list_callers (Profile *profile,
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
profile_free (Profile *profile)
|
profile_free (Profile *profile)
|
||||||
|
|||||||
@ -1447,7 +1447,7 @@ build_gui (Application *app)
|
|||||||
/* callers view */
|
/* callers view */
|
||||||
app->callers_view = (GtkTreeView *)glade_xml_get_widget (xml, "callers_view");
|
app->callers_view = (GtkTreeView *)glade_xml_get_widget (xml, "callers_view");
|
||||||
gtk_tree_view_set_enable_search (app->callers_view, FALSE);
|
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, _("Self"), CALLERS_SELF, "%.2f ");
|
||||||
add_double_format_column (app->callers_view, _("Total"), CALLERS_TOTAL, "%.2f ");
|
add_double_format_column (app->callers_view, _("Total"), CALLERS_TOTAL, "%.2f ");
|
||||||
g_signal_connect (app->callers_view, "row-activated",
|
g_signal_connect (app->callers_view, "row-activated",
|
||||||
|
|||||||
Reference in New Issue
Block a user