check_gcc for -m64, pmap shows shmid
This commit is contained in:
parent
74954d33e3
commit
f4367392c8
32
Makefile
32
Makefile
@ -61,12 +61,13 @@ MANFILES := $(man1)uptime.1 $(man1)tload.1 $(man1)free.1 $(man1)w.1 \
|
||||
|
||||
TARFILES := AUTHORS BUGS NEWS README TODO COPYING COPYING.LIB \
|
||||
Makefile procps.lsm procps.spec v t README.top \
|
||||
minimal.c $(notdir $(MANFILES)) \
|
||||
minimal.c $(notdir $(MANFILES)) dummy.c \
|
||||
uptime.c tload.c free.c w.c top.c vmstat.c watch.c skill.c \
|
||||
sysctl.c pgrep.c top.h pmap.c slabtop.c
|
||||
|
||||
# Stuff (tests, temporary hacks, etc.) left out of the standard tarball
|
||||
_TARFILES :=
|
||||
# plus the top-level Makefile to make it work stand-alone.
|
||||
_TARFILES := Makefile
|
||||
|
||||
CURSES := -I/usr/include/ncurses -lncurses
|
||||
|
||||
@ -94,6 +95,27 @@ PKG_LDFLAGS := -Wl,-warn-common
|
||||
LDFLAGS :=
|
||||
ALL_LDFLAGS := $(PKG_LDFLAGS) $(LDFLAGS)
|
||||
|
||||
############ Add some extra flags if gcc allows
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),tar)
|
||||
ifneq ($(MAKECMDGOALS),extratar)
|
||||
|
||||
# Unlike the kernel one, this check_gcc goes all the way to
|
||||
# producing an executable. There might be a -m64 that works
|
||||
# until you go looking for a 64-bit curses library.
|
||||
check_gcc = $(shell if $(CC) $(ALL_CFLAGS) dummy.c $(ALL_LDFLAGS) $(1) -o /dev/null $(CURSES) > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
|
||||
|
||||
ALL_CFLAGS += $(call check_gcc,-Wdeclaration-after-statement,)
|
||||
ALL_CFLAGS += $(call check_gcc,-Wpadded,)
|
||||
|
||||
# Be 64-bit if at all possible.
|
||||
ALL_CFLAGS += $(call check_gcc,-m64,)
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
############ misc.
|
||||
|
||||
# free.c pmap.c sysctl.c uptime.c vmstat.c watch.c pgrep.c skill.c tload.c top.c w.c
|
||||
@ -179,13 +201,13 @@ w.o: w.c
|
||||
############ prog.o --> prog
|
||||
|
||||
pmap w uptime tload free sysctl vmstat utmp pgrep skill: % : %.o $(LIBPROC)
|
||||
$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^
|
||||
$(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@
|
||||
|
||||
slabtop top: % : %.o $(LIBPROC)
|
||||
$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^ $(CURSES)
|
||||
$(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@ $(CURSES)
|
||||
|
||||
watch: % : %.o
|
||||
$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $^ $(CURSES)
|
||||
$(CC) $(ALL_CFLAGS) $^ $(ALL_LDFLAGS) -o $@ $(CURSES)
|
||||
|
||||
############ progX --> progY
|
||||
|
||||
|
31
dummy.c
Normal file
31
dummy.c
Normal file
@ -0,0 +1,31 @@
|
||||
// This is to test the compiler.
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Foul POS defines all sorts of stuff...
|
||||
#include <term.h>
|
||||
#undef tab
|
||||
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <values.h>
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
227
pmap.c
227
pmap.c
@ -17,8 +17,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include "proc/readproc.h"
|
||||
#include "proc/version.h"
|
||||
#include "proc/escape.h"
|
||||
|
||||
static void usage(void) NORETURN;
|
||||
static void usage(void){
|
||||
@ -40,81 +45,111 @@ static int d_option;
|
||||
static int q_option;
|
||||
|
||||
|
||||
static const char *get_args(unsigned pid){
|
||||
static char cmdbuf[64];
|
||||
char buf[32];
|
||||
int fd;
|
||||
ssize_t count;
|
||||
static unsigned shm_minor = ~0u;
|
||||
|
||||
do{
|
||||
sprintf(buf,"/proc/%u/cmdline",pid);
|
||||
if( (( fd=open(buf,O_RDONLY) )) == -1) break;
|
||||
count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
|
||||
close(fd);
|
||||
if(count<1) break;
|
||||
cmdbuf[count] = '\0';
|
||||
if(!isprint(cmdbuf[0])) break;
|
||||
while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
|
||||
return cmdbuf;
|
||||
}while(0);
|
||||
static void discover_shm_minor(void){
|
||||
void *addr;
|
||||
int shmid;
|
||||
char mapbuf[256];
|
||||
|
||||
do{
|
||||
char *cp;
|
||||
sprintf(buf,"/proc/%u/stat",pid);
|
||||
if( (( fd=open(buf,O_RDONLY) )) == -1) break;
|
||||
count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
|
||||
close(fd);
|
||||
if(count<1) break;
|
||||
cmdbuf[count] = '\0';
|
||||
while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
|
||||
cp = strrchr(cmdbuf,')');
|
||||
if(!cp) break;
|
||||
cp[0] = ']';
|
||||
cp[1] = '\0';
|
||||
cp = strchr(cmdbuf,'(');
|
||||
if(!cp) break;
|
||||
if(!isprint(cp[1])) break;
|
||||
cp[0] = '[';
|
||||
return cp;
|
||||
}while(0);
|
||||
if(!freopen("/proc/self/maps", "r", stdin)) return;
|
||||
|
||||
return "[]"; // as good as anything
|
||||
// create
|
||||
shmid = shmget(IPC_PRIVATE, 42, IPC_CREAT | 0666);
|
||||
if(shmid==-1) return; // failed; oh well
|
||||
// attach
|
||||
addr = shmat(shmid, NULL, SHM_RDONLY);
|
||||
if(addr==(void*)-1) goto out_destroy;
|
||||
|
||||
while(fgets(mapbuf, sizeof mapbuf, stdin)){
|
||||
char flags[32];
|
||||
char *tmp; // to clean up unprintables
|
||||
unsigned KLONG start, end;
|
||||
unsigned long long file_offset, inode;
|
||||
unsigned dev_major, dev_minor;
|
||||
sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
|
||||
tmp = strchr(mapbuf,'\n');
|
||||
if(tmp) *tmp='\0';
|
||||
tmp = mapbuf;
|
||||
while(*tmp){
|
||||
if(!isprint(*tmp)) *tmp='?';
|
||||
tmp++;
|
||||
}
|
||||
if(start > (unsigned long)addr) continue;
|
||||
if(dev_major) continue;
|
||||
if(flags[3] != 's') continue;
|
||||
if(strstr(mapbuf,"/SYSV")){
|
||||
shm_minor = dev_minor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(shmdt(addr)) perror("shmdt");
|
||||
|
||||
out_destroy:
|
||||
if(shmctl(shmid, IPC_RMID, NULL)) perror("IPC_RMID");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static const char *anon_name(int pid, unsigned KLONG addr, unsigned KLONG len){
|
||||
const char *cp = " [ anon ]";
|
||||
proc_t proc;
|
||||
static int oldpid = -1;
|
||||
if (pid==oldpid || get_proc_stats(pid, &proc)){
|
||||
oldpid = pid;
|
||||
if( (proc.start_stack >= addr) && (proc.start_stack <= addr+len) ) cp = " [ stack ]";
|
||||
|
||||
static const char *mapping_name(proc_t *p, unsigned KLONG addr, unsigned KLONG len, const char *mapbuf, unsigned advance, unsigned dev_major, unsigned dev_minor, unsigned long long inode){
|
||||
const char *cp;
|
||||
|
||||
if(!dev_major && dev_minor==shm_minor && strstr(mapbuf,"/SYSV")){
|
||||
static char shmbuf[64];
|
||||
snprintf(shmbuf, sizeof shmbuf, " [ shmid=0x%Lx ]", inode);
|
||||
return shmbuf;
|
||||
}
|
||||
|
||||
cp = strrchr(mapbuf,'/');
|
||||
if(cp){
|
||||
if(cp[1]) cp += advance;
|
||||
return cp;
|
||||
}
|
||||
|
||||
cp = " [ anon ]";
|
||||
if( (p->start_stack >= addr) && (p->start_stack <= addr+len) ) cp = " [ stack ]";
|
||||
return cp;
|
||||
}
|
||||
|
||||
static int one_proc(unsigned pid){
|
||||
|
||||
// Overkill, but who knows what is proper? The "w" prog
|
||||
// uses the tty width to determine this.
|
||||
#define maxcmd 0xfffff
|
||||
|
||||
static int one_proc(proc_t *p){
|
||||
char buf[32];
|
||||
char mapbuf[9600];
|
||||
char cmdbuf[512];
|
||||
unsigned long total_shared = 0ul;
|
||||
unsigned long total_private_readonly = 0ul;
|
||||
unsigned long total_private_writeable = 0ul;
|
||||
|
||||
sprintf(buf,"/proc/%u/maps",pid);
|
||||
sprintf(buf,"/proc/%u/maps",p->tgid);
|
||||
if(!freopen(buf, "r", stdin)) return 1;
|
||||
printf("%u: %s\n", pid, get_args(pid));
|
||||
|
||||
if(x_option && !q_option)
|
||||
printf("Address Kbytes RSS Anon Locked Mode Mapping\n");
|
||||
if(d_option && !q_option)
|
||||
printf("Address Kbytes Mode Offset Device Mapping\n");
|
||||
escape_command(cmdbuf, p, sizeof cmdbuf, maxcmd, ESC_ARGS|ESC_BRACKETS);
|
||||
printf("%u: %s\n", p->tgid, cmdbuf);
|
||||
|
||||
if(!q_option && (x_option|d_option)){
|
||||
if(x_option){
|
||||
if(sizeof(KLONG)==4) printf("Address Kbytes RSS Anon Locked Mode Mapping\n");
|
||||
else printf("Address Kbytes RSS Anon Locked Mode Mapping\n");
|
||||
}
|
||||
if(d_option){
|
||||
if(sizeof(KLONG)==4) printf("Address Kbytes Mode Offset Device Mapping\n");
|
||||
else printf("Address Kbytes Mode Offset Device Mapping\n");
|
||||
}
|
||||
}
|
||||
|
||||
while(fgets(mapbuf,sizeof mapbuf,stdin)){
|
||||
char flags[32];
|
||||
char *tmp; // to clean up unprintables
|
||||
unsigned KLONG start, end, diff;
|
||||
unsigned long long file_offset;
|
||||
unsigned long long file_offset, inode;
|
||||
unsigned dev_major, dev_minor;
|
||||
sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x", &start, &end, flags, &file_offset, &dev_major, &dev_minor);
|
||||
sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
|
||||
tmp = strchr(mapbuf,'\n');
|
||||
if(tmp) *tmp='\0';
|
||||
tmp = mapbuf;
|
||||
@ -126,19 +161,18 @@ static int one_proc(unsigned pid){
|
||||
diff = end-start;
|
||||
if(flags[3]=='s') total_shared += diff;
|
||||
if(flags[3]=='p'){
|
||||
flags[3] = '-';
|
||||
if(flags[1]=='w') total_private_writeable += diff;
|
||||
else total_private_readonly += diff;
|
||||
}
|
||||
|
||||
// format used by Solaris 9 and procps-3.2.0+
|
||||
if(flags[3] == 'p') flags[3] = '-';
|
||||
flags[4] = '-'; // an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)
|
||||
// an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)
|
||||
flags[4] = '-';
|
||||
flags[5] = '\0';
|
||||
|
||||
if(x_option){
|
||||
const char *cp = strrchr(mapbuf,'/');
|
||||
if(cp && cp[1]) cp++;
|
||||
if(!cp) cp = anon_name(pid, start, diff);
|
||||
const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);
|
||||
printf(
|
||||
(sizeof(KLONG)==8)
|
||||
? "%016"KLF"x %7lu - - - %s %s\n"
|
||||
@ -150,13 +184,11 @@ static int one_proc(unsigned pid){
|
||||
);
|
||||
}
|
||||
if(d_option){
|
||||
const char *cp = strrchr(mapbuf,'/');
|
||||
if(cp && cp[1]) cp++;
|
||||
if(!cp) cp = anon_name(pid, start, diff);
|
||||
const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);
|
||||
printf(
|
||||
(sizeof(KLONG)==8)
|
||||
? "%016"KLF"x %7lu %s %016Lx %03x:%05x %s\n"
|
||||
: "%08lx %7lu %s %016Lx %03x:%05x %s\n",
|
||||
? "%016"KLF"x %7lu %s %016Lx %03x:%05x %s\n"
|
||||
: "%08lx %7lu %s %016Lx %03x:%05x %s\n",
|
||||
start,
|
||||
(unsigned long)(diff>>10),
|
||||
flags,
|
||||
@ -166,8 +198,7 @@ static int one_proc(unsigned pid){
|
||||
);
|
||||
}
|
||||
if(!x_option && !d_option){
|
||||
const char *cp = strchr(mapbuf,'/');
|
||||
if(!cp) cp = anon_name(pid, start, diff);
|
||||
const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
|
||||
printf(
|
||||
(sizeof(KLONG)==8)
|
||||
? "%016"KLF"x %6luK %s %s\n"
|
||||
@ -181,32 +212,34 @@ static int one_proc(unsigned pid){
|
||||
|
||||
}
|
||||
|
||||
if(x_option && !q_option){
|
||||
if(sizeof(KLONG)==8){
|
||||
printf("---------------- ------ ------ ------ ------\n");
|
||||
printf(
|
||||
"total kB %15ld - - -\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10
|
||||
);
|
||||
}else{
|
||||
printf("-------- ------- ------- ------- -------\n");
|
||||
printf(
|
||||
"total kB %7ld - - -\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10
|
||||
);
|
||||
if(!q_option){
|
||||
if(x_option){
|
||||
if(sizeof(KLONG)==8){
|
||||
printf("---------------- ------ ------ ------ ------\n");
|
||||
printf(
|
||||
"total kB %15ld - - -\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10
|
||||
);
|
||||
}else{
|
||||
printf("-------- ------- ------- ------- -------\n");
|
||||
printf(
|
||||
"total kB %7ld - - -\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10
|
||||
);
|
||||
}
|
||||
}
|
||||
if(d_option){
|
||||
printf(
|
||||
"mapped %ldK writeable/private: %ldK shared: %ldK\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10,
|
||||
total_private_writeable >> 10,
|
||||
total_shared >> 10
|
||||
);
|
||||
}
|
||||
if(!x_option && !d_option){
|
||||
if(sizeof(KLONG)==8) printf(" total %16ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
|
||||
else printf(" total %8ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
|
||||
}
|
||||
}
|
||||
if(d_option && !q_option){
|
||||
printf(
|
||||
"mapped %ldK writeable/private: %ldK shared: %ldK\n",
|
||||
(total_shared + total_private_writeable + total_private_readonly) >> 10,
|
||||
total_private_writeable >> 10,
|
||||
total_shared >> 10
|
||||
);
|
||||
}
|
||||
if(!x_option && !d_option && !q_option){
|
||||
if(sizeof(KLONG)==8) printf(" total %16ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
|
||||
else printf(" total %8ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -216,7 +249,8 @@ static int one_proc(unsigned pid){
|
||||
int main(int argc, char *argv[]){
|
||||
unsigned *pidlist;
|
||||
unsigned count = 0;
|
||||
unsigned u;
|
||||
PROCTAB* PT;
|
||||
proc_t p;
|
||||
int ret = 0;
|
||||
|
||||
if(argc<2) usage();
|
||||
@ -276,8 +310,17 @@ int main(int argc, char *argv[]){
|
||||
if(count<1) usage(); // no processes
|
||||
if(d_option && x_option) usage();
|
||||
|
||||
u=0;
|
||||
while(u<count) ret |= one_proc(pidlist[u++]);
|
||||
discover_shm_minor();
|
||||
|
||||
pidlist[count] = 0; // old libproc interface is zero-terminated
|
||||
PT = openproc(PROC_FILLSTAT|PROC_FILLARG|PROC_PID, pidlist);
|
||||
while(readproc(PT, &p)){
|
||||
ret |= one_proc(&p);
|
||||
if(p.cmdline) free((void*)*p.cmdline);
|
||||
count--;
|
||||
}
|
||||
closeproc(PT);
|
||||
|
||||
if(count) ret |= 42; // didn't find all processes asked for
|
||||
return ret;
|
||||
}
|
||||
|
@ -55,9 +55,11 @@ proc/.depend: $(LIBSRC) $(LIBHDR)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),tar)
|
||||
ifneq ($(MAKECMDGOALS),extratar)
|
||||
-include proc/.depend
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
$(lib)/$(SONAME) : proc/$(SONAME)
|
||||
|
Loading…
Reference in New Issue
Block a user