pmap: Fix detail parsing on long mapping lines

If the mapping descriptor is longer than 128 chars, the last parsed
character won't be a newline even if the current buffer contains it a
bit further than that. The current code always interprets it as a short
fgets() read instead, and thus keeps calling fgets() until it gets a
newline, dropping valid lines and failing with the following error:

pmap: ERROR: inconsistent detail field in smaps file, line:
 Rss:                 212 kB
This commit is contained in:
Emanuele Aina 2016-02-09 23:02:31 +01:00 committed by Craig Small
parent 6eb4726e6f
commit b921e2e765

6
pmap.c
View File

@ -318,17 +318,17 @@ static void print_extended_maps (FILE *f)
while (ret != NULL) { while (ret != NULL) {
/* === READ MAPPING === */ /* === READ MAPPING === */
map_desc[0] = '\0'; map_desc[0] = '\0';
c = '\n';
nfields = sscanf(mapbuf, nfields = sscanf(mapbuf,
"%"NUML"[0-9a-f]-%"NUML"[0-9a-f] " "%"NUML"[0-9a-f]-%"NUML"[0-9a-f] "
"%"DETL"s %"NUML"[0-9a-f] " "%"DETL"s %"NUML"[0-9a-f] "
"%63[0-9a-f:] %"NUML"s %127[^\n]%c", "%63[0-9a-f:] %"NUML"s %127[^\n]",
start, end, perms, offset, start, end, perms, offset,
dev, inode, map_desc, &c); dev, inode, map_desc);
/* Must read at least up to inode, else something has changed! */ /* Must read at least up to inode, else something has changed! */
if (nfields < 6) if (nfields < 6)
xerrx(EXIT_FAILURE, _("Unknown format in smaps file!")); xerrx(EXIT_FAILURE, _("Unknown format in smaps file!"));
/* If line too long we dump everything else. */ /* If line too long we dump everything else. */
c = mapbuf[strlen(mapbuf) - 1];
while (c != '\n') { while (c != '\n') {
ret = fgets(mapbuf, sizeof mapbuf, f); ret = fgets(mapbuf, sizeof mapbuf, f);
c = mapbuf[strlen(mapbuf) - 1]; c = mapbuf[strlen(mapbuf) - 1];