PS命令

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容