[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] xenctx: Add an option to output more registers.



From: Don Slutz <Don@xxxxxxxxxxxxxxx>

Also fixup handling of symbol files, and output of 2 page stacks, and output of 
non stack memory.

Signed-off-by: Don Slutz <Don@xxxxxxxxxxxxxxx>
---
 tools/xentrace/xenctx.c |  562 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 496 insertions(+), 66 deletions(-)

diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 1214185..83aaece 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -35,6 +35,7 @@ static struct xenctx {
     int frame_ptrs;
     int stack_trace;
     int disp_all;
+    int two_pages;
     int all_vcpus;
     int self_paused;
     xc_dominfo_t dominfo;
@@ -68,6 +69,7 @@ struct symbol {
 } *symbol_table = NULL;
 
 guest_word_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext, 
kernel_hypercallpage;
+guest_word_t kernel_text, kernel_end;
 
 #if defined (__i386__)
 unsigned long long kernel_start = 0xc0000000;
@@ -77,17 +79,24 @@ unsigned long long kernel_start = 0xffffffff80000000UL;
 
 static int is_kernel_text(guest_word_t addr)
 {
-    if (symbol_table == NULL)
-        return (addr > kernel_start);
+    if (symbol_table == NULL) {
+        if (addr > kernel_start)
+            return 2;
+        else
+            return 0;
+    }
 
     if (addr >= kernel_stext &&
         addr <= kernel_etext)
-        return 1;
-    if (addr >= kernel_hypercallpage &&
-        addr <= kernel_hypercallpage + 4096)
-        return 1;
+        return 2;
+    if (kernel_hypercallpage && (addr >= kernel_hypercallpage &&
+                                 addr <= kernel_hypercallpage + 4096))
+        return 2;
     if (addr >= kernel_sinittext &&
         addr <= kernel_einittext)
+        return 2;
+    if (addr >= kernel_text &&
+        addr <= kernel_end)
         return 1;
     return 0;
 }
@@ -143,11 +152,11 @@ static struct symbol *lookup_symbol(guest_word_t address)
     return s->next && s->next->address <= address ? s->next : s;
 }
 
-static void print_symbol(guest_word_t addr)
+static void print_symbol(guest_word_t addr, int type)
 {
     struct symbol *s;
 
-    if (!is_kernel_text(addr))
+    if (is_kernel_text(addr) < type)
         return;
 
     s = lookup_symbol(addr);
@@ -156,9 +165,9 @@ static void print_symbol(guest_word_t addr)
         return;
 
     if (addr==s->address)
-        printf("%s ", s->name);
+        printf(" %s", s->name);
     else
-        printf("%s+%#x ", s->name, (unsigned int)(addr - s->address));
+        printf(" %s+%#x", s->name, (unsigned int)(addr - s->address));
 }
 
 static void read_symbol_table(const char *symtab)
@@ -215,6 +224,10 @@ static void read_symbol_table(const char *symtab)
             kernel_stext = symbol->address;
         else if (strcmp(symbol->name, "_etext") == 0)
             kernel_etext = symbol->address;
+        else if (strcmp(symbol->name, "_text") == 0)
+            kernel_text = symbol->address;
+        else if (strcmp(symbol->name, "_end") == 0)
+            kernel_end = symbol->address;
         else if (strcmp(symbol->name, "_sinittext") == 0)
             kernel_sinittext = symbol->address;
         else if (strcmp(symbol->name, "_einittext") == 0)
