summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2009-02-23 21:01:43 +0100
committerNeal H. Walfield <neal@gnu.org>2009-02-23 21:01:43 +0100
commitf744541b1f6e7d15df61ca11e35debd3f07d287f (patch)
tree1945708db5daf9935c3c3f6e19db7534af6d4cd9
parentf36fe8af3fe9288386a2d40c1730d353e7f1bef6 (diff)
Record a thread's last four fault locations.
-rw-r--r--viengoos/server.c8
-rw-r--r--viengoos/thread.c39
-rw-r--r--viengoos/thread.h5
3 files changed, 45 insertions, 7 deletions
diff --git a/viengoos/server.c b/viengoos/server.c
index eca721f..4caddf8 100644
--- a/viengoos/server.c
+++ b/viengoos/server.c
@@ -122,8 +122,12 @@ page_fault_handler (struct thread *thread, uintptr_t fault, int access)
(fault & MEM_WRITABLE) ? "Write" : "Read", fault,
thread_ip (thread), thread_sp (thread));
- thread->last_fault = fault;
- thread->last_fault_ip = thread_ip (thread);
+ thread->last_fault[thread->last_fault_idx] = fault;
+ thread->last_fault_ip[thread->last_fault_idx] = thread_ip (thread);
+ thread->last_fault_idx ++;
+ if (thread->last_fault_idx
+ == sizeof (thread->last_fault) / sizeof (thread->last_fault[0]))
+ thread->last_fault_idx = 0;
struct activity *activity
= (struct activity *) vg_cap_to_object (root_activity,
diff --git a/viengoos/thread.c b/viengoos/thread.c
index 7f7a2cb..e647793 100644
--- a/viengoos/thread.c
+++ b/viengoos/thread.c
@@ -79,7 +79,7 @@ thread_dump (int argc, char *argv[])
"time: %d ns (last payout at %ld.%09ld s)\n"
"total time: %ld.%09ld s\n"
"\n"
- "last fault: %"PRIxPTR" (ip: %"PRIxPTR")\n",
+ "last fault:\n",
REGS_PRINTF (thread),
VG_CAP_PRINTF (&thread->aspace),
VG_CAP_PRINTF (&thread->activity),
@@ -90,8 +90,41 @@ thread_dump (int argc, char *argv[])
thread->last_payout / 1000 / 1000 / 1000,
thread->last_payout % (1000 * 1000 * 1000),
thread->total_time / 1000 / 1000 / 1000,
- thread->total_time % (1000 * 1000 * 1000),
- thread->last_fault, thread->last_fault_ip);
+ thread->total_time % (1000 * 1000 * 1000));
+
+ int cnt = sizeof (thread->last_fault) / sizeof (thread->last_fault[0]);
+ int i;
+ for (i = -1; i >= -cnt; i --)
+ {
+ int idx = (cnt + thread->last_fault_idx + i) % cnt;
+ printf (" %d: %"PRIxPTR" (%"PRIxPTR")\n",
+ i, thread->last_fault[idx], thread->last_fault_ip[idx]);
+ }
+
+ struct vg_object *object = vg_cap_to_object (root_activity, &thread->utcb);
+ if (object)
+ {
+ struct vg_utcb *utcb = (struct vg_utcb *) object;
+ printf ("\nUTCB:\n"
+ " activated mode: %d\n"
+ " pending_message: %d\n"
+ " interrupt in transition: %d\n"
+ " saved ip: %"PRIxPTR"\n"
+ " saved sp: %"PRIxPTR"\n"
+ " activation handler sp: %"PRIxPTR"\n"
+ " activation handler ip: %"PRIxPTR"\n"
+ " activation handler end: %"PRIxPTR"\n"
+ " messenger id: %"PRIxPTR"\n",
+ utcb->activated_mode,
+ utcb->pending_message,
+ utcb->interrupt_in_transition,
+ utcb->saved_ip,
+ utcb->saved_sp,
+ utcb->activation_handler_sp,
+ utcb->activation_handler_ip,
+ utcb->activation_handler_end,
+ utcb->messenger_id);
+ }
}
static struct debug_command debug_command =
diff --git a/viengoos/thread.h b/viengoos/thread.h
index ea6b49e..a1826ac 100644
--- a/viengoos/thread.h
+++ b/viengoos/thread.h
@@ -86,8 +86,9 @@ struct thread
struct vg_object_name name;
/* The last fault. */
- uintptr_t last_fault;
- uintptr_t last_fault_ip;
+ int last_fault_idx;
+ uintptr_t last_fault[4];
+ uintptr_t last_fault_ip[4];
enum thread_state state;
struct list_node run_queue_node;