From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by sourceware.org (Postfix) with ESMTPS id 88E0A3887004 for ; Mon, 13 Apr 2020 18:20:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 88E0A3887004 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gmx.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=n54@gmx.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1586802041; bh=F7V8Sj1jCqhUqEJDPODF4CBMkEV6dZDXxRv5VY4qgIY=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date; b=DvHZoXpi3hRN6tqg4w5VqOg1JIWSV1SbNsNitdqqIUAM9eHGpGV1m05H8cMO0PVhM 5BcoiORiIosi9kp5PwV11Mr78AEduoQZDk2PbTbIPPzEdrlM3CQUc+XroXsym1J0W4 HtkJRrCI6Uo4qFtuRS9n7zDctppmfkJih0Fz4Ldg= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([89.79.191.25]) by mail.gmx.com (mrgmx004 [212.227.17.184]) with ESMTPSA (Nemesis) id 1M4axg-1jNVT52i9u-001lN4; Mon, 13 Apr 2020 20:20:41 +0200 From: Kamil Rytarowski To: gdb-patches@sourceware.org Subject: [PATCH] Implement IP_STAT on NetBSD Date: Mon, 13 Apr 2020 20:19:11 +0200 Message-Id: <20200413181911.17133-1-n54@gmx.com> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:+r1SBy86UrUIPLrV4Gp1HA4gBk3i8TTvpFWTAwWAIUM/fiyjtnM Wx2UUt3+jg7bNKRup5mjfH4Zw0NPxcjPZNr2rq79q6Yft0XntFH1JO7Oi5XwjqndjAhkY7g oeuC/YTiDE26L7ZErGmYTHqD+n95eOj79eBQMJWJq6sO+XRLZjIHf4HBNfqcVsxT8YSkjtX eOPByl9149NgJ7PrDutWw== X-UI-Out-Filterresults: notjunk:1;V03:K0:fiD6qVJMMog=:fjUWcp97pHfavL/KoNZ+Cb lF4NjquQHeTsUI0UjMxoL6shzM6l9rfYi8JGRr75dDi9x8VpngMMLv6CFxb+YQSlFQL+9hhqi LBQ6q8RQr3wwkOwePGOtFtP0BrXzcsOuTydWo7GAjVafGYvaQC6TuhsbMVEis7B6WQVspBlLX Gmp5e6faAiW1ITfaQNTNYc88NHb3ZY0J+j0mY+oOedLAass0CLM7LhjF/bo8xYX3umTqsenU9 GDnz8WaDKfHXZfDidYo6TU+NwzifX1zPX9jLtFTA1kbH7UVS61ZcM4iANE7Wg38T5ZPL//WX0 o8eQ84wMJc6MTMFmYRrOMgzMoiiIf+/53hkMVF4r0irBMSJ+xToV4hJ+3p5BdPOH4DTxSP4YW pobjetuHMWmLcwUPyVa+ddGPuWBQ2X546pEiYPG4aOTbg0lDBJIIoSs3rhRr2x/ixZTxOYctz Pz9KMP3WpWdfsELVC73HZ4uRQh94wSQ64Xac18ndUmrYyc/ct4z3yWcYTOhArHuNAduzPcijg PyAh6m3jTnJ3VpPsNAblJBSPfT6cMQQMrQjNGsAgWaJ7069vUfKD1ajajm6J3j6MKWnsSXQTF I28nEkKi3/TmyUnez6q6J2C3VBWGS1yim9uvq189npBk9JCb+rvhcpzgxiDfg/TKDiVPDHbS5 Q5pU1h9c+Ou5FZJDUQCw0wrmgs2S5tUrDkGtxQh7tWOh7jijwhQ5WK7Vy0zPtrYDxULThAiwp VE3YAvndXtEX//8c/zcjuGCUe3k0jIULTMA3d9sBzq+SIilO5B/0qUZzuzSh51oH9M8jrCJRl bH8DLSmubUDrB5W9CUZg0XLBI9rHWaQTTSkYGLHvWd2DYV/tsytLiFe0AMxW2XGqK7//EQ/br v/S1oAnPDUvjGiCseUdCKwXOVhJPonBHP6t2CveUZOy10/vFdc4aOvud+gJldphifNkytqJXL lvYW+XqH8Auvn6CxZHol0S7e4baoMMwcXVU5SDI6qqJQneNfL9lCcbeA53EEtHKzXn7Gafcce Ejnf8fLSsqcl1UyBqLW3WYAvpsdSgcBVtFh/oVde+Oif4/EvMdD4SA0n3GJsXMZR4HHdKOhUi LeBOmq3k64wb71e62gVYoSapMEv1B+C5LW9i5Lg3WnYFykIDWwgEUQ+SSp6fve+ZkC+RwJRVL hJkQzZMWuqQugwLGzqAZs4xIZCDWxBQrhdi7hEOmCAiU9ZVx6y3QnEjj7zPeoS7RYjScA= X-Spam-Status: No, score=-27.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 18:20:45 -0000 NetBSD ships with a compatibility layer in a /proc virtual file system and delivers optionally /proc//stat. In case of missing /proc//stat fallback to emulating it with sysctl(3) APIs. gdb/ChangeLog: * nbsd-nat.c: Include "sys/resource.h" and "machine/vmparam.h". (nbsd_pid_to_kinfo_proc2, nbsd_pid_to_rlimit_cur) (nbsd_pid_to_statstr): New. (nbsd_nat_target::info_proc): Add do_stat. =2D-- gdb/ChangeLog | 7 ++ gdb/nbsd-nat.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7d91abf6334..5ff76e85cb3 100644 =2D-- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-04-13 Kamil Rytarowski + + * nbsd-nat.c: Include "sys/resource.h" and "machine/vmparam.h". + (nbsd_pid_to_kinfo_proc2, nbsd_pid_to_rlimit_cur) + (nbsd_pid_to_statstr): New. + (nbsd_nat_target::info_proc): Add do_stat. + 2020-04-12 Kamil Rytarowski * nbsd-nat.c (nbsd_nat_target::info_proc): Add IP_MINIMAL and diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c index 5eaf9dec8af..b2a05d63122 100644 =2D-- a/gdb/nbsd-nat.c +++ b/gdb/nbsd-nat.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include /* Return the name of a file that can be opened to get the symbols for the child process identified by PID. */ @@ -58,6 +60,134 @@ nbsd_pid_to_cwd (int pid) return buf; } +/* Return the kinfo_proc2 structure for the process identified by PID. *= / + +static bool +nbsd_pid_to_kinfo_proc2(pid_t pid, struct kinfo_proc2 *ki) +{ + gdb_assert (ki !=3D nullptr); + + size_t size =3D sizeof (*ki); + int mib[6] =3D {CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, + static_cast (size), 1}; + return sysctl (mib, ARRAY_SIZE (mib), ki, &size, NULL, 0); +} + +/* Return the RLIMIT value for the process identified by PID. */ + +static bool +nbsd_pid_to_rlimit_cur(pid_t pid, rlim_t *rlim, int type) +{ + gdb_assert (rlim !=3D nullptr); + + size_t size =3D sizeof (*rlim); + int mib[5] =3D {CTL_PROC, pid, PROC_PID_LIMIT, type, PROC_PID_LIMIT_TYP= E_SOFT}; + return sysctl (mib, ARRAY_SIZE (mib), rlim, &size, NULL, 0); +} + +/* Return the emulated /proc/#/stat string for the process identified by = PID. + NetBSD keeps the /proc filesystem that is optional and not recommended= for + new software, thus this call emulates it with sysctl(3). */ + +static gdb::unique_xmalloc_ptr +nbsd_pid_to_statstr (int pid) +{ + struct kinfo_proc2 ki; + if (nbsd_pid_to_kinfo_proc2 (pid, &ki)) + return nullptr; + + struct rusage cru =3D {}; + /* We can check only the current process. */ + if (getpid() =3D=3D pid) + getrusage (RUSAGE_SELF, &cru); + + rlim_t rsslim_cur; + if (nbsd_pid_to_rlimit_cur (pid, &rsslim_cur, PROC_PID_LIMIT_RSS)) + return nullptr; + + auto print_p_stat + =3D [] (int8_t state) + { + return "0RRSTZXR8"[(state > 8) ? 0 : state]; + }; + + auto print_p_tdev + =3D [] (uint32_t dev) + { + return (dev !=3D static_cast (NODEV)) ? dev : 0; + }; + + auto print_utime2ticks + =3D [] (uint32_t sec, uint32_t usec) + { + return (static_cast (sec) * 1000000 + (usec)) / 10000; + }; + + auto print_pgtokb + =3D [] (int32_t rsssize) + { + return static_cast (rsssize) << (PAGE_SHIFT - 10); + }; + + std::string statstr + =3D string_printf("%d (%s) %c %d %d %d %u %d " + "%u " + "%" PRIu64 " %lu %" PRIu64 " %lu %" PRIu64 " %" PRIu64 " " + "%" PRIu64 " %" PRIu64 " " + "%d %d %" PRIu64 " " + "%lld %" PRIu64 " %" PRId64 " %lu %" PRIu64 " " + "%lu %lu %lu " + "%u %u " + "%u %u %u %u " + "%" PRIu64 " %" PRIu64 " %" PRIu64 " %d %" PRIu64 "\n", + ki.p_pid, /* 1 pid */ + ki.p_comm, /* 2 tcomm */ + print_p_stat(ki.p_stat), /* 3 state */ + ki.p_ppid, /* 4 ppid */ + ki.p__pgid, /* 5 pgrp */ + ki.p_sid, /* 6 sid */ + print_p_tdev(ki.p_tdev), /* 7 tty_nr */ + ki.p_tpgid, /* 8 tty_pgrp */ + ki.p_flag, /* 9 flags */ + ki.p_uru_minflt, /* 10 min_flt */ + cru.ru_minflt, + ki.p_uru_majflt, /* 12 maj_flt */ + cru.ru_majflt, + print_utime2ticks(ki.p_uutime_sec, + ki.p_uutime_usec), /* 14 utime */ + print_utime2ticks(ki.p_ustime_sec, + ki.p_ustime_usec), /* 15 stime */ + print_utime2ticks(cru.ru_utime.tv_sec, + cru.ru_utime.tv_usec),/* 16 cutime */ + print_utime2ticks(cru.ru_stime.tv_sec, + cru.ru_stime.tv_usec),/* 17 cstime */ + ki.p_priority, /* 18 priority */ + ki.p_nice - NZERO, /* 19 nice */ + ki.p_nlwps, /* 20 num_threads */ + static_cast (ki.p_rtime_sec), + print_utime2ticks(ki.p_ustart_sec, + ki.p_ustart_usec), /* 22 start_time */ + ki.p_vm_msize, /* 23 vsize */ + print_pgtokb(ki.p_vm_rssize), /* 24 rss */ + rsslim_cur, /* 25 rsslim */ + 0L, /* 26 start_code */ + 0L, /* 27 end_code */ + 0L, /* 28 start_stack */ + 0, /* 29 esp */ + 0, /* 30 eip */ + ki.p_siglist.__bits[0], /* 31 pending */ + 0, /* 32 blocked */ + ki.p_sigignore.__bits[0], /* 33 sigign */ + ki.p_sigcatch.__bits[0], /* 34 sigcatch */ + ki.p_wchan, /* 35 wchan */ + ki.p_uru_nvcsw, + ki.p_uru_nivcsw, + ki.p_exitsig, /* 38 exit_signal */ + ki.p_cpuid); /* 39 task_cpu */ + + return gdb::unique_xmalloc_ptr (xstrprintf ("%s", statstr.c_str (= ))); +} + /* Return the command line for the process identified by PID. */ static gdb::unique_xmalloc_ptr @@ -344,6 +474,7 @@ nbsd_nat_target::info_proc (const char *args, enum inf= o_proc_what what) bool do_cwd =3D false; bool do_exe =3D false; bool do_mappings =3D false; + bool do_stat =3D false; switch (what) { @@ -352,6 +483,9 @@ nbsd_nat_target::info_proc (const char *args, enum inf= o_proc_what what) do_cwd =3D true; do_exe =3D true; break; + case IP_STAT: + do_stat =3D true; + break; case IP_MAPPINGS: do_mappings =3D true; break; @@ -369,6 +503,7 @@ nbsd_nat_target::info_proc (const char *args, enum inf= o_proc_what what) do_cwd =3D true; do_exe =3D true; do_mappings =3D true; + do_stat =3D true; break; default: error (_("Not supported on this target.")); @@ -433,6 +568,149 @@ nbsd_nat_target::info_proc (const char *args, enum i= nfo_proc_what what) else warning (_("unable to fetch virtual memory map")); } + if (do_stat) + { + /* First, try with Linux-compat /proc//stat. */ + char filename[100]; + xsnprintf (filename, sizeof filename, "/proc/%d/stat", pid); + gdb::unique_xmalloc_ptr statstr + =3D target_fileio_read_stralloc (NULL, filename); + + /* Then fallback to emulating /proc//stat with sysctl(3). */ + if (statstr =3D=3D nullptr) + statstr =3D nbsd_pid_to_statstr (pid); + + if (statstr) + { + const char *p =3D statstr.get (); + + printf_filtered (_("Process: %s\n"), + pulongest (strtoulst (p, &p, 10))); + + p =3D skip_spaces (p); + if (*p =3D=3D '(') + { + /* ps command also relies on no trailing fields + ever contain ')'. */ + const char *ep =3D strrchr (p, ')'); + if (ep !=3D NULL) + { + printf_filtered ("Exec file: %.*s\n", + (int) (ep - p - 1), p + 1); + p =3D ep + 1; + } + } + + p =3D skip_spaces (p); + if (*p) + printf_filtered (_("State: %c\n"), *p++); + + if (*p) + printf_filtered (_("Parent process: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Process group: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Session id: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("TTY: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("TTY owner process group: %s\n"), + pulongest (strtoulst (p, &p, 10))); + + if (*p) + printf_filtered (_("Flags: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Minor faults (no memory page): %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Minor faults, children: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Major faults (memory page faults): %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Major faults, children: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("utime: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("stime: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("utime, children: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("stime, children: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("jiffies remaining in current " + "time slice: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("'nice' value: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("jiffies until next timeout: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("jiffies until next SIGALRM: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("start time (jiffies since " + "system boot): %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Virtual memory size: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Resident set size: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("rlim: %s\n"), + pulongest (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Start of text: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("End of text: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Start of stack: %s\n"), + hex_string (strtoulst (p, &p, 10))); +#if 0 /* Don't know how architecture-dependent the rest is... + Anyway the signal bitmap info is available from "status". */ + if (*p) + printf_filtered (_("Kernel stack pointer: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Kernel instr pointer: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Pending signals bitmap: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Blocked signals bitmap: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Ignored signals bitmap: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("Catched signals bitmap: %s\n"), + hex_string (strtoulst (p, &p, 10))); + if (*p) + printf_filtered (_("wchan (system call): %s\n"), + hex_string (strtoulst (p, &p, 10))); +#endif + } + else + warning (_("unable to open /proc file '%s'"), filename); + } return true; } =2D- 2.25.0