*** 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. Should avoid a lot of potential broken/raciness with dlopen etc.
- grep FIXME - grep FIXME
- hide internal stuff in ProfileDescendant - hide internal stuff in ProfileDescendant
- add an 'everything' object. It _is_ really needed for a lot of things
- loading and saving - loading and saving
@ -13,8 +14,6 @@
- Port to GtkAction - 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 - 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 - 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); file_crc = calc_crc32 (file_crc, buffer, count);
close (fd); close (fd);
if (crc != file_crc)
g_print ("warning: %s has wrong crc\n", name);
return crc == file_crc; 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); 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 *
process_get_from_pid (int pid) process_get_from_pid (int pid)
{ {
Process *p; Process *p;
gchar *filename = NULL;
gchar *cmdline = NULL; gchar *cmdline = NULL;
initialize(); 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 * const Symbol *
process_lookup_symbol (Process *process, gulong address) process_lookup_symbol (Process *process, gulong address)

View File

@ -391,7 +391,7 @@ generate_presentation_name (Process *process, gulong address)
} }
static void 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); char *key = generate_key (process, address);
@ -434,12 +434,12 @@ generate_object_table (Process *process, GSList *trace, gint size, gpointer data
Info *info = data; Info *info = data;
GSList *list; 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) for (list = trace; list != NULL; list = list->next)
{ {
update (); 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; info->profile->size += size;
@ -592,29 +592,27 @@ compute_object_total (gpointer key, gpointer value, gpointer data)
Profile * Profile *
profile_new (StackStash *stash) profile_new (StackStash *stash)
{ {
Profile *profile = g_new (Profile, 1);
Info info; Info info;
profile->call_tree = NULL; info.profile = g_new (Profile, 1);
info.profile->call_tree = NULL;
profile->nodes_by_object = info.profile->nodes_by_object =
g_hash_table_new (direct_hash_no_null, g_direct_equal); g_hash_table_new (direct_hash_no_null, g_direct_equal);
info.profile->size = 0;
profile->size = 0;
/* profile objects */
info.profile = profile;
info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal, info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL); g_free, NULL);
stack_stash_foreach (stash, generate_object_table, &info); stack_stash_foreach (stash, generate_object_table, &info);
stack_stash_foreach (stash, generate_call_tree, &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); g_hash_table_destroy (info.profile_objects);
return profile; return info.profile;
} }
static void static void

19
sfile.c
View File

@ -727,17 +727,26 @@ handle_text (GMarkupParseContext *context,
{ {
case POINTER: case POINTER:
if (!get_number (text, &action.u.pointer.target_id)) 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; break;
case INTEGER: case INTEGER:
if (!get_number (text, &action.u.integer.value)) 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; break;
case STRING: case STRING:
if (!decode_text (text, &action.u.string.value)) 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; break;
default: default:
@ -947,6 +956,7 @@ void
sfile_begin_add_record (SFileOutput *file, sfile_begin_add_record (SFileOutput *file,
const char *name) const char *name)
{ {
Action action;
TransitionType type; TransitionType type;
file->state = state_transition_begin (file->state, name, &type, NULL); file->state = state_transition_begin (file->state, name, &type, NULL);
@ -960,9 +970,10 @@ void
sfile_begin_add_list (SFileOutput *file, sfile_begin_add_list (SFileOutput *file,
const char *name) const char *name)
{ {
Action action;
TransitionType type; 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); g_return_if_fail (file->state && type == BEGIN_LIST);

View File

@ -304,7 +304,7 @@ on_timer(unsigned long dong)
{ {
struct task_struct *p; 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) { for_each_process (p) {
if (p->state == (cpu_profiler? TASK_RUNNING : TASK_UNINTERRUPTIBLE)) { if (p->state == (cpu_profiler? TASK_RUNNING : TASK_UNINTERRUPTIBLE)) {