@@ -285,8 +298,8 @@ static void print_ctx_32(vcpu_guest_context_x86_32_t *ctx)
 {
     struct cpu_user_regs_x86_32 *regs = &ctx->user_regs;
 
-    printf("cs:eip: %04x:%08x ", regs->cs, regs->eip);
-    print_symbol(regs->eip);
+    printf("cs:eip: %04x:%08x", regs->cs, regs->eip);
+    print_symbol(regs->eip, 2);
     print_flags(regs->eflags);
     printf("ss:esp: %04x:%08x\n", regs->ss, regs->esp);
 
@@ -314,8 +327,8 @@ static void print_ctx_32on64(vcpu_guest_context_x86_64_t 
*ctx)
 {
     struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
 
-    printf("cs:eip: %04x:%08x ", regs->cs, (uint32_t)regs->eip);
-    print_symbol((uint32_t)regs->eip);
+    printf("cs:eip: %04x:%08x", regs->cs, (uint32_t)regs->eip);
+    print_symbol((uint32_t)regs->eip, 2);
     print_flags((uint32_t)regs->eflags);
     printf("ss:esp: %04x:%08x\n", regs->ss, (uint32_t)regs->esp);
 
@@ -343,8 +356,8 @@ static void print_ctx_64(vcpu_guest_context_x86_64_t *ctx)
 {
     struct cpu_user_regs_x86_64 *regs = &ctx->user_regs;
 
-    printf("rip: %016"PRIx64" ", regs->rip);
-    print_symbol(regs->rip);
+    printf("rip: %016"PRIx64, regs->rip);
+    print_symbol(regs->rip, 2);
     print_flags(regs->rflags);
     printf("rsp: %016"PRIx64"\n", regs->rsp);
 
@@ -393,6 +406,247 @@ static void print_ctx(vcpu_guest_context_any_t *ctx)
         print_ctx_64(&ctx->x64);
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+static void print_cpuctx_regs64(struct hvm_hw_cpu *ctx)
+{
+    printf("rip: %016"PRIx64, ctx->rip);
+    print_symbol(ctx->rip, 2);
+    print_flags(ctx->rflags);
+    printf("rsp: %016"PRIx64"\n", ctx->rsp);
+
+    printf("rax: %016"PRIx64"\t", ctx->rax);
+    printf("rcx: %016"PRIx64"\t", ctx->rcx);
+    printf("rdx: %016"PRIx64"\n", ctx->rdx);
+
+    printf("rbx: %016"PRIx64"\t", ctx->rbx);
+    printf("rsi: %016"PRIx64"\t", ctx->rsi);
+    printf("rdi: %016"PRIx64"\n", ctx->rdi);
+
+    printf("rbp: %016"PRIx64"\t", ctx->rbp);
+    printf(" r8: %016"PRIx64"\t", ctx->r8);
+    printf(" r9: %016"PRIx64"\n", ctx->r9);
+
+    printf("r10: %016"PRIx64"\t", ctx->r10);
+    printf("r11: %016"PRIx64"\t", ctx->r11);
+    printf("r12: %016"PRIx64"\n", ctx->r12);
+
+    printf("r13: %016"PRIx64"\t", ctx->r13);
+    printf("r14: %016"PRIx64"\t", ctx->r14);
+    printf("r15: %016"PRIx64"\n", ctx->r15);
+
+    printf("  cs: %04x @ %016"PRIx64, ctx->cs_sel, ctx->cs_base);
+    if (ctx->cs_base)
+        print_symbol(ctx->cs_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+    printf("  ss: %04x @ %016"PRIx64, ctx->ss_sel, ctx->ss_base);
+    if (ctx->ss_base)
+        print_symbol(ctx->ss_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+    printf("  ds: %04x @ %016"PRIx64, ctx->ds_sel, ctx->ds_base);
+    if (ctx->ds_base)
+        print_symbol(ctx->ds_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+    printf("  es: %04x @ %016"PRIx64, ctx->es_sel, ctx->es_base);
+    if (ctx->es_base)
+        print_symbol(ctx->es_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+    printf("  fs: %04x @ %016"PRIx64, ctx->fs_sel, ctx->fs_base);
+    if (ctx->fs_base)
+        print_symbol(ctx->fs_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+    printf("  gs: %04x @ %016"PRIx64"\\%016"PRIx64, ctx->gs_sel,
+           ctx->gs_base, ctx->shadow_gs);
+    if (ctx->gs_base)
+        print_symbol(ctx->gs_base, 1);
+    printf("\\");
+    if (ctx->shadow_gs)
+        print_symbol(ctx->shadow_gs, 1);
+    printf("\n           /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+    if (xenctx.disp_all) {
+        printf("  tr: %04x @ %016"PRIx64, ctx->tr_sel, ctx->tr_base);
+        if (ctx->tr_base)
+            print_symbol(ctx->tr_base, 1);
+        printf("\n           /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+        printf(" ldt: %04x @ %016"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+        if (ctx->ldtr_base)
+            print_symbol(ctx->ldtr_base, 1);
+        printf("\n           /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+        printf("\n");
+        printf("cr0: %08"PRIx64"\n", ctx->cr0);
+        printf("cr2: %08"PRIx64, ctx->cr2);
+        print_symbol(ctx->cr2, 1);
+        printf("\n");
+        printf("cr3: %08"PRIx64"\n", ctx->cr3);
+        printf("cr4: %08"PRIx64"\n", ctx->cr4);
+        printf("\n");
+        printf("dr0: %08"PRIx64, ctx->dr0);
+        print_symbol(ctx->dr0, 1);
+        printf("\n");
+        printf("dr1: %08"PRIx64, ctx->dr1);
+        print_symbol(ctx->dr1, 1);
+        printf("\n");
+        printf("dr2: %08"PRIx64, ctx->dr2);
+        print_symbol(ctx->dr2, 1);
+        printf("\n");
+        printf("dr3: %08"PRIx64, ctx->dr3);
+        print_symbol(ctx->dr3, 1);
+        printf("\n");
+        printf("dr6: %08"PRIx64"\n", ctx->dr6);
+        printf("dr7: %08"PRIx64"\n", ctx->dr7);
+        printf("\n");
+        printf("gdt: %016"PRIx64"/%lx", ctx->gdtr_base, 
(long)(ctx->gdtr_limit));
+        print_symbol(ctx->gdtr_base, 1);
+        printf("\n");
+        printf("idt: %016"PRIx64"/%lx", ctx->idtr_base, 
(long)(ctx->idtr_limit));
+        print_symbol(ctx->idtr_base, 1);
+        printf("\n");
+        printf("\n");
+        printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+               ctx->msr_efer, ctx->msr_flags);
+        printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+               ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+        print_symbol(ctx->sysenter_eip, 1);
+        printf("\n");
+        printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+               ctx->msr_star, ctx->msr_syscall_mask);
+        printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+        print_symbol(ctx->msr_lstar, 1);
+        printf("\n");
+        printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+        print_symbol(ctx->msr_cstar, 1);
+        printf("\n");
+        printf("\n");
+        printf("\n");
+        printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+        printf("\n");
+        printf("\n");
+        printf("pending_event: %lx  pending_vector: %lx\n",
+               (long)(ctx->pending_event), (long)(ctx->pending_vector));
+        printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+    }
+}
+
+static void print_cpuctx_regs32(struct hvm_hw_cpu *ctx)
+{
+    printf("cs:eip: %04x:%08x", ctx->cs_sel, (uint32_t)ctx->rip);
+    print_symbol((uint32_t)ctx->rip, 2);
+    print_flags((uint32_t)ctx->rflags);
+    printf("ss:esp: %04x:%08x\n", ctx->ss_sel, (uint32_t)ctx->rsp);
+    printf("\n");
+
+    printf("eax: %08x\t", (uint32_t)ctx->rax);
+    printf("ebx: %08x\t", (uint32_t)ctx->rbx);
+    printf("ecx: %08x\t", (uint32_t)ctx->rcx);
+    printf("edx: %08x\n", (uint32_t)ctx->rdx);
+
+    printf("esi: %08x\t", (uint32_t)ctx->rsi);
+    printf("edi: %08x\t", (uint32_t)ctx->rdi);
+    printf("ebp: %08x\n", (uint32_t)ctx->rbp);
+    printf("\n");
+
+    printf("  cs: %04x @ %08"PRIx64, ctx->cs_sel, ctx->cs_base);
+    if (ctx->cs_base)
+        print_symbol(ctx->cs_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->cs_limit, ctx->cs_arbytes);
+    printf("  ss: %04x @ %08"PRIx64, ctx->ss_sel, ctx->ss_base);
+    if (ctx->ss_base)
+        print_symbol(ctx->ss_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->ss_limit, ctx->ss_arbytes);
+    printf("  ds: %04x @ %08"PRIx64, ctx->ds_sel, ctx->ds_base);
+    if (ctx->ds_base)
+        print_symbol(ctx->ds_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->ds_limit, ctx->ds_arbytes);
+    printf("  es: %04x @ %08"PRIx64, ctx->es_sel, ctx->es_base);
+    if (ctx->es_base)
+        print_symbol(ctx->es_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->es_limit, ctx->es_arbytes);
+    printf("  fs: %04x @ %08"PRIx64, ctx->fs_sel, ctx->fs_base);
+    if (ctx->fs_base)
+        print_symbol(ctx->fs_base, 1);
+    printf("\n           /%08x(%x)\n", ctx->fs_limit, ctx->fs_arbytes);
+    printf("  gs: %04x @ %08"PRIx64"\\%08"PRIx64, ctx->gs_sel,
+           ctx->gs_base, ctx->shadow_gs);
+    if (ctx->gs_base)
+        print_symbol(ctx->gs_base, 1);
+    printf("\\");
+    if (ctx->shadow_gs)
+        print_symbol(ctx->shadow_gs, 1);
+    printf("\n           /%08x(%x)\n", ctx->gs_limit, ctx->gs_arbytes);
+
+    if (xenctx.disp_all) {
+        printf("  tr: %04x @ %08"PRIx64, ctx->tr_sel, ctx->tr_base);
+        if (ctx->tr_base)
+            print_symbol(ctx->tr_base, 1);
+        printf("\n           /%08x(%x)\n", ctx->tr_limit, ctx->tr_arbytes);
+        printf(" ldt: %04x @ %08"PRIx64, ctx->ldtr_sel, ctx->ldtr_base);
+        if (ctx->ldtr_base)
+            print_symbol(ctx->ldtr_base, 1);
+        printf("\n           /%08x(%x)\n", ctx->ldtr_limit, ctx->ldtr_arbytes);
+        printf("\n");
+        printf("cr0: %08"PRIx64"\n", ctx->cr0);
+        printf("cr2: %08"PRIx64, ctx->cr2);
+        print_symbol(ctx->cr2, 1);
+        printf("\n");
+        printf("cr3: %08"PRIx64"\n", ctx->cr3);
+        printf("cr4: %08"PRIx64"\n", ctx->cr4);
+        printf("\n");
+        printf("dr0: %08"PRIx64, ctx->dr0);
+        print_symbol(ctx->dr0, 1);
+        printf("\n");
+        printf("dr1: %08"PRIx64, ctx->dr1);
+        print_symbol(ctx->dr1, 1);
+        printf("\n");
+        printf("dr2: %08"PRIx64, ctx->dr2);
+        print_symbol(ctx->dr2, 1);
+        printf("\n");
+        printf("dr3: %08"PRIx64, ctx->dr3);
+        print_symbol(ctx->dr3, 1);
+        printf("\n");
+        printf("dr6: %08"PRIx64"\n", ctx->dr6);
+        printf("dr7: %08"PRIx64"\n", ctx->dr7);
+        printf("\n");
+        printf("gdt: %08"PRIx64"/%lx", ctx->gdtr_base, 
(long)(ctx->gdtr_limit));
+        print_symbol(ctx->gdtr_base, 1);
+        printf("\n");
+        printf("idt: %08"PRIx64"/%lx", ctx->idtr_base, 
(long)(ctx->idtr_limit));
+        print_symbol(ctx->idtr_base, 1);
+        printf("\n");
+        printf("\n");
+        printf(" EFER: %08"PRIx64" flags: %08"PRIx64"\n",
+               ctx->msr_efer, ctx->msr_flags);
+        printf("SYSENTER cs: %08"PRIx64" esp: %08"PRIx64" eip: %08"PRIx64,
+               ctx->sysenter_cs, ctx->sysenter_esp, ctx->sysenter_eip);
+        print_symbol(ctx->sysenter_eip, 1);
+        printf("\n");
+        printf(" STAR: %08"PRIx64" SFMASK: %08"PRIx64"\n",
+               ctx->msr_star, ctx->msr_syscall_mask);
+        printf("LSTAR: %08"PRIx64, ctx->msr_lstar);
+        print_symbol(ctx->msr_lstar, 1);
+        printf("\n");
+        printf("CSTAR: %08"PRIx64, ctx->msr_cstar);
+        print_symbol(ctx->msr_cstar, 1);
+        printf("\n");
+        printf("\n");
+        printf(" tsc: %016"PRIx64"\n", ctx->tsc);
+        printf("\n");
+        printf("\n");
+        printf("pending_event: %lx  pending_vector: %lx\n",
+               (long)(ctx->pending_event), (long)(ctx->pending_vector));
+        printf("pending error_code: %lx\n\n", (long)(ctx->error_code));
+    }
+}
+
+static void print_cpuctx(struct hvm_hw_cpu *ctx)
+{
+    if (guest_word_size == 8)
+        print_cpuctx_regs64(ctx);
+    else
+        print_cpuctx_regs32(ctx);
+
+}
+#endif
+
 #define NONPROT_MODE_SEGMENT_SHIFT 4
 
 static guest_word_t instr_pointer(vcpu_guest_context_any_t *ctx)
@@ -591,7 +845,7 @@ static void *map_page(vcpu_guest_context_any_t *ctx, int 
vcpu, guest_word_t virt
     mapped = xc_map_foreign_range(xenctx.xc_handle, xenctx.domid, 
XC_PAGE_SIZE, PROT_READ, mfn);
 
     if (mapped == NULL) {
-        fprintf(stderr, "failed to map page.\n");
+        fprintf(stdout, "\nfailed to map page for %08llx.\n", virt);
         return NULL;
     }
 
@@ -607,6 +861,28 @@ static guest_word_t read_stack_word(guest_word_t *src, int 
width)
     return word;
 }
 
+static guest_word_t read_mem_word(vcpu_guest_context_any_t *ctx, int vcpu, 
guest_word_t virt, int width)
+{
+
+    if ((virt & 7) == 0) {
+        guest_word_t *p = map_page(ctx, vcpu, virt);
+
+        return read_stack_word(p, width);
+    } else {
+        guest_word_t word = 0;
+        char *src, *dst;
+        int i;
+
+        dst = (char*)&word;
+        for(i=0; i<width; i++) {
+            src = map_page(ctx, vcpu, virt+i);
+            *dst++ = *src;
+        }
+        return word;
+    }
+}
+
+
 static void print_stack_word(guest_word_t word, int width)
 {
     if (width == 4)
@@ -615,6 +891,45 @@ static void print_stack_word(guest_word_t word, int width)
         printf(FMT_64B_WORD, word);
 }
 
+static void print_mem(vcpu_guest_context_any_t *ctx, int vcpu, int width, long 
memAddr)
+{
+    guest_word_t instr;
+    guest_word_t instr_start;
+    guest_word_t word;
+    guest_word_t ascii[4];
+    unsigned char *bytep;
+    int i, j, k, l;
+
+    instr_start = memAddr;
+    instr = memAddr;
+    printf("Memory (addr %08llx)\n", instr);
+    for (i=1; i<10; i++) {
+        print_stack_word(instr, width);
+        printf(":");
+        j = 0;
+        while(instr < instr_start + i*16) {
+            word = read_mem_word(ctx, vcpu, instr, width);
+            ascii[j++] = word;
+            printf(" ");
+            print_stack_word(word, width);
+            instr += width;
+        }
+        printf("  ");
+        for (k=0; k < j; k++) {
+            bytep = (unsigned char*)&ascii[k];
+            for (l=0; l < width; l++) {
+                if ((*bytep < 127) && (*bytep >= 32))
+                    printf("%c", *bytep);
+                else
+                    printf(".");
+                bytep++;
+            }
+        }
+        printf("\n");
+    }
+    printf("\n");
+}
+
 static int print_code(vcpu_guest_context_any_t *ctx, int vcpu)
 {
     guest_word_t instr;
@@ -638,29 +953,52 @@ static int print_code(vcpu_guest_context_any_t *ctx, int 
vcpu)
     return 0;
 }
 
-static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width)
+static int print_stack(vcpu_guest_context_any_t *ctx, int vcpu, int width, 
long stkAddr)
 {
-    guest_word_t stack = stack_pointer(ctx);
+    long stkAddrStart = stack_pointer(ctx);
+    guest_word_t stack;
     guest_word_t stack_limit;
     guest_word_t frame;
     guest_word_t word;
-    guest_word_t *p;
-    int i;
 
-    stack_limit = ((stack_pointer(ctx) + XC_PAGE_SIZE)
-                   & ~((guest_word_t) XC_PAGE_SIZE - 1));
+    guest_word_t ascii[4];
+    unsigned char *bytep;
+    int i, j, k, l;
+
+    if (stkAddr && !xenctx.frame_ptrs)
+        stkAddrStart = stkAddr;
+    stack = stkAddrStart;
+    stack_limit = ((stkAddrStart + XC_PAGE_SIZE)
+                   & ~((guest_word_t) XC_PAGE_SIZE - 1)); 
+    if (xenctx.two_pages)
+        stack_limit += XC_PAGE_SIZE;
     printf("\n");
     printf("Stack:\n");
-    for (i=1; i<5 && stack < stack_limit; i++) {
-        while(stack < stack_limit && stack < stack_pointer(ctx) + i*32) {
-            p = map_page(ctx, vcpu, stack);
+    for (i=1; i<10 && stack < stack_limit; i++) {
+        print_stack_word(stack, width);
+        printf(":");
+        j = 0;
+        while(stack < stack_limit && stack < stkAddrStart + i*16) {
+            void *p = map_page(ctx, vcpu, stack);
             if (!p)
                 return -1;
             word = read_stack_word(p, width);
+            ascii[j++] = word;
             printf(" ");
             print_stack_word(word, width);
             stack += width;
         }
+        printf("  ");
+        for (k=0; k < j; k++) {
+            bytep = (unsigned char*)&ascii[k];
+            for (l=0; l < width; l++) {
+                if ((*bytep < 127) && (*bytep >= 32))
+                    printf("%c", *bytep);
+                else
+                    printf(".");
+                bytep++;
+            }
+        }
         printf("\n");
     }
     printf("\n");
@@ -669,13 +1007,17 @@ static int print_stack(vcpu_guest_context_any_t *ctx, 
int vcpu, int width)
         printf("Stack Trace:\n");
     else
         printf("Call Trace:\n");
-    printf("%c [<", xenctx.stack_trace ? '*' : ' ');
-    print_stack_word(instr_pointer(ctx), width);
-    printf(">] ");
+    if (!stkAddr || xenctx.frame_ptrs) {
+        printf("%c [<", xenctx.stack_trace ? '*' : ' ');
+        print_stack_word(instr_pointer(ctx), width);
+        printf(">]");
+        print_symbol(instr_pointer(ctx), 1);
+        printf(" <--\n");
+    }
 
-    print_symbol(instr_pointer(ctx));
-    printf(" <--\n");
     if (xenctx.frame_ptrs) {
+        void *p;
+
         stack = stack_pointer(ctx);
         frame = frame_pointer(ctx);
         while(frame && stack < stack_limit) {
@@ -709,26 +1051,27 @@ static int print_stack(vcpu_guest_context_any_t *ctx, 
int vcpu, int width)
                 if (!p)
                     return -1;
                 word = read_stack_word(p, width);
-                printf("%c [<", xenctx.stack_trace ? '|' : ' ');
+                print_stack_word(stack, width);
+                printf(": %c [<", xenctx.stack_trace ? '|' : ' ');
                 print_stack_word(word, width);
-                printf(">] ");
-                print_symbol(word);
+                printf(">]");
+                print_symbol(word, 1);
                 printf("\n");
                 stack += width;
             }
         }
     } else {
-        stack = stack_pointer(ctx);
+        stack = stkAddrStart;
         while(stack < stack_limit) {
-            p = map_page(ctx, vcpu, stack);
+            void *p = map_page(ctx, vcpu, stack);
             if (!p)
                 return -1;
             word = read_stack_word(p, width);
-            if (is_kernel_text(word)) {
+            if (is_kernel_text(word) >= 2) {
                 printf("  [<");
                 print_stack_word(word, width);
-                printf(">] ");
-                print_symbol(word);
+                printf(">]");
+                print_symbol(word, 2);
                 printf("\n");
             } else if (xenctx.stack_trace) {
                 printf("    ");
@@ -742,9 +1085,12 @@ static int print_stack(vcpu_guest_context_any_t *ctx, int 
vcpu, int width)
 }
 #endif
 
-static void dump_ctx(int vcpu)
+static void dump_ctx(int vcpu, int fcpu, long memAddr, long stkAddr)
 {
     vcpu_guest_context_any_t ctx;
+#if defined(__i386__) || defined(__x86_64__)
+    struct hvm_hw_cpu cpuctx;
+#endif
 
     if (xc_vcpu_getcontext(xenctx.xc_handle, xenctx.domid, vcpu, &ctx) < 0) {
         perror("xc_vcpu_getcontext");
@@ -753,12 +1099,11 @@ static void dump_ctx(int vcpu)
 
 #if defined(__i386__) || defined(__x86_64__)
     {
-        if (xenctx.dominfo.hvm) {
-            struct hvm_hw_cpu cpuctx;
+        if ((fcpu >= 0) && xenctx.dominfo.hvm) {
             xen_capabilities_info_t xen_caps = "";
             if (xc_domain_hvm_getcontext_partial(
                     xenctx.xc_handle, xenctx.domid, HVM_SAVE_CODE(CPU),
-                    vcpu, &cpuctx, sizeof cpuctx) != 0) {
+                    fcpu, &cpuctx, sizeof cpuctx) != 0) {
                 perror("xc_domain_hvm_getcontext_partial");
                 return;
             }
@@ -771,33 +1116,93 @@ static void dump_ctx(int vcpu)
             }
             ctxt_word_size = (strstr(xen_caps, "xen-3.0-x86_64")) ? 8 : 4;
         } else {
-            unsigned int gw;
-            if ( !xc_domain_get_guest_width(xenctx.xc_handle, xenctx.domid, 
&gw) )
-                ctxt_word_size = guest_word_size = gw;
+            struct xen_domctl domctl;
+            memset(&domctl, 0, sizeof domctl);
+            domctl.domain = xenctx.domid;
+            domctl.cmd = XEN_DOMCTL_get_address_size;
+            if (xc_domctl(xenctx.xc_handle, &domctl) == 0)
+                ctxt_word_size = guest_word_size = domctl.u.address_size.size 
/ 8;
         }
     }
 #endif
 
-    print_ctx(&ctx);
+    if (memAddr)
+        print_mem(&ctx, vcpu, guest_word_size, memAddr);
+    else {
+        if (!stkAddr) {
+#if defined(__i386__) || defined(__x86_64__)
+            if ((fcpu >= 0) && xenctx.dominfo.hvm && (ctxt_word_size == 8)) {
+                if (guest_word_size == 4) {
+                    if ((((uint32_t)ctx.x64.user_regs.eip) != cpuctx.rip) ||
+                        (((uint32_t)ctx.x64.user_regs.esp) != cpuctx.rsp) ||
+                        (((uint32_t)ctx.x64.ctrlreg[3]) != cpuctx.cr3)) {
+                        fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx 
vs %llx cr3=%llx vs %llx\n",
+                                (long long)((uint32_t)ctx.x64.user_regs.eip),
+                                (long long)cpuctx.rip,
+                                (long long)((uint32_t)ctx.x64.user_regs.esp),
+                                (long long)cpuctx.rsp,
+                                (long long)((uint32_t)ctx.x64.ctrlreg[3]),
+                                (long long)cpuctx.cr3);
+                        fprintf(stdout, "=============Regs mismatch 
start=============\n");
+                        print_ctx(&ctx);
+                        fprintf(stdout, "=============Regs mismatch 
end=============\n");
+                    }
+                } else {
+                    if ((ctx.x64.user_regs.eip != cpuctx.rip) ||
+                        (ctx.x64.user_regs.esp != cpuctx.rsp) ||
+                        (ctx.x64.ctrlreg[3] != cpuctx.cr3)) {
+                        fprintf(stderr, "Regs mismatch ip=%llx vs %llx sp=%llx 
vs %llx cr3=%llx vs %llx\n",
+                                (long long)ctx.x64.user_regs.eip,
+                                (long long)cpuctx.rip,
+                                (long long)ctx.x64.user_regs.esp,
+                                (long long)cpuctx.rsp,
+                                (long long)ctx.x64.ctrlreg[3],
+                                (long long)cpuctx.cr3);
+                        fprintf(stdout, "=============Regs mismatch 
start=============\n");
+                        print_ctx(&ctx);
+                        fprintf(stdout, "=============Regs mismatch 
end=============\n");
+                    }
+                }
+                print_cpuctx(&cpuctx);
+            }
+            else
+#endif
+                print_ctx(&ctx);
+        }
 #ifndef NO_TRANSLATION
-    if (print_code(&ctx, vcpu))
-        return;
-    if (is_kernel_text(instr_pointer(&ctx)))
-        if (print_stack(&ctx, vcpu, guest_word_size))
-            return;
+        if (!stkAddr) {
+            print_code(&ctx, vcpu);
+            if (is_kernel_text(instr_pointer(&ctx)))
+                if (print_stack(&ctx, vcpu, guest_word_size, stkAddr))
+                    return;
+        } else {
+            if (print_stack(&ctx, vcpu, guest_word_size, stkAddr))
+                return;
+        }
 #endif
+    }
 }
 
-static void dump_all_vcpus(void)
+static void dump_all_vcpus(long memAddr, long stkAddr)
 {
     xc_vcpuinfo_t vinfo;
     int vcpu;
+    int fcpu = 0;
+
     for (vcpu = 0; vcpu <= xenctx.dominfo.max_vcpu_id; vcpu++)
     {
         if ( xc_vcpu_getinfo(xenctx.xc_handle, xenctx.domid, vcpu, &vinfo) )
             continue;
-        if ( vinfo.online )
-            dump_ctx(vcpu);
+        if ( vinfo.online ) {
+            printf("vcpu=%d(%d)\n", vcpu, fcpu);
+            dump_ctx(vcpu, fcpu, memAddr, stkAddr);
+            fcpu++;
+            printf("\n");
+        } else {
+            printf("vcpu=%d offline\n", vcpu);
+            dump_ctx(vcpu, -1, memAddr, stkAddr);
+            printf("\n");
+        }
     }
 }
 
@@ -805,7 +1210,7 @@ static void usage(void)
 {
     printf("usage:\n\n");
 
-    printf("  xenctx [options] <DOMAIN> [VCPU]\n\n");
+    printf("  xenctx [options] <DOMAIN> [VCPU] [fCPU]\n\n");
 
     printf("options:\n");
     printf("  -f, --frame-pointers\n");
@@ -813,31 +1218,41 @@ static void usage(void)
     printf("                    frame pointers.\n");
     printf("  -s SYMTAB, --symbol-table=SYMTAB\n");
     printf("                    read symbol table from SYMTAB.\n");
-    printf("  -S --stack-trace  print a complete stack trace.\n");
+    printf("  -S, --stack-trace print a complete stack trace.\n");
     printf("  -k, --kernel-start\n");
     printf("                    set user/kernel split. (default 
0xc0000000)\n");
-    printf("  -a --all          display more registers\n");
-    printf("  -C --all-vcpus    print info for all vcpus\n");
+    printf("  -a, --all         display more registers\n");
+    printf("  -2, --two-pages   assume the kernel was compiled with 8k 
stacks.\n");
+    printf("  -C, --all-vcpus   print info for all vcpus\n");
+    printf("  -m, --memory      dump memory at.\n");
+    printf("  -d, --dump-as-stack\n");
+    printf("                    dump memory as a stack at.\n");
 }
 
 int main(int argc, char **argv)
 {
     int ch;
     int ret;
-    static const char *sopts = "fs:hak:SC";
+    static const char *sopts = "fs:hak:SCm:d:2";
     static const struct option lopts[] = {
         {"stack-trace", 0, NULL, 'S'},
         {"symbol-table", 1, NULL, 's'},
         {"frame-pointers", 0, NULL, 'f'},
         {"kernel-start", 1, NULL, 'k'},
+        {"two-pages", 0, NULL, '2'},
+        {"memory", 1, NULL, 'm'},
+        {"dump-as-stack", 1, NULL, 'd'},
         {"all", 0, NULL, 'a'},
         {"all-vcpus", 0, NULL, 'C'},
         {"help", 0, NULL, 'h'},
         {0, 0, 0, 0}
     };
     const char *symbol_table = NULL;
+    long memAddr = 0;
+    long stkAddr = 0;
 
     int vcpu = 0;
+    int fcpu = 0;
 
     while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
         switch(ch) {
@@ -853,12 +1268,21 @@ int main(int argc, char **argv)
         case 'a':
             xenctx.disp_all = 1;
             break;
+        case '2':
+            xenctx.two_pages = 1;
+            break;
         case 'C':
             xenctx.all_vcpus = 1;
             break;
         case 'k':
             kernel_start = strtoull(optarg, NULL, 0);
             break;
+        case 'm':
+            memAddr = strtoul(optarg, NULL, 0);
+            break;
+        case 'd':
+            stkAddr = strtoul(optarg, NULL, 0);
+            break;
         case 'h':
             usage();
             exit(-1);
@@ -870,8 +1294,8 @@ int main(int argc, char **argv)
 
     argv += optind; argc -= optind;
 
-    if (argc < 1 || argc > 2) {
-        printf("usage: xenctx [options] <domid> <optional vcpu>\n");
+    if (argc < 1 || argc > 3) {
+        printf("usage: xenctx [options] <domid> <optional vcpu> <optional 
fcpu>\n");
         exit(-1);
     }
 
@@ -881,14 +1305,20 @@ int main(int argc, char **argv)
             exit(-1);
     }
 
-    if (argc == 2)
+    if (argc == 2) {
         vcpu = atoi(argv[1]);
+        fcpu = vcpu;
+    }
+
+    if (argc == 3) {
+        fcpu = atoi(argv[2]);
+    }
 
     if (symbol_table)
         read_symbol_table(symbol_table);
 
     xenctx.xc_handle = xc_interface_open(0,0,0); /* for accessing control 
interface */
-    if (xenctx.xc_handle < 0) {
+    if (!xenctx.xc_handle) {
         perror("xc_interface_open");
         exit(-1);
     }
@@ -909,9 +1339,9 @@ int main(int argc, char **argv)
     }
 
     if (xenctx.all_vcpus)
-        dump_all_vcpus();
+        dump_all_vcpus(memAddr, stkAddr);
     else
-        dump_ctx(vcpu);
+        dump_ctx(vcpu, fcpu, memAddr, stkAddr);
 
     if (xenctx.self_paused) {
         ret = xc_domain_unpause(xenctx.xc_handle, xenctx.domid);
-- 
1.7.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.