pmap: fixing broken indentation in the -X/-XX modes
This commit changes the processing principle of the -X/-XX modes from 1-pass to 2-pass. A separate width measurement stage has been added, so that the real maximum widths can be measured and used for correct indentation. The firstmapping variable now has a new value (2) used for the width measurement stage (1st pass). The printing is disabled in this stage. The file position is reset to the beginning of the file once the end of file is reached and the printing stage (2nd pass) begins. It's questionable if this approach is sensitive to Read-after-Write race conditions. Anyway, this feature is a good candidate for a complete redesign in the future. Additionally this commit introduces a final cleaning of the list used for the evaluation of totals in the -X/-XX modes.
This commit is contained in:
parent
ca76af22ca
commit
20ce346ebd
92
pmap.c
92
pmap.c
@ -184,7 +184,7 @@ struct listnode {
|
||||
struct listnode *next;
|
||||
};
|
||||
|
||||
static struct listnode *listhead=NULL, *listtail=NULL;
|
||||
static struct listnode *listhead=NULL, *listtail=NULL, *listnode;
|
||||
|
||||
|
||||
static int is_unimportant (char *s)
|
||||
@ -201,7 +201,6 @@ static int is_unimportant (char *s)
|
||||
|
||||
static void print_extended_maps (FILE *f)
|
||||
{
|
||||
struct listnode *listnode;
|
||||
char flags[DETAIL_LENGTH], map_desc[128],
|
||||
detail_desc[DETAIL_LENGTH], value_str[NUM_LENGTH],
|
||||
start[NUM_LENGTH], end[NUM_LENGTH],
|
||||
@ -216,7 +215,7 @@ static void print_extended_maps (FILE *f)
|
||||
char has_vmflags = 0;
|
||||
|
||||
ret = fgets(mapbuf, sizeof mapbuf, f);
|
||||
firstmapping = 1;
|
||||
firstmapping = 2;
|
||||
while (ret != NULL) {
|
||||
/* === READ MAPPING === */
|
||||
map_desc[0] = '\0';
|
||||
@ -254,7 +253,7 @@ static void print_extended_maps (FILE *f)
|
||||
goto loop_end;
|
||||
/* === CREATE LIST AND FILL description FIELD === */
|
||||
if (listnode == NULL) {
|
||||
assert(firstmapping == 1);
|
||||
assert(firstmapping == 2);
|
||||
listnode = calloc(1, sizeof *listnode);
|
||||
if (listhead == NULL) {
|
||||
assert(listtail == NULL);
|
||||
@ -271,15 +270,14 @@ static void print_extended_maps (FILE *f)
|
||||
listnode->max_width = 7;
|
||||
} else {
|
||||
/* === LIST EXISTS === */
|
||||
if ((listnode == NULL) ||
|
||||
(strcmp(listnode->description, detail_desc) != 0))
|
||||
if (strcmp(listnode->description, detail_desc) != 0)
|
||||
xerrx(EXIT_FAILURE, "ERROR: %s %s",
|
||||
_("inconsistent detail field in smaps file, line:\n"),
|
||||
mapbuf);
|
||||
}
|
||||
strcpy(listnode->value_str, value_str);
|
||||
sscanf(value_str, "%"KLF"u", &listnode->value);
|
||||
listnode->total += listnode->value;
|
||||
if (firstmapping == 2) listnode->total += listnode->value;
|
||||
if (strlen(value_str) > listnode->max_width)
|
||||
listnode->max_width = strlen(value_str);
|
||||
listnode = listnode->next;
|
||||
@ -297,51 +295,60 @@ loop_end:
|
||||
if (strlen(vmflags) > maxwv) maxwv = strlen(vmflags);
|
||||
}
|
||||
|
||||
/* === PRINT THIS MAPPING === */
|
||||
/* Print header */
|
||||
if (firstmapping && !q_option) {
|
||||
if (strlen("Address") > maxw1) maxw1 = strlen("Address");
|
||||
if (strlen("Flags") > maxw2) maxw2 = strlen("Flags");
|
||||
if (strlen("Offset") > maxw3) maxw3 = strlen("Offset");
|
||||
if (strlen("Device") > maxw4) maxw4 = strlen("Device");
|
||||
if (strlen("Inode") > maxw5) maxw5 = strlen("Inode");
|
||||
if (has_vmflags && strlen("VmFlags") > maxwv) maxwv = strlen("VmFlags");
|
||||
if (firstmapping == 2) { /* width measurement stage, do not print anything yet */
|
||||
if (ret == NULL) { /* once the end of file is reached ...*/
|
||||
firstmapping = 1; /* ... we reset the file position to the beginning of the file */
|
||||
fseek(f, 0, SEEK_SET); /* ... and repeat the process with printing enabled */
|
||||
ret = fgets(mapbuf, sizeof mapbuf, f); /* this is not ideal and needs to be redesigned one day */
|
||||
}
|
||||
} else { /* the maximum widths have been measured, we've already reached the printing stage */
|
||||
/* === PRINT THIS MAPPING === */
|
||||
/* Print header */
|
||||
if (firstmapping && !q_option) {
|
||||
if (strlen("Address") > maxw1) maxw1 = strlen("Address");
|
||||
if (strlen("Flags") > maxw2) maxw2 = strlen("Flags");
|
||||
if (strlen("Offset") > maxw3) maxw3 = strlen("Offset");
|
||||
if (strlen("Device") > maxw4) maxw4 = strlen("Device");
|
||||
if (strlen("Inode") > maxw5) maxw5 = strlen("Inode");
|
||||
if (has_vmflags && strlen("VmFlags") > maxwv) maxwv = strlen("VmFlags");
|
||||
sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
|
||||
maxw1, maxw2, maxw3, maxw4, maxw5);
|
||||
printf(fmt_str, "Address", "Flags", "Offset", "Device", "Inode");
|
||||
|
||||
for (listnode=listhead; listnode=listnode->next;
|
||||
listnode!=NULL) {
|
||||
sprintf(fmt_str, " %%%ds", listnode->max_width);
|
||||
printf(fmt_str, listnode->description);
|
||||
}
|
||||
|
||||
if (has_vmflags) {
|
||||
sprintf(fmt_str, " %%%ds", maxwv);
|
||||
printf(fmt_str, "VmFlags");
|
||||
}
|
||||
|
||||
printf(" %s\n", "Description");
|
||||
}
|
||||
/* Print data */
|
||||
sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
|
||||
maxw1, maxw2, maxw3, maxw4, maxw5);
|
||||
printf(fmt_str, "Address", "Flags", "Offset", "Device", "Inode");
|
||||
printf(fmt_str, start, flags, offset, dev, inode);
|
||||
|
||||
for (listnode=listhead; listnode=listnode->next;
|
||||
listnode!=NULL) {
|
||||
sprintf(fmt_str, " %%%ds", listnode->max_width);
|
||||
printf(fmt_str, listnode->description);
|
||||
printf(fmt_str, listnode->value_str);
|
||||
}
|
||||
|
||||
if (has_vmflags) {
|
||||
sprintf(fmt_str, " %%%ds", maxwv);
|
||||
printf(fmt_str, "VmFlags");
|
||||
printf(fmt_str, vmflags);
|
||||
}
|
||||
|
||||
printf(" %s\n", "Description");
|
||||
printf(" %s\n", map_desc);
|
||||
|
||||
firstmapping = 0;
|
||||
|
||||
}
|
||||
/* Print data */
|
||||
sprintf(fmt_str, "%%%ds %%%ds %%%ds %%%ds %%%ds",
|
||||
maxw1, maxw2, maxw3, maxw4, maxw5);
|
||||
printf(fmt_str, start, flags, offset, dev, inode);
|
||||
|
||||
for (listnode=listhead; listnode=listnode->next;
|
||||
listnode!=NULL) {
|
||||
sprintf(fmt_str, " %%%ds", listnode->max_width);
|
||||
printf(fmt_str, listnode->value_str);
|
||||
}
|
||||
|
||||
if (has_vmflags) {
|
||||
sprintf(fmt_str, " %%%ds", maxwv);
|
||||
printf(fmt_str, vmflags);
|
||||
}
|
||||
|
||||
printf(" %s\n", map_desc);
|
||||
|
||||
firstmapping = 0;
|
||||
}
|
||||
/* === PRINT TOTALS === */
|
||||
if (!q_option && listhead!=NULL) {
|
||||
@ -722,6 +729,13 @@ int main(int argc, char **argv)
|
||||
closeproc(PT);
|
||||
free(pidlist);
|
||||
|
||||
/* cleaning the list used for the -X/-XX modes */
|
||||
for (listnode = listhead; listnode != NULL ; ) {
|
||||
listnode = listnode -> next;
|
||||
free(listhead);
|
||||
listhead = listnode;
|
||||
}
|
||||
|
||||
if (count)
|
||||
/* didn't find all processes asked for */
|
||||
ret |= 42;
|
||||
|
Loading…
Reference in New Issue
Block a user