blob: 9e541c707a1bfde1f6b988cf3d2a6b7acba70539 [file] [log] [blame]
Alexander Shishkin0834a6d2010-08-28 23:20:34 +02001/*
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 */
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020010//config:config PMAP
Denys Vlasenko72089cf2017-07-21 09:50:55 +020011//config: bool "pmap (6 kb)"
12//config: default y
13//config: help
14//config: Display processes' memory mappings.
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020015
Denys Vlasenko66426762011-06-05 03:58:28 +020016//applet:IF_PMAP(APPLET(pmap, BB_DIR_USR_BIN, BB_SUID_DROP))
Denys Vlasenko0c4dbd42017-09-18 16:28:43 +020017
Denys Vlasenko66426762011-06-05 03:58:28 +020018//kbuild:lib-$(CONFIG_PMAP) += pmap.o
19
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020020//usage:#define pmap_trivial_usage
Denys Vlasenko947b2392017-08-04 18:36:55 +020021//usage: "[-xq] PID..."
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020022//usage:#define pmap_full_usage "\n\n"
Denys Vlasenko049b0072015-10-24 03:45:57 +020023//usage: "Display process memory usage"
Denys Vlasenko66426762011-06-05 03:58:28 +020024//usage: "\n"
25//usage: "\n -x Show details"
26//usage: "\n -q Quiet"
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020027
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
Denys Vlasenkoaad76962018-12-30 20:24:59 +010040#if ULLONG_MAX == 0xffffffff
41# define AFMTLL "8"
42#else
43# define AFMTLL "16"
44#endif
45
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020046enum {
47 OPT_x = 1 << 0,
48 OPT_q = 1 << 1,
49};
50
51static void print_smaprec(struct smaprec *currec, void *data)
52{
Denys Vlasenkod3036ef2010-10-22 13:15:15 +020053 unsigned opt = (uintptr_t)data;
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020054
Denys Vlasenkoaad76962018-12-30 20:24:59 +010055 printf("%0" AFMTLL "llx ", currec->smap_start);
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020056
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
Denys Vlasenko049b0072015-10-24 03:45:57 +020075 read_cmdline(buf, sizeof(buf), pid, NULL);
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020076 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
Denys Vlasenkod3036ef2010-10-22 13:15:15 +020083 ret = procps_read_smaps(pid, &total, print_smaprec, (void*)(uintptr_t)opt);
Alexander Shishkin0834a6d2010-08-28 23:20:34 +020084 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
Denys Vlasenko22542ec2017-08-08 21:55:02 +0200105 opts = getopt32(argv, "^" "xq" "\0" "-1"); /* min one arg */
Alexander Shishkin0834a6d2010-08-28 23:20:34 +0200106 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}