summaryrefslogtreecommitdiff
path: root/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch')
-rw-r--r--debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch372
1 files changed, 0 insertions, 372 deletions
diff --git a/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch b/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch
deleted file mode 100644
index 97a96ebd..00000000
--- a/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch
+++ /dev/null
@@ -1,372 +0,0 @@
-From 3e02ff327e6ec3961bfbb68850e30ba62c817e5b Mon Sep 17 00:00:00 2001
-From: Justus Winter <4winter@informatik.uni-hamburg.de>
-Date: Fri, 23 May 2014 08:42:45 +0200
-Subject: [PATCH hurd 8/9] utils/rpctrace: support attaching to servers
-
-* utils/rpctrace.c (options): Add `--pid' and `--reference-port'.
-(print_contents): Prevent the translation of rights if `req' is NULL.
-We will use this to print messages in `trace_server'.
-(parse_task): New function.
-(trace_server): Mach server function that displays relayed messages.
-(trace_class_rpcs): New function that attaches to a server and starts
-tracing.
-(parse_opt): Handle `--pid' and `--reference-port'.
-(main): Handle new arguments, call trace_class_rpcs if desired.
----
- utils/Makefile | 5 +-
- utils/rpctrace.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 247 insertions(+), 3 deletions(-)
-
-diff --git a/utils/Makefile b/utils/Makefile
-index 603b722..94a389b 100644
---- a/utils/Makefile
-+++ b/utils/Makefile
-@@ -34,7 +34,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
- nullauth.c match-options.c msgids.c rpcscan.c
-
- OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
--HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
-+HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc introspection
- LDLIBS += -lpthread
- login-LDLIBS = -lutil -lcrypt
- addauth-LDLIBS = -lcrypt
-@@ -68,7 +68,8 @@ ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
-
- $(filter-out $(special-targets), $(targets)): %: %.o
-
--rpctrace: ../libports/libports.a
-+rpctrace: ../libports/libports.a \
-+ ../libintrospection/libintrospection.a hurd_portUser.o
- rpctrace rpcscan: msgids.o \
- ../libihash/libihash.a
- msgids-CPPFLAGS = -DDATADIR=\"${datadir}\"
-diff --git a/utils/rpctrace.c b/utils/rpctrace.c
-index b2f7b2b..98a8c7a 100644
---- a/utils/rpctrace.c
-+++ b/utils/rpctrace.c
-@@ -23,6 +23,7 @@
- #include <hurd.h>
- #include <hurd/ports.h>
- #include <hurd/ihash.h>
-+#include <hurd/introspection.h>
- #include <mach/message.h>
- #include <assert.h>
- #include <fcntl.h>
-@@ -40,14 +41,22 @@
- #include <envz.h>
-
- #include "msgids.h"
-+#include "hurd_port_U.h"
-
- const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace);
-
- static unsigned strsize = 80;
-+static int trace_class;
-
- static const struct argp_option options[] =
- {
- {"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."},
-+ {"pid", 'p', "PID", 0, "Attach to PID and trace all requests to objects "
-+ "of the same class as the given reference port. This will only work "
-+ "for Hurd servers implementing the introspection protocol."},
-+ {"port", 'P', "PORT", 0, "Trace all requests PORT. "
-+ "PORT must denote a receive right in PID."},
-+ {"class", 'c', NULL, 0, "Trace all requests to the same class as PORT."},
- {0, 's', "SIZE", 0, "Specify the maximum string size to print (the default is 80)."},
- {0, 'E', "var[=value]", 0,
- "Set/change (var=value) or remove (var) an environment variable among the "
-@@ -852,7 +861,7 @@ print_contents (mach_msg_header_t *inp,
- what task that port name is meaningful in. If it's meaningful in
- a traced task, then it refers to our intercepting port rather than
- the original port anyway. */
-- if (MACH_MSG_TYPE_PORT_ANY_RIGHT (name))
-+ if (MACH_MSG_TYPE_PORT_ANY_RIGHT (name) && req != NULL)
- {
- /* These are port rights. Translate them into wrappers. */
- mach_port_t *const portnames = data;
-@@ -1674,10 +1683,217 @@ traced_spawn (char **argv, char **envp)
-
- return pid;
- }
-+
-+/* Return the task corresponding to the user argument ARG, exiting with an
-+ appriate error message if we can't. */
-+static task_t
-+parse_task (char *arg)
-+{
-+ error_t err;
-+ task_t task;
-+ char *arg_end;
-+ pid_t pid = strtoul (arg, &arg_end, 10);
-+ static process_t proc = MACH_PORT_NULL;
-+
-+ if (*arg == '\0' || *arg_end != '\0')
-+ error (10, 0, "%s: Invalid process id", arg);
-+
-+ if (proc == MACH_PORT_NULL)
-+ proc = getproc ();
-+
-+ err = proc_pid2task (proc, pid, &task);
-+ if (err)
-+ error (11, err, "%s", arg);
-+ else if (task == MACH_PORT_NULL)
-+ error (11, 0, "%s: Process %d is dead and has no task", arg, (int) pid);
-+
-+ return task;
-+}
-+
-+static mach_port_t trace_notification_port;
-+static mach_port_t reference_port;
-+
-+boolean_t
-+trace_server (mach_msg_header_t *inp,
-+ mach_msg_header_t *outp)
-+{
-+ error_t err;
-+ static struct hurd_ihash ongoing_requests =
-+ HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
-+ struct msgid_info *info;
-+ mach_port_t trace_id;
-+ int is_reply;
-+
-+ if (inp->msgh_local_port == trace_notification_port
-+ && inp->msgh_id == MACH_NOTIFY_NO_SENDERS)
-+ {
-+ error (0, 0, "The tracee vanished.");
-+ exit (EXIT_SUCCESS);
-+ }
-+
-+ err = introspection_extract_message (inp, &trace_id);
-+ if (err)
-+ {
-+ error (0, err, "introspection_extract_message");
-+ goto out;
-+ }
-+ info = msgid_info (inp->msgh_id);
-+
-+ /* XXX This hardcodes an assumption about reply message ids. */
-+ is_reply = (inp->msgh_id / 100) % 2 == 1;
-+ if (is_reply)
-+ {
-+ /* This looks like a traced reply or a pseudo-reply. A
-+ pseudo-reply is a message containing the result of a simple
-+ procedure that is only sent to us. */
-+ mig_reply_header_t *reply = (mig_reply_header_t *) inp;
-+
-+ mach_port_t request_port;
-+ request_port = hurd_ihash_find (&ongoing_requests, trace_id);
-+ if (! MACH_PORT_VALID (request_port))
-+ {
-+ fprintf (stderr, "unsolicited reply packet with id: %d\n",
-+ trace_id);
-+ goto out;
-+ }
-+ hurd_ihash_remove (&ongoing_requests, trace_id);
-+
-+ if (! (trace_class || request_port == reference_port))
-+ goto out;
-+
-+ if (last_reply_port != trace_id)
-+ {
-+ print_ellipsis ();
-+ fprintf (ostream, "%u...", (unsigned int) trace_id);
-+ }
-+ last_reply_port = MACH_PORT_NULL;
-+
-+ fprintf (ostream, " = ");
-+
-+ if (reply->RetCode == 0)
-+ fprintf (ostream, "0");
-+ else
-+ {
-+ const char *str = strerror (reply->RetCode);
-+ if (str == 0)
-+ fprintf (ostream, "%#x", reply->RetCode);
-+ else
-+ fprintf (ostream, "%#x (%s)", reply->RetCode, str);
-+ }
-+
-+ if (inp->msgh_size > sizeof *reply)
-+ {
-+ fprintf (ostream, " ");
-+ print_contents (inp, (void *) inp + sizeof *reply, NULL);
-+ }
-+ fprintf (ostream, "\n");
-+ }
-+ else
-+ {
-+ /* Remember the request port. */
-+ hurd_ihash_add (&ongoing_requests, trace_id, inp->msgh_local_port);
-+
-+ if (! (trace_class || inp->msgh_local_port == reference_port))
-+ goto out;
-+
-+ /* This looks like a traced request. */
-+ print_ellipsis ();
-+ last_reply_port = trace_id;
-+
-+ if (info)
-+ fprintf (ostream, "% 4d->%s (", inp->msgh_local_port, info->name);
-+ else
-+ fprintf (ostream, "% 4d->%d (", inp->msgh_local_port, inp->msgh_id);
-+
-+ print_contents (inp, (void *) inp + sizeof *inp, NULL);
-+ fprintf (ostream, ")");
-+ }
-+
-+ out:
-+ /* vm_deallocate any out-of-band memory. */
-+ mach_msg_destroy (inp);
-+
-+ /* Prevent mach_msg_server from sending messages. */
-+ ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY;
-+ return TRUE;
-+}
-+
-+int
-+trace_class_rpcs (mach_port_t task,
-+ mach_port_t name)
-+{
-+ error_t err;
-+ mach_port_t trace_port;
-+ mach_port_t introspection_port;
-+ mach_port_t previous;
-+ mach_port_t port_set;
-+
-+ err = introspection_get_port (task, &introspection_port);
-+ if (err)
-+ error (13, err, "Failed to get introspection port");
-+
-+ if (! MACH_PORT_VALID (introspection_port))
-+ error (13, 0, "The server does not implement the introspection protocol");
-+
-+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
-+ &trace_port);
-+ if (err)
-+ error (13, err, "mach_port_allocate");
-+
-+ err = hurd_port_trace_class_rpcs (introspection_port, name,
-+ trace_port, MACH_MSG_TYPE_MAKE_SEND);
-+ if (err)
-+ {
-+ if (err == EINVAL)
-+ error (13, 0,
-+ "%d does not denote a receive right managed by libports", name);
-+ else
-+ error (13, err, "hurd_port_trace_class_rpcs");
-+ }
-+
-+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
-+ &trace_notification_port);
-+ if (err)
-+ error (13, err, "mach_port_allocate");
-+
-+ err = mach_port_request_notification (mach_task_self (),
-+ trace_port,
-+ MACH_NOTIFY_NO_SENDERS,
-+ 0,
-+ trace_notification_port,
-+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
-+ &previous);
-+ if (err)
-+ error (13, err, "mach_port_request_notification");
-+ assert (! MACH_PORT_VALID (previous));
-+
-+
-+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
-+ &port_set);
-+ if (err)
-+ error (13, err, "mach_port_allocate");
-+
-+ err = mach_port_move_member (mach_task_self (), trace_port, port_set);
-+ if (err)
-+ error (13, err, "mach_port_move_member");
-
-+ err = mach_port_move_member (mach_task_self (), trace_notification_port,
-+ port_set);
-+ if (err)
-+ error (13, err, "mach_port_move_member");
-+
-+ error (0, 0, "entering service loop");
-+ while (1)
-+ mach_msg_server (trace_server, 0, port_set);
-+
-+ /* Not reached. */
-+ return 0;
-+}
-+
- int
- main (int argc, char **argv, char **envp)
- {
-+ mach_port_t target_task = MACH_PORT_NULL;
- const char *outfile = 0;
- char **cmd_argv = 0;
- pthread_t thread;
-@@ -1689,12 +1905,27 @@ main (int argc, char **argv, char **envp)
- /* Parse our options... */
- error_t parse_opt (int key, char *arg, struct argp_state *state)
- {
-+ char *arg_end;
- switch (key)
- {
- case 'o':
- outfile = arg;
- break;
-
-+ case 'p':
-+ target_task = parse_task (arg);
-+ break;
-+
-+ case 'P':
-+ reference_port = strtoul (arg, &arg_end, 10);
-+ if (*arg == '\0' || *arg_end != '\0')
-+ argp_error (state, "Invalid port name: %s", arg);
-+ break;
-+
-+ case 'c':
-+ trace_class = 1;
-+ break;
-+
- case 's':
- strsize = atoi (arg);
- break;
-@@ -1728,10 +1959,16 @@ main (int argc, char **argv, char **envp)
- break;
-
- case ARGP_KEY_NO_ARGS:
-+ if (MACH_PORT_VALID (target_task))
-+ break;
-+
- argp_usage (state);
- return EINVAL;
-
- case ARGP_KEY_ARG:
-+ if (MACH_PORT_VALID (target_task))
-+ argp_error (state, "Superfluous argument: %s", arg);
-+
- cmd_argv = &state->argv[state->next - 1];
- state->next = state->argc;
- break;
-@@ -1751,6 +1988,9 @@ main (int argc, char **argv, char **envp)
- /* Parse our arguments. */
- argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0);
-
-+ if (MACH_PORT_VALID (target_task) != MACH_PORT_VALID (reference_port))
-+ error (10, 0, "Please specify either both -p and -P, or neither.");
-+
- err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_DEAD_NAME,
- &unknown_task);
- assert_perror (err);
-@@ -1765,6 +2005,9 @@ main (int argc, char **argv, char **envp)
- ostream = stderr;
- setlinebuf (ostream);
-
-+ if (MACH_PORT_VALID (target_task))
-+ return trace_class_rpcs (target_task, reference_port);
-+
- traced_bucket = ports_create_bucket ();
- traced_class = ports_create_class (&traced_clean, NULL);
- other_class = ports_create_class (0, 0);
---
-2.1.4
-