@@ -17,13 +17,20 @@
|
|||||||
unsigned long long
|
unsigned long long
|
||||||
get_scaled(const char *buffer, const char *key)
|
get_scaled(const char *buffer, const char *key)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
const char *ptr = buffer;;
|
||||||
char *next;
|
char *next;
|
||||||
unsigned long long value = 0;
|
unsigned long long value;
|
||||||
|
|
||||||
|
if (key) {
|
||||||
if (G_LIKELY((ptr = strstr(buffer, key))))
|
if (G_LIKELY((ptr = strstr(buffer, key))))
|
||||||
{
|
|
||||||
ptr += strlen(key);
|
ptr += strlen(key);
|
||||||
|
else {
|
||||||
|
g_warning("Could not read key '%s' in buffer '%s'",
|
||||||
|
key, buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value = strtoull(ptr, &next, 0);
|
value = strtoull(ptr, &next, 0);
|
||||||
|
|
||||||
for ( ; *next; ++next) {
|
for ( ; *next; ++next) {
|
||||||
@@ -35,9 +42,6 @@ get_scaled(const char *buffer, const char *key)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
g_warning("Could not read key '%s' in buffer '%s'",
|
|
||||||
key, buffer);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@@ -66,49 +66,78 @@ _glibtop_init_proc_map_s (glibtop *server)
|
|||||||
/* Provides detailed information about a process. */
|
/* Provides detailed information about a process. */
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_smaps(glibtop *server, FILE *smaps, glibtop_map_entry *entry)
|
|
||||||
{
|
|
||||||
#define SMAP_OFFSET(MEMBER) offsetof(glibtop_map_entry, MEMBER)
|
|
||||||
|
|
||||||
struct smap_value {
|
struct smap_value {
|
||||||
char name[15];
|
char name[16];
|
||||||
|
size_t name_len;
|
||||||
ptrdiff_t offset;
|
ptrdiff_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare(const void* a_key, const void* a_smap)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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[] = {
|
const struct smap_value values[] = {
|
||||||
{ "Size:", SMAP_OFFSET(size) },
|
{ STR_AND_LEN("Private_Clean:"), SMAP_OFFSET(private_clean) },
|
||||||
{ "Rss:", SMAP_OFFSET(rss) },
|
{ STR_AND_LEN("Private_Dirty:"), SMAP_OFFSET(private_dirty) },
|
||||||
{ "Shared_Clean:", SMAP_OFFSET(shared_clean) },
|
{ STR_AND_LEN("Rss:"), SMAP_OFFSET(rss) },
|
||||||
{ "Shared_Dirty:", SMAP_OFFSET(shared_dirty) },
|
{ STR_AND_LEN("Shared_Clean:"), SMAP_OFFSET(shared_clean) },
|
||||||
{ "Private_Clean:", SMAP_OFFSET(private_clean) },
|
{ STR_AND_LEN("Shared_Dirty:"), SMAP_OFFSET(shared_dirty) },
|
||||||
{ "Private_Dirty:", SMAP_OFFSET(private_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) {
|
struct smap_value* smap;
|
||||||
char line[80];
|
|
||||||
|
smap = bsearch(line, values, G_N_ELEMENTS(values), sizeof values[0], compare);
|
||||||
|
|
||||||
|
if (smap) {
|
||||||
char *offset;
|
char *offset;
|
||||||
guint64 *value;
|
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 = (void*) entry;
|
||||||
offset += values[i].offset;
|
offset += smap->offset;
|
||||||
value = (void*) 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;
|
return is_smap_value(line);
|
||||||
|
|
||||||
#undef SMAP_OFFSET
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -150,7 +179,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
|
|||||||
|
|
||||||
while(TRUE)
|
while(TRUE)
|
||||||
{
|
{
|
||||||
unsigned long perm = 0;
|
unsigned long perm;
|
||||||
guint len;
|
guint len;
|
||||||
int line_end;
|
int line_end;
|
||||||
|
|
||||||
@@ -164,6 +193,8 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
|
|||||||
if (getline(&line, &line_size, maps) == -1)
|
if (getline(&line, &line_size, maps) == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
new_entry_line:
|
||||||
|
|
||||||
if (sscanf(line, PROC_MAPS_FORMAT,
|
if (sscanf(line, PROC_MAPS_FORMAT,
|
||||||
&start, &end, flags, &offset,
|
&start, &end, flags, &offset,
|
||||||
&dev_major, &dev_minor, &inode, &line_end) != 7)
|
&dev_major, &dev_minor, &inode, &line_end) != 7)
|
||||||
@@ -173,6 +204,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
|
|||||||
g_strstrip(filename);
|
g_strstrip(filename);
|
||||||
|
|
||||||
/* Compute access permissions. */
|
/* Compute access permissions. */
|
||||||
|
perm = 0;
|
||||||
|
|
||||||
if (flags [0] == 'r')
|
if (flags [0] == 'r')
|
||||||
perm |= GLIBTOP_MAP_PERM_READ;
|
perm |= GLIBTOP_MAP_PERM_READ;
|
||||||
@@ -205,11 +237,22 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
|
|||||||
entry->inode = inode;
|
entry->inode = inode;
|
||||||
g_strlcpy(entry->filename, filename, sizeof entry->filename);
|
g_strlcpy(entry->filename, filename, sizeof entry->filename);
|
||||||
|
|
||||||
if (has_smaps)
|
if (has_smaps) {
|
||||||
add_smaps(server, maps, entry);
|
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);
|
free(line);
|
||||||
fclose (maps);
|
fclose (maps);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user