busybox/procps/pmap.c
<<
>>
Prefs
   1/*
   2 * pmap implementation for busybox
   3 *
   4 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
   5 * Written by Alexander Shishkin <virtuoso@slind.org>
   6 *
   7 * Licensed under GPLv2 or later, see the LICENSE file in this source tree
   8 * for details.
   9 */
  10//config:config PMAP
  11//config:       bool "pmap (6 kb)"
  12//config:       default y
  13//config:       help
  14//config:       Display processes' memory mappings.
  15
  16//applet:IF_PMAP(APPLET(pmap, BB_DIR_USR_BIN, BB_SUID_DROP))
  17
  18//kbuild:lib-$(CONFIG_PMAP) += pmap.o
  19
  20//usage:#define pmap_trivial_usage
  21//usage:       "[-xq] PID..."
  22//usage:#define pmap_full_usage "\n\n"
  23//usage:       "Display process memory usage"
  24//usage:     "\n"
  25//usage:     "\n        -x      Show details"
  26//usage:     "\n        -q      Quiet"
  27
  28#include "libbb.h"
  29
  30#if ULONG_MAX == 0xffffffff
  31# define TABS "\t"
  32# define AFMT "8"
  33# define DASHES ""
  34#else
  35# define TABS "\t\t"
  36# define AFMT "16"
  37# define DASHES "--------"
  38#endif
  39
  40#if ULLONG_MAX == 0xffffffff
  41# define AFMTLL "8"
  42#else
  43# define AFMTLL "16"
  44#endif
  45
  46enum {
  47        OPT_x = 1 << 0,
  48        OPT_q = 1 << 1,
  49};
  50
  51static void print_smaprec(struct smaprec *currec, void *data)
  52{
  53        unsigned opt = (uintptr_t)data;
  54
  55        printf("%0" AFMTLL "llx ", currec->smap_start);
  56
  57        if (opt & OPT_x)
  58                printf("%7lu %7lu %7lu %7lu ",
  59                        currec->smap_size,
  60                        currec->smap_pss,
  61                        currec->private_dirty,
  62                        currec->smap_swap);
  63        else
  64                printf("%7luK", currec->smap_size);
  65
  66        printf(" %.4s  %s\n", currec->smap_mode, currec->smap_name);
  67}
  68
  69static int procps_get_maps(pid_t pid, unsigned opt)
  70{
  71        struct smaprec total;
  72        int ret;
  73        char buf[256];
  74
  75        read_cmdline(buf, sizeof(buf), pid, NULL);
  76        printf("%u: %s\n", (int)pid, buf);
  77
  78        if (!(opt & OPT_q) && (opt & OPT_x))
  79                puts("Address" TABS "  Kbytes     PSS   Dirty    Swap  Mode  Mapping");
  80
  81        memset(&total, 0, sizeof(total));
  82
  83        ret = procps_read_smaps(pid, &total, print_smaprec, (void*)(uintptr_t)opt);
  84        if (ret)
  85                return ret;
  86
  87        if (!(opt & OPT_q)) {
  88                if (opt & OPT_x)
  89                        printf("--------" DASHES "  ------  ------  ------  ------\n"
  90                                "total" TABS " %7lu %7lu %7lu %7lu\n",
  91                                total.smap_size, total.smap_pss, total.private_dirty, total.smap_swap);
  92                else
  93                        printf("mapped: %luK\n", total.smap_size);
  94        }
  95
  96        return 0;
  97}
  98
  99int pmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 100int pmap_main(int argc UNUSED_PARAM, char **argv)
 101{
 102        unsigned opts;
 103        int ret;
 104
 105        opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */
 106        argv += optind;
 107
 108        ret = 0;
 109        while (*argv) {
 110                pid_t pid = xatoi_positive(*argv++);
 111                /* GNU pmap returns 42 if any of the pids failed */
 112                if (procps_get_maps(pid, opts) != 0)
 113                        ret = 42;
 114        }
 115
 116        return ret;
 117}
 118