|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |