*** empty log message ***

This commit is contained in:
Søren Sandmann Pedersen
2004-11-23 00:10:55 +00:00
parent 95ca4eaa27
commit c5b66034c5
6 changed files with 125 additions and 52 deletions

3
TODO
View File

@ -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

View File

@ -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
View File

@ -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)

View File

@ -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
View File

@ -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);

View File

@ -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)) {