Use an array instead of list of maps.

2006-10-24  Soren Sandmann <sandmann@daimi.au.dk>

	* process.c (struct Process): Use an array instead of list of
	maps.
This commit is contained in:
Soren Sandmann
2006-10-24 04:00:59 +00:00
committed by Søren Sandmann Pedersen
parent e255c00a6d
commit c02712dc85
2 changed files with 56 additions and 66 deletions

View File

@ -1,3 +1,8 @@
2006-10-24 Soren Sandmann <sandmann@daimi.au.dk>
* process.c (struct Process): Use an array instead of list of
maps.
2006-10-23 Soren Sandmann <sandmann@daimi.au.dk> 2006-10-23 Soren Sandmann <sandmann@daimi.au.dk>
* module/sysprof-module.c (init_module): Use PAGE_SIZE - 1 instead * module/sysprof-module.c (init_module): Use PAGE_SIZE - 1 instead

103
process.c
View File

@ -54,7 +54,9 @@ struct Process
{ {
char *cmdline; char *cmdline;
GList *maps; int n_maps;
Map *maps;
GList *bad_pages; GList *bad_pages;
int pid; int pid;
@ -72,24 +74,23 @@ initialize (void)
} }
} }
static GList * static Map *
read_maps (int pid) read_maps (int pid, int *n_maps)
{ {
char *name = g_strdup_printf ("/proc/%d/maps", pid); char *name = g_strdup_printf ("/proc/%d/maps", pid);
char buffer[1024]; char buffer[1024];
FILE *in; FILE *in;
GList *result = NULL; GArray *result;
in = fopen (name, "r"); in = fopen (name, "r");
if (!in) if (!in)
{ {
#if 0
g_print ("could not open %d: %s\n", pid, g_strerror (errno));
#endif
g_free (name); g_free (name);
return NULL; return NULL;
} }
result = g_array_new (FALSE, FALSE, sizeof (Map));
while (fgets (buffer, sizeof (buffer) - 1, in)) while (fgets (buffer, sizeof (buffer) - 1, in))
{ {
char file[256]; char file[256];
@ -99,77 +100,65 @@ read_maps (int pid)
gulong offset; gulong offset;
gulong inode; gulong inode;
#if 0
g_print ("buffer: %s\n", buffer);
#endif
count = sscanf ( count = sscanf (
buffer, "%lx-%lx %*15s %lx %*x:%*x %lu %255s", buffer, "%lx-%lx %*15s %lx %*x:%*x %lu %255s",
&start, &end, &offset, &inode, file); &start, &end, &offset, &inode, file);
if (count == 5) if (count == 5)
{ {
Map *map; Map map;
map = g_new (Map, 1); map.filename = g_strdup (file);
map.start = start;
map.end = end;
map->filename = g_strdup (file); if (strcmp (map.filename, "[vdso]") == 0)
map->start = start;
map->end = end;
if (strcmp (map->filename, "[vdso]") == 0)
{ {
/* For the vdso, the kernel reports 'offset' as the /* For the vdso, the kernel reports 'offset' as the
* the same as the mapping addres. This doesn't make * the same as the mapping addres. This doesn't make
* any sense to me, so we just zero it here. * any sense to me, so we just zero it here.
*/ */
#if 0 map.offset = 0;
g_print ("fixing up\n"); map.inode = -1;
#endif
map->offset = 0;
map->inode = -1;
} }
else else
{ {
map->offset = offset; map.offset = offset;
map->inode = inode; map.inode = inode;
} }
map->bin_file = NULL; map.bin_file = NULL;
result = g_list_prepend (result, map); g_array_append_val (result, map);
} }
#if 0
else
{
g_print ("scanf\n");
}
#endif
} }
g_free (name); g_free (name);
fclose (in); fclose (in);
return result;
if (n_maps)
*n_maps = result->len;
return (Map *)g_array_free (result, FALSE);
} }
static void static void
free_maps (GList *maps) free_maps (int n_maps,
Map *maps)
{ {
GList *list; int i;
for (list = maps; list != NULL; list = list->next) for (i = 0; i < n_maps; ++i)
{ {
Map *map = list->data; Map *map = &(maps[i]);
if (map->filename) if (map->filename)
g_free (map->filename); g_free (map->filename);
if (map->bin_file) if (map->bin_file)
bin_file_free (map->bin_file); bin_file_free (map->bin_file);
g_free (map);
} }
g_list_free (maps); g_free (maps);
} }
const guint8 * const guint8 *
@ -181,12 +170,14 @@ process_get_vdso_bytes (gsize *length)
if (!has_data) if (!has_data)
{ {
GList *maps = read_maps (getpid()); Map *maps;
GList *list; int n_maps, i;
for (list = maps; list != NULL; list = list->next) maps = read_maps (getpid(), &n_maps);
for (i = 0; i < n_maps; ++i)
{ {
Map *map = list->data; Map *map = &(maps[i]);
if (strcmp (map->filename, "[vdso]") == 0) if (strcmp (map->filename, "[vdso]") == 0)
{ {
@ -196,7 +187,7 @@ process_get_vdso_bytes (gsize *length)
} }
has_data = TRUE; has_data = TRUE;
free_maps (maps); free_maps (n_maps, maps);
} }
if (length) if (length)
@ -234,11 +225,11 @@ create_process (const char *cmdline, int pid)
static Map * static Map *
process_locate_map (Process *process, gulong addr) process_locate_map (Process *process, gulong addr)
{ {
GList *list; int i;
for (list = process->maps; list != NULL; list = list->next) for (i = 0; i < process->n_maps; ++i)
{ {
Map *map = list->data; Map *map = &(process->maps[i]);
if ((addr >= map->start) && if ((addr >= map->start) &&
(addr < map->end)) (addr < map->end))
@ -256,15 +247,9 @@ free_process (gpointer key, gpointer value, gpointer data)
char *cmdline = key; char *cmdline = key;
Process *process = value; Process *process = value;
#if 0 free_maps (process->n_maps, process->maps);
g_print ("freeing: %p\n", process);
memset (process, '\0', sizeof (Process));
#endif
g_free (process->cmdline); g_free (process->cmdline);
#if 0
process->cmdline = "You are using free()'d memory";
#endif
free_maps (process->maps);
g_list_free (process->bad_pages); g_list_free (process->bad_pages);
g_free (cmdline); g_free (cmdline);
@ -311,9 +296,9 @@ process_ensure_map (Process *process, int pid, gulong addr)
/* a map containing addr was not found */ /* a map containing addr was not found */
if (process->maps) if (process->maps)
free_maps (process->maps); free_maps (process->n_maps, process->maps);
process->maps = read_maps (pid); process->maps = read_maps (pid, &process->n_maps);
if (!process_has_page (process, addr)) if (!process_has_page (process, addr))
{ {