[sysprof] Add process and map tracking to tracker
- From: Søren Sandmann Pedersen <ssp src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [sysprof] Add process and map tracking to tracker
- Date: Mon, 14 Sep 2009 09:08:01 +0000 (UTC)
commit cdc7ce7e12c22c63bde9a2ccc1474ab8cc6af57d
Author: Søren Sandmann Pedersen <ssp redhat com>
Date: Mon Sep 7 19:16:52 2009 -0400
Add process and map tracking to tracker
collector.c | 10 +++-
tracker.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
tracker.h | 16 +++---
3 files changed, 151 insertions(+), 31 deletions(-)
---
diff --git a/collector.c b/collector.c
index acea8f8..b6b1ff2 100644
--- a/collector.c
+++ b/collector.c
@@ -217,8 +217,13 @@ on_read (gpointer data)
}
if (!skip_samples || header->type != PERF_EVENT_SAMPLE)
+ {
+ if (header->type == PERF_EVENT_SAMPLE)
+ collector->n_samples++;
+
process_event (collector, (counter_event_t *)header);
-
+ }
+
tail += header->size;
}
@@ -422,7 +427,6 @@ process_sample (Collector *collector,
{
uint64_t *ips;
int n_ips;
-
if (sample->n_ips == 0)
{
ips = &sample->ip;
@@ -433,7 +437,7 @@ process_sample (Collector *collector,
ips = sample->ips;
n_ips = sample->n_ips;
}
-
+
tracker_add_sample (collector->tracker,
sample->pid, ips, n_ips);
}
diff --git a/tracker.c b/tracker.c
index 7f8b2e0..bb76cd2 100644
--- a/tracker.c
+++ b/tracker.c
@@ -5,6 +5,7 @@
#include "tracker.h"
#include "stackstash.h"
+#include "binfile.h"
typedef struct new_process_t new_process_t;
typedef struct new_map_t new_map_t;
@@ -13,10 +14,10 @@ typedef struct sample_t sample_t;
struct tracker_t
{
StackStash *stash;
-
- size_t n_event_bytes;
- size_t n_allocated_bytes;
- uint8_t *events;
+
+ size_t n_event_bytes;
+ size_t n_allocated_bytes;
+ uint8_t * events;
};
typedef enum
@@ -37,7 +38,7 @@ struct new_map_t
{
event_type_t type;
int32_t pid;
- char file_name[PATH_MAX];
+ char filename[PATH_MAX];
uint64_t start;
uint64_t end;
uint64_t offset;
@@ -274,7 +275,7 @@ tracker_add_map (tracker_t * tracker,
event.type = NEW_MAP;
event.pid = pid;
- COPY_STRING (event.file_name, filename);
+ COPY_STRING (event.filename, filename);
event.start = start;
event.end = end;
event.offset = offset;
@@ -304,26 +305,135 @@ tracker_add_sample (tracker_t *tracker,
/* */
typedef struct state_t state_t;
+typedef struct process_t process_t;
+typedef struct map_t map_t;
+
+struct process_t
+{
+ pid_t pid;
+
+ char * comm;
+ char * undefined;
+
+ GPtrArray * maps;
+};
+
+struct map_t
+{
+ char * filename;
+ uint64_t start;
+ uint64_t end;
+ uint64_t offset;
+ uint64_t inode;
+
+ BinFile * bin_file;
+};
struct state_t
{
-
+ GHashTable *processes_by_pid;
};
static void
-new_process (state_t *tracker, new_process_t *new_process)
+destroy_map (map_t *map)
{
+ if (map->bin_file)
+ bin_file_free (map->bin_file);
+ g_free (map->filename);
+ g_free (map);
}
static void
-new_map (state_t *tracker, new_map_t *new_map)
+create_map (state_t *state, new_map_t *new_map)
{
+ process_t *process;
+ map_t *map;
+ int i;
+ process = g_hash_table_lookup (
+ state->processes_by_pid, GINT_TO_POINTER (new_map->pid));
+
+ if (!process)
+ return;
+
+ map = g_new0 (map_t, 1);
+ map->filename = g_strdup (new_map->filename);
+ map->start = new_map->start;
+ map->end = new_map->end;
+ map->offset = new_map->offset;
+ map->inode = new_map->inode;
+
+ /* Remove existing maps that overlap the new one */
+ for (i = 0; i < process->maps->len; ++i)
+ {
+ map_t *m = process->maps->pdata[i];
+
+ if (m->start < map->end && m->end > map->start)
+ {
+ destroy_map (m);
+
+ g_ptr_array_remove_index (process->maps, i);
+ }
+ }
+
+ g_ptr_array_add (process->maps, map);
}
static void
-sample (state_t *tracker, sample_t *sample)
+destroy_process (process_t *process)
+{
+ int i;
+
+ g_free (process->comm);
+ g_free (process->undefined);
+
+ for (i = 0; i < process->maps->len; ++i)
+ {
+ map_t *map = process->maps->pdata[i];
+
+ destroy_map (map);
+ }
+
+ g_ptr_array_free (process->maps, TRUE);
+ g_free (process);
+}
+
+static void
+create_process (state_t *state, new_process_t *new_process)
+{
+ process_t *process = g_new0 (process_t, 1);
+
+ process->pid = new_process->pid;
+ process->comm = g_strdup (new_process->command_line);
+ process->undefined = NULL;
+ process->maps = g_ptr_array_new ();
+
+ g_hash_table_insert (
+ state->processes_by_pid, GINT_TO_POINTER (process->pid), process);
+}
+
+static void
+free_process (gpointer data)
+{
+ process_t *process = data;
+
+ destroy_process (process);
+}
+
+static state_t *
+state_new (void)
+{
+ state_t *state = g_new0 (state_t, 1);
+
+ state->processes_by_pid =
+ g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_process);
+
+ return state;
+}
+
+static void
+process_sample (state_t *tracker, sample_t *sample)
{
}
@@ -331,33 +441,39 @@ Profile *
tracker_create_profile (tracker_t *tracker)
{
uint8_t *end = tracker->events + tracker->n_event_bytes;
+ StackStash *resolved_stash;
+ Profile *profile;
+ state_t *state;
uint8_t *event;
-
+
+ state = state_new ();
+ resolved_stash = stack_stash_new (g_free);
+
event = tracker->events;
while (event < end)
{
event_type_t type = *(event_type_t *)event;
- new_process_t *new_process;
- new_map_t *new_map;
- sample_t *sample;
switch (type)
{
case NEW_PROCESS:
-
-
+ create_process (state, (new_process_t *)event);
break;
case NEW_MAP:
-
-
+ create_map (state, (new_map_t *)event);
break;
case SAMPLE:
-
-
+ process_sample (state, (sample_t *)event);
break;
}
}
+
+ profile = profile_new (resolved_stash);
+
+ stack_stash_unref (resolved_stash);
+
+ return profile;
}
diff --git a/tracker.h b/tracker.h
index e4caf60..71b33d8 100644
--- a/tracker.h
+++ b/tracker.h
@@ -9,16 +9,16 @@ void tracker_free (tracker_t *);
void tracker_add_process (tracker_t *tracker,
pid_t pid,
const char *command_line);
-void
-tracker_add_map (tracker_t * tracker,
- pid_t pid,
- uint64_t start,
- uint64_t end,
- uint64_t offset,
- uint64_t inode,
- const char *filename);
+void tracker_add_map (tracker_t * tracker,
+ pid_t pid,
+ uint64_t start,
+ uint64_t end,
+ uint64_t offset,
+ uint64_t inode,
+ const char *filename);
void tracker_add_sample (tracker_t *tracker,
pid_t pid,
uint64_t *ips,
int n_ips);
+
Profile *tracker_create_profile (tracker_t *tracker);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]