pmap: make 32-bit version work better on 64-bit kernels

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-12-30 20:24:59 +01:00
parent 8b710ef000
commit aad76968cd
3 changed files with 17 additions and 6 deletions

View File

@ -1828,7 +1828,12 @@ struct smaprec {
unsigned long stack; unsigned long stack;
unsigned long smap_pss, smap_swap; unsigned long smap_pss, smap_swap;
unsigned long smap_size; unsigned long smap_size;
unsigned long smap_start; // For mixed 32/64 userspace, 32-bit pmap still needs
// 64-bit field here to correctly show 64-bit processes:
unsigned long long smap_start;
// (strictly speaking, other fields need to be wider too,
// but they are in kbytes, not bytes, and they hold sizes,
// not start addresses, sizes tend to be less than 4 terabytes)
char smap_mode[5]; char smap_mode[5];
char *smap_name; char *smap_name;
}; };

View File

@ -120,11 +120,11 @@ void FAST_FUNC free_procps_scan(procps_status_t* sp)
} }
#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
static unsigned long fast_strtoul_16(char **endptr) static unsigned long long fast_strtoull_16(char **endptr)
{ {
unsigned char c; unsigned char c;
char *str = *endptr; char *str = *endptr;
unsigned long n = 0; unsigned long long n = 0;
/* Need to stop on both ' ' and '\n' */ /* Need to stop on both ' ' and '\n' */
while ((c = *str++) > ' ') { while ((c = *str++) > ' ') {
@ -238,8 +238,8 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
*tp = ' '; *tp = ' ';
tp = buf; tp = buf;
currec.smap_start = fast_strtoul_16(&tp); currec.smap_start = fast_strtoull_16(&tp);
currec.smap_size = (fast_strtoul_16(&tp) - currec.smap_start) >> 10; currec.smap_size = (fast_strtoull_16(&tp) - currec.smap_start) >> 10;
strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1); strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1);

View File

@ -37,6 +37,12 @@
# define DASHES "--------" # define DASHES "--------"
#endif #endif
#if ULLONG_MAX == 0xffffffff
# define AFMTLL "8"
#else
# define AFMTLL "16"
#endif
enum { enum {
OPT_x = 1 << 0, OPT_x = 1 << 0,
OPT_q = 1 << 1, OPT_q = 1 << 1,
@ -46,7 +52,7 @@ static void print_smaprec(struct smaprec *currec, void *data)
{ {
unsigned opt = (uintptr_t)data; unsigned opt = (uintptr_t)data;
printf("%0" AFMT "lx ", currec->smap_start); printf("%0" AFMTLL "llx ", currec->smap_start);
if (opt & OPT_x) if (opt & OPT_x)
printf("%7lu %7lu %7lu %7lu ", printf("%7lu %7lu %7lu %7lu ",