libgtop r2713 - trunk/sysdeps/linux
- From: bdejean svn gnome org
- To: svn-commits-list gnome org
- Subject: libgtop r2713 - trunk/sysdeps/linux
- Date: Sun, 24 Feb 2008 17:52:24 +0000 (GMT)
Author: bdejean
Date: Sun Feb 24 17:52:24 2008
New Revision: 2713
URL: http://svn.gnome.org/viewvc/libgtop?rev=2713&view=rev
Log:
Smarter smaps parsing.
See #518145.
Modified:
trunk/sysdeps/linux/glibtop_private.c
trunk/sysdeps/linux/procmap.c
Modified: trunk/sysdeps/linux/glibtop_private.c
==============================================================================
--- trunk/sysdeps/linux/glibtop_private.c (original)
+++ trunk/sysdeps/linux/glibtop_private.c Sun Feb 24 17:52:24 2008
@@ -17,27 +17,31 @@
unsigned long long
get_scaled(const char *buffer, const char *key)
{
- const char *ptr;
+ const char *ptr = buffer;;
char *next;
- unsigned long long value = 0;
+ unsigned long long value;
- if (G_LIKELY((ptr = strstr(buffer, key))))
- {
- ptr += strlen(key);
- value = strtoull(ptr, &next, 0);
+ if (key) {
+ if (G_LIKELY((ptr = strstr(buffer, key))))
+ ptr += strlen(key);
+ else {
+ g_warning("Could not read key '%s' in buffer '%s'",
+ key, buffer);
+ return 0;
+ }
+ }
- for ( ; *next; ++next) {
- if (*next == 'k') {
- value *= 1024;
- break;
- } else if (*next == 'M') {
- value *= 1024 * 1024;
- break;
- }
+ value = strtoull(ptr, &next, 0);
+
+ for ( ; *next; ++next) {
+ if (*next == 'k') {
+ value *= 1024;
+ break;
+ } else if (*next == 'M') {
+ value *= 1024 * 1024;
+ break;
}
- } else
- g_warning("Could not read key '%s' in buffer '%s'",
- key, buffer);
+ }
return value;
}
Modified: trunk/sysdeps/linux/procmap.c
==============================================================================
--- trunk/sysdeps/linux/procmap.c (original)
+++ trunk/sysdeps/linux/procmap.c Sun Feb 24 17:52:24 2008
@@ -66,49 +66,78 @@
/* Provides detailed information about a process. */
-static void
-add_smaps(glibtop *server, FILE *smaps, glibtop_map_entry *entry)
+
+struct smap_value {
+ char name[16];
+ size_t name_len;
+ ptrdiff_t offset;
+};
+
+static int
+compare(const void* a_key, const void* a_smap)
{
-#define SMAP_OFFSET(MEMBER) offsetof(glibtop_map_entry, MEMBER)
+ const char* key = a_key;
+ const struct smap_value* smap = a_smap;
+ return strncmp(key, smap->name, smap->name_len);
+}
+
+
+static gboolean
+is_smap_value(const char* s)
+{
+ for ( ; *s; ++s) {
+
+ if (isspace(*s))
+ return FALSE;
+
+ if (*s == ':')
+ return TRUE;
+ }
+
+ return FALSE;
+}
- struct smap_value {
- char name[15];
- ptrdiff_t offset;
- };
+/*
+ Returns whether line is a 'value' line
+ and add if we know its meaning
+*/
+static gboolean
+parse_smaps(glibtop_map_entry *entry, const char* line)
+{
+#define SMAP_OFFSET(MEMBER) offsetof(glibtop_map_entry, MEMBER)
+#define STR_AND_LEN(X) (X), (sizeof X - 1)
+
+ /* keep sorted */
const struct smap_value values[] = {
- { "Size:", SMAP_OFFSET(size) },
- { "Rss:", SMAP_OFFSET(rss) },
- { "Shared_Clean:", SMAP_OFFSET(shared_clean) },
- { "Shared_Dirty:", SMAP_OFFSET(shared_dirty) },
- { "Private_Clean:", SMAP_OFFSET(private_clean) },
- { "Private_Dirty:", SMAP_OFFSET(private_dirty) }
+ { STR_AND_LEN("Private_Clean:"), SMAP_OFFSET(private_clean) },
+ { STR_AND_LEN("Private_Dirty:"), SMAP_OFFSET(private_dirty) },
+ { STR_AND_LEN("Rss:"), SMAP_OFFSET(rss) },
+ { STR_AND_LEN("Shared_Clean:"), SMAP_OFFSET(shared_clean) },
+ { STR_AND_LEN("Shared_Dirty:"), SMAP_OFFSET(shared_dirty) },
+ { STR_AND_LEN("Size:"), SMAP_OFFSET(size) }
};
- size_t i;
+#undef STR_AND_LEN
+#undef SMAP_OFFSET
- for (i = 0; i < G_N_ELEMENTS(values); ++i) {
- char line[80];
+ struct smap_value* smap;
+
+ smap = bsearch(line, values, G_N_ELEMENTS(values), sizeof values[0], compare);
+
+ if (smap) {
char *offset;
guint64 *value;
- if (!fgets(line, sizeof line, smaps) || !g_str_has_prefix(line, values[i].name)) {
- glibtop_warn_io_r(server,
- "Could not read smaps value %s",
- values[i].name);
- return;
- }
-
offset = (void*) entry;
- offset += values[i].offset;
+ offset += smap->offset;
value = (void*) offset;
- *value = get_scaled(line, values[i].name);
+ *value = get_scaled(line + smap->name_len, NULL);
+ return TRUE;
}
- entry->flags |= _glibtop_sysdeps_map_entry_smaps;
-
-#undef SMAP_OFFSET
+ return is_smap_value(line);
}
@@ -150,7 +179,7 @@
while(TRUE)
{
- unsigned long perm = 0;
+ unsigned long perm;
guint len;
int line_end;
@@ -164,6 +193,8 @@
if (getline(&line, &line_size, maps) == -1)
break;
+ new_entry_line:
+
if (sscanf(line, PROC_MAPS_FORMAT,
&start, &end, flags, &offset,
&dev_major, &dev_minor, &inode, &line_end) != 7)
@@ -173,6 +204,7 @@
g_strstrip(filename);
/* Compute access permissions. */
+ perm = 0;
if (flags [0] == 'r')
perm |= GLIBTOP_MAP_PERM_READ;
@@ -205,11 +237,22 @@
entry->inode = inode;
g_strlcpy(entry->filename, filename, sizeof entry->filename);
- if (has_smaps)
- add_smaps(server, maps, entry);
+ if (has_smaps) {
+ ssize_t ret;
+ entry->flags |= _glibtop_sysdeps_map_entry_smaps;
+
+ while ((ret = getline(&line, &line_size, maps)) != -1) {
+ if (!parse_smaps(entry, line))
+ goto new_entry_line;
+ }
+ if (ret == -1)
+ goto eof;
+ }
}
+eof:
+
free(line);
fclose (maps);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]