mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
*** empty log message ***
This commit is contained in:
3
TODO
3
TODO
@ -3,6 +3,7 @@
|
||||
Should avoid a lot of potential broken/raciness with dlopen etc.
|
||||
- grep FIXME
|
||||
- hide internal stuff in ProfileDescendant
|
||||
- add an 'everything' object. It _is_ really needed for a lot of things
|
||||
|
||||
- loading and saving
|
||||
|
||||
@ -13,8 +14,6 @@
|
||||
|
||||
- Port to GtkAction
|
||||
|
||||
- If we can't get a name, look in /proc/<pid>/status
|
||||
|
||||
- Charge 'self' properly to processes that don't get any stack trace at all
|
||||
|
||||
- figure out a way to deal with both disk and CPU. Need to make sure that
|
||||
|
||||
@ -154,6 +154,9 @@ separate_debug_file_exists (const char *name, unsigned long crc)
|
||||
file_crc = calc_crc32 (file_crc, buffer, count);
|
||||
|
||||
close (fd);
|
||||
|
||||
if (crc != file_crc)
|
||||
g_print ("warning: %s has wrong crc\n", name);
|
||||
|
||||
return crc == file_crc;
|
||||
}
|
||||
|
||||
122
process.c
122
process.c
@ -217,44 +217,106 @@ process_ensure_map (Process *process, int pid, gulong addr)
|
||||
g_list_prepend (process->bad_pages, (gpointer)addr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_idle_free (gpointer d)
|
||||
{
|
||||
g_free (d);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
idle_free (char *d)
|
||||
{
|
||||
g_idle_add (do_idle_free, d);
|
||||
return d;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_cmdline (int pid)
|
||||
{
|
||||
char *cmdline;
|
||||
char *filename = idle_free (g_strdup_printf ("/proc/%d/cmdline", pid));
|
||||
|
||||
if (g_file_get_contents (filename, &cmdline, NULL, NULL))
|
||||
{
|
||||
if (*cmdline == '\0')
|
||||
{
|
||||
g_free (cmdline);
|
||||
return NULL;
|
||||
}
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_statname (int pid)
|
||||
{
|
||||
char *stat;
|
||||
char *filename = idle_free (g_strdup_printf ("/proc/%d/stat", pid));
|
||||
|
||||
#if 0
|
||||
g_print ("stat %d\n", pid);
|
||||
#endif
|
||||
|
||||
if (g_file_get_contents (filename, &stat, NULL, NULL))
|
||||
{
|
||||
char result[200];
|
||||
|
||||
idle_free (stat);
|
||||
|
||||
if (sscanf (stat, "%*d %200s %*s", result) == 1)
|
||||
return g_strndup (result, 200);
|
||||
}
|
||||
#if 0
|
||||
g_print ("return null\n");
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_pidname (int pid)
|
||||
{
|
||||
return g_strdup_printf ("[pid %d]", pid);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_name (int pid)
|
||||
{
|
||||
char *cmdline = NULL;
|
||||
|
||||
if ((cmdline = get_cmdline (pid)))
|
||||
return cmdline;
|
||||
|
||||
if ((cmdline = get_statname (pid)))
|
||||
return cmdline;
|
||||
|
||||
return get_pidname (pid);
|
||||
}
|
||||
|
||||
Process *
|
||||
process_get_from_pid (int pid)
|
||||
{
|
||||
Process *p;
|
||||
gchar *filename = NULL;
|
||||
gchar *cmdline = NULL;
|
||||
|
||||
initialize();
|
||||
|
||||
p = g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid));
|
||||
if (p)
|
||||
goto out;
|
||||
|
||||
filename = g_strdup_printf ("/proc/%d/cmdline", pid);
|
||||
|
||||
if (g_file_get_contents (filename, &cmdline, NULL, NULL))
|
||||
{
|
||||
p = g_hash_table_lookup (processes_by_cmdline, cmdline);
|
||||
if (p)
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline = g_strdup_printf ("[pid %d]", pid);
|
||||
}
|
||||
|
||||
p = create_process (cmdline, pid);
|
||||
|
||||
out:
|
||||
if (cmdline)
|
||||
g_free (cmdline);
|
||||
|
||||
if (filename)
|
||||
g_free (filename);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
p = g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid));
|
||||
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
cmdline = get_name (pid);
|
||||
|
||||
p = g_hash_table_lookup (processes_by_cmdline, cmdline);
|
||||
if (p)
|
||||
return p;
|
||||
else
|
||||
return create_process (idle_free (cmdline), pid);
|
||||
}
|
||||
|
||||
const Symbol *
|
||||
process_lookup_symbol (Process *process, gulong address)
|
||||
|
||||
28
profile.c
28
profile.c
@ -391,7 +391,7 @@ generate_presentation_name (Process *process, gulong address)
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_profile_node (GHashTable *profile_objects, Process *process, gulong address)
|
||||
ensure_profile_object (GHashTable *profile_objects, Process *process, gulong address)
|
||||
{
|
||||
char *key = generate_key (process, address);
|
||||
|
||||
@ -434,12 +434,12 @@ generate_object_table (Process *process, GSList *trace, gint size, gpointer data
|
||||
Info *info = data;
|
||||
GSList *list;
|
||||
|
||||
ensure_profile_node (info->profile_objects, process, 0);
|
||||
ensure_profile_object (info->profile_objects, process, 0);
|
||||
|
||||
for (list = trace; list != NULL; list = list->next)
|
||||
{
|
||||
update ();
|
||||
ensure_profile_node (info->profile_objects, process, (gulong)list->data);
|
||||
ensure_profile_object (info->profile_objects, process, (gulong)list->data);
|
||||
}
|
||||
|
||||
info->profile->size += size;
|
||||
@ -592,29 +592,27 @@ compute_object_total (gpointer key, gpointer value, gpointer data)
|
||||
Profile *
|
||||
profile_new (StackStash *stash)
|
||||
{
|
||||
Profile *profile = g_new (Profile, 1);
|
||||
Info info;
|
||||
|
||||
profile->call_tree = NULL;
|
||||
|
||||
profile->nodes_by_object =
|
||||
|
||||
info.profile = g_new (Profile, 1);
|
||||
info.profile->call_tree = NULL;
|
||||
info.profile->nodes_by_object =
|
||||
g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
||||
|
||||
profile->size = 0;
|
||||
|
||||
info.profile = profile;
|
||||
info.profile->size = 0;
|
||||
|
||||
/* profile objects */
|
||||
info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
||||
stack_stash_foreach (stash, generate_object_table, &info);
|
||||
stack_stash_foreach (stash, generate_call_tree, &info);
|
||||
link_parents (profile->call_tree, NULL);
|
||||
link_parents (info.profile->call_tree, NULL);
|
||||
|
||||
g_hash_table_foreach (profile->nodes_by_object, compute_object_total, NULL);
|
||||
g_hash_table_foreach (info.profile->nodes_by_object, compute_object_total, NULL);
|
||||
|
||||
g_hash_table_destroy (info.profile_objects);
|
||||
|
||||
return profile;
|
||||
return info.profile;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
19
sfile.c
19
sfile.c
@ -727,17 +727,26 @@ handle_text (GMarkupParseContext *context,
|
||||
{
|
||||
case POINTER:
|
||||
if (!get_number (text, &action.u.pointer.target_id))
|
||||
/* FIXME: set error */;
|
||||
{
|
||||
set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
if (!get_number (text, &action.u.integer.value))
|
||||
/* FIXME: set error */;
|
||||
{
|
||||
set_invalid_content_error (err, "Contents '%s' of integer element not a number", text);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
if (!decode_text (text, &action.u.string.value))
|
||||
/* FIXME: set error */
|
||||
{
|
||||
set_invalid_content_error (err, "Contents '%s' of text element is illformed", text);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -947,6 +956,7 @@ void
|
||||
sfile_begin_add_record (SFileOutput *file,
|
||||
const char *name)
|
||||
{
|
||||
Action action;
|
||||
TransitionType type;
|
||||
|
||||
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||
@ -960,9 +970,10 @@ void
|
||||
sfile_begin_add_list (SFileOutput *file,
|
||||
const char *name)
|
||||
{
|
||||
Action action;
|
||||
TransitionType type;
|
||||
|
||||
file->state = state_transition_begin (file->state, name, &type, NULL);
|
||||
file->state = state_transition_begin (file->state, name, &action.type, NULL);
|
||||
|
||||
g_return_if_fail (file->state && type == BEGIN_LIST);
|
||||
|
||||
|
||||
@ -304,7 +304,7 @@ on_timer(unsigned long dong)
|
||||
{
|
||||
struct task_struct *p;
|
||||
|
||||
static const int cpu_profiler = 0; /* set to 0 to profile disk */
|
||||
static const int cpu_profiler = 1; /* set to 0 to profile disk */
|
||||
|
||||
for_each_process (p) {
|
||||
if (p->state == (cpu_profiler? TASK_RUNNING : TASK_UNINTERRUPTIBLE)) {
|
||||
|
||||
Reference in New Issue
Block a user