summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2023-04-18 13:49:15 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-04-18 14:01:23 +0200
commit9f7cfaa5c02ffbf83f909ed6e5cb9467bcc76a49 (patch)
treebd464fd167760db549b092628d082020358b887e /utils
parent35e7d72e5f643bb342aff114b9bf5d7e03f6d5e2 (diff)
utils/msgport.c: Add cmd_report_wait
This exposes msg_report_wait. For example: $ msgport --report-wait --pid $$ 26997: 2 threads 26997: thread 0: proc_wait_request [init#3] 26997: thread 1: msgport Message-Id: <20230418104915.12301-1-bugaevc@gmail.com>
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile2
-rw-r--r--utils/msgport.c74
2 files changed, 75 insertions, 1 deletions
diff --git a/utils/Makefile b/utils/Makefile
index 0cefd27b..426166b2 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -69,7 +69,7 @@ ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
$(filter-out $(special-targets), $(targets)): %: %.o
rpctrace: ../libports/libports.a
-rpctrace rpcscan: msgids.o \
+rpctrace rpcscan msgport: msgids.o \
../libihash/libihash.a \
../libshouldbeinlibc/libshouldbeinlibc.a
msgids-CPPFLAGS = -DDATADIR=\"${datadir}\"
diff --git a/utils/msgport.c b/utils/msgport.c
index c96fdec8..a07cc0e2 100644
--- a/utils/msgport.c
+++ b/utils/msgport.c
@@ -31,7 +31,9 @@
#include <error.h>
#include <version.h>
#include "pids.h"
+#include "msgids.h"
#include <sys/mman.h>
+#include <assert-backtrace.h>
/* From libc (not in hurd.h) */
char *
@@ -423,6 +425,71 @@ cmd_umask (pid_t pid, mach_port_t msgport, int argc, char *argv[])
return err;
}
+error_t
+cmd_report_wait (pid_t pid, mach_port_t msgport, int argc, char *argv[])
+{
+ error_t err;
+ task_t task;
+ process_t proc = getproc ();
+ thread_t *threads = NULL;
+ mach_msg_type_number_t thread_count = 0;
+ size_t i;
+ static int msgids_initialized = 0;
+
+ if (!msgids_initialized)
+ {
+ err = msgids_scan_std ();
+ if (err)
+ error (0, err, "msgids_scan_std");
+ else
+ msgids_initialized = 1;
+ }
+
+ err = proc_pid2task (proc, pid, &task);
+ if (err)
+ return err;
+
+ err = task_threads (task, &threads, &thread_count);
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), task);
+ return err;
+ }
+
+ printf ("%d: %lu threads\n", pid, (unsigned long) thread_count);
+ for (i = 0; i < thread_count; i++)
+ {
+ char wait_desc[1024];
+ mach_msg_id_t wait_rpc;
+ const struct msgid_info *info = NULL;
+
+ err = msg_report_wait (msgport, threads[i], wait_desc, &wait_rpc);
+ if (err)
+ {
+ error (0, err, "%d: thread %lu", pid, (unsigned long) i);
+ err = mach_port_deallocate (mach_task_self (), threads[i]);
+ assert_perror_backtrace (err);
+ continue;
+ }
+ printf ("%d: thread %lu: ", pid, (unsigned long) i);
+ if (wait_rpc != 0)
+ info = msgid_info (wait_rpc);
+ if (info && info->name)
+ printf ("%s ", info->name);
+ else if (wait_rpc != 0)
+ printf ("msgid %lu ", (unsigned long) wait_rpc);
+ printf ("%s\n", wait_desc);
+ err = mach_port_deallocate (mach_task_self (), threads[i]);
+ assert_perror_backtrace (err);
+ }
+ err = vm_deallocate (mach_task_self (), (vm_address_t) threads,
+ sizeof (thread_t) * thread_count);
+ assert_perror_backtrace (err);
+ err = mach_port_deallocate (mach_task_self (), task);
+ assert_perror_backtrace (err);
+ return 0;
+}
+
#define OA OPTION_ARG_OPTIONAL
@@ -439,6 +506,7 @@ cmd_umask (pid_t pid, mach_port_t msgport, int argc, char *argv[])
#define CMD_STDERR 1010
#define CMD_PWD 1011
#define CMD_GETROOT 1012
+#define CMD_REPORT_WAIT 1013
/* Params to be passed as the input when parsing CMDS_ARGP. */
struct cmds_argp_params
@@ -466,6 +534,7 @@ static const struct argp_option cmd_options[] =
{"chroot", CMD_CHCRDIR,"DIR", 0, "Change current root directory"},
{"cdroot", CMD_CDROOT, 0, 0, "Change cwd to root directory"},
{"umask", CMD_UMASK, "MASK", OA, "Change umask"},
+ {"report-wait", CMD_REPORT_WAIT, 0, 0, "Describe what threads are blocked on"},
{0, 0}
};
@@ -574,6 +643,9 @@ parse_cmd_opt (int key, char *arg, struct argp_state *state)
case CMD_STDERR:
add_cmd (&cmd_stderr, 1, 2, arg, state);
break;
+ case CMD_REPORT_WAIT:
+ add_cmd (&cmd_report_wait, 0, 0, arg, state);
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -633,6 +705,8 @@ main(int argc, char *argv[])
"Commands:", 2},
{ &pids_argp, 0,
"Process selection:", 3},
+ { &msgid_argp, 0,
+ "Message ID lookup:", 4 },
{0} };
struct argp argp = { options, parse_opt, args_doc, doc, argp_kids };