PS命令

作者: zsg555666 | 来源:发表于2019-07-04 10:29 被阅读0次

    1、ps命令源码目录:system/core/toolbox/ps.c

    #include <ctype.h>
    #include <dirent.h>
    #include <fcntl.h>
    #include <inttypes.h>
    #include <pwd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #include <cutils/sched_policy.h>
    
    static char *nexttoksep(char **strp, char *sep)
    {
        char *p = strsep(strp,sep);
        return (p == 0) ? "" : p;
    }
    static char *nexttok(char **strp)
    {
        return nexttoksep(strp, " ");
    }
    
    #define SHOW_PRIO 1
    #define SHOW_TIME 2
    #define SHOW_POLICY 4
    #define SHOW_CPU  8
    #define SHOW_MACLABEL 16
    #define SHOW_NUMERIC_UID 32
    #define SHOW_ABI 64
    
    #if __LP64__
    #define PC_WIDTH 10 /* Realistically, the top bits will be 0, so don't waste space. */
    #else
    #define PC_WIDTH (2*sizeof(uintptr_t))
    #endif
    
    static int display_flags = 0;
    static int ppid_filter = 0;
    
    static void print_exe_abi(int pid);
    
    static int ps_line(int pid, int tid)
    {
        char statline[1024];
        char cmdline[1024];
        char macline[1024];
        char user[32];
        struct stat stats;
        int r;
        char *ptr, *name, *state;
        int ppid;
        unsigned rss, vss;
        uintptr_t eip;
        unsigned utime, stime;
        int prio, nice, rtprio, sched, psr;
        struct passwd *pw;
    
        sprintf(statline, "/proc/%d", tid ? tid : pid);
        stat(statline, &stats);
    
        if(tid) {
            sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
            cmdline[0] = 0;
            snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
        } else {
            sprintf(statline, "/proc/%d/stat", pid);
            sprintf(cmdline, "/proc/%d/cmdline", pid);
            snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
            int fd = open(cmdline, O_RDONLY);
            if(fd == 0) {
                r = 0;
            } else {
                r = read(fd, cmdline, 1023);
                close(fd);
                if(r < 0) r = 0;
            }
            cmdline[r] = 0;
        }
    
        int fd = open(statline, O_RDONLY);
        if(fd == 0) return -1;
        r = read(fd, statline, 1023);
        close(fd);
        if(r < 0) return -1;
        statline[r] = 0;
    
        ptr = statline;
        nexttok(&ptr); // skip pid
        ptr++;          // skip "("
    
        name = ptr;
        ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
        *ptr++ = '\0';           // and null-terminate name.
    
        ptr++;          // skip " "
        state = nexttok(&ptr);
        ppid = atoi(nexttok(&ptr));
        nexttok(&ptr); // pgrp
        nexttok(&ptr); // sid
        nexttok(&ptr); // tty
        nexttok(&ptr); // tpgid
        nexttok(&ptr); // flags
        nexttok(&ptr); // minflt
        nexttok(&ptr); // cminflt
        nexttok(&ptr); // majflt
        nexttok(&ptr); // cmajflt
    #if 1
        utime = atoi(nexttok(&ptr));
        stime = atoi(nexttok(&ptr));
    #else
        nexttok(&ptr); // utime
        nexttok(&ptr); // stime
    #endif
        nexttok(&ptr); // cutime
        nexttok(&ptr); // cstime
        prio = atoi(nexttok(&ptr));
        nice = atoi(nexttok(&ptr));
        nexttok(&ptr); // threads
        nexttok(&ptr); // itrealvalue
        nexttok(&ptr); // starttime
        vss = strtoul(nexttok(&ptr), 0, 10); // vsize
        rss = strtoul(nexttok(&ptr), 0, 10); // rss
        nexttok(&ptr); // rlim
        nexttok(&ptr); // startcode
        nexttok(&ptr); // endcode
        nexttok(&ptr); // startstack
        nexttok(&ptr); // kstkesp
        eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
        nexttok(&ptr); // signal
        nexttok(&ptr); // blocked
        nexttok(&ptr); // sigignore
        nexttok(&ptr); // sigcatch
        nexttok(&ptr); // wchan
        nexttok(&ptr); // nswap
        nexttok(&ptr); // cnswap
        nexttok(&ptr); // exit signal
        psr = atoi(nexttok(&ptr)); // processor
        rtprio = atoi(nexttok(&ptr)); // rt_priority
        sched = atoi(nexttok(&ptr)); // scheduling policy
    
        nexttok(&ptr); // tty
    
        if(tid != 0) {
            ppid = pid;
            pid = tid;
        }
    
        pw = getpwuid(stats.st_uid);
        if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
            sprintf(user,"%d",(int)stats.st_uid);
        } else {
            strcpy(user,pw->pw_name);
        }
    
        if(ppid_filter != 0 && ppid != ppid_filter) {
            return 0;
        }
    
        if (display_flags & SHOW_MACLABEL) {
            fd = open(macline, O_RDONLY);
            strcpy(macline, "-");
            if (fd >= 0) {
                r = read(fd, macline, sizeof(macline)-1);
                close(fd);
                if (r > 0)
                    macline[r] = 0;
            }
            printf("%-30s ", macline);
        }
    
        printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
        if (display_flags & SHOW_CPU)
            printf(" %-2d", psr);
        if (display_flags & SHOW_PRIO)
            printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
        if (display_flags & SHOW_POLICY) {
            SchedPolicy p;
            if (get_sched_policy(pid, &p) < 0)
                printf(" un ");
            else
                printf(" %.2s ", get_sched_policy_name(p));
        }
        char path[PATH_MAX];
        snprintf(path, sizeof(path), "/proc/%d/wchan", pid);
        char wchan[10];
        fd = open(path, O_RDONLY);
        ssize_t wchan_len = read(fd, wchan, sizeof(wchan));
        if (wchan_len == -1) {
            wchan[wchan_len = 0] = '\0';
        }
        close(fd);
        printf(" %10.*s %0*" PRIxPTR " %s ", (int) wchan_len, wchan, (int) PC_WIDTH, eip, state);
        if (display_flags & SHOW_ABI) {
            print_exe_abi(pid);
        }
        printf("%s", cmdline[0] ? cmdline : name);
        if(display_flags&SHOW_TIME)
            printf(" (u:%d, s:%d)", utime, stime);
    
        printf("\n");
        return 0;
    }
    
    static void print_exe_abi(int pid)
    {
        int fd, r;
        char exeline[1024];
    
        sprintf(exeline, "/proc/%d/exe", pid);
        fd = open(exeline, O_RDONLY);
        if(fd == 0) {
            printf("    ");
            return;
        }
        r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
        close(fd);
        if(r < 0) {
            printf("    ");
            return;
        }
        if (memcmp("\177ELF", exeline, 4) != 0) {
            printf("??  ");
            return;
        }
        switch (exeline[4]) {
            case 1:
                printf("32  ");
                return;
            case 2:
                printf("64  ");
                return;
            default:
                printf("??  ");
                return;
        }
    }
    
    void ps_threads(int pid)
    {
        char tmp[128];
        DIR *d;
        struct dirent *de;
    
        sprintf(tmp,"/proc/%d/task",pid);
        d = opendir(tmp);
        if(d == 0) return;
    
        while((de = readdir(d)) != 0){
            if(isdigit(de->d_name[0])){
                int tid = atoi(de->d_name);
                if(tid == pid) continue;
                ps_line(pid, tid);
            }
        }
        closedir(d);
    }
    
    int ps_main(int argc, char **argv)
    {
        DIR *d;
        struct dirent *de;
        int pidfilter = 0;
        int threads = 0;
    
        while(argc > 1){
            if(!strcmp(argv[1],"-t")) {
                threads = 1;
            } else if(!strcmp(argv[1],"-n")) {
                display_flags |= SHOW_NUMERIC_UID;
            } else if(!strcmp(argv[1],"-x")) {
                display_flags |= SHOW_TIME;
            } else if(!strcmp(argv[1], "-Z")) {
                display_flags |= SHOW_MACLABEL;
            } else if(!strcmp(argv[1],"-P")) {
                display_flags |= SHOW_POLICY;
            } else if(!strcmp(argv[1],"-p")) {
                display_flags |= SHOW_PRIO;
            } else if(!strcmp(argv[1],"-c")) {
                display_flags |= SHOW_CPU;
            } else if(!strcmp(argv[1],"--abi")) {
                display_flags |= SHOW_ABI;
            } else if(!strcmp(argv[1],"--ppid")) {
                ppid_filter = atoi(argv[2]);
                if (ppid_filter == 0) {
                    /* Bug 26554285: Use printf because some apps require at least
                     * one line of output to stdout even for errors.
                     */
                    printf("bad ppid '%s'\n", argv[2]);
                    return 1;
                }
                argc--;
                argv++;
            } else {
                pidfilter = atoi(argv[1]);
                if (pidfilter == 0) {
                    /* Bug 26554285: Use printf because some apps require at least
                     * one line of output to stdout even for errors.
                     */
                    printf("bad pid '%s'\n", argv[1]);
                    return 1;
                }
            }
            argc--;
            argv++;
        }
    
        if (display_flags & SHOW_MACLABEL) {
            printf("LABEL                          ");
        }
        printf("USER      PID   PPID  VSIZE  RSS  %s%s %sWCHAN      %*s  %sNAME\n",
               (display_flags&SHOW_CPU)?"CPU ":"",
               (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
               (display_flags&SHOW_POLICY)?"PCY " : "",
               (int) PC_WIDTH, "PC",
               (display_flags&SHOW_ABI)?"ABI " : "");
    
        d = opendir("/proc");
        if(d == 0) return -1;
    
        while((de = readdir(d)) != 0){
            if(isdigit(de->d_name[0])){
                int pid = atoi(de->d_name);
                if(!pidfilter || (pidfilter == pid)) {
                    ps_line(pid, 0);
                    if(threads) ps_threads(pid);
                }
            }
        }
        closedir(d);
        return 0;
    }
    
    USER      PID   PPID  VSIZE  RSS   WCHAN              PC  NAME
    root      1     0     24376  1960  SyS_epoll_ 0000000000 S /init
    root      2     0     0      0       kthreadd 0000000000 S kthreadd
    root      7     2     0      0     rcu_gp_kth 0000000000 S rcu_preempt
    root      8     2     0      0     rcu_gp_kth 0000000000 S rcu_sched
    
    USER:  进程的当前用户
    PID:   进程ID
    PPID:  父进程ID
    VSIZE:  进程虚拟地址空间大小,virtual size
    RSS:    进程正在使用的物理内存的大小
    WCHAN:  进程如果处于休眠状态的话,在内核中的地址
    PC:     program counter
    NAME:   进程名称
    
    
    PS命令参数说明:

    -t 显示所有线程的信息
    -n 显示数字UID
    -Z 显示mac label,此选择是和其他选项对立的
    -P 显示进程策略,存在三种策略fg、bg、空白
    -p 对应的是prio, nice, rtprio, sched四种信息
    -c 显示CPU占用率
    –abi 显示进程位宽
    数字 筛选指定数字pid
    字符 筛选指定字符pid

    相关文章

      网友评论

        本文标题:PS命令

        本文链接:https://www.haomeiwen.com/subject/azgkhctx.html