[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix xc_ptrace (live debug, not coredump debug) for 32-bit pae.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID ec01850d0ee93a9d7ea5a23b4763050ce5aa2f12 # Parent fc4375af58549bd65ccbff766053ad40fb4cdefd Fix xc_ptrace (live debug, not coredump debug) for 32-bit pae. Clean up interfaces and add simple documentation for using the domU debug interfaces. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r fc4375af5854 -r ec01850d0ee9 Config.mk --- a/Config.mk Mon Sep 19 14:06:49 2005 +++ b/Config.mk Mon Sep 19 15:21:09 2005 @@ -3,7 +3,7 @@ # Currently supported architectures: x86_32, x86_64 XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH) -XEN_TARGET_X86_PAE ?= n +XEN_TARGET_X86_PAE ?= y # Tools to run on system hosting the build HOSTCC = gcc diff -r fc4375af5854 -r ec01850d0ee9 tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Mon Sep 19 14:06:49 2005 +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Mon Sep 19 15:21:09 2005 @@ -37,9 +37,10 @@ #include <errno.h> #include <xenctrl.h> #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */ -long (*myptrace)(enum __ptrace_request, pid_t, long, long); -int (*myxcwait)(int domain, int *status, int options) ; - + +long (*myptrace)(int xc_handle, enum __ptrace_request, u32, long, long); +int (*myxcwait)(int xc_handle, int domain, int *status, int options) ; +static int xc_handle; #define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ #define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ @@ -47,11 +48,7 @@ #define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ #define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */ - - struct inferior_list all_processes; - - static int current_domain; static int expect_signal = 0; static int signal_to_send = 0; @@ -150,7 +147,7 @@ { struct process_info *new_process; current_domain = domain; - if (myptrace (PTRACE_ATTACH, domain, 0, 0) != 0) { + if (myptrace (xc_handle, PTRACE_ATTACH, domain, 0, 0) != 0) { fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain, strerror (errno), errno); fflush (stderr); @@ -173,8 +170,7 @@ { struct thread_info *thread = (struct thread_info *) entry; struct process_info *process = get_thread_process (thread); - myptrace (PTRACE_KILL, pid_of (process), 0, 0); - + myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0); } static void @@ -190,7 +186,7 @@ struct thread_info *thread = (struct thread_info *) entry; struct process_info *process = get_thread_process (thread); - myptrace (PTRACE_DETACH, pid_of (process), 0, 0); + myptrace (xc_handle, PTRACE_DETACH, pid_of (process), 0, 0); } @@ -216,7 +212,7 @@ linux_wait (char *status) { int w; - if (myxcwait(current_domain, &w, 0)) + if (myxcwait(xc_handle, current_domain, &w, 0)) return -1; if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) { @@ -241,7 +237,7 @@ expect_signal = resume_info->sig; for_each_inferior(&all_threads, regcache_invalidate_one); - myptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0); + myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0); } @@ -265,7 +261,7 @@ } buf = malloc (regset->size); - res = myptrace (regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf); + res = myptrace (xc_handle, regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf); if (res < 0) { if (errno == EIO) @@ -317,7 +313,7 @@ buf = malloc (regset->size); regset->fill_function (buf); - res = myptrace (regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf); + res = myptrace (xc_handle, regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf); if (res < 0) { if (errno == EIO) @@ -395,7 +391,7 @@ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { errno = 0; - buffer[i] = myptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); + buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); if (errno) return errno; } @@ -428,13 +424,13 @@ /* Fill start and end extra bytes of buffer with existing memory data. */ - buffer[0] = myptrace (PTRACE_PEEKTEXT, inferior_pid, + buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); if (count > 1) { buffer[count - 1] - = myptrace (PTRACE_PEEKTEXT, inferior_pid, + = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE)), 0); @@ -448,7 +444,7 @@ for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { errno = 0; - myptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]); + myptrace (xc_handle, PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]); if (errno) return errno; } @@ -539,7 +535,7 @@ void initialize_low (void) { - + xc_handle = xc_interface_open(); set_target_ops (&linux_xen_target_ops); set_breakpoint_data (the_low_target.breakpoint, the_low_target.breakpoint_len); diff -r fc4375af5854 -r ec01850d0ee9 tools/libxc/Makefile --- a/tools/libxc/Makefile Mon Sep 19 14:06:49 2005 +++ b/tools/libxc/Makefile Mon Sep 19 15:21:09 2005 @@ -30,8 +30,10 @@ ifeq ($(XEN_TARGET_ARCH),ia64) BUILD_SRCS += xc_ia64_stubs.c else +ifeq ($(XEN_TARGET_ARCH),x86_32) SRCS += xc_ptrace.c SRCS += xc_ptrace_core.c +endif BUILD_SRCS += xc_load_aout9.c BUILD_SRCS += xc_linux_restore.c BUILD_SRCS += xc_linux_save.c diff -r fc4375af5854 -r ec01850d0ee9 tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Mon Sep 19 14:06:49 2005 +++ b/tools/libxc/xc_ptrace.c Mon Sep 19 15:21:09 2005 @@ -1,6 +1,7 @@ #include <sys/ptrace.h> #include <sys/wait.h> #include "xc_private.h" +#include "xg_private.h" #include <time.h> #define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */ @@ -9,14 +10,6 @@ #define PDRSHIFT 22 #define PSL_T 0x00000100 /* trace enable bit */ #define VCPU 0 /* XXX */ - -/* - * long - * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); - */ - - -int waitdomain(int domain, int *status, int options); char * ptrace_names[] = { "PTRACE_TRACEME", @@ -122,8 +115,6 @@ #define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff) /* XXX application state */ - -static int xc_handle; static long nr_pages = 0; unsigned long *page_array = NULL; static int regs_valid[MAX_VIRT_CPUS]; @@ -133,14 +124,60 @@ static inline int paging_enabled(vcpu_guest_context_t *v) { unsigned long cr0 = v->ctrlreg[0]; - return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); } /* --------------------- */ static void * -map_domain_va(unsigned long domid, int cpu, void * guest_va, int perm) +map_domain_va_pae( + int xc_handle, + unsigned long domid, + int cpu, + void *guest_va, + int perm) +{ + unsigned long l2p, l1p, p, va = (unsigned long)guest_va; + u64 *l3, *l2, *l1; + static void *v; + + FETCH_REGS(cpu); + + l3 = xc_map_foreign_range( + xc_handle, domid, PAGE_SIZE, PROT_READ, cr3[cpu] >> PAGE_SHIFT); + if ( l3 == NULL ) + goto error_out; + + l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT; + l2 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, l2p); + if ( l2 == NULL ) + goto error_out; + + l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT; + l1 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, l1p); + if ( l1 == NULL ) + goto error_out; + + p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT; + if ( v != NULL ) + munmap(v, PAGE_SIZE); + v = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, p); + if ( v == NULL ) + goto error_out; + + return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1))); + + error_out: + return NULL; +} + +static void * +map_domain_va( + int xc_handle, + unsigned long domid, + int cpu, + void *guest_va, + int perm) { unsigned long pde, page; unsigned long va = (unsigned long)guest_va; @@ -151,20 +188,35 @@ static unsigned long pde_phys[MAX_VIRT_CPUS]; static unsigned long *pde_virt[MAX_VIRT_CPUS]; static unsigned long page_phys[MAX_VIRT_CPUS]; - static unsigned long *page_virt[MAX_VIRT_CPUS]; - + static unsigned long *page_virt[MAX_VIRT_CPUS]; static int prev_perm[MAX_VIRT_CPUS]; - - if (nr_pages != npgs) { - if (nr_pages > 0) + static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode; + + if ( mode == MODE_UNKNOWN ) + { + xen_capabilities_info_t caps; + (void)xc_version(xc_handle, XENVER_capabilities, caps); + mode = MODE_32; + if ( strstr(caps, "_x86_32p") ) + mode = MODE_PAE; + } + + if ( mode == MODE_PAE ) + return map_domain_va_pae(xc_handle, domid, cpu, guest_va, perm); + + if ( nr_pages != npgs ) + { + if ( nr_pages > 0 ) free(page_array); nr_pages = npgs; - if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) { + if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) + { printf("Could not allocate memory\n"); goto error_out; } - - if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) { + if ( xc_get_pfn_list(xc_handle, domid, + page_array, nr_pages) != nr_pages ) + { printf("Could not get the page frame list\n"); goto error_out; } @@ -172,48 +224,52 @@ FETCH_REGS(cpu); - if (cr3[cpu] != cr3_phys[cpu]) + if ( cr3[cpu] != cr3_phys[cpu] ) { cr3_phys[cpu] = cr3[cpu]; - if (cr3_virt[cpu]) + if ( cr3_virt[cpu] ) munmap(cr3_virt[cpu], PAGE_SIZE); - if ((cr3_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, - PROT_READ, - cr3_phys[cpu] >> PAGE_SHIFT)) == NULL) - goto error_out; - } - if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */ - goto error_out; - if ((ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu])) + cr3_virt[cpu] = xc_map_foreign_range( + xc_handle, domid, PAGE_SIZE, PROT_READ, + cr3_phys[cpu] >> PAGE_SHIFT); + if ( cr3_virt[cpu] == NULL ) + goto error_out; + } + if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 ) + goto error_out; + if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) ) pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT; - if (pde != pde_phys[cpu]) + if ( pde != pde_phys[cpu] ) { pde_phys[cpu] = pde; - if (pde_virt[cpu]) + if ( pde_virt[cpu] ) munmap(pde_virt[cpu], PAGE_SIZE); - if ((pde_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, - PROT_READ, - pde_phys[cpu] >> PAGE_SHIFT)) == NULL) - goto error_out; - } - if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */ - goto error_out; - if (ctxt[cpu].flags & VGCF_VMX_GUEST && paging_enabled(&ctxt[cpu])) + pde_virt[cpu] = xc_map_foreign_range( + xc_handle, domid, PAGE_SIZE, PROT_READ, + pde_phys[cpu] >> PAGE_SHIFT); + if ( pde_virt[cpu] == NULL ) + goto error_out; + } + if ( (page = pde_virt[cpu][vtopti(va)]) == 0 ) + goto error_out; + if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) ) page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT; - if (page != page_phys[cpu] || perm != prev_perm[cpu]) + if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) ) { page_phys[cpu] = page; - if (page_virt[cpu]) + if ( page_virt[cpu] ) munmap(page_virt[cpu], PAGE_SIZE); - if ((page_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, - perm, - page_phys[cpu] >> PAGE_SHIFT)) == NULL) { - printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va)); + page_virt[cpu] = xc_map_foreign_range( + xc_handle, domid, PAGE_SIZE, perm, + page_phys[cpu] >> PAGE_SHIFT); + if ( page_virt[cpu] == NULL ) + { page_phys[cpu] = 0; goto error_out; } prev_perm[cpu] = perm; } + return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); error_out: @@ -221,7 +277,11 @@ } int -xc_waitdomain(int domain, int *status, int options) +xc_waitdomain( + int xc_handle, + int domain, + int *status, + int options) { dom0_op_t op; int retval; @@ -229,38 +289,39 @@ ts.tv_sec = 0; ts.tv_nsec = 10*1000*1000; - if (!xc_handle) - if ((xc_handle = xc_interface_open()) < 0) - { - printf("xc_interface_open failed\n"); - return -1; - } op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = domain; + retry: - retval = do_dom0_op(xc_handle, &op); - if (retval || op.u.getdomaininfo.domain != domain) { + if ( retval || (op.u.getdomaininfo.domain != domain) ) + { printf("getdomaininfo failed\n"); goto done; } *status = op.u.getdomaininfo.flags; - if (options & WNOHANG) + if ( options & WNOHANG ) goto done; - - - if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) { + + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) + { nanosleep(&ts,NULL); goto retry; } + done: return retval; } long -xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata) +xc_ptrace( + int xc_handle, + enum __ptrace_request request, + u32 domid, + long eaddr, + long edata) { dom0_op_t op; int status = 0; @@ -273,44 +334,51 @@ op.interface_version = DOM0_INTERFACE_VERSION; - if (!xc_handle) - if ((xc_handle = xc_interface_open()) < 0) - return -1; -#if 0 - printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data); -#endif - switch (request) { + switch ( request ) + { case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: - if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ)) == NULL) { + guest_va = (unsigned long *)map_domain_va( + xc_handle, domid, cpu, addr, PROT_READ); + if ( guest_va == NULL ) + { status = EFAULT; goto error_out; } - retval = *guest_va; break; + case PTRACE_POKETEXT: case PTRACE_POKEDATA: - if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ|PROT_WRITE)) == NULL) { + guest_va = (unsigned long *)map_domain_va( + xc_handle, domid, cpu, addr, PROT_READ|PROT_WRITE); + if ( guest_va == NULL ) + { status = EFAULT; goto error_out; } - *guest_va = (unsigned long)data; break; + case PTRACE_GETREGS: case PTRACE_GETFPREGS: case PTRACE_GETFPXREGS: FETCH_REGS(cpu); - - if (request == PTRACE_GETREGS) { + if ( request == PTRACE_GETREGS ) + { SET_PT_REGS(pt, ctxt[cpu].user_regs); memcpy(data, &pt, sizeof(struct gdb_regs)); - } else if (request == PTRACE_GETFPREGS) + } + else if (request == PTRACE_GETFPREGS) + { memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt)); + } else /*if (request == PTRACE_GETFPXREGS)*/ + { memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt)); - break; + } + break; + case PTRACE_SETREGS: op.cmd = DOM0_SETDOMAININFO; SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs); @@ -321,17 +389,19 @@ retval = do_dom0_op(xc_handle, &op); if (retval) goto error_out; - - break; + break; + case PTRACE_ATTACH: op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = domid; retval = do_dom0_op(xc_handle, &op); - if (retval || op.u.getdomaininfo.domain != domid) { + if ( retval || (op.u.getdomaininfo.domain != domid) ) + { perror("dom0 op failed"); goto error_out; } - if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) { + if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED ) + { printf("domain currently paused\n"); goto error_out; } @@ -340,6 +410,7 @@ op.u.pausedomain.domain = domid; retval = do_dom0_op(xc_handle, &op); break; + case PTRACE_SINGLESTEP: ctxt[VCPU].user_regs.eflags |= PSL_T; op.cmd = DOM0_SETDOMAININFO; @@ -347,24 +418,29 @@ op.u.setdomaininfo.vcpu = 0; op.u.setdomaininfo.ctxt = &ctxt[cpu]; retval = do_dom0_op(xc_handle, &op); - if (retval) { + if ( retval ) + { perror("dom0 op failed"); goto error_out; } /* FALLTHROUGH */ + case PTRACE_CONT: case PTRACE_DETACH: - if (request != PTRACE_SINGLESTEP) { + if ( request != PTRACE_SINGLESTEP ) + { FETCH_REGS(cpu); /* Clear trace flag */ - if (ctxt[cpu].user_regs.eflags & PSL_T) { + if ( ctxt[cpu].user_regs.eflags & PSL_T ) + { ctxt[cpu].user_regs.eflags &= ~PSL_T; op.cmd = DOM0_SETDOMAININFO; op.u.setdomaininfo.domain = domid; op.u.setdomaininfo.vcpu = cpu; op.u.setdomaininfo.ctxt = &ctxt[cpu]; retval = do_dom0_op(xc_handle, &op); - if (retval) { + if ( retval ) + { perror("dom0 op failed"); goto error_out; } @@ -375,6 +451,7 @@ op.u.unpausedomain.domain = domid > 0 ? domid : -domid; retval = do_dom0_op(xc_handle, &op); break; + case PTRACE_SETFPREGS: case PTRACE_SETFPXREGS: case PTRACE_PEEKUSER: @@ -387,15 +464,18 @@ /* XXX not yet supported */ status = ENOSYS; break; + case PTRACE_TRACEME: printf("PTRACE_TRACEME is an invalid request under Xen\n"); status = EINVAL; } - if (status) { + if ( status ) + { errno = status; retval = -1; } + error_out: return retval; } diff -r fc4375af5854 -r ec01850d0ee9 tools/libxc/xc_ptrace_core.c --- a/tools/libxc/xc_ptrace_core.c Mon Sep 19 14:06:49 2005 +++ b/tools/libxc/xc_ptrace_core.c Mon Sep 19 15:21:09 2005 @@ -166,7 +166,11 @@ } int -xc_waitdomain_core(int domfd, int *status, int options) +xc_waitdomain_core( + int xc_handle, + int domfd, + int *status, + int options) { int retval = -1; int nr_vcpus; @@ -215,7 +219,12 @@ } long -xc_ptrace_core(enum __ptrace_request request, u32 domfd, long eaddr, long edata) +xc_ptrace_core( + int xc_handle, + enum __ptrace_request request, + u32 domfd, + long eaddr, + long edata) { int status = 0; struct gdb_regs pt; diff -r fc4375af5854 -r ec01850d0ee9 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Sep 19 14:06:49 2005 +++ b/tools/libxc/xenctrl.h Mon Sep 19 15:21:09 2005 @@ -101,23 +101,31 @@ } xc_core_header_t; -long xc_ptrace(enum __ptrace_request request, - u32 domid, - long addr, - long data); - -long xc_ptrace_core(enum __ptrace_request request, - u32 domid, - long addr, - long data); - -int xc_waitdomain(int domain, - int *status, - int options); - -int xc_waitdomain_core(int domain, - int *status, - int options); +long xc_ptrace( + int xc_handle, + enum __ptrace_request request, + u32 domid, + long addr, + long data); + +long xc_ptrace_core( + int xc_handle, + enum __ptrace_request request, + u32 domid, + long addr, + long data); + +int xc_waitdomain( + int xc_handle, + int domain, + int *status, + int options); + +int xc_waitdomain_core( + int xc_handle, + int domain, + int *status, + int options); /* * DOMAIN MANAGEMENT FUNCTIONS diff -r fc4375af5854 -r ec01850d0ee9 tools/debugger/gdb/README --- /dev/null Mon Sep 19 14:06:49 2005 +++ b/tools/debugger/gdb/README Mon Sep 19 15:21:09 2005 @@ -0,0 +1,18 @@ + +DomU GDB server for 32-bit (PAE and non-PAE) systems +---------------------------------------------------- + +To build: + 1. Run ./gdbbuild from within this directory. + 2. Copy ./gdb-6.2.1-linux-i386-xen/gdb/gdbserver/gdbserver-xen + to your test machine. + +To debug a running domain: + 1. Use 'xm list' to discover its domain id ($domid). + 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid' + 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU' + 4. From within the gdb client session: + # target remote 127.0.0.1:9999 + # bt + # disass + 5. And so on... _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |