Aloha -
I'm attaching two more patches to rpctrace that close bug 48863.
agape
brent
From 10a2a49e370ca55b6cea4cdc4a54ae106b243817 Mon Sep 17 00:00:00 2001
From: Brent Baccala <[email protected]>
Date: Tue, 1 Nov 2016 01:07:52 -1000
Subject: [PATCH 1/2] rpctrace: don't wrap send-once rights sent to the task
owning the receive right
---
utils/rpctrace.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 72ca614..6eb9892 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -708,11 +708,22 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t *type,
/* There is no way to know if this send-once right is to the same
receive right as any other send-once or send right we have seen.
Fortunately, it doesn't matter, since the recipient of the
- send-once right we pass along can't tell either. We always just
- make a new send-once wrapper object, that will trace the one
- message it receives, and then die. */
- *type = MACH_MSG_TYPE_MAKE_SEND_ONCE;
- return TRACED_INFO (new_send_once_wrapper (*right, right, source))->name;
+ send-once right we pass along can't tell either. We make a new
+ send-once wrapper object, that will trace the one message it
+ receives, and then die, unless the source and destination tasks
+ are the same. This can only happen for the reply message to a
+ mach_port RPC, a special case detected in trace_and_forward(),
+ in which case we leave the send-once right alone, since we're
+ passing it to the owner of its corresponding receive right. */
+ if (source == dest)
+ {
+ return NULL;
+ }
+ else
+ {
+ *type = MACH_MSG_TYPE_MAKE_SEND_ONCE;
+ return TRACED_INFO (new_send_once_wrapper (*right, right, source))->name;
+ }
case MACH_MSG_TYPE_PORT_RECEIVE:
/* We have got a receive right, call it A and the send wrapper for
--
2.6.4
From 251d19fb55f99a358ad5cf2097be07a50a9a3057 Mon Sep 17 00:00:00 2001
From: Brent Baccala <[email protected]>
Date: Tue, 1 Nov 2016 01:09:21 -1000
Subject: [PATCH 2/2] rpctrace: don't use reply code unless we've found a
matching request, and remove unused is_req field from request structure
---
utils/rpctrace.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 6eb9892..2664ffd 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -189,7 +189,6 @@ struct send_once_info
/* This structure stores the information of the RPC requests. */
struct req_info
{
- boolean_t is_req;
mach_msg_id_t req_id;
mach_port_t reply_port;
task_t from;
@@ -210,7 +209,6 @@ add_request (mach_msg_id_t req_id, mach_port_t reply_port,
req->from = from;
req->to = to;
req->reply_port = reply_port;
- req->is_req = TRUE;
req->next = req_head;
req_head = req;
@@ -1322,18 +1320,18 @@ trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
if (msgid_display (msgid))
{
+ struct req_info *req = NULL;
+
if (inp->msgh_local_port == MACH_PORT_NULL
&& info->type == MACH_MSG_TYPE_MOVE_SEND_ONCE
&& inp->msgh_size >= sizeof (mig_reply_header_t)
/* The notification message is considered as a request. */
&& (inp->msgh_id > 72 || inp->msgh_id < 64)
&& !memcmp(&((mig_reply_header_t *) inp)->RetCodeType,
- &RetCodeType, sizeof (RetCodeType)))
+ &RetCodeType, sizeof (RetCodeType))
+ && (req = remove_request (inp->msgh_id - 100,
+ inp->msgh_remote_port)))
{
- struct req_info *req = remove_request (inp->msgh_id - 100,
- inp->msgh_remote_port);
- assert (req);
- req->is_req = FALSE;
/* This sure looks like an RPC reply message. */
mig_reply_header_t *rh = (void *) inp;
print_reply_header ((struct send_once_info *) info, rh, req);
@@ -1352,7 +1350,6 @@ trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
else
{
struct task_info *task_info;
- struct req_info *req = NULL;
/* Print something about the message header. */
print_request_header ((struct sender_info *) info, inp);
--
2.6.4