[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH2/4] fully enable rpctrace to trace multitask programs.
From: |
Da Zheng |
Subject: |
[PATCH2/4] fully enable rpctrace to trace multitask programs. |
Date: |
Mon, 20 Jul 2009 19:40:32 +0800 |
User-agent: |
Thunderbird 2.0.0.22 (Macintosh/20090605) |
The second patch fixes bug #3939, so rpctrace can handle the signal correctly.
Zheng Da
2009-07-20 Zheng Da <zhengda1936@gmail.com>
fix bug #3939
* rpctrace.c (traced_task): Relocate.
(wrap_all_threads): New function.
(wrap_new_thread): Likewise.
(trace_and_forward): Wrap all thread ports.
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index b7379a7..f36e566 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -82,6 +82,8 @@ msgid_ihash_cleanup (void *element, void *arg)
static struct hurd_ihash msgid_ihash
= HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
+task_t traced_task;
+
/* Parse a file of RPC names and message IDs as output by mig's -list
option: "subsystem base-id routine n request-id reply-id". Put each
request-id value into `msgid_ihash' with the routine name as its value. */
@@ -642,6 +644,80 @@ print_contents (mach_msg_header_t *inp,
}
}
+/* Wrap all thread port in the task */
+static void
+wrap_all_threads (task_t task)
+{
+ struct traced_info *thread_send_wrapper;
+ thread_t *threads = NULL;
+ size_t nthreads = 0;
+ error_t err;
+
+ err = task_threads (task, &threads, &nthreads);
+ if (err)
+ error (2, err, "task_threads");
+
+ for (int i = 0; i < nthreads; i++)
+ {
+ thread_send_wrapper = hurd_ihash_find (&traced_names, threads[i]);
+ /* We haven't seen the port. */
+ if (thread_send_wrapper == NULL)
+ {
+ mach_port_t new_thread_port;
+ thread_send_wrapper = new_send_wrapper (threads[i], &new_thread_port);
+ free (thread_send_wrapper->name);
+ asprintf (&thread_send_wrapper->name, "thread%d", threads[i]);
+
+ err = mach_port_insert_right (mach_task_self (),
+ new_thread_port, new_thread_port,
+ MACH_MSG_TYPE_MAKE_SEND);
+ if (err)
+ error (2, err, "mach_port_insert_right");
+
+ err = thread_set_kernel_port (threads[i], new_thread_port);
+ if (err)
+ error (2, err, "thread_set_kernel_port");
+
+ mach_port_deallocate (mach_task_self (), new_thread_port);
+ }
+ }
+ vm_deallocate (mach_task_self (), threads, nthreads * sizeof (thread_t));
+}
+
+/* Wrap the new thread port that is in the message. */
+static void
+wrap_new_thread (mach_msg_header_t *inp)
+{
+ error_t err;
+ mach_port_t thread_port;
+ struct
+ {
+ mach_msg_header_t head;
+ mach_msg_type_t retcode_type;
+ kern_return_t retcode;
+ mach_msg_type_t child_thread_type;
+ mach_port_t child_thread;
+ } *reply = (void *) inp;
+ /* This function is called after rewrite_right,
+ * so the wrapper for the thread port has been created. */
+ struct traced_info *send_wrapper = ports_lookup_port (traced_bucket,
+ reply->child_thread, 0);
+
+ assert (send_wrapper);
+ err = mach_port_insert_right (mach_task_self (), reply->child_thread,
+ reply->child_thread, MACH_MSG_TYPE_MAKE_SEND);
+ if (err)
+ error (2, err, "mach_port_insert_right");
+ thread_port = send_wrapper->forward;
+ err = thread_set_kernel_port (thread_port, reply->child_thread);
+ if (err)
+ error (2, err, "thread_set_kernel_port");
+ free (send_wrapper->name);
+ asprintf (&send_wrapper->name, "thread%d", thread_port);
+ mach_port_deallocate (mach_task_self (), reply->child_thread);
+ ports_port_deref (send_wrapper);
+}
+
int
trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp)
{
@@ -770,6 +846,9 @@ trace_and_forward (mach_msg_header_t *inp,
mach_msg_header_t *outp)
putc (' ', ostream);
print_contents (&rh->Head, rh + 1);
putc ('\n', ostream);
+
+ if (inp->msgh_id == 2161)/* the reply message for thread_create */
+ wrap_new_thread (inp);
}
else
{
@@ -781,6 +860,11 @@ trace_and_forward (mach_msg_header_t *inp,
mach_msg_header_t *outp)
else
/* Leave a partial line that will be finished later. */
fprintf (ostream, ")");
+
+ /* If it's the request of exec_startup_get_info,
+ * it means that the traced process starts to run */
+ if (inp->msgh_id == 30500)
+ wrap_all_threads (traced_task);
}
}
@@ -1014,8 +1098,6 @@ print_data (mach_msg_type_name_t type,
/*** Main program and child startup ***/
-task_t traced_task;
-
/* Run a child and have it do more or else `execvpe (argv, envp);'. */
pid_t