⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmap.c

📁 linux下获取一些环境信息的代码
💻 C
字号:
/* * Copyright 2002 by Albert Cahalan; all rights reserved. * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#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){  fprintf(stderr,    "Usage: pmap [-x | -d] [-q] pid...\n"    "-x  show details\n"    "-d  show offset and device number\n"    "-q  quiet; less header/footer info\n"    "-V  show the version number\n"  );  exit(1);}static int V_option;static int r_option;  // ignored -- for SunOS compatibilitystatic int x_option;static int d_option;static int q_option;static unsigned shm_minor = ~0u;static void discover_shm_minor(void){  void *addr;  int shmid;  char mapbuf[256];  if(!freopen("/proc/self/maps", "r", stdin)) return;  // 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 *mapping_name(proc_t *p, unsigned KLONG addr, unsigned KLONG len, const char *mapbuf, unsigned showpath, 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(showpath) return strchr(mapbuf,'/');    return cp[1] ? cp+1 : cp;  }  cp = strchr(mapbuf,'/');  if(cp){    if(showpath) return cp;    return strrchr(cp,'/') + 1;  // it WILL succeed  }  cp = "  [ anon ]";  if( (p->start_stack >= addr) && (p->start_stack <= addr+len) )  cp = "  [ stack ]";  return cp;}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;  // Overkill, but who knows what is proper? The "w" prog  // uses the tty width to determine this.  int maxcmd = 0xfffff;  sprintf(buf,"/proc/%u/maps",p->tgid);  if(!freopen(buf, "r", stdin)) return 1;  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, 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++;    }        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+    // an 'R' if swap not reserved (MAP_NORESERVE, SysV ISM shared mem, etc.)    flags[4] = '-';    flags[5] = '\0';    if(x_option){      const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);      printf(        (sizeof(KLONG)==8)          ? "%016"KLF"x %7lu       -       -       - %s  %s\n"          :      "%08lx %7lu       -       -       - %s  %s\n",        start,        (unsigned long)(diff>>10),        flags,        cp      );    }    if(d_option){      const char *cp = mapping_name(p, start, diff, mapbuf, 0, 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",        start,        (unsigned long)(diff>>10),        flags,        file_offset,        dev_major, dev_minor,        cp      );    }    if(!x_option && !d_option){      const char *cp = mapping_name(p, start, diff, mapbuf, 1, dev_major, dev_minor, inode);      printf(        (sizeof(KLONG)==8)          ? "%016"KLF"x %6luK %s  %s\n"          :      "%08lx %6luK %s  %s\n",        start,        (unsigned long)(diff>>10),        flags,        cp      );    }      }  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);    }  }  return 0;}int main(int argc, char *argv[]){  unsigned *pidlist;  unsigned count = 0;  PROCTAB* PT;  proc_t p;  int ret = 0;  if(argc<2) usage();  pidlist = malloc(sizeof(unsigned)*argc);  // a bit more than needed perhaps  while(*++argv){    if(!strcmp("--version",*argv)){      V_option++;      continue;    }    if(**argv=='-'){      char *walk = *argv;      if(!walk[1]) usage();      while(*++walk){        switch(*walk){        case 'V':          V_option++;          break;        case 'x':          x_option++;          break;        case 'r':          r_option++;          break;        case 'd':          d_option++;          break;        case 'q':          q_option++;          break;        default:          usage();        }      }    }else{      char *walk = *argv;      char *endp;      unsigned long pid;      if(!strncmp("/proc/",walk,6)){        walk += 6;        // user allowed to do: pmap /proc/*        if(*walk<'0' || *walk>'9') continue;      }      if(*walk<'0' || *walk>'9') usage();      pid = strtoul(walk, &endp, 0);      if(pid<1ul || pid>0x7ffffffful || *endp) usage();      pidlist[count++] = pid;    }  }  if( (x_option|V_option|r_option|d_option|q_option) >> 1 ) usage(); // dupes  if(V_option){    if(count|x_option|r_option|d_option|q_option) usage();    fprintf(stdout, "pmap (%s)\n", procps_version);    return 0;  }  if(count<1) usage();   // no processes  if(d_option && x_option) usage();  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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